home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_11_02 / 1102019a < prev    next >
Text File  |  1992-12-09  |  2KB  |  81 lines

  1. /* _Getdst function */
  2. #include <ctype.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "xtime.h"
  6.  
  7. static int getint(const char *s, int n)
  8.     {    /* accumulate digits */
  9.     int value;
  10.  
  11.     for (value = 0; 0 <= --n && isdigit(*s); ++s)
  12.         value = value * 10 + *s - '0';
  13.     return (0 <= n ? -1 : value);
  14.     }
  15.  
  16. Dstrule *_Getdst(const char *s)
  17.     {    /* parse DST rules */
  18.     const char delim = *s++;
  19.     Dstrule *pr, *rules;
  20.  
  21.     if (delim == '\0')
  22.         return (NULL);
  23.      {    /* buy space for rules */
  24.     const char *s1, *s2;
  25.     int i;
  26.  
  27.     for (s1 = s, i = 2;
  28.         (s2 = strchr(s1, delim)) != NULL; ++i)
  29.             s1 = s2 + 1;
  30.     if ((rules = (Dstrule *)malloc(sizeof (Dstrule)
  31.             * i)) == NULL)
  32.         return (NULL);
  33.      }
  34.      {    /* parse rules */
  35.     int year = 0;
  36.  
  37.     for (pr = rules; ; ++pr, ++s)
  38.         {    /* parse next rule */
  39.         if (*s == '(')
  40.             {    /* got a year qualifier */
  41.             year = getint(s + 1, 4) - 1900;
  42.             if (year < 0 || s[5] != ')')
  43.                 break;    /* invalid year */
  44.             s += 6;
  45.             }
  46.         pr->year = year;
  47.         pr->mon = getint(s, 2) - 1, s += 2;
  48.         pr->day = getint(s, 2) - 1, s += 2;
  49.         if (isdigit(*s))
  50.             pr->hour = getint(s, 2), s += 2;
  51.         else
  52.             pr->hour = 0;
  53.         if (12 <= pr->mon || 99 < pr->day
  54.             || 99 < pr->hour)
  55.             break;    /* invalid month, day, or hour */
  56.         if (*s != '+' && *s != '-')
  57.             pr->wday = 0;
  58.         else if (s[1] < '0' || '6' < s[1])
  59.             break;    /* invalid week day */
  60.         else
  61.             {    /* compute week day field */
  62.             pr->wday = s[1] == '0' ? 7 : s[1] - '0';
  63.             if (*s == '+')    /* '-': strictly before */
  64.                 pr->wday += 7;    /* '+': on or after */
  65.             s += 2;
  66.             }
  67.         if (*s == '\0')
  68.             {    /* done, terminate list */
  69.             (pr + 1)->wday = (unsigned char)-1;
  70.             (pr + 1)->year = year;
  71.             return (rules);
  72.             }
  73.         else if (*s != delim)
  74.             break;
  75.         }
  76.     free(rules);
  77.     return (NULL);
  78.      }
  79.     }
  80.  
  81.