home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / beehive / utilitys / chx8012b.arc / CHECKD.C < prev    next >
Text File  |  1990-07-21  |  23KB  |  716 lines

  1. /*  checkd.c -- 5th source file for check register program                   */
  2.  
  3. /*  copyright (c) 1986 by Jim Woolley and WoolleyWare, San Jose, CA          */
  4.  
  5. /*  vers. 1.0, 12/85 thru 5/86
  6.  *
  7.  *  vers. 1.2, 7/86
  8.  *  save():  added display "Saving ... "
  9.  *  reconcile() & abreviations(): added doscroll() with ^C and ^R scrolling
  10.  *      and revised keyboard look ahead for scrolling
  11.  *  reconcile(): added one space to end of total bars (---------  ----...)
  12.  *  abreviations(): cleared text from rest of line when scrolling
  13.  *  reorder(): added display "Sorting ... "
  14.  *  integrated CLEARS using #ifdef
  15.  */
  16.  
  17. /*  this file contains:
  18.  *      delete()
  19.  *      undo()
  20.  *      insert()
  21.  *      ctrlqork()
  22.  *      erase( c)
  23.  *      abandon()
  24.  *      save()
  25.  *      reconcile()
  26.  *      abreviations()
  27.  *      char doscroll( c, scroll, i, firstline, lastline, maxline, header)
  28.  *      print()
  29.  *      order()
  30.  *      reorder( f)
  31.  *      datemax( md, d)
  32.  */
  33.  
  34. #include    "a:checks.h"
  35.  
  36. delete()                                /*  delete Entry[ Recno]             */
  37. {
  38.     int r;
  39.  
  40.     if ( Recno > Maxentry)
  41.         return;
  42.     if ( isibbf( Recno))
  43.     {
  44.         prompt( "Cannot delete ");
  45.         puts( BBF);
  46.         waitesc();
  47.         return;
  48.     }
  49.     r = Recno - First + HEAD;
  50.     movmem( &Entry[ Recno], &Entryundo, RECSIZ);
  51.     Modified = Ctrlyundo = TRUE;
  52. #ifndef CLEARS
  53.     if ( Savrecno == Recno)
  54.         Savrecno = -1;
  55.     else if ( Savrecno > Recno)
  56.         --Savrecno;
  57. #endif
  58.     if ( Recno < Maxentry)
  59.         movmem( &Entry[ Recno + 1], &Entry[ Recno], ( Maxentry - Recno)*RECSIZ);
  60.     --Maxentry;
  61.     if ( Maxentry < 0)
  62.     {
  63.         First = 0;
  64.         Last = Maxentry = -1;
  65.     }
  66.     else First = min( First, ( Last = min( Last, Maxentry)));
  67.     dellin( r);
  68.     update( Recno);
  69.     if ( Recno > Maxentry)
  70.         Field = 0;
  71.     putcursor( Recno, Field);
  72. }
  73.  
  74. undo()                                  /*  undo delete for Entry[ Recno]    */
  75. {
  76.     if ( Ctrlyundo && insert())
  77.     {
  78.         movmem( &Entryundo, &Entry[ Recno], RECSIZ);
  79.         putrecord( Recno);
  80.         update( Recno);
  81.         putcursor( Recno, Field);
  82.     }
  83. }
  84.  
  85. insert()                                /*  insert Entry[ Recno]             */
  86. {                                       /*  return TRUE if successful        */
  87.     int i;
  88.  
  89.     if ( Maxentry == ( ENTRYSIZE - 1))
  90.     {
  91.         prompt( "Number of entries is maximum allowed");
  92.         waitesc();
  93.         return ( FALSE);
  94.     }
  95.     if ( Recno <= Maxentry)
  96.     {
  97.         i = Maxentry - Recno + 1;
  98.         movmem( &Entry[ Recno], &Entry[ Recno + 1], i*RECSIZ);
  99.         movmem( &Balance[ Recno], &Balance[ Recno + 1], i*sizeof( Balance[ 0]));
  100.     }
  101. #ifndef CLEARS
  102.     if ( Savrecno >= Recno)
  103.         ++Savrecno;
  104. #endif
  105.     ++Maxentry;
  106.     newentry( Recno);                   /*  Modified will be set TRUE        */
  107.     Last = min(( Last + 1), ( First + LAST));
  108.     inslin( Recno - First + HEAD);
  109.     putcursor( Recno, Field);
  110.     return ( TRUE);
  111. }
  112.  
  113. ctrlqork( c)                            /*  process CTRLQ or CTRLK command   */
  114. char c;
  115. {
  116.     char n;
  117.     int i;
  118.  
  119.     cursorto( 0, 2);
  120.     n = putnext();
  121.     if ( c == CTRLQ)                    /*  process CTRLQ command            */
  122.     {
  123.         switch ( n)
  124.         {
  125.         case 'R':
  126.             gotop();
  127.             break;
  128.         case 'C':
  129.             gobottom();
  130.             break;
  131.         case 'D':
  132.             if ( Recno > Maxentry)
  133.                 break;
  134.             putcursor( Recno, ( Field = MAXFIELD - 1));
  135.             break;
  136.         case 'S':  case 'H':
  137. #ifndef CLEARS
  138.             Character = 0;
  139. #endif
  140.             putcursor( Recno, ( Field = 0));
  141.             break;
  142.         case 'E':
  143.             putcursor(( Recno = First), Field);
  144.             break;
  145.         case 'X':
  146.             Recno = min(( Maxentry + 1), ( First + ( LAST - 1)));
  147.             if ( Recno > Maxentry)
  148.                 Field = 0;
  149.             putcursor( Recno, Field);
  150.             break;
  151.         case 'W':  case 'Z':
  152.             goupdown( n);
  153.             break;
  154.         case 'Y':  case DEL:  case ( CTRL_ + CTRLTOA):
  155. #ifdef  CLEARS
  156.             prompt( Usechex);
  157.             puts( "edit entries");
  158.             waitesc();
  159. #else
  160.             if ( Field == PAYFIELD)
  161.             {
  162.                 strcpy( Savpayee, Entry[ Recno].payee);
  163.                 Savrecno = Recno;
  164.                 putcursor( Recno, Field);
  165.                 erase( n);
  166.             }
  167. #endif
  168.             break;
  169.         default:
  170.             putchar( BEL);
  171.             break;
  172.         }
  173.     }
  174.     else                                /*  process CTRLK command            */
  175.     {
  176.         switch ( n)
  177.         {
  178.         case 'O':
  179.             order( 0);
  180.             break;
  181.         case 'D':  case 'X':
  182.             done();                     /*  never returns                    */
  183.             break;
  184.         case 'S':
  185.             save();
  186.             break;
  187.         case 'Q':
  188.             abandon();                  /*  may not return                   */
  189.             break;
  190.         case 'R':
  191.             reconcile();
  192.             break;
  193.         case 'P':
  194.             print();
  195.             break;
  196.         case 'A':
  197. #ifdef  CLEARS
  198.             prompt( Usechex);
  199.             puts( "work with abreviations");
  200.             waitesc();
  201. #else
  202.             abreviations();
  203. #endif
  204.             break;
  205.         default:
  206.             putchar( BEL);
  207.             break;
  208.         }
  209.     }
  210. }
  211.  
  212. #ifndef CLEARS
  213.  
  214. erase( c)                               /*  erase payee left or right        */
  215. char c;
  216. {
  217.     char *p, *q;
  218.     int count;
  219.  
  220.     q = Entry[ Recno].payee;
  221.     p = q + Character;
  222.     if ( c == 'Y')
  223.     {
  224.         count = strlen( p);
  225.         *p = '\0';
  226.     }
  227.     else if ( !Character)
  228.         return;
  229.     else
  230.     {
  231.         strcpy( q, p);
  232.         count = Character;
  233.         Character = 0;
  234.         putcursor( Recno, Field);
  235.         puts( q);
  236.     }
  237.     while ( count--)
  238.         putchar( PAYEEFILL);
  239.     Modified = TRUE;
  240. }
  241.  
  242. #endif
  243.  
  244. abandon()                               /*  abandon without resave           */
  245. {
  246.     if ( Modified)
  247.     {
  248.         prompt( "Abandon without saving changes (Y/N)? ");
  249.         if ( getyesno( NO))
  250.             aexit();
  251.     }
  252.     else
  253.     {
  254.         prompt( "Abandoning unchanged file");
  255.         aexit();
  256.     }
  257. }
  258.  
  259. save()                                  /*  save entries and continue        */
  260. {
  261. #ifdef  CLEARS
  262.     char compdate();
  263.  
  264.     reorder( 0, compdate);              /*  must sort by date                */
  265. #else
  266.     prompt( "Saving ... ");
  267. #endif
  268.     if ( savedat( TRUE))                /*  if error                         */
  269.         return;
  270.     waitesc();                          /*  else, wait for recognition       */
  271.     Modified = FALSE;
  272. }
  273.  
  274. reconcile()                             /*  display summary by category      */
  275. {
  276.     char c, *spaces, *sh, *ss, scroll, nbr[ DEL];
  277.     int i, j, count, lines, firstline, lastline, maxline;
  278.     struct
  279.         {
  280.         struct calendar maxdate;
  281.         char sumcategory;
  282.         struct money beginbal, clrcheck, clrdeposit, allcheck, alldeposit;
  283.         } sum, *a, *start;
  284.     struct record *e;
  285.     struct money *m, clrendbal, allendbal;
  286.  
  287.     spaces = "           ";
  288.     sh =
  289. "--------  --------  --------  --------  --------  --------  --------";
  290.     ss = "-------- - ";
  291.     prompt( "");
  292.     setmem( nbr, DEL, 0);               /*  initialize                       */
  293.     for ( j = 0; j <= Maxentry; ++j)    /*  count number in each category    */
  294.         ++nbr[ Entry[ j].category & 0x7f];
  295.     lines = 0;
  296.     for ( i = ' '; i < DEL; ++i)        /*  count separate categories, then  */
  297.         if ( nbr[ i])                   /*      allocate space for each      */
  298.             ++lines;
  299.     if ( !lines)
  300.         return;
  301.     if ( !( a = start = alloc( lines*sizeof( *a))))
  302.     {
  303.         prompt( "Insufficient memory to reconcile all categories");
  304.         waitesc();
  305.         return;
  306.     }
  307.     recheading( ss, sh);
  308.     setmem( &sum, sizeof( sum), 0);      /*  initialize                       */
  309.     setmem( a, ( lines*sizeof( *a)), 0);
  310.     for ( i = ' '; i < DEL; ++i)        /*  summarize each category          */
  311.     {
  312.         if ( !nbr[ i])                  /*  if category does not exist       */
  313.             continue;                   /*      next category                */
  314.         a->sumcategory = i;
  315.         count = 0;
  316.         for ( j = 0; j <= Maxentry; ++j)
  317.         {                               /*  loop thru entries                */
  318.             e = &Entry[ j];
  319.             if ((( c = e->category) & 0x7f) != i)
  320.                 continue;               /*  next entry                       */
  321.             datemax( &( a->maxdate), &( e->date));
  322.             m = &( e->amount);
  323.             if ( c & 0x80)              /*  if a BBF entry                   */
  324.                 addmoney( &a->beginbal, &a->beginbal, m, e->deposit);
  325.             else                        /*  not a BBF entry                  */
  326.             {
  327.                 if ( e->deposit)        /*  if a deposit                     */
  328.                 {
  329.                     addmoney( &a->alldeposit, &a->alldeposit, m, TRUE);
  330. #ifdef  CLEARS
  331.                     if ( !e->clear)
  332. #else
  333.                     if ( e->clear)
  334. #endif
  335.                         addmoney( &a->clrdeposit, &a->clrdeposit, m, TRUE);
  336.                 }
  337.                 else                    /*  not a deposit                    */
  338.                 {
  339.                     addmoney( &a->allcheck, &a->allcheck, m, TRUE);
  340. #ifdef  CLEARS
  341.                     if ( !e->clear)
  342. #else
  343.                     if ( e->clear)
  344. #endif
  345.                         addmoney( &a->clrcheck, &a->clrcheck, m, TRUE);
  346.                 }
  347.             }
  348.             if ( ++count == nbr[ i])    /*  if all entries for this category */
  349.                 break;                  /*      break j loop over entries    */
  350.         }                               /*  end j loop over entries          */
  351.         datemax( &( sum.maxdate), &( a->maxdate));
  352.         addmoney( &sum.beginbal, &sum.beginbal, &a->beginbal, TRUE);
  353.         addmoney( &sum.alldeposit, &sum.alldeposit, &a->alldeposit, TRUE);
  354.         addmoney( &sum.clrdeposit, &sum.clrdeposit, &a->clrdeposit, TRUE);
  355.         addmoney( &sum.allcheck, &sum.allcheck, &a->allcheck, TRUE);
  356.         addmoney( &sum.clrcheck, &sum.clrcheck, &a->clrcheck, TRUE);
  357.         ++a;                            /*  next summary line                */
  358.     }                                   /*  end i loop over categories       */
  359.     firstline = i = 0;
  360.     maxline = lines + 1;
  361.     lastline = min( maxline, ( LAST - 1));
  362.     Printing = scroll = FALSE;
  363.     FOREVER                             /*  begin display loop               */
  364.     {
  365.         cursorto((( HEAD + 1) + i - firstline), 0);
  366.         if ( i == lines)
  367.         {
  368.             puts( spaces);
  369.             puts( sh);
  370.             putchar( ' ');              /*  clear ')' from negative balance   */
  371.         }
  372.         else
  373.         {
  374.             if ( i < lines)
  375.             {
  376.                 a = start + i;
  377.                 c = a->sumcategory;
  378.             }
  379.             else
  380.             {
  381.                 a = ∑
  382.                 c = ' ';
  383.             }
  384.             putdate( &( a->maxdate));
  385.             putchar( c);
  386.             addmoney( &clrendbal, &a->beginbal, &a->clrcheck, FALSE);
  387.             addmoney( &clrendbal, &clrendbal, &a->clrdeposit, TRUE);
  388.             addmoney( &allendbal, &a->beginbal, &a->allcheck, FALSE);
  389.             addmoney( &allendbal, &allendbal, &a->alldeposit, TRUE);
  390.             putchar( ' ');
  391.             putmoney( &a->beginbal);
  392.             putchar( ' ');
  393.             putmoney( &a->clrcheck);
  394.             putchar( ' ');
  395.             putmoney( &a->clrdeposit);
  396.             putchar( ' ');
  397.             putmoney( &clrendbal);
  398.             putchar( ' ');
  399.             putmoney( &a->allcheck);
  400.             putchar( ' ');
  401.             putmoney( &a->alldeposit);
  402.             putchar( ' ');
  403.             putmoney( &allendbal);
  404.         }
  405.         if ( Printing)
  406.         {
  407.             if ( ++i > maxline)
  408.             {
  409.                 resetlst();
  410.                 i = count;              /*  reset line index                 */
  411.             }
  412.         }
  413.         else if ( !( scroll = ( scroll || i == lastline)))
  414.         {
  415.             ++i;                        /*  fill screen                      */
  416.             if ( kbhit())               /*  look ahead                       */
  417.             {
  418.                 ungetch( c = getchar());
  419.                 switch ( c)
  420.                 {
  421.                 case CTRLZ:
  422.                     scroll = ( !( *Lindel) && lastline != maxline);
  423.                     break;
  424.                 case CTRLW:
  425.                     scroll = ( !( *Linins) && firstline);
  426.                     break;
  427.                 case CTRLC:
  428.                     scroll = ( lastline != maxline);
  429.                     break;
  430.                 case CTRLR:
  431.                     scroll = ( firstline != 0);
  432.                     break;
  433.                 default:                /*  scroll is already FALSE          */
  434.                     break;
  435.                 }
  436.             }
  437.         }
  438.         else
  439.         {
  440.             prompt( "");
  441.             if ( firstline)             /*  if line 0 is off screen          */
  442.                 puts( "^W/^R to see prior, ");
  443.             if ( lastline < maxline)    /*  if final line is off screen      */
  444.                 puts( "^Z/^C to see next, ");
  445.             puts( "^P to print, ESCAPE to see full register");
  446.             FOREVER                     /*  loop until valid key             */
  447.             {
  448.                 if (( c = getchar()) == CTRLP)
  449.                 {
  450.                     if ( setlst())
  451.                     {
  452.                         recheading( ss, sh);
  453.                         count = i;      /*  save current line index          */
  454.                         i = 0;
  455.                     }
  456.                     break;              /*  break FOREVER loop               */
  457.                 }
  458.                 if ( c == ESC)
  459.                 {
  460.                     free( start);
  461.                     clrscr();
  462.                     disheading();
  463.                     display( First);
  464.                     return;
  465.                 }
  466.                 if (( c = doscroll( c, &scroll, &i, &firstline, &lastline,
  467.                                     maxline, (HEAD + 1))) == 1)
  468.                     break;              /*  break FOREVER loop               */
  469.                 if ( c == 2)
  470.                     putchar( BEL);
  471.             }                           /*  end FOREVER loop until valid key */
  472.         }                               /*  end if ... else scroll test      */
  473.     }                                   /*  end FOREVER display loop         */
  474. }                                       /*  end reconcile()                  */
  475.  
  476. #ifndef CLEARS
  477.  
  478. abreviations()                          /*  display installed abreviations   */
  479. {
  480.     char c, scroll;
  481.     int i, lines, hashval, firstline, lastline, compabrev();
  482.     struct nlist *np, **start;
  483.  
  484.     prompt( "");
  485.     lines = 0;                          /*  allocate abrev pointer space     */
  486.     for ( hashval = 0; hashval < HASHSIZE; ++hashval)
  487.         for ( np = Hashtab[ hashval]; np; np = np->next)
  488.             ++lines;                    /*  count abreviations               */
  489.     if ( !lines)
  490.     {
  491.         prompt( "There are no abreviations installed");
  492.         goto quit;
  493.     }
  494.     if ( !( start = alloc( lines*sizeof( np))))
  495.     {
  496.         prompt( "Insufficient memory to display all abreviations");
  497. quit:   waitesc();
  498.         return;
  499.     }
  500.     clrscr();
  501.     putscr( Ivon);
  502.     puttitle();
  503.     puts(
  504. "            Abreviation  Payee                                                 "
  505.          );
  506.     putchar( '\n');
  507.     puts(
  508. "            -----------  ------------------------------------------            "
  509.          );
  510.     putscr( Ivoff);
  511.     i = 0;
  512.     for ( hashval = 0; hashval < HASHSIZE; ++hashval)
  513.         for ( np = Hashtab[ hashval]; np; np = np->next)
  514.             *( start + ( i++)) = np;    /*  save pointer to each abreviation */
  515.     qsort( start, lines, sizeof( np), compabrev);
  516.     firstline = i = 0;
  517.     lastline = min( --lines, LAST);
  518.     scroll = FALSE;
  519.     FOREVER                             /*  begin display loop               */
  520.     {
  521.         cursorto(( HEAD + i - firstline), 0);
  522.         np = *( start + i);
  523.         puts( "                ");      /*  16 spaces                        */
  524.         puts( np->abrev);               /*   3 chars                         */
  525.         puts( "      ");                /*   6 spaces                        */
  526.         puts( np->fullname);
  527.         clreol(( COLS - 25) - strlen( np->fullname));
  528.         if ( !( scroll = ( scroll || i == lastline)))
  529.         {
  530.             ++i;                        /*  fill screen                      */
  531.             if ( kbhit())               /*  look ahead                       */
  532.             {
  533.                 ungetch( c = getchar());
  534.                 switch ( c)
  535.                 {
  536.                 case CTRLZ:
  537.                     scroll = ( !( *Lindel) && lastline != lines);
  538.                     break;
  539.                 case CTRLW:
  540.                     scroll = ( !( *Linins) && firstline);
  541.                     break;
  542.                 case CTRLC:
  543.                     scroll = ( lastline != lines);
  544.                     break;
  545.                 case CTRLR:
  546.                     scroll = ( firstline != 0);
  547.                     break;
  548.                 default:                /*  scroll is already FALSE          */
  549.                     break;
  550.                 }
  551.             }
  552.         }
  553.         else
  554.         {
  555.             prompt( "");
  556.             if ( firstline)             /*  if line 0 is off screen          */
  557.                 puts( "^W/^R to see prior, ");
  558.             if ( lastline < lines)      /*  if final line is off screen  */
  559.                 puts( "^Z/^C to see next, ");
  560.             puts( "ESCAPE to see full register");
  561.             FOREVER                     /*  loop until valid key             */
  562.             {
  563.                 if (( c = getchar()) == ESC)
  564.                 {
  565.                     free( start);
  566.                     clrscr();
  567.                     disheading();
  568.                     display( First);
  569.                     return;
  570.                 }
  571.                 if (( c = doscroll( c, &scroll, &i, &firstline, &lastline,
  572.                                     lines, HEAD)) == 1)
  573.                     break;              /*  break FOREVER loop               */
  574.                 if ( c == 2)
  575.                     putchar( BEL);
  576.             }                           /*  end FOREVER loop until valid key */
  577.         }                               /*  end if ... else scroll test      */
  578.     }                                   /*  end FOREVER display loop         */
  579. }                                       /*  end abreviations()               */
  580.  
  581. #endif
  582.  
  583. char doscroll( c, scroll, i, firstline, lastline, maxline, header)
  584. char c, *scroll;                        /*  used by reconcile()              */
  585. int *i, *firstline, *lastline;          /*  and by abreviations()            */
  586. int maxline, header;                    /*  return 1 if valid key,           */
  587. {                                       /*  2 if invalid key,                */
  588.                                         /*  0 if valid key at wrong time     */
  589.     switch ( c)
  590.     {
  591.     case CTRLW:
  592.         if ( *firstline)
  593.         {
  594.             *i = --( *firstline);
  595.             --( *lastline);
  596.             if ( !linins( header))
  597.                 *scroll = FALSE;
  598.             return ( 1);
  599.         }
  600.         break;
  601.     case CTRLR:
  602.         if ( *firstline)
  603.         {
  604.             *i = min( *firstline, PAGE);
  605.             *lastline -= *i;
  606.             *i = ( *firstline -= *i);
  607.             *scroll = FALSE;
  608.             return ( 1);
  609.         }
  610.         break;
  611.     case CTRLZ:
  612.         if ( *lastline < maxline)
  613.         {
  614.             ++( *firstline);
  615.             *i = ++( *lastline);
  616.             if ( !lindel( header))
  617.             {
  618.                 *i = *firstline;
  619.                 *scroll = FALSE;
  620.             }
  621.             return ( 1);
  622.         }
  623.         break;
  624.     case CTRLC:
  625.         if ( *lastline < maxline)
  626.         {
  627.             *i = min(( maxline - *lastline), PAGE);
  628.             *lastline += *i;
  629.             *i = ( *firstline += *i);
  630.             *scroll = FALSE;
  631.             return ( 1);
  632.         }
  633.         break;
  634.     default:
  635.         return ( 2);
  636.         break;
  637.     }
  638.     return ( 0);
  639. }
  640.  
  641. print()                                 /*  print entries                    */
  642. {
  643.     int i;
  644.  
  645.     if ( setlst())
  646.     {
  647.         disheading();
  648.         for ( i = 0; i <= Maxentry; ++i)
  649.             putrecord( i);              /*  cannot use display()             */
  650.         resetlst();
  651.     }
  652. }
  653.  
  654. order( i)                               /*  reorder entries i to Maxentry    */
  655. int i;
  656. {
  657.     char c;
  658.     int compdate(), comppayee(), compcateg(), compamount(), ( *f)();
  659.  
  660.     prompt(
  661. "Order entries by Date, Payee, Category, Amount, or Neither (D/P/C/A/N)? N"
  662.            );
  663.     putchar( '\b');
  664.     switch ( c = toupper( getchar()))
  665.     {
  666.     case 'D':
  667.         f = compdate;
  668.         break;
  669.     case 'P':
  670.         f = comppayee;
  671.         break;
  672.     case 'C':
  673.         f = compcateg;
  674.         break;
  675.     case 'A':
  676.         f = compamount;
  677.         break;
  678.     default:
  679.         c = 0;
  680.         break;
  681.     }
  682.     if ( c)
  683.     {
  684.         putchar( c);
  685.         reorder( i, f);
  686.     }
  687. }
  688.  
  689. reorder( i, f)                          /*  reorder from i using function f  */
  690. int i, ( *f)();
  691. {
  692.     prompt( "Sorting ... ");
  693.     qsort( &Entry[ i], ( Maxentry - i + 1), RECSIZ, f);
  694.     for ( ; i <= Maxentry; ++i)    /*  update balance and display            */
  695.     {
  696.         newbalance( i);
  697.         if ( First <= i && i <= Last)
  698.             putrecord( i);
  699.     }
  700. #ifndef CLEARS
  701.     Character = 0;                      /*  avoid dangling cursor            */
  702. #endif
  703. }
  704.  
  705. datemax( md, d)                         /*  determine max date               */
  706. struct calendar *md;                    /*  max date                         */
  707. struct calendar *d;                     /*  trial date                       */
  708. {
  709.     if ( datecomp( md, d) < 0)
  710.     {
  711.         md->mm = d->mm;
  712.         md->dd = d->dd;
  713.         md->yy = d->yy;
  714.     }
  715. }
  716.