From: Pierre Habouzit Date: Mon, 6 Nov 2006 01:36:01 +0000 (+0100) Subject: simplify mutt_parse_date X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=commitdiff_plain;h=e25b0de8c4e7d6aeeb467f8ea1ad8dd6b2a9470e simplify mutt_parse_date Signed-off-by: Pierre Habouzit --- diff --git a/lib-lib/mem.h b/lib-lib/mem.h index b3bcd62..9ff2589 100644 --- a/lib-lib/mem.h +++ b/lib-lib/mem.h @@ -25,6 +25,7 @@ #include #define ssizeof(foo) (ssize_t)sizeof(foo) +#define countof(foo) (ssizeof(foo) / ssizeof(foo[0])) #define p_new(type, count) ((type *)xmalloc(sizeof(type) * (count))) #define p_clear(p, count) ((void)memset((p), 0, sizeof(*(p)) * (count))) diff --git a/lib-mime/rfc822parse.c b/lib-mime/rfc822parse.c index e0cd6b0..6032132 100644 --- a/lib-mime/rfc822parse.c +++ b/lib-mime/rfc822parse.c @@ -671,138 +671,127 @@ static struct tz_t { * This routine assumes that `h' has been initialized to 0. the `timezone' * field is optional, defaulting to +0000 if missing. */ -time_t mutt_parse_date (const char *s, HEADER * h) +time_t mutt_parse_date(const char *s, HEADER *h) { - int count = 0; - char *t; - int hour, min, sec; - struct tm tm; - int i; - int tz_offset = 0; - int zhours = 0; - int zminutes = 0; - int zoccident = 0; - const char *ptz; - char tzstr[SHORT_STRING]; - char scratch[SHORT_STRING]; - - /* Don't modify our argument. Fixed-size buffer is ok here since - * the date format imposes a natural limit. - */ - - m_strcpy(scratch, sizeof(scratch), s); - - /* kill the day of the week, if it exists. */ - if ((t = strchr (scratch, ','))) - t++; - else - t = scratch; - t = vskipspaces(t); - - p_clear(&tm, 1); - - while ((t = strtok (t, " \t")) != NULL) { - switch (count) { - case 0: /* day of the month */ - if (!isdigit ((unsigned char) *t)) - return (-1); - tm.tm_mday = atoi (t); - if (tm.tm_mday > 31) - return (-1); - break; - - case 1: /* month of the year */ - if ((i = mutt_check_month (t)) < 0) - return (-1); - tm.tm_mon = i; - break; - - case 2: /* year */ - tm.tm_year = atoi (t); - if (tm.tm_year < 50) - tm.tm_year += 100; - else if (tm.tm_year >= 1900) - tm.tm_year -= 1900; - break; - - case 3: /* time of day */ - if (sscanf (t, "%d:%d:%d", &hour, &min, &sec) == 3); - else if (sscanf (t, "%d:%d", &hour, &min) == 2) - sec = 0; - else { - debug_print (1, ("could not process time format: %s\n", t)); - return (-1); - } - tm.tm_hour = hour; - tm.tm_min = min; - tm.tm_sec = sec; - break; - - case 4: /* timezone */ - /* sometimes we see things like (MST) or (-0700) so attempt to - * compensate by uncommenting the string if non-RFC822 compliant - */ - ptz = uncomment_timezone (tzstr, sizeof (tzstr), t); - - if (*ptz == '+' || *ptz == '-') { - if (ptz[1] && ptz[2] && ptz[3] && ptz[4] - && isdigit ((unsigned char) ptz[1]) - && isdigit ((unsigned char) ptz[2]) - && isdigit ((unsigned char) ptz[3]) - && isdigit ((unsigned char) ptz[4])) { - zhours = (ptz[1] - '0') * 10 + (ptz[2] - '0'); - zminutes = (ptz[3] - '0') * 10 + (ptz[4] - '0'); - - if (ptz[0] == '-') - zoccident = 1; - } - } - else { - struct tz_t *tz; - - tz = bsearch (ptz, TimeZones, sizeof TimeZones / sizeof (struct tz_t), - sizeof (struct tz_t), - (int (*)(const void *, const void *)) ascii_strcasecmp - /* This is safe to do: A pointer to a struct equals - * a pointer to its first element*/ ); - - if (tz) { - zhours = tz->zhours; - zminutes = tz->zminutes; - zoccident = tz->zoccident; - } + int count = 0; + char *p; + struct tm tm; + int tz_offset = 0; + int zhours = 0, zminutes = 0, zoccident = 0; + const char *ptz; + char tzstr[SHORT_STRING]; + char scratch[SHORT_STRING]; + + /* Don't modify our argument. Fixed-size buffer is ok here since + the date format imposes a natural limit. */ + + m_strcpy(scratch, sizeof(scratch), s); + + /* kill the day of the week, if it exists. */ + p = strchr(scratch, ','); + p = vskipspaces(p ? p + 1 : scratch); + + p_clear(&tm, 1); + + while ((p = strtok (p, " \t")) != NULL) { + switch (count) { + case 0: /* day of the month */ + if (!isdigit((unsigned char)*p)) + return -1; + tm.tm_mday = atoi(p); + if (tm.tm_mday > 31) + return -1; + break; - /* ad hoc support for the European MET (now officially CET) TZ */ - if (ascii_strcasecmp (t, "MET") == 0) { - if ((t = strtok (NULL, " \t")) != NULL) { - if (!ascii_strcasecmp (t, "DST")) - zhours++; - } + case 1: /* month of the year */ + tm.tm_mon = mutt_check_month(p); + if (tm.tm_mon < 0) + return -1; + break; + + case 2: /* year */ + tm.tm_year = atoi(p); + if (tm.tm_year < 50) + tm.tm_year += 100; + else if (tm.tm_year >= 1900) + tm.tm_year -= 1900; + break; + + case 3: /* time of day */ + tm.tm_hour = strtol(p, &p, 10); + if (*p++ != ':') + return -1; + tm.tm_min = strtol(p, &p, 10); + if (*p++ == ':') { + tm.tm_sec = strtol(p, &p, 10); + } else { + tm.tm_sec = 0; + } + break; + + case 4: /* timezone */ + /* sometimes we see things like (MST) or (-0700) so attempt to + * compensate by uncommenting the string if non-RFC822 compliant + */ + ptz = uncomment_timezone(tzstr, sizeof(tzstr), p); + + if (*ptz == '+' || *ptz == '-') { + if (isdigit((unsigned char)ptz[1]) + && isdigit((unsigned char)ptz[2]) + && isdigit((unsigned char)ptz[3]) + && isdigit((unsigned char)ptz[4])) + { + zoccident = ptz[0] == '-'; + zhours = (ptz[1] - '0') * 10 + (ptz[2] - '0'); + zminutes = (ptz[3] - '0') * 10 + (ptz[4] - '0'); + } + } else { + struct tz_t *tz; + + /* This is safe to do: A pointer to a struct equals a pointer to its + * first element*/ + tz = bsearch(ptz, TimeZones, countof(TimeZones), sizeof(TimeZones[0]), + (int (*)(const void *, const void *))ascii_strcasecmp); + + if (tz) { + zhours = tz->zhours; + zminutes = tz->zminutes; + zoccident = tz->zoccident; + } + + /* ad hoc support for the European MET (now officially CET) TZ */ + if (ascii_strcasecmp(p, "MET") == 0) { + if ((p = strtok (NULL, " \t")) && !ascii_strcasecmp(p, "DST")) { + zhours++; + } + } + } + + tz_offset = zhours * 3600 + zminutes * 60; + if (!zoccident) + tz_offset = -tz_offset; + break; } - } - tz_offset = zhours * 3600 + zminutes * 60; - if (!zoccident) - tz_offset = -tz_offset; - break; + count++; + p = NULL; } - count++; - t = 0; - } - if (count < 4) { /* don't check for missing timezone */ - debug_print (1, ("error parsing date format, using received time\n")); - return (-1); - } + if (count < 4) { /* don't check for missing timezone */ + debug_print (1, ("error parsing date format, using received time\n")); + return -1; + } - if (h) { - h->zhours = zhours; - h->zminutes = zminutes; - h->zoccident = zoccident; - } + if (h) { + h->zhours = zhours; + h->zminutes = zminutes; + h->zoccident = zoccident; + } - return (mutt_mktime (&tm, 0) + tz_offset); + return mutt_mktime(&tm, 0) + tz_offset; } +/*** XXX: MC READ MARK ***/ + /* extract the first substring that looks like a message-id */ static char *extract_message_id(const char *s) {