DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Getting Started

Complete Electronic Calendar Program

The following code can also be found as the calendar_sc program in the UnixWare demos directory /usr/ccs/demos/sc_demos; see the Makefile there for how to build it.

   #include <Args.h>
   #include <Regex.h>
   #include <Time.h>
   #include <String.h>
   #include <Block.h>
   #include <Array_alg.h>
   #include <Map.h>
   #include <Objection.h>
   #include <iostream.h>
   // an Appointment consists of a time and a description
   struct Appointment {
       Time time;
       String desc;
   };
   int operator<(const Appointment& a,
     const Appointment& b) {
       return a.time < b.time;
   }
   // an Appts contains all of the Appointments
   // for a given day, in time order
   class Appts {
       Block<Appointment> appts;
       int nappts;
   public:
       Appts() : nappts(0) {}
       void add(const Appointment& a) {
           appts.reserve(nappts);
           insert(&a[0], &appts[0], &appts[nappts]);
           ++nappts;
       }
       int num() const {
           return nappts;
       }
       const Appointment& operator[](int i) const {
           return appts[i];
       }
   };
   Time midnight_before(const Time& t) {
       return t - t.clock_part();
   }
   // represent Dates by the midnight of that date
   class Date {
       friend ostream& operator<<(ostream& os, Date d);
       friend int operator<(Date a, Date b);
       Time midnight;
   public:
       Date() {}
       Date(Time t) : midnight(midnight_before(t)) {}
   };
   ostream& operator<<(ostream& os, Date d) {
       os << d.midnight.make_string("%x");
       return os;
   }
   int operator<(Date a, Date b) {
       return a.midnight < b.midnight;
   }
   typedef Mapiter<Date,Appts> Calendariter;
   // a Calendar is basically a Map from Dates to Appts
   class Calendar {
       Map<Date,Appts> m;
   public:
       void add(const Appointment& a) {
           Date d(a.time);
           m[d].add(a);
       }
       Calendariter element(Date d) const {
           return m.element(d);
       }
       Calendariter first() const {
           return m.first();
       }
       const Appts& operator[](Date t) const {
           return ((Calendar*)this)->m[t];
       }
   };
   // set by handler(), tells read_appts to skip
   // this input line
   int skip = 0;
   int lineno = 0;
   void show_clock_part(ostream& os, const Time& t) {
       os << t.clock_part().make_string("%X");
   }
   ostream& operator<<(ostream& os,
     const Appointment& a) {
       show_clock_part(os, a.time);
       os << "\t" << a.desc;
       return os;
   }
   // called when a time in the input is malformed
   int handler(const char*) {
       cerr << "Badly formatted date on line "
            << lineno
            << " (appointment ignored)"
            << endl;
       skip = 1;
       return 1;
   }
   // read all the Appointments in the input
   // into the Calendar
   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);
           }
       }
   }
   // show the Appointments in appts matching r
   void show_appts(const Appts& appts,const Regex& r){
       for (int i = 0; i < appts.num(); ++i)
           if (r.match(appts[i].desc))
               cout << "\t" << appts[i] << endl;
   }
   // show today's Appointments matching r
   void show_todays_appts(const Calendar& cal,
     const Regex& r) {
       Time now = make_time("now");
       Date today(now);
       if (!cal.element(today))
           cout << "cal: no appointments for today"
                << endl;
       else {
           cout << "your appointments for " << today
                << ":" << endl;
           show_appts(cal[today], r);
       }
   }
   // search in appts for first Appointment
   // after now matching r
   int search_in_appts(const Appts& appts, Time now,
     const Regex& r) {
       for (int i = 0; i < appts.num(); ++i) {
           const Appointment& a = appts[i];
           if (a.time > now && r.match(a.desc)) {
               cout << "Your next appointment is on "
                    << a.time.make_string("%x:")
                    << endl;
               cout << "\t" << a << endl;
               return 1;
           }
       }
       return 0;
   }
   // starting at i, search for first Appointment
   // after now matching r
   void search_forward_in_cal(Calendariter& i, Time now,
     const Regex& r) {
       for ( ; i; i.next())
           if (search_in_appts(i.curr()->value, now, r))
               return;
   }
   // show first Appointment in Calendar matching r
   void show_next_appt(const Calendar& cal,
     const Regex& r) {
       Time now = make_time("now");
       Date today(now);
       Calendariter i = cal.element(today);
       if (!i) i = cal.first();
       search_forward_in_cal(i, now, r);
   }
   // process the -t and -n queries
   void process_queries(const Calendar& cal, int argc,
     const char*const* argv) {
       Args args(argc, argv, "tnr:");
       Regex r("); // matches everything
       if (args.isset('r'))
           r.assign(args.value('r'),
               Regex::case_insensitive);
       if (args.isset('t'))
           show_todays_appts(cal, r);
       if (args.isset('n'))
           show_next_appt(cal, r);
   }
   // initialize the handler, read in the Calendar,
   // then process the queries
   main(int argc, const char*const* argv) {
       Time::string_objection.appoint(handler);
       Calendar cal;
       read_appts(cal);
       process_queries(cal, argc, argv);
   }

Previous topic: Making the program robust and user-friendly

© 2004 The SCO Group, Inc. All rights reserved.
UnixWare 7 Release 7.1.4 - 27 April 2004