|
|
The program developed so far works for correct inputs, but is not very robust. For example, if the TZ environment variable is not set (see Internal errors) the program will terminate with the message:
TZ environment variable not set!which is likely to perplex a busy executive who has no idea what an environment variable is, let alone what to do about the fact that one is not set! Similarly, if the ASCII file contains badly formatted times, then the part of the program that reads data into the Calendar may also fail mysteriously:
void read_appts(Calendar& cal) { // ... // The following will raise Time::string_objection // if buf contains a bad time string. The default // action, according to the manpage, is to abort // with an error message. a.time = make_time(buf); // ... }To make the program robust against such errors, we will use the facilities of the Objection(C++) component.
The first thing we do is define a function (called a handler) to be called by make_time() when it encounters a bad string:
#include <Objection.h> int skip = 0; // skip input line int lineno = 0; int handler(const char* buf) { cerr << "Badly formatted date on line " << lineno << " (appointment ignored)" << endl; skip = 1; return 1; }
Next, read_appts() is modified to skip the remaining input on the current line when the above handler is raised:
void read_appts(Calendar& cal) { char buf[100]; while (cin.getline(buf, 100, '\t')) { ++lineno; Appointment a; a.time = make_time(buf); // make_time() may raise handler() cin.getline(buf, 100, '\n'); if (skip) skip = 0; else { a.desc = buf; cal.add(a); } } }
Finally, the main program appoints the handler to the appropriate Objection:
main(int argc,const char*const* argv) { Time::string_objection.appoint(handler); // ... }
The TZ problem described above could be handled similarly. This completes the electronic appointment calendar. The complete text of calendar.c can be found below.