home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume1 / calentool / part02 / cal2ct.c next >
Encoding:
C/C++ Source or Header  |  1989-05-27  |  6.6 KB  |  294 lines

  1. /*
  2.  * $Header: cal2ct.c,v 2.1 89/05/09 14:18:41 billr Exp $
  3.  */
  4. /*
  5.  * cal2ct - convert calendar reminder files to calentool style files
  6.  *
  7.  * Author: Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>
  8.  *
  9.  * Copyright (C) 1989 Tektronix, Inc.  All Rights Reserved
  10.  *
  11.  * Permission is hereby granted to use and modify this code in source
  12.  * or binary form as long as it is not sold for profit and this copyright
  13.  * notice remains intact.
  14.  */
  15.  
  16. #include "ct.h"
  17. #include <stdio.h>
  18. #include <ctype.h>
  19. #include <sys/time.h>
  20.  
  21. struct appt_entry appts, *aptr;
  22. char filename[128], *file;
  23. FILE *fp;
  24. struct tm current, today, *localtime();
  25. struct timeval tp;
  26.  
  27. extern char *getenv();
  28.  
  29. main(argc, argv)
  30. int argc;
  31. char *argv[];
  32. {
  33.     if (argc > 1)
  34.         file = argv[1];
  35.     else {
  36.         strcpy(filename, getenv("HOME"));
  37.         strcat(filename, "/calendar");
  38.         file = filename;
  39.     }
  40.  
  41.     if ((fp = fopen(file, "r")) == NULL) {
  42.         fprintf(stderr, "can't open calendar file for reading\n");
  43.         exit(1);
  44.     }
  45.     gettimeofday(&tp, NULL);
  46.     today = *localtime(&tp.tv_sec);
  47.     if (!read_cal_file()) {
  48.         fprintf(stderr, "no reminders read from %s\n", file);
  49.         exit(1);
  50.     }
  51.     fclose(fp);
  52.     strcpy(filename, getenv("HOME"));
  53.     strcat(filename, "/.appointments");
  54.     if ((fp = fopen(filename, "w")) == NULL) {
  55.         fprintf(stderr, "can't open .appointments file for writing\n");
  56.         exit(1);
  57.     }
  58.     write_ct_file();
  59. }
  60.  
  61. /*
  62.  * read dates from calendar file and stuff into appts struct
  63.  */
  64. read_cal_file()
  65. {
  66.     char *fgets();
  67.     char buf[512];
  68.     struct appt_entry *optr;
  69.  
  70.     aptr = &appts;
  71.     while (fgets(buf, 512, fp) != NULL) {
  72.         aptr->repeat = aptr->lookahead = 0;
  73.         aptr->flags = A_NOTE;
  74.         aptr->next = NULL;
  75.         if (!parse_date(buf))
  76.             return(1);
  77.         aptr->next = (struct appt_entry *)malloc(sizeof(struct appt_entry));
  78.         if (aptr->next == NULL) {
  79.             fprintf(stderr, "out of memory\n");
  80.             return;
  81.         }
  82.         optr = aptr;
  83.         aptr = aptr->next;
  84.     }
  85.     if (aptr == &appts)
  86.         return(0);    /* nothing read */
  87.     /* don't need the last one */
  88.     free(aptr);
  89.     optr->next = NULL;
  90.     return(1);
  91. }
  92.  
  93. /*
  94.  * write out the new .appointments file
  95.  */
  96. write_ct_file()
  97. {
  98.     aptr = &appts;
  99.     fputs(HEADER, fp);
  100.     while (aptr) {
  101.         if (put_aentry(fp, aptr)) {
  102.             fprintf(stderr, "error writing .appointments file\n");
  103.             return;
  104.         }
  105.         aptr = aptr->next;
  106.     }
  107. }
  108.  
  109. char *dayname[7] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
  110. char *monthname[12] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
  111.     "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
  112.  
  113. /*
  114.  * parse the date on the command line and reset the "current"
  115.  * date to reflect that date. The date may take the form of a
  116.  * day name (e.g. Tu, Tue, Tuesday) or a date in m/d/y format
  117.  * where the month and/or year may be missing (e.g. 27 = 27th
  118.  * of this month, 8/27 = August 27 of this year, 8/27/89 =
  119.  * August 27 of 1989. month may also be a string (e.g. "Dec"
  120.  * or "december") or a '*' (all months).
  121.  */
  122. parse_date(str)
  123. char *str;
  124. {
  125.     char c[4];
  126.     int i, dow = -1, mon = -1, m = -1, d = -1;
  127.  
  128.     current = today;    /* start with this month, day, year */
  129.     while (isspace(*str))
  130.         ++str;
  131.  
  132.     if (isdigit(*str)) {
  133.         /* must be a m/d date */
  134.         /* assume it's a month first */
  135.         m = *str++ - '0';
  136.         if (isdigit(*str))
  137.             m = m*10 + *str++ - '0';
  138.         if (*str != '/') {
  139.             /* no more chars => day only */
  140.             d = m;
  141.             m = -1;
  142.         } else {
  143.             ++str;
  144.             while (isspace(*str))
  145.                 ++str;
  146.             if (isdigit(*str)) {
  147.                 d = *str++ - '0';
  148.                 if (isdigit(*str))
  149.                     d = d*10 + *str++ - '0';
  150.             } else {
  151.                 fprintf(stderr, "badly formed date: %s\n", str-2);
  152.                 return(0);
  153.             }
  154.         }
  155.         if (m > 0)
  156.             current.tm_mon = m - 1;
  157.         if (d > 0)
  158.             current.tm_mday = d;
  159.     } else if (*str == '*') {
  160.         aptr->flags |= ALL_MONTHS;
  161.         ++str;
  162.         while (isspace(*str) || *str == '/')
  163.             ++str;
  164.         d = *str++ - '0';
  165.         if (isdigit(*str))
  166.             d = d*10 + *str++ - '0';
  167.         current.tm_mday = d;
  168.     } else {
  169.         /* day of week or month name */
  170.         /* check for day names */
  171.         c[0] = islower(*str) ? toupper(*str) : *str;
  172.         ++str;
  173.         c[1] = islower(*str) ? toupper(*str) : *str;
  174.         if (*++str) {
  175.             c[2] = islower(*str) ? toupper(*str) : *str;
  176.             c[3] = '\0';
  177.         } else
  178.             c[2] = '\0';
  179.         while (!isspace(*str))
  180.             ++str;
  181.         /* check month names */
  182.         for (i=0; i<12; i++) {
  183.             if (!strcmp(c, monthname[i])) {
  184.                 mon = i;
  185.                 break;;
  186.             }
  187.         }
  188.         if (mon >= 0) {
  189.             /* match found */
  190.             current.tm_mon = mon;
  191.             while (!isspace(*str))
  192.                 ++str;
  193.             d = *++str - '0';
  194.             ++str;
  195.             if (isdigit(*str))
  196.                 d = d*10 + *str++ - '0';
  197.             current.tm_mday = d;
  198.         } else {
  199.             /* check day names */
  200.             c[2] = '\0';
  201.             for (i=0; i<7; i++) {
  202.                 if (!strcmp(c, dayname[i])) {
  203.                     dow = i;
  204.                     break;
  205.                 }
  206.             }
  207.             if (dow >= 0) {
  208.                 /* match found */
  209.                 current.tm_mday += dow - current.tm_wday;
  210.                 fix_current_day();
  211.             } else
  212.                 fprintf(stderr, "badly formed date: %s\n", str-2);
  213.         }
  214.     }
  215.     while (isspace(*str))
  216.         ++str;
  217.     strcpy(aptr->str, str);
  218.     aptr->year = current.tm_year;
  219.     aptr->month = current.tm_mon;
  220.     aptr->day = current.tm_mday;
  221.     return(1);
  222. }
  223.  
  224. /*
  225.  *    Reset some values in current tm structure. Year, month and
  226.  *    day-of-month are valid but day and/or month may be < 0 or
  227.  *    greater than the maximum value, in which case they are adjusted
  228.  *    accordingly. Day-of-year and day-of-week are then recalculated.
  229.  */
  230. fix_current_day()
  231. {
  232.     int month, totdays = 0;
  233.     struct tm from, to;
  234.  
  235.     if (current.tm_mon < JAN) {
  236.         current.tm_mon = DEC;
  237.         current.tm_year--;
  238.     } else if (current.tm_mon > DEC) {
  239.         current.tm_mon = JAN;
  240.         current.tm_year++;
  241.     }
  242.     if (current.tm_mday < 1) {
  243.         current.tm_mon--;
  244.         if (current.tm_mon < JAN) {
  245.             current.tm_mon = DEC;
  246.             current.tm_year--;
  247.         }
  248.         current.tm_mday += monthlength(current.tm_mon);
  249.     } else if (current.tm_mday > monthlength(current.tm_mon)) {
  250.         current.tm_mday -= monthlength(current.tm_mon);
  251.         current.tm_mon++;
  252.         if (current.tm_mon > DEC) {
  253.             current.tm_mon = JAN;
  254.             current.tm_year++;
  255.         }
  256.     }
  257.     current.tm_yday = current.tm_mday - 1;
  258.     for (month = 0; month < current.tm_mon; month++) {
  259.         current.tm_yday += monthlength(month);
  260.     }
  261.     if ((current.tm_year < today.tm_year)
  262.         || ((current.tm_year == today.tm_year)
  263.         && (current.tm_yday < today.tm_yday))) {
  264.         from = current;
  265.         to = today;
  266.     } else {
  267.         from = today;
  268.         to = current;
  269.     }
  270.     if (from.tm_year != to.tm_year) {
  271.         for (totdays = 0; from.tm_year < to.tm_year; from.tm_year++)
  272.             totdays += dysize(from.tm_year + 1900);
  273.     }
  274.     totdays += to.tm_yday - from.tm_yday;
  275.     if ((current.tm_year < today.tm_year)
  276.         || ((current.tm_year == today.tm_year)
  277.         && (current.tm_yday < today.tm_yday)))
  278.         totdays = -totdays;
  279.     current.tm_wday =
  280.         ((totdays % 7) + 7 + today.tm_wday) % 7;
  281. }
  282.  
  283. int
  284. monthlength(month)
  285. int    month;
  286. {
  287.     static int    monthlengths[] = {31,28,31,30,31,30,31,31,30,31,30,31};
  288.  
  289.     if (month == FEB && (dysize(current.tm_year + 1900) == 366))
  290.         return(29);
  291.     else
  292.         return(monthlengths[month]);
  293. }
  294.