]> diplodocus.org Git - nmh/blobdiff - sbr/dtime.c
Replaced use of snprintf() with memcpy()/memmove().
[nmh] / sbr / dtime.c
index 26b451daba8b18b6ce0a1beb22cf09a815ffdca2..0ed012b6b0d3697026dd11e202fd9a9f4c95a540 100644 (file)
@@ -5,21 +5,32 @@
  * complete copyright information.
  */
 
-#include <h/mh.h>   /* for snprintf() */
-#include <h/nmh.h>
-#include <h/utils.h>
-#include <h/tws.h>
+#include "h/mh.h"
+#include "dtime.h"
+#include "h/nmh.h"
+#include "h/utils.h"
+#include "h/tws.h"
 #include <time.h>
 
 #if !defined(HAVE_STRUCT_TM_TM_GMTOFF)
 extern long timezone;
 #endif
 
+/* Size of largest possible int representing a time zone offset in minutes:
+   2,147,483,648 / 60 = 35,791,394 */
+#define DTZ_BUFFER_SIZE (sizeof "+3579139459")
+
+/*
+ * 1 if leap year, 0 otherwise.
+ */
+#define        isleapyear01(y) \
+       (((y) % 4) ? 0 : (((y) % 100) ? 1 : (((y) % 400) ? 0 : 1)))
+
 /*
  * The number of days in the year, accounting for leap years
  */
 #define        dysize(y)       \
-       (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
+       (365 + isleapyear01(y))
 
 char *tw_moty[] = {
     "Jan", "Feb", "Mar", "Apr",
@@ -40,8 +51,13 @@ char *tw_ldotw[] = {
     "Saturday",  NULL
 };
 
-static int dmsize[] = {
-    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+static int dmsize[][12] = {
+    { /* Not a leap year */
+        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+    },
+    { /* Leap year: February = 29 */
+        31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+    }
 };
 
 
@@ -248,7 +264,8 @@ dtime (time_t *clock, int alpha_timezone)
 char *
 dasctime (struct tws *tw, int flags)
 {
-    char buffer[80];
+    char buffer[77];
+    char tzbuffer[DTZ_BUFFER_SIZE];
     static char result[80];
     int twf;
 
@@ -257,14 +274,14 @@ dasctime (struct tws *tw, int flags)
 
     /* Display timezone if known */
     if (tw->tw_flags & TW_SZEXP)
-       snprintf(result, sizeof(result), " %s", dtimezone(tw->tw_zone, tw->tw_flags | flags));
+       snprintf(tzbuffer, sizeof(tzbuffer), " %s", dtimezone(tw->tw_zone, tw->tw_flags | flags));
     else
-       result[0] = '\0';
+       tzbuffer[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);
+           tw->tw_hour, tw->tw_min, tw->tw_sec, tzbuffer);
 
     if ((twf = tw->tw_flags & TW_SDAY)) {
         if (twf == TW_SEXP)
@@ -288,7 +305,7 @@ dasctime (struct tws *tw, int flags)
 char *
 dtimezone(int offset, int flags)
 {
-    static char buffer[sizeof "+3579139459"]; /* 2,147,483,648 / 60 = 35,791,394 */
+    static char buffer[DTZ_BUFFER_SIZE];
     bool pos;
     unsigned os, hours, mins;
 
@@ -307,6 +324,16 @@ dtimezone(int offset, int flags)
 }
 
 
+/*
+ * Last day of month (1-12) in given year.
+ */
+
+int
+dmlastday(int year, int mon)
+{
+    return dmsize[isleapyear01 (year)][mon - 1];
+}
+
 /*
  * Convert nmh time structure for local "broken-down"
  * time to calendar time (clock value).  This routine
@@ -317,7 +344,7 @@ dtimezone(int offset, int flags)
 time_t
 dmktime (struct tws *tw)
 {
-    int i, sec, min, hour, mday, mon, year;
+    int i, sec, min, hour, mday, mon, year, *msize;
     time_t result;
 
     if (tw->tw_clock != 0)
@@ -341,10 +368,9 @@ dmktime (struct tws *tw)
 
     for (i = 1970; i < year; i++)
        result += dysize (i);
-    if (dysize (year) == 366 && mon >= 3)
-       result++;
+    msize = dmsize[isleapyear01 (year)];
     while (--mon)
-       result += dmsize[mon - 1];
+       result += msize[mon - 1];
     result += mday - 1;
     result *= 24; /* Days to hours. */
     result += hour;