]> diplodocus.org Git - nmh/blobdiff - sbr/dtime.c
new.c: Order two return statements to match comment.
[nmh] / sbr / dtime.c
index 7ec75511a38928b7c635ffeb86ebd88185aa0e75..b5039ed6d96c0c6987ffb8c03bb6578cd8ab1bde 100644 (file)
@@ -1,6 +1,4 @@
-
-/*
- * dtime.c -- time/date routines
+/* dtime.c -- time/date routines
  *
  * This code is Copyright (c) 2002, by the authors of nmh.  See the
  * COPYRIGHT file in the root directory of the nmh distribution for
@@ -9,17 +7,12 @@
 
 #include <h/mh.h>   /* for snprintf() */
 #include <h/nmh.h>
+#include <h/utils.h>
 #include <h/tws.h>
 #include <time.h>
 
 #if !defined(HAVE_STRUCT_TM_TM_GMTOFF)
-extern int daylight;
 extern long timezone;
-extern char *tzname[];
-#endif
-
-#ifndef        abs
-# define abs(a) (a >= 0 ? a : -a)
 #endif
 
 /*
@@ -47,12 +40,6 @@ char *tw_ldotw[] = {
     "Saturday",  NULL
 };
 
-struct zone {
-    char *std;
-    char *dst;
-    int shift;
-};
-
 static int dmsize[] = {
     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
 };
@@ -114,18 +101,24 @@ dlocaltime (time_t *clock)
     if (tm->tm_isdst)                  /* if DST is in effect */
        tw.tw_zone -= 60;               /* reset to normal offset */
 #else
-    tzset();
+    {
+        static bool deja_vu;
+
+        if (!deja_vu) {
+            deja_vu = true;
+            tzset();
+        }
+    }
     tw.tw_zone = -(timezone / 60);
 #endif
 
     tw.tw_flags &= ~TW_SDAY;
     tw.tw_flags |= TW_SEXP;
-    tw.tw_flags &= ~TW_SZONE;
     tw.tw_flags |= TW_SZEXP;
 
     tw.tw_clock = *clock;
 
-    return (&tw);
+    return &tw;
 }
 
 
@@ -168,12 +161,11 @@ dgmtime (time_t *clock)
 
     tw.tw_flags &= ~TW_SDAY;
     tw.tw_flags |= TW_SEXP;
-    tw.tw_flags &= ~TW_SZONE;
     tw.tw_flags |= TW_SZEXP;
 
     tw.tw_clock = *clock;
 
-    return (&tw);
+    return &tw;
 }
 
 
@@ -192,10 +184,10 @@ dctime (struct tws *tw)
     if (!tw)
        return NULL;
 
-    snprintf (buffer, sizeof(buffer), "%.3s %.3s %02d %02d:%02d:%02d %.4d\n",
+    snprintf (buffer, sizeof(buffer), "%.3s %.3s %02d %02d:%02d:%02d %s\n",
            tw_dotw[tw->tw_wday], tw_moty[tw->tw_mon], tw->tw_mday,
            tw->tw_hour, tw->tw_min, tw->tw_sec,
-           tw->tw_year < 100 ? tw->tw_year + 1900 : tw->tw_year);
+           m_strn(tw->tw_year < 100 ? tw->tw_year + 1900 : tw->tw_year, 4));
 
     return buffer;
 }
@@ -207,8 +199,8 @@ dctime (struct tws *tw)
  *     Mon, 16 Jun 1992 15:30:48 -700 (or)
  *     Mon, 16 Jun 1992 15:30:48 EDT
  *
- * for the current time, as specified by rfc822.
- * The first form is required by rfc1123.
+ * for the current time, as specified by RFC 822.
+ * The first form is required by RFC 1123.
  */
 
 char *
@@ -228,8 +220,8 @@ dtimenow (int alpha_timezone)
  *     Mon, 16 Jun 1992 15:30:48 -700  (or)
  *     Mon, 16 Jun 1992 15:30:48 EDT
  *
- * as specified by rfc822.  The first form is required
- * by rfc1123 for outgoing messages.
+ * as specified by RFC 822.  The first form is required
+ * by RFC 1123 for outgoing messages.
  */
 
 char *
@@ -238,9 +230,9 @@ dtime (time_t *clock, int alpha_timezone)
     if (alpha_timezone)
        /* use alpha-numeric timezones */
        return dasctime (dlocaltime (clock), TW_NULL);
-    else
-       /* use numeric timezones */
-       return dasctime (dlocaltime (clock), TW_ZONE);
+
+    /* use numeric timezones */
+    return dasctime (dlocaltime (clock), TW_ZONE);
 }
 
 
@@ -250,7 +242,7 @@ dtime (time_t *clock, int alpha_timezone)
  *
  *     Mon, 16 Jun 1992 15:30:48 -0700
  *
- * as specified by rfc822 and rfc1123.
+ * as specified by RFC 822 and RFC 1123.
  */
 
 char *
@@ -258,62 +250,58 @@ dasctime (struct tws *tw, int flags)
 {
     char buffer[80];
     static char result[80];
+    int twf;
 
     if (!tw)
        return NULL;
 
     /* Display timezone if known */
-    if ((tw->tw_flags & TW_SZONE) == TW_SZNIL)
-       result[0] = '\0';
-    else
+    if (tw->tw_flags & TW_SZEXP)
        snprintf(result, sizeof(result), " %s", dtimezone(tw->tw_zone, tw->tw_flags | flags));
+    else
+       result[0] = '\0';
 
     snprintf(buffer, sizeof(buffer), "%02d %s %0*d %02d:%02d:%02d%s",
            tw->tw_mday, tw_moty[tw->tw_mon],
            tw->tw_year < 100 ? 2 : 4, tw->tw_year,
            tw->tw_hour, tw->tw_min, tw->tw_sec, result);
 
-    if ((tw->tw_flags & TW_SDAY) == TW_SEXP)
-       snprintf (result, sizeof(result), "%s, %s", tw_dotw[tw->tw_wday], buffer);
-    else
-       if ((tw->tw_flags & TW_SDAY) == TW_SNIL)
-           strncpy (result, buffer, sizeof(result));
-       else
-           snprintf (result, sizeof(result), "%s (%s)", buffer, tw_dotw[tw->tw_wday]);
+    if ((twf = tw->tw_flags & TW_SDAY)) {
+        if (twf == TW_SEXP)
+            snprintf(result, sizeof(result), "%s, %s", tw_dotw[tw->tw_wday], buffer);
+        else
+           snprintf(result, sizeof(result), "%s (%s)", buffer, tw_dotw[tw->tw_wday]);
+    } else
+        strncpy(result, buffer, sizeof(result));
 
     return result;
 }
 
 
 /*
- * Get the timezone for given offset
+ * Get the timezone for given offset.
+ * This used to return a three-letter abbreviation for some offset
+ * values.  But not many.  Until there's a good way to do that,
+ * return the string representation of the numeric offset.
  */
 
-char *
-dtimezone (int offset, int flags)
+char *dtimezone(int offset, int flags)
 {
-    int hours, mins;
-    static char buffer[10];
-
-    if (offset < 0) {
-       mins = -((-offset) % 60);
-       hours = -((-offset) / 60);
-    } else {
-       mins = offset % 60;
-       hours = offset / 60;
-    }
+    static char buffer[sizeof "+3579139459"]; /* 2,147,483,648 / 60 = 35,791,394 */
+    bool pos;
+    unsigned os, hours, mins;
 
-    if (!(flags & TW_ZONE) && mins == 0) {
-       tzset();
-       return ((flags & TW_DST) ? tzname[1] : tzname[0]);
-    }
+    pos = offset >= 0;
+    os = pos ? offset : ~offset + 1; /* abs(3) undefined on INT_MIN. */
+    hours = os / 60;
+    mins = os % 60;
+
+    if (flags & TW_DST) /* Shift towards +infinity. */
+        hours += pos ? 1 : -1;
+
+    snprintf(buffer, sizeof(buffer), "%c%02u%02u",
+        pos ? '+' : '-', hours, mins);
 
-#ifdef ADJUST_NUMERIC_ONLY_TZ_OFFSETS_WRT_DST
-    if (flags & TW_DST)
-       hours += 1;
-#endif /* ADJUST_NUMERIC_ONLY_TZ_OFFSETS_WRT_DST */
-    snprintf (buffer, sizeof(buffer), "%s%02d%02d",
-               offset < 0 ? "-" : "+", abs (hours), abs (mins));
     return buffer;
 }
 
@@ -357,12 +345,15 @@ dmktime (struct tws *tw)
     while (--mon)
        result += dmsize[mon - 1];
     result += mday - 1;
-    result = 24 * result + hour;
-    result = 60 * result + min;
-    result = 60 * result + sec;
+    result *= 24; /* Days to hours. */
+    result += hour;
+    result *= 60; /* Hours to minutes. */
+    result += min;
+    result *= 60; /* Minutes to seconds. */
+    result += sec;
     result -= 60 * tw->tw_zone;
     if (tw->tw_flags & TW_DST)
-       result -= 60 * 60;
+       result -= 60 * 60; /* One hour. */
 
     return (tw->tw_clock = result);
 }
@@ -398,32 +389,8 @@ set_dotw (struct tws *tw)
     if (tw->tw_wday < 0)
        tw->tw_wday += 7;
 
-    tw->tw_flags &= ~TW_SDAY, tw->tw_flags |= TW_SIMP;
-}
-
-
-/*
- * Copy nmh time structure
- */
-
-void
-twscopy (struct tws *tb, struct tws *tw)
-{
-    *tb = *tw;  /* struct copy */
-
-#if 0
-    tb->tw_sec   = tw->tw_sec;
-    tb->tw_min   = tw->tw_min;
-    tb->tw_hour  = tw->tw_hour;
-    tb->tw_mday  = tw->tw_mday;
-    tb->tw_mon   = tw->tw_mon;
-    tb->tw_year  = tw->tw_year;
-    tb->tw_wday  = tw->tw_wday;
-    tb->tw_yday  = tw->tw_yday;
-    tb->tw_zone  = tw->tw_zone;
-    tb->tw_clock = tw->tw_clock;
-    tb->tw_flags = tw->tw_flags;
-#endif
+    tw->tw_flags &= ~TW_SDAY;
+    tw->tw_flags |= TW_SIMP;
 }
 
 
@@ -441,6 +408,6 @@ twsort (struct tws *tw1, struct tws *tw2)
     if (tw2->tw_clock == 0)
        dmktime (tw2);
 
-    return ((c1 = tw1->tw_clock) > (c2 = tw2->tw_clock) ? 1
-           : c1 == c2 ? 0 : -1);
+    return (c1 = tw1->tw_clock) > (c2 = tw2->tw_clock) ? 1
+           : c1 == c2 ? 0 : -1;
 }