home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / ut-c.lbr / CAL.CZ / CAL.C
Encoding:
C/C++ Source or Header  |  1993-10-25  |  6.0 KB  |  231 lines

  1. /*  cal.c -- UTOOL. Calendar.  Print lines with date match.
  2.      author: David H. Wolen
  3.      last change: 6/2/83
  4.  
  5.      usage: cal file  mm/dd/yy
  6.             prog |cal -r mm/dd/yy mm/dd/yy
  7.             cal file -ge mm/dd/yy
  8.  
  9.      options: -g (>)
  10.               -l (<)
  11.               -e (=)
  12.               -r (>= date1 and <= date2)
  13.  
  14.      input:    file or STDIN
  15.      output:   STDOUT
  16.  
  17.      notes:    -ge, -le, -gl, are ok (effect is "or" relation)
  18.                only first valid date on line is examined for match
  19.                if -r, no other options are allowed
  20.                if no options, default is -e
  21.  
  22.      linkage: a:clink cal -f dio -ca (uses deff3.crl)
  23. */
  24.  
  25. #include "a:bdscio.h"
  26. #include "a:dio.h"
  27. #define STDIN 0
  28. #define STDOUT 1
  29. #define BASEYR 45   /* yy < BASEYR converted to 20yy */
  30.                     /* yy >= BASEYR converted to 19yy */
  31.  
  32. struct date
  33.      {int  day;
  34.       int  month;
  35.       int  year;
  36.      };
  37.  
  38. main(argc,argv)
  39. int  argc;
  40. char *argv[];
  41. {
  42.      struct date argdate1, argdate2, linedate;
  43.      int  gt, lt, eq, range, isstdin;
  44.      char *s, line[MAXLINE], cdate[9], ibuf[BUFSIZ];
  45.  
  46.      dioinit(&argc,argv);
  47.      eq=gt=lt=range=FALSE;
  48.  
  49.      if(*(argv+1)[0] != '-' && !isdigit(*(argv+1)[0]))
  50.           {isstdin=FALSE;          /* file input */
  51.           if(fopen(*++argv,ibuf)==ERROR)
  52.                error("cal: can't open file");
  53.           --argc;
  54.           }
  55.      else
  56.           isstdin=TRUE;
  57.  
  58.      while(--argc > 0 && (*++argv)[0] == '-')
  59.           for(s=argv[0]+1; *s != '\0'; s++)
  60.                switch (*s)
  61.                     {case 'E':
  62.                          eq=TRUE;  break;
  63.                     case 'G':
  64.                          gt=TRUE;  break;
  65.                     case 'L':
  66.                          lt=TRUE;  break;
  67.                     case 'R':
  68.                          range=TRUE;  break;
  69.                     default:
  70.                          error("cal: invalid option");
  71.                     }
  72.  
  73.      if(convdate(*argv++,&argdate1)==ERROR)
  74.           error("cal: invalid date1");
  75.  
  76.      if(range)
  77.           {if(convdate(*argv,&argdate2)==ERROR)
  78.                error("cal: invalid date2");
  79.           if(eq || gt || lt)
  80.                error("cal: no other options allowed with -r");
  81.           }
  82.  
  83.      if(!eq && !gt && !lt && !range)    /* default -e if no options */
  84.           eq=TRUE;
  85.  
  86.      while(isstdin ? fgets(line,STDIN) : fgets(line,ibuf))
  87.           {if(!finddate(line,cdate))  continue;
  88.           else
  89.                convdate(cdate,&linedate);
  90.  
  91.           if(eq && datecmp(&linedate,&argdate1)==0)
  92.                fputs(line,STDOUT);
  93.  
  94.           if(gt && datecmp(&linedate,&argdate1) > 0)
  95.                fputs(line,STDOUT);
  96.  
  97.           if(lt && datecmp(&linedate,&argdate1) < 0)
  98.                fputs(line,STDOUT);
  99.  
  100.           if(range && datecmp(&linedate,&argdate1) >= 0
  101.                && datecmp(&linedate,&argdate2) <= 0)
  102.                fputs(line,STDOUT);
  103.           }
  104.  
  105.      dioflush();
  106. }
  107.  
  108.  
  109.  
  110. /* convdate -- convert mm/dd/yy to structure date */
  111. convdate(mmddyy,pd)
  112. char *mmddyy;
  113. struct date *pd;
  114. {
  115.      int  tmonth, tday, tyear;
  116.      char mm[3], dd[3], yy[3];
  117.  
  118.      mm[0]=mmddyy[0];
  119.      mm[1]=mmddyy[1];
  120.      dd[0]=mmddyy[3];
  121.      dd[1]=mmddyy[4];
  122.      yy[0]=mmddyy[6];
  123.      yy[1]=mmddyy[7];
  124.      mm[2]=dd[2]=yy[2]='\0';
  125.  
  126.      tmonth=atoi(mm);
  127.      tday=atoi(dd);
  128.      tyear=atoi(yy);
  129.  
  130.      if(tyear < BASEYR)
  131.           tyear += 2000;
  132.      else
  133.           tyear += 1900;
  134.  
  135.      if(tmonth < 1 || tmonth > 12)  return(ERROR);
  136.      if(tday < 1 || tday > 31)  return(ERROR);
  137.  
  138.      switch(tmonth)
  139.           {case 1:  case 3:  case 5:  case 7:  case 8:  case 10:  case 12:
  140.                if(tday > 31)  return(ERROR);
  141.                break;
  142.           case 4:  case 6:  case 9:  case 11:
  143.                if(tday > 30)  return(ERROR);
  144.                break;
  145.           case 2:
  146.                if(tyear % 4 == 0 && tyear % 100 != 0 || tyear % 400 == 0)
  147.                     {if(tday > 29)           /* leap year */
  148.                          return(ERROR);
  149.                     break;
  150.                     }
  151.                else
  152.                     {if(tday > 28)           /* not leap year */
  153.                          return(ERROR);
  154.                     break;
  155.                     }
  156.           default:
  157.                error("in convdate -- can't happen");
  158.           }
  159.  
  160.      pd->day=tday;
  161.      pd->month=tmonth;
  162.      pd->year=tyear;
  163.      return(OK);
  164. }
  165.  
  166.  
  167.  
  168. /* finddate -- find mm/dd/yy in line */
  169. finddate(line,mmddyy)
  170. char *line, *mmddyy;
  171. {
  172.      struct date dtest;
  173.      char ctemp[9];
  174.      int  i, len, start;
  175.  
  176.      if((start=index(line,"/")) < 0)  return(FALSE);
  177.      start=max(start-2,0);
  178.      len=strlen(line);
  179.  
  180.      for(i=start; i<len-8; i++)
  181.           if(dpat(line,i))
  182.                {movmem(&line[i],ctemp,8);
  183.                ctemp[8]='\0';
  184.                if(convdate(ctemp,&dtest) != ERROR)
  185.                     {strcpy(mmddyy,ctemp);
  186.                     return(TRUE);
  187.                     }
  188.                }
  189.  
  190.      return(FALSE);
  191. }
  192.  
  193.  
  194.  
  195. /* dpat -- see if the pattern nn/nn/nn starts at line[i] */
  196. dpat(line,i)
  197. char *line;
  198. int  i;
  199. {
  200.      if(!isdigit(line[i++]))  return(FALSE);
  201.      if(!isdigit(line[i++]))  return(FALSE);
  202.      if(line[i++] != '/')     return(FALSE);
  203.      if(!isdigit(line[i++]))  return(FALSE);
  204.      if(!isdigit(line[i++]))  return(FALSE);
  205.      if(line[i++] != '/')     return(FALSE);
  206.      if(!isdigit(line[i++]))  return(FALSE);
  207.      if(!isdigit(line[i++]))  return(FALSE);
  208.  
  209.      return(TRUE);
  210. }
  211.  
  212.  
  213.  
  214. /* datecmp -- compare two date structures.  Return
  215.      <0, 0, >0 if first is <,==,> second.
  216. */
  217. datecmp(pd1,pd2)
  218. struct date *pd1, *pd2;
  219. {
  220.      if(pd1->year > pd2->year)  return(1);
  221.      if(pd1->year < pd2->year)  return(-1);
  222.  
  223.      if(pd1->month > pd2->month) return(1);
  224.      if(pd1->month < pd2->month) return(-1);
  225.  
  226.      if(pd1->day > pd2->day) return(1);
  227.      if(pd1->day < pd2->day) return(-1);
  228.  
  229.      return(0);
  230. }
  231.