home *** CD-ROM | disk | FTP | other *** search
- /* cal.c -- UTOOL. Calendar. Print lines with date match.
- author: David H. Wolen
- last change: 6/2/83
-
- usage: cal file mm/dd/yy
- prog |cal -r mm/dd/yy mm/dd/yy
- cal file -ge mm/dd/yy
-
- options: -g (>)
- -l (<)
- -e (=)
- -r (>= date1 and <= date2)
-
- input: file or STDIN
- output: STDOUT
-
- notes: -ge, -le, -gl, are ok (effect is "or" relation)
- only first valid date on line is examined for match
- if -r, no other options are allowed
- if no options, default is -e
-
- linkage: a:clink cal -f dio -ca (uses deff3.crl)
- */
-
- #include "a:bdscio.h"
- #include "a:dio.h"
- #define STDIN 0
- #define STDOUT 1
- #define BASEYR 45 /* yy < BASEYR converted to 20yy */
- /* yy >= BASEYR converted to 19yy */
-
- struct date
- {int day;
- int month;
- int year;
- };
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- struct date argdate1, argdate2, linedate;
- int gt, lt, eq, range, isstdin;
- char *s, line[MAXLINE], cdate[9], ibuf[BUFSIZ];
-
- dioinit(&argc,argv);
- eq=gt=lt=range=FALSE;
-
- if(*(argv+1)[0] != '-' && !isdigit(*(argv+1)[0]))
- {isstdin=FALSE; /* file input */
- if(fopen(*++argv,ibuf)==ERROR)
- error("cal: can't open file");
- --argc;
- }
- else
- isstdin=TRUE;
-
- while(--argc > 0 && (*++argv)[0] == '-')
- for(s=argv[0]+1; *s != '\0'; s++)
- switch (*s)
- {case 'E':
- eq=TRUE; break;
- case 'G':
- gt=TRUE; break;
- case 'L':
- lt=TRUE; break;
- case 'R':
- range=TRUE; break;
- default:
- error("cal: invalid option");
- }
-
- if(convdate(*argv++,&argdate1)==ERROR)
- error("cal: invalid date1");
-
- if(range)
- {if(convdate(*argv,&argdate2)==ERROR)
- error("cal: invalid date2");
- if(eq || gt || lt)
- error("cal: no other options allowed with -r");
- }
-
- if(!eq && !gt && !lt && !range) /* default -e if no options */
- eq=TRUE;
-
- while(isstdin ? fgets(line,STDIN) : fgets(line,ibuf))
- {if(!finddate(line,cdate)) continue;
- else
- convdate(cdate,&linedate);
-
- if(eq && datecmp(&linedate,&argdate1)==0)
- fputs(line,STDOUT);
-
- if(gt && datecmp(&linedate,&argdate1) > 0)
- fputs(line,STDOUT);
-
- if(lt && datecmp(&linedate,&argdate1) < 0)
- fputs(line,STDOUT);
-
- if(range && datecmp(&linedate,&argdate1) >= 0
- && datecmp(&linedate,&argdate2) <= 0)
- fputs(line,STDOUT);
- }
-
- dioflush();
- }
-
-
-
- /* convdate -- convert mm/dd/yy to structure date */
- convdate(mmddyy,pd)
- char *mmddyy;
- struct date *pd;
- {
- int tmonth, tday, tyear;
- char mm[3], dd[3], yy[3];
-
- mm[0]=mmddyy[0];
- mm[1]=mmddyy[1];
- dd[0]=mmddyy[3];
- dd[1]=mmddyy[4];
- yy[0]=mmddyy[6];
- yy[1]=mmddyy[7];
- mm[2]=dd[2]=yy[2]='\0';
-
- tmonth=atoi(mm);
- tday=atoi(dd);
- tyear=atoi(yy);
-
- if(tyear < BASEYR)
- tyear += 2000;
- else
- tyear += 1900;
-
- if(tmonth < 1 || tmonth > 12) return(ERROR);
- if(tday < 1 || tday > 31) return(ERROR);
-
- switch(tmonth)
- {case 1: case 3: case 5: case 7: case 8: case 10: case 12:
- if(tday > 31) return(ERROR);
- break;
- case 4: case 6: case 9: case 11:
- if(tday > 30) return(ERROR);
- break;
- case 2:
- if(tyear % 4 == 0 && tyear % 100 != 0 || tyear % 400 == 0)
- {if(tday > 29) /* leap year */
- return(ERROR);
- break;
- }
- else
- {if(tday > 28) /* not leap year */
- return(ERROR);
- break;
- }
- default:
- error("in convdate -- can't happen");
- }
-
- pd->day=tday;
- pd->month=tmonth;
- pd->year=tyear;
- return(OK);
- }
-
-
-
- /* finddate -- find mm/dd/yy in line */
- finddate(line,mmddyy)
- char *line, *mmddyy;
- {
- struct date dtest;
- char ctemp[9];
- int i, len, start;
-
- if((start=index(line,"/")) < 0) return(FALSE);
- start=max(start-2,0);
- len=strlen(line);
-
- for(i=start; i<len-8; i++)
- if(dpat(line,i))
- {movmem(&line[i],ctemp,8);
- ctemp[8]='\0';
- if(convdate(ctemp,&dtest) != ERROR)
- {strcpy(mmddyy,ctemp);
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
-
-
- /* dpat -- see if the pattern nn/nn/nn starts at line[i] */
- dpat(line,i)
- char *line;
- int i;
- {
- if(!isdigit(line[i++])) return(FALSE);
- if(!isdigit(line[i++])) return(FALSE);
- if(line[i++] != '/') return(FALSE);
- if(!isdigit(line[i++])) return(FALSE);
- if(!isdigit(line[i++])) return(FALSE);
- if(line[i++] != '/') return(FALSE);
- if(!isdigit(line[i++])) return(FALSE);
- if(!isdigit(line[i++])) return(FALSE);
-
- return(TRUE);
- }
-
-
-
- /* datecmp -- compare two date structures. Return
- <0, 0, >0 if first is <,==,> second.
- */
- datecmp(pd1,pd2)
- struct date *pd1, *pd2;
- {
- if(pd1->year > pd2->year) return(1);
- if(pd1->year < pd2->year) return(-1);
-
- if(pd1->month > pd2->month) return(1);
- if(pd1->month < pd2->month) return(-1);
-
- if(pd1->day > pd2->day) return(1);
- if(pd1->day < pd2->day) return(-1);
-
- return(0);
- }
-