|
|
Some people now use the setjmp(3) and longjmp(3) functions to deal with errors encountered in low-level subroutines. Objections are designed to replace this facility in some instances, but they can be used in conjunction with setjmp(3) and longjmp(3) as well. Users who are not already familiar with setjmp(3) and longjmp(3) will probably find these examples more confusing than helpful, and may want to skip this section.
The following is a template for a program using these functions to perform
the recovery actions for an Objection. The
returner()
routine is used simply to jump to a recovery
portion of the program.
It may also print the library error message as a warning
that recovery is taking place, or do it all silently.
#include <setjmp.h>
static jmp_buf jump_buf;
int returner(const char* s)
{
// may or may not display error message
longjmp(jump_buf, 1);
return 1;
}
main()
{
some_objection.appoint(returner);
if (setjmp(jump_buf)) { // Objection raised
// recovery
}
// code for normal processing
}
In the section,
``Superseding an Objection'',
the Stack class client programmer defined a
function called dec_pnum()
to augment the recovery actions of the Stack library.
The user could have done
this with
setjmp(3)
and
longjmp(3)
in the following way:
#include <Stack.h>
#include <setjmp.h>
#include <iostream.h>
static jmp_buf jump_buf;
int pnum;
Stack st;
int returner(const char*)
{
longjmp(jump_buf, 1);
return 1;
}
void
silly_routine()
{
Stack::overflow.appoint(returner);
int i;
pnum = 0;
if (setjmp(jump_buf)) { // full stack
// recovery action (nothing to do - pnum isn't
// incremented if an overflow occurs)
}
while( cin >> i ) {
st.push(i);
pnum++;
}
while(pnum > 0) {
cout << st.pop() << "\ n";
pnum--;
}
}
The Stack user in the section,
``Superseding an Objection'',
who wants the program to abort, but defines a
cleanup()
function to happen first, could have
done the following with
setjmp(3)
and
longjmp(3):
#include <Stack.h>
#include <setjmp.h>
#include <iostream.h>
static jmp_buf jump_buf;
int pnum;
Stack st;
int returner(const char* msg)
{
cout << msg << "\ n";
longjmp(jump_buf, 1);
return 1;
}
void
silly_routine()
{
Stack::overflow.appoint(returner);
int i;
pnum = 0;
if (setjmp(jump_buf)) { // full stack
while(pnum > 0) {
cout << st.pop() << "\ n";
pnum--;
}
abort();
}
while( cin >> i ) {
st.push(i);
pnum++;
}
}