home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / AZTEC-C / MINDER.ARK / MNDREP.C < prev    next >
C/C++ Source or Header  |  1986-06-19  |  9KB  |  447 lines

  1. /* mndrep
  2.  
  3.     Reporting module of reminder service
  4.  
  5.     1985 Mark E. Mallett
  6. */
  7.  
  8. #include "minder.h"
  9. #include "comnd.h"
  10. #include "setjmp.h"
  11.  
  12.  
  13.  
  14. /* Local definitions */
  15.  
  16.  
  17.  
  18.  
  19. /* External routines */
  20.  
  21.  
  22. /* External data */
  23.  
  24. extern    int    Curdat;            /* Current date */
  25. extern    int    Curtim;            /* Current time */
  26. extern    EVT    *Evthdr;        /* Heads the event list */
  27. extern    CFB    Inicfb;            /* CFB for initialization */
  28. extern    int    Osdate;            /* Can OS give date/time ? */
  29. extern    char    Tmpabf[];        /* Temp atom buffer */
  30. extern    CSB    Tmpcsb;            /* Temp command state block */
  31. extern    jmp_buf    Tmpenv;            /* setjmp environment buffer */
  32.  
  33.  
  34. /* Local routines */
  35.  
  36. extern    int    dspack();        /* disposition: ack */
  37. extern    int    dspnxt();        /* disposition: next */
  38.  
  39.  
  40. /* Local data */
  41.  
  42. static    char    *Mntbl[] = {        /* Names of months */
  43.         "Foo",            /* (month 0) */
  44.         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  45.         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  46.                };
  47.  
  48.  
  49.  
  50.     /* dispositions command keyword and dispatch tables */
  51.  
  52.  
  53. BYTE        *Dspktb[] =    {    /* Command keywords.. */
  54.             "ACKNOWLEDGE",    /* Ack the event, as required */
  55.             "NEXT",        /* Move along to next event */
  56.             NULL        /* Ends with a null pointer */
  57.                 };
  58.  
  59. int        (*Dspdsp[])() = {
  60.             dspack,        /* ACKNOWLEDGE */
  61.             dspnxt,        /* NEXT */
  62.             0        /* Ends with a zero for convenience */
  63.                 };
  64.  
  65.  
  66.  
  67.  
  68.     /* COMND blocks */
  69.  
  70. CFB        Dskcfb = {_CMKEY, _CFHPP|_CFDPP, 0, &Dspktb,
  71.                "Command, ", "NEXT"};
  72. /*
  73.  
  74. *//* report()
  75.  
  76.     The reporting function of the minder program
  77.  
  78. This routine is responsible for showing events which have become active.
  79.  
  80.  
  81. Accepts :
  82.  
  83.  
  84. Returns :
  85.  
  86.  
  87. */
  88.  
  89. report ()
  90.  
  91. {
  92. IND    EVT    *EVTptr;        /* Pointer to event.. */
  93. IND    EVT    *EVTptr1;        /* another pointer */
  94. IND    EVT    *EVTlst;        /* Points to action list */
  95. IND    int    intcnt;            /* Counts interactive events */
  96. IND    int    okflg;            /* OK to proceed flag */
  97.  
  98. if (Osdate)                /* If OS gives it */
  99.     curdtm (&Curdat, &Curtim);        /* Get current date/time */
  100.  
  101. /* Go through and report events with automatic dispositions; also
  102.    make note of events which need interaction */
  103.  
  104. EVTptr = Evthdr;            /* Point to header */
  105. intcnt = 0;                /* Count of events rq action */
  106.  
  107. while (EVTptr)
  108.     {
  109.     EVTptr -> EVT_FLG &= ~(_EFACT|_EFRDA);
  110.                     /* Mark not active, no action */
  111.  
  112.     okflg = chkfor (EVTptr);        /* Init ok-to-look flag */
  113.  
  114.     if (okflg)                /* If ok.. */
  115.     {
  116.     if (chkact ((EVTptr->EVT_DTD - EVTptr->EVT_ADV), EVTptr -> EVT_DTM))
  117.         {
  118.         EVTptr -> EVT_FLG |= _EFACT;    /* Set active */
  119.         if (EVTptr -> EVT_FLG & _EFACK)    /* If ack rqd... */
  120.         intcnt++;        /* Count interactive.. */
  121.         else            /* Not auto mode */
  122.         {
  123.         if (chkact (EVTptr -> EVT_DTD, EVTptr -> EVT_DTM))
  124.             EVTptr -> EVT_FLG |= _EFRDA;
  125.                     /* If action should be taken */
  126.         prtrep (EVTptr);    /* Print report for this alarm */
  127.         }
  128.         }
  129.     }
  130.     EVTptr = EVTptr -> EVT_FLK;        /* Link to next */
  131.     }
  132.  
  133. /* Now process active events, if any, requiring interaction */
  134.  
  135. if (intcnt)
  136.     {
  137.     printf ("\n***Event(s) requiring interaction follow***\n\n");
  138.     EVTptr = Evthdr;            /* Start at beginning again */
  139.     while (EVTptr)
  140.     {
  141.     if ((EVTptr -> EVT_FLG & _EFACT)    /* Marked active ? */
  142.         && (EVTptr -> EVT_FLG & _EFACK))
  143.         {
  144.         prtrep (EVTptr);        /* Print report */
  145.         repdsp (EVTptr);        /* Do disposition */
  146.         }
  147.     EVTptr = EVTptr -> EVT_FLK;
  148.     }
  149.     }
  150.  
  151. /* Now attend to events marked as needing attention.  */
  152.  
  153. EVTlst = NULL;                /* No disposed-of list, yet */
  154. EVTptr = Evthdr;            /* Start at beginning of list */
  155. while (EVTptr)                /* Go through it */
  156.     {
  157.     EVTptr1 = EVTptr;            /* Get working copy */
  158.     EVTptr = EVTptr -> EVT_FLK;        /* Get addr of next one, now */
  159.     if (EVTptr1 -> EVT_FLG & _EFRDA)    /* Take action ? */
  160.     {
  161.     remev (EVTptr1);        /* Remove this from the list */
  162.     switch (EVTptr1 -> EVT_DIS)    /* Process by disposition */
  163.         {
  164.         case _EDDEL:        /* delete? */
  165.         break;            /*  just lose it! */
  166.  
  167.         case _EDSCH:        /* Reschedule ... */
  168.         resched (EVTptr1);    /* Process rescheduling */
  169.                     /* Drop through to keep case */
  170.  
  171.  
  172.         case _EDKEEP:        /* Keep event */
  173.         EVTptr1 -> EVT_FLK = EVTlst;
  174.         EVTlst = EVTptr1;
  175.         break;
  176.  
  177.         default:
  178.         printf ("Bad value in disposition\n");
  179.         }
  180.     }
  181.     }
  182.  
  183. while (EVTlst)                /* Add processed EVTs back in */
  184.     {
  185.     EVTptr = EVTlst;
  186.     EVTlst = EVTlst -> EVT_FLK;
  187.     addev (EVTptr);
  188.     }
  189. }
  190. /*
  191.  
  192. *//* repdsp (EVTptr)
  193.  
  194.         Handles interactive disposition of an event
  195.  
  196. Accepts :
  197.  
  198.         EVTptr        Address of the event block
  199.  
  200. Returns :
  201.  
  202.  
  203. */
  204.  
  205. repdsp (EVTptr)
  206.  
  207. EVT        *EVTptr;        /* Address of event block */
  208.  
  209. {
  210. IND    int        i;        /* Scratch */
  211. IND    BYTE        **kptr;        /* Points to kwd table entry */
  212.  
  213. printf ("\nPlease enter disposition for this event\n");
  214. Tmpcsb.CSB_PMT = "MIND-DISP> ";        /* Set prompt */
  215.  
  216. /* Enter command loop */
  217.  
  218. while (TRUE)                /* Forever */
  219.     {
  220.     if (COMND (&Tmpcsb, &Inicfb) != _CROK) /* eh? */
  221.     {
  222.     printf ("Fatal error initializing COMND\n");
  223.     exit();
  224.     }
  225.  
  226.     setjmp (Tmpenv);            /* Mark here for reparse */
  227.  
  228.     if (COMNDi (&Tmpcsb, &Dskcfb) != _CROK)    /* Collect keyword */
  229.     continue;
  230.  
  231.     kptr = (char **) (Tmpcsb.CSB_RVL._ADR);
  232.     i = kptr - (&Dspktb[0]);        /* Get keyword index */
  233.     if ((*Dspdsp[i])(EVTptr))        /* Process command */
  234.     break;                /* Exit command loop on done */
  235.     }
  236. }
  237. /*
  238.  
  239. *//* dspack (EVTptr)
  240.  
  241.     Processes the ACKNOWLEDGE disposition-command.
  242.  
  243.  
  244. Accepts :
  245.  
  246.     EVTptr        Address of event block
  247.  
  248.  
  249. Returns :
  250.  
  251.  
  252. */
  253.  
  254. dspack (EVTptr)
  255.  
  256. EVT        *EVTptr;        /* Addr of EVT block */
  257.  
  258. {
  259. if (!noise (&Tmpcsb, "event"))        /* Give guide words */
  260.     return;
  261.  
  262. if (!confrm (&Tmpcsb))            /* Confirm the command */
  263.     return;
  264.  
  265. EVTptr -> EVT_FLG |= _EFRDA;        /* Do the action. */
  266.  
  267. return (TRUE);
  268. }
  269. /*
  270.  
  271. *//* dspnxt (EVTptr)
  272.  
  273.     Processes the NEXT disposition-command.
  274.  
  275.  
  276. Accepts :
  277.  
  278.     EVTptr        Address of event block
  279.  
  280.  
  281. Returns :
  282.  
  283.  
  284. */
  285.  
  286. dspnxt (EVTptr)
  287.  
  288. EVT        *EVTptr;        /* Addr of EVT block */
  289.  
  290. {
  291. if (!noise (&Tmpcsb, "event"))         /* Give guide words */
  292.     return;
  293.  
  294. if (!confrm (&Tmpcsb))            /* Confirm the command */
  295.     return;
  296.  
  297. return (TRUE);
  298. }
  299. /*
  300.  
  301. *//* prtrep (EVTptr)
  302.  
  303.     Print report for an event
  304.  
  305.  
  306. Accepts :
  307.  
  308.     EVTptr        Address of event block
  309.  
  310.  
  311. Returns :
  312.  
  313.  
  314. */
  315.  
  316. prtrep (EVTptr)
  317.  
  318. EVT        *EVTptr;        /* Addr of event block */
  319.  
  320. {
  321. IND    int    i;            /* Scratch */
  322. IND    int    m,d,y,hh,mm;        /* Date/time components */
  323. IND    int    nl;            /* Newline flag */
  324.  
  325. cvided (EVTptr -> EVT_DTD, EVTptr -> EVT_DTM, &m, &d, &y, &hh, &mm);
  326.  
  327. nl = FALSE;
  328. if (EVTptr -> EVT_FRM)            /* If any from */
  329.     {
  330.     printf ("From: %-10s  ", EVTptr -> EVT_FRM);
  331.     nl = TRUE;
  332.     }
  333. if (!chkact (EVTptr -> EVT_DTD, EVTptr -> EVT_DTM))
  334.     if (chkact (EVTptr->EVT_DTD - EVTptr->EVT_ADV, EVTptr->EVT_DTM))
  335.     {
  336.     printf ("         *** Advance Notice ***");
  337.     nl = TRUE;
  338.     }
  339.  
  340. if (nl)
  341.     printf ("\n");
  342.  
  343. printf ("   *** \"%s\"", EVTptr -> EVT_NAM);
  344. i = 20 - strlen(EVTptr -> EVT_NAM);
  345. while (i-- > 0)
  346.     putchar (' ');
  347.  
  348. printf ("%s %2d, %04d  %02d:%02d", Mntbl[m], d, y, hh, mm);
  349. if (strlen (EVTptr -> EVT_MSG) >= 23)
  350.     printf ("\n");
  351. printf ("    >>%s<<\n\n", EVTptr -> EVT_MSG);
  352. }
  353. /*
  354.  
  355. *//* chkact (chkdat, chktim)
  356.  
  357.     Check a date and time for activation
  358.  
  359.  
  360. Accepts :
  361.  
  362.     chkdat        Date to check for active
  363.     chktim        Time to check for active
  364.  
  365.  
  366. Returns :
  367.  
  368.     <value>        TRUE if chkdat/chktim is le Curdat/Curtim
  369.             FALSE if not
  370.  
  371.  
  372. */
  373.  
  374. chkact (chkdat, chktim)
  375.  
  376. int        chkdat;            /* date to check */
  377. int        chktim;            /* time to check */
  378.  
  379. {
  380. if (chkdat < Curdat)            /* If lt. */
  381.     return (TRUE);            /*  then definitely active */
  382. if (chkdat == Curdat)            /* If same */
  383.     if (chktim <= Curtim)        /* If times lt */
  384.     return (TRUE);            /*  then true */
  385.  
  386. return (FALSE);                /* Not true */
  387. }
  388. /*
  389.  
  390. *//* resched (EVTptr)
  391.  
  392.     Reschedule an event based on its information
  393.  
  394.  
  395. Accepts :
  396.  
  397.     EVTptr        Address of EVT
  398.  
  399.  
  400. Returns :
  401.  
  402.     Event data modified for rescheduling.
  403.  
  404.  
  405. */
  406.  
  407. resched (EVTptr)
  408.  
  409. EVT        *EVTptr;        /* Addr of EVT */
  410.  
  411. {
  412. IND    int    id, it, m, d, y, hh, mm; /* Date/time values */
  413.  
  414. id = EVTptr -> EVT_DTD;            /* Pickup date/time */
  415. it = EVTptr -> EVT_DTM;
  416.  
  417. cvided (id, it, &m, &d, &y, &hh, &mm); /* Get components */
  418. switch (EVTptr -> EVT_RSU)
  419.     {                    /* Reschedule by units */
  420.     case 0:                /* Days */
  421.     id += EVTptr -> EVT_RSV;    /* Just add in the days */
  422.     break;                /* Done. */
  423.  
  424.     case 1:                /* Weeks */
  425.     id += EVTptr -> EVT_RSV*7;
  426.     break;
  427.  
  428.     case 2:                /* Months */
  429.     m += EVTptr -> EVT_RSV;
  430.     while (m > 12)
  431.         {
  432.         y++;
  433.         m -= 12;
  434.         }
  435.     cvedid (&id, &it, m, d, y, mm, hh);
  436.     break;
  437.  
  438.     case 3:                /* Years */
  439.     y += EVTptr -> EVT_RSV;
  440.     cvedid (&id, &it, m, d, y, mm, hh);
  441.     break;
  442.     }
  443.  
  444. EVTptr -> EVT_DTD = id;            /* Store date */
  445. EVTptr -> EVT_DTM = it;            /* And time. */
  446. }
  447.