Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Handling error/status messages by interface to C++ programs

Reply
Thread Tools

Handling error/status messages by interface to C++ programs

 
 
Leslaw Bieniasz
Guest
Posts: n/a
 
      09-08-2009


Cracow, 8.09.2009

Hi,

I am writing a C++ program that does a job similar to a typical compiler:
It reads some source text, analyses it for errors, and performs some
conversion to a target format. I have a problem how to design the
communication between my code and user interfaces, to achieve
the following goals:

1) The code should be able to run either in the console mode, or
within a Windows GUI, but the kernel part of the code should be designed
in such a way so that it is independent on the interface.

2) The code should make available to the program user a list of
errors detected during its operation, with some additional information
about the location of the errors in the source text analysed.
Also, the user should be informed about the current status of
the program operation, by suitable messages.

3) The operation of the code is rather fast, so that it seems that
it is not necessary to run it in a separate thread (but who knows
what will be needed in the future?)

Owing to these features, I notice an analogy of my code to some of the
commercial C++ compilers, such as, for example, Borland compilers,
like C++ Builder. They can also run either in the console or Windows mode,
and send appropriate error and status messages. In the case of the Windows
GUI, the Builder displays status messages in a small Dialog-type window,
opened for the time of the compilation, and error messages are
added to a ListBox-type window. Later on, a user can click on any
of the error messages, which causes that a part of the
source text, containing the particular error, is displayed in another window.
In the case of the console mode, the messages are sent to the console.

I would like to have a similar behaviour in my code, so that if anybody
knows how such things are designed, please help me.

In the case of console programs, the easiest thing to do is to send
various messages to an output stream, during the program operation, for example:

cout << "Error detected: missing right parenthesis".

However, this solution does not seem the best if the same code is to run
also under graphical GUI, because there is no direct way to connect the output
stream to the various windows. It therefore seems that the interface-independent
kernel of my code should not send the messages but only keep a list of them somewhere.
The interface would later display the messages in this or other way. But this solution
is also not perfect, because then there would be a time shift between the actual
events and the information about the events, revealed to the user.

A related issue is how the code should behave internally when it detects
an error. Is this a good idea to use exceptions in such cases? If yes,
which part of the code (or interface?) should be responsible for
catching the exceptions?

I have to say I have already asked many programmers over the years,
about the above problems, and I have never obtained any real help.
This seems strange, as I can imagine these problems frequently arise
in the design of any serious large applications.

I would appreciate very much your help, ideally together with
some examples, using OOP and C++.

Leslaw
 
Reply With Quote
 
 
 
 
Francesco
Guest
Posts: n/a
 
      09-08-2009
On Sep 8, 12:07*pm, Leslaw Bieniasz <(E-Mail Removed)> wrote:
> * * * * * * * * * * * * * * * * * * * * Cracow, 8.09.2009
>
> Hi,
>
> I am writing a C++ program that does a job similar to a typical compiler:
> It reads some source text, analyses it for errors, and performs some
> conversion to a target format. I have a problem how to design the
> communication between my code and user interfaces, to achieve
> the following goals:
>
> 1) The code should be able to run either in the console mode, or
> within a Windows GUI, but the kernel part of the code should be designed
> in such a way so that it is independent on the interface.
>
> 2) The code should make available to the program user a list of
> errors detected during its operation, with some additional information
> about the location of the errors in the source text analysed.
> Also, the user should be informed about the current status of
> the program operation, by suitable messages.


Hi Leslaw,
you can use the same technique used by GCC, that is, the compiler
itself is a console program that is called by passing the source
filename and the options to it, then it performs a single run dropping
all messages to the standard output stream.

When you have to call it from a GUI interface, simply intercept its
output and display it on your interface.

Actually, that compiler is not interactive, and I believe it is the
best technique - after all, once it intercepts a problem in the source
you have either to change the source or change its parameters, and
then the best solution is to restart it from scratch with the new
input.

> 3) The operation of the code is rather fast, so that it seems that
> it is not necessary to run it in a separate thread (but who knows
> what will be needed in the future?)
>
> Owing to these features, I notice an analogy of my code to some of the
> commercial C++ compilers, such as, for example, Borland compilers,
> like C++ Builder. They can also run either in the console or Windows mode,
> and send appropriate error and status messages. In the case of the Windows
> GUI, the Builder displays status messages in a small Dialog-type window,
> opened for the time of the compilation, and error messages are
> added to a ListBox-type window. Later on, a user can click on any
> of the error messages, which causes that a part of the
> source text, containing the particular error, is displayed in another window.


Your GUI can simply display the messages in a clickable list and
"decode" each error message - which should report the filename and the
line of code where the error happened.

Hope this small help comes useful somehow.

Have good coding, your project is really interesting and would be nice
to read here about your progresses.

Best regards,
Francesco
 
Reply With Quote
 
 
 
 
Francesco
Guest
Posts: n/a
 
      09-08-2009
On Sep 8, 12:07*pm, Leslaw Bieniasz <(E-Mail Removed)> wrote:
> * * * * * * * * * * * * * * * * * * * * Cracow, 8.09.2009
> In the case of console programs, the easiest thing to do is to send
> various messages to an output stream, during the program operation, for example:
>
> cout << "Error detected: missing right parenthesis".
>
> However, this solution does not seem the best if the same code is to run
> also under graphical GUI, because there is no direct way to connect the output
> stream to the various windows.


I think I have overlooked this point. Are you sure that you cannot
intercept the output? Any operating system should be able to redirect
the output.

For example, under Windows the ">" character, appended to a program
call, redirects the output to anything on the right side of that
character. For example...

c:\compiler.exe sourcefilename -option > messenger.exe

....redirects the output of compiler.exe to an hypothetical small
messenger.exe utility whose unique task is to transform the output
into a list which can be polled at runtime via the Windows API.

Another solution, really simple, would be to dump the output to a file
and then read it from your interface:
c:\compiler.exe sourcefilename -option > dump.txt

Hope this helps, once more.
Just a couple of pointers that you will be surely able to dig.

Kind regards,
Francesco
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      09-08-2009
Francesco wrote:
> On Sep 8, 12:07 pm, Leslaw Bieniasz <(E-Mail Removed)> wrote:
>> Cracow, 8.09.2009
>> In the case of console programs, the easiest thing to do is to send
>> various messages to an output stream, during the program operation, for example:
>>
>> cout << "Error detected: missing right parenthesis".
>>
>> However, this solution does not seem the best if the same code is to run
>> also under graphical GUI, because there is no direct way to connect the output
>> stream to the various windows.

>
> I think I have overlooked this point. Are you sure that you cannot
> intercept the output? Any operating system should be able to redirect
> the output.
>
> For example, under Windows the ">" character, appended to a program
> call, redirects the output to anything on the right side of that
> character. For example...
>
> c:\compiler.exe sourcefilename -option > messenger.exe


I believe you've confused two separate elements of the MS-DOS interface.
The '>' redirects the output of the left operand (executable) to the
file specified as the right operand, while '|' ("pipe") redirects the
output and makes it standard *input* of the executable on the right.

> ...redirects the output of compiler.exe to an hypothetical small
> messenger.exe utility whose unique task is to transform the output
> into a list which can be polled at runtime via the Windows API.


I think the command should actually be

c:\compiler.exe sourcefilename -option | messenger.exe

> Another solution, really simple, would be to dump the output to a file
> and then read it from your interface:
> c:\compiler.exe sourcefilename -option > dump.txt


Yes, AFA redirection to a file is concerned.

> [..]


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Francesco
Guest
Posts: n/a
 
      09-08-2009


Victor Bazarov ha scritto:
> Francesco wrote:
> > On Sep 8, 12:07 pm, Leslaw Bieniasz <(E-Mail Removed)> wrote:
> >> Cracow, 8.09.2009
> >> In the case of console programs, the easiest thing to do is to send
> >> various messages to an output stream, during the program operation, for example:
> >>
> >> cout << "Error detected: missing right parenthesis".
> >>
> >> However, this solution does not seem the best if the same code is to run
> >> also under graphical GUI, because there is no direct way to connect the output
> >> stream to the various windows.

> >
> > I think I have overlooked this point. Are you sure that you cannot
> > intercept the output? Any operating system should be able to redirect
> > the output.
> >
> > For example, under Windows the ">" character, appended to a program
> > call, redirects the output to anything on the right side of that
> > character. For example...
> >
> > c:\compiler.exe sourcefilename -option > messenger.exe

>
> I believe you've confused two separate elements of the MS-DOS interface.
> The '>' redirects the output of the left operand (executable) to the
> file specified as the right operand, while '|' ("pipe") redirects the
> output and makes it standard *input* of the executable on the right.
>
> > ...redirects the output of compiler.exe to an hypothetical small
> > messenger.exe utility whose unique task is to transform the output
> > into a list which can be polled at runtime via the Windows API.

>
> I think the command should actually be
>
> c:\compiler.exe sourcefilename -option | messenger.exe


Oh, yes, I mistaken it, thank you for the correction.

In any case, that was just a pointer about a possible solution.

Francesco
 
Reply With Quote
 
Rüdiger Ranft
Guest
Posts: n/a
 
      09-08-2009
Leslaw Bieniasz schrieb:

> Hi,
>
> I am writing a C++ program that does a job similar to a typical compiler:
> It reads some source text, analyses it for errors, and performs some
> conversion to a target format. I have a problem how to design the
> communication between my code and user interfaces, to achieve
> the following goals:
>
> 1) The code should be able to run either in the console mode, or
> within a Windows GUI, but the kernel part of the code should be designed
> in such a way so that it is independent on the interface.


You have (at least) two different solutions for this problem. You can
either create a console mode program, or put the compiler stuff into a
library. I choose to create a library such cases, with a small stub
executable for the console mode which calls the functions from the
library. The main advantage of this approach is that in the GUI the
errors from the compilation does not to be parsed, but can come from a
well specified interface. Also I use the strategy pattern[1] to notify
the GUI about the progress.

This is the outline of such a system:

class Progress
{
public:
// The function which the compiler calls when something changed
virtual void progress(int state) = 0;
// Errors callback
virtual void error(int line, std::string message) = 0;

// Always add a destructor to classes with virtual functions
~Progress();
};

class GuiProgress: public Progress
{
public:
virtual void progress( int state )
{
m_progressBar.setState( state );
}

virtual void error(int line, std::string message)
{
showDialog( message );
}
};

class GuiProgress: public Progress
{
public:
virtual void progress( int state )
{
std::cout << "progress: " << state / 100.0 << '%' << std::endl;
}

virtual void error(int line, std::string message)
{
std::cerr << "Error on line " << line << ": " << message << '\n';
}
};

class Compiler
{
public:
void compile( std::istream& input, Progress& pg );
};

bye
Rudi

[1] http://en.wikipedia.org/wiki/Strategy_pattern
 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      09-08-2009
On Tue, 8 Sep 2009 03:42:28 -0700 (PDT), Francesco <(E-Mail Removed)> wrote:
> On Sep 8, 12:07*pm, Leslaw Bieniasz <(E-Mail Removed)> wrote:
>> * * * * * * * * * * * * * * * * * * * * Cracow, 8.09.2009


Mildly offtopic, but I have to mention it anyway. I thought I had seen
all theoretically possible date formats already, but "8.09.2009" is
new to me. "8.9.2009" yes, but not a form with padded month numbers.

>> I am writing a C++ program that does a job similar to a typical compiler:
>> It reads some source text, analyses it for errors, and performs some
>> conversion to a target format. I have a problem how to design the
>> communication between my code and user interfaces, to achieve
>> the following goals:
>>
>> 1) The code should be able to run either in the console mode, or
>> within a Windows GUI, but the kernel part of the code should be designed
>> in such a way so that it is independent on the interface.
>>
>> 2) The code should make available to the program user a list of
>> errors detected during its operation, with some additional information
>> about the location of the errors in the source text analysed.
>> Also, the user should be informed about the current status of
>> the program operation, by suitable messages.

>
> Hi Leslaw,
> you can use the same technique used by GCC, that is, the compiler
> itself is a console program that is called by passing the source
> filename and the options to it, then it performs a single run dropping
> all messages to the standard output stream.
>
> When you have to call it from a GUI interface, simply intercept its
> output and display it on your interface.
>
> Actually, that compiler is not interactive, and I believe it is the
> best technique - after all, once it intercepts a problem in the source
> you have either to change the source or change its parameters, and
> then the best solution is to restart it from scratch with the new
> input.


Yes. All this is how compilers and compiler-like programs (not just
GCC) have worked for the past forty years.

Actually it would surprise me if even Windows compilers were
implemented in any other way. It has too many benefits. (One is that
you can implement the compiler in portable C++.)

>> 3) The operation of the code is rather fast, so that it seems that
>> it is not necessary to run it in a separate thread (but who knows
>> what will be needed in the future?)


This is one of the many things that the solution above makes non-issues.
It's even trivial to make the GUI thing call a standard make tool instead
of your "compiler", so the user can e.g. build a dozen things in
parallel to speed things up on an SMP machine. No code needed.

>> Owing to these features, I notice an analogy of my code to some of the
>> commercial C++ compilers, such as, for example, Borland compilers,
>> like C++ Builder. They can also run either in the console or Windows mode,
>> and send appropriate error and status messages. In the case of the Windows
>> GUI, the Builder displays status messages in a small Dialog-type window,
>> opened for the time of the compilation, and error messages are
>> added to a ListBox-type window. Later on, a user can click on any
>> of the error messages, which causes that a part of the
>> source text, containing the particular error, is displayed in another window.

>
> Your GUI can simply display the messages in a clickable list and
> "decode" each error message - which should report the filename and the
> line of code where the error happened.


And if those error messages look even /remotely/ like those from other
"compilers", I bet existing GUIs know what to do with them. I know
Emacs (M-x compile) does.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      09-08-2009
On Sep 8, 2:18 pm, Victor Bazarov <(E-Mail Removed)> wrote:
> Francesco wrote:
> > On Sep 8, 12:07 pm, Leslaw Bieniasz <(E-Mail Removed)> wrote:
> >> Cracow, 8.09.2009
> >> In the case of console programs, the easiest thing to do is
> >> to send various messages to an output stream, during the
> >> program operation, for example:


> >> cout << "Error detected: missing right parenthesis".


> >> However, this solution does not seem the best if the same
> >> code is to run also under graphical GUI, because there is
> >> no direct way to connect the output stream to the various
> >> windows.


Just for the record, I've never seen a compiler which had a
graphical interface.

> > I think I have overlooked this point. Are you sure that you
> > cannot intercept the output? Any operating system should be
> > able to redirect the output.


> > For example, under Windows the ">" character, appended to a
> > program call, redirects the output to anything on the right
> > side of that character. For example...


> > c:\compiler.exe sourcefilename -option > messenger.exe


> I believe you've confused two separate elements of the MS-DOS
> interface. The '>' redirects the output of the left operand
> (executable) to the file specified as the right operand, while
> '|' ("pipe") redirects the output and makes it standard
> *input* of the executable on the right.


The usual solution is for the GUI (the IDE) to use something
like system() to invoke the compiler, redirecting the output to
a temporary file which it then reads and exploits, e.g.:

system( "c:\compiler.exe sourcefilename > c:\temp
\compiler.out" ) ;

> > ...redirects the output of compiler.exe to an hypothetical
> > small messenger.exe utility whose unique task is to
> > transform the output into a list which can be polled at
> > runtime via the Windows API.


> I think the command should actually be


> c:\compiler.exe sourcefilename -option | messenger.exe


I doubt the that messenger.exe is even necessary; typically, the
IDE will start the compiler in a separate thread, which then
waits for it to finish using something like the wait() system
call under Unix. It then reads the compiler output files.

--
James Kanze
 
Reply With Quote
 
Joshua Maurice
Guest
Posts: n/a
 
      09-08-2009
On Sep 8, 2:57*pm, James Kanze <(E-Mail Removed)> wrote:
> On Sep 8, 2:18 pm, Victor Bazarov <(E-Mail Removed)> wrote:
> > Francesco wrote:
> > > ...redirects the output of compiler.exe to an hypothetical
> > > small messenger.exe utility whose unique task is to
> > > transform the output into a list which can be polled at
> > > runtime via the Windows API.

> > I think the command should actually be
> > * * c:\compiler.exe sourcefilename -option | messenger.exe

>
> I doubt the that messenger.exe is even necessary; typically, the
> IDE will start the compiler in a separate thread, which then
> waits for it to finish using something like the wait() system
> call under Unix. *It then reads the compiler output files.


Slightly off-topic from thread's topic: Do people actually do such
complex and convoluted things like make a messenger program which uses
windows specific things and then poll from it? The first thing I do is
whip out my portable wrappers which work on posix and windows for
threading and processes. Ex:

ProcessBuilder pb = ProcessBuilder()
.exe("compiler.exe")
.arg("sourcefilename")
.arg("-option")
.redirectErrToOut()
.pipeOut();
auto_ptr<Process> p(pb.spawn());
auto_ptr<ProcessIstream> childsOut(
p->releaseReadEndFromChildsStdout());
for (string line; getline(*childsOut, line); )
cout << line << endl;

Boost is good too, for those shops which actually use it.
 
Reply With Quote
 
Jerry Coffin
Guest
Posts: n/a
 
      09-10-2009
In article <(E-Mail Removed)-kr.edu.pl>,
http://www.velocityreviews.com/forums/(E-Mail Removed) says...

[ ... ]

> 1) The code should be able to run either in the console mode, or
> within a Windows GUI, but the kernel part of the code should be designed
> in such a way so that it is independent on the interface.


That's certainly good so far.

> 2) The code should make available to the program user a list of
> errors detected during its operation, with some additional information
> about the location of the errors in the source text analysed.
> Also, the user should be informed about the current status of
> the program operation, by suitable messages.


Likewise, perfectly reasonable.

> 3) The operation of the code is rather fast, so that it seems that
> it is not necessary to run it in a separate thread (but who knows
> what will be needed in the future?)


Using multiple threads may make sense, even if it's not really
_necessary_. This does seem to contradict your second point though:
if the process takes long enough to run that the user will ever see
any message about its current status other than "finished", it's
taking long enough that it probably justifies running in a separate
thread (or process).

[ ... ]

> In the case of console programs, the easiest thing to do is to send
> various messages to an output stream, during the program operation, for example:
>
> cout << "Error detected: missing right parenthesis".
>
> However, this solution does not seem the best if the same code is to run
> also under graphical GUI, because there is no direct way to connect the output
> stream to the various windows.


Yes and no. If you use cerr directly, that's true. OTOH, it's fairly
easy to use an object of _some_ sort that can write to a stream or a
window, depending on what you prefer. For example, years ago I wrote
a program that had an ABC named 'display', with two descendants name
text_display and window_display. You could produce output via either
one (or, theoretically both). IIRC, if you instantiated more than one
window_display, each would create its own list-box to hold output. I
never really put that to much use, but in something like an IDE, I
could see using it to put output from different tools into different
windows.

> It therefore seems that the interface-independent
> kernel of my code should not send the messages but only keep a list of them somewhere.
> The interface would later display the messages in this or other way. But this solution
> is also not perfect, because then there would be a time shift between the actual
> events and the information about the events, revealed to the user.


There's always going to be at least some delay between detecting an
error and displaying the associated message -- but as long as the
delay is less than 100 ms or so, the user won't be able to see the
difference. Even 200 ms still looks very close. In any case, a small
delay is rarely a huge problem. At very best, a typical screen is
only updated about 60 times a second, so trying to update faster than
that accomplishes nothing.

It's perfectly reasonable to queue a message in one thread, and have
a different thread update the display on the screen in response to
that message.

> A related issue is how the code should behave internally when it detects
> an error. Is this a good idea to use exceptions in such cases? If yes,
> which part of the code (or interface?) should be responsible for
> catching the exceptions?


Assuming your code really is a lot like a compiler, I'd say the
answer is probably no. An exception is for dealing with something
unexpected -- but compilers normally deal with human input, and
finding an error in human input is _never_ unexpected. In reality,
rather the opposite is true -- the _usual_ situation is for a
compiler to find at least one error, and issue a message about it. In
most cases, such an error means no other output is created, so the
majority of the time, the ONLY output from a compiler is error
messages. Once the compiler runs successfully and generates code as
output, there's not a great deal of reason to run it on that code
again (except for things like installing a package from source code).

--
Later,
Jerry.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
There are no more messages on this topic. All messages in this topic may have expired or been deleted Coach 02 Computer Support 1 03-12-2007 03:44 PM
absence of router advertisment messages in reponse to roiuter solicitation messages sonia sainani Software 0 10-20-2006 09:20 AM
Programs take a long time to launch from A.Programs Me MCSE 9 01-20-2005 04:05 PM
i sent 2 messages about double messages monique Computer Support 0 11-27-2004 07:18 PM
will all these messages cause a problem . I am a new subscriber and my computer is downloading 100,000 messages. Will this cause any kind of a problem with my ability to store other items?? Camille White Camille White Computer Support 9 11-08-2004 01:13 AM



Advertisments