new common tz code
authorderaadt <deraadt@openbsd.org>
Mon, 29 Jan 1996 02:08:12 +0000 (02:08 +0000)
committerderaadt <deraadt@openbsd.org>
Mon, 29 Jan 1996 02:08:12 +0000 (02:08 +0000)
lib/libc/time/ctime.3
lib/libc/time/difftime.c
lib/libc/time/localtime.c
lib/libc/time/private.h
lib/libc/time/tzfile.h
lib/libc/time/zic.c

index f4aabc8..b0da26c 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $NetBSD: ctime.3,v 1.8 1996/01/08 22:50:54 jtc Exp $
+.\"    $NetBSD: ctime.3,v 1.9 1996/01/20 02:29:47 jtc Exp $
 .TH CTIME 3
 .SH NAME
 asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time to ASCII
@@ -56,13 +56,6 @@ return pointers to ``tm'' structures, described below.
 .I Localtime\^
 corrects for the time zone and any time zone adjustments
 (such as Daylight Saving Time in the U.S.A.).
-Before doing so,
-.I localtime\^
-calls
-.I tzset\^
-(if
-.I tzset\^
-has not been called in the current process).
 After filling in the ``tm'' structure,
 .I localtime
 sets the
@@ -218,4 +211,4 @@ will also be overwritten at the next call
 Avoid using out-of-range values with
 .I mktime
 when setting up lunch with promptness sticklers in Riyadh.
-.\" @(#)newctime.3     7.11
+.\" @(#)newctime.3     7.12
index 5f24fe8..cb8e48b 100644 (file)
@@ -1,8 +1,8 @@
-/*     $NetBSD: difftime.c,v 1.2 1995/03/09 23:41:15 jtc Exp $ */
+/*     $NetBSD: difftime.c,v 1.3 1996/01/20 02:30:46 jtc Exp $ */
 
 #ifndef lint
 #ifndef NOID
-static char    elsieid[] = "@(#)difftime.c     7.5";
+static char    elsieid[] = "@(#)difftime.c     7.6";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -45,9 +45,7 @@ const time_t  time0;
        /*
        ** Repair delta overflow.
        */
-       hibit = 1;
-       while ((hibit <<= 1) > 0)
-               continue;
+       hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1);
        /*
        ** The following expression rounds twice, which means
        ** the result may not be the closest to the true answer.
@@ -67,10 +65,10 @@ const time_t        time0;
        ** This problem occurs only with very large differences.
        ** It's too painful to fix this portably.
        ** We are not alone in this problem;
-       ** many C compilers round twice when converting
+       ** some C compilers round twice when converting
        ** large unsigned types to small floating types,
        ** so if time_t is unsigned the "return delta" above
-       ** has the same double-rounding problem.
+       ** has the same double-rounding problem with those compilers.
        */
        return delta - 2 * (long_double) hibit;
 }
index 79f88ef..7717d20 100644 (file)
@@ -1,8 +1,8 @@
-/*     $NetBSD: localtime.c,v 1.5 1996/01/08 22:50:55 jtc Exp $        */
+/*     $NetBSD: localtime.c,v 1.6 1996/01/20 02:31:04 jtc Exp $        */
 
 #ifndef lint
 #ifndef NOID
-static char    elsieid[] = "@(#)localtime.c    7.50";
+static char    elsieid[] = "@(#)localtime.c    7.53";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -1178,13 +1178,11 @@ register struct tm * const              tmp;
        tmp->tm_hour = (int) (rem / SECSPERHOUR);
        rem = rem % SECSPERHOUR;
        tmp->tm_min = (int) (rem / SECSPERMIN);
-       tmp->tm_sec = (int) (rem % SECSPERMIN);
-       if (hit)
-               /*
-               ** A positive leap second requires a special
-               ** representation.  This uses "... ??:59:60" et seq.
-               */
-               tmp->tm_sec += hit;
+       /*
+       ** A positive leap second requires a special
+       ** representation.  This uses "... ??:59:60" et seq.
+       */
+       tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
        tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
        if (tmp->tm_wday < 0)
                tmp->tm_wday += DAYSPERWEEK;
@@ -1357,17 +1355,16 @@ int * const             okayp;
                yourtm.tm_sec = 0;
        }
        /*
-       ** Calculate the number of magnitude bits in a time_t
-       ** (this works regardless of whether time_t is
-       ** signed or unsigned, though lint complains if unsigned).
+       ** Divide the search space in half
+       ** (this works whether time_t is signed or unsigned).
        */
-       for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
-               continue;
+       bits = TYPE_BIT(time_t) - 1;
        /*
-       ** If time_t is signed, then 0 is the median value,
-       ** if time_t is unsigned, then 1 << bits is median.
+       ** If time_t is signed, then 0 is just above the median,
+       ** assuming two's complement arithmetic.
+       ** If time_t is unsigned, then (1 << bits) is just above the median.
        */
-       t = (t < 0) ? 0 : ((time_t) 1 << bits);
+       t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits);
        for ( ; ; ) {
                (*funcp)(&t, offset, &mytm);
                dir = tmcomp(&mytm, &yourtm);
@@ -1375,10 +1372,10 @@ int * const             okayp;
                        if (bits-- < 0)
                                return WRONG;
                        if (bits < 0)
-                               --t;
+                               --t; /* may be needed if new t is minimal */
                        else if (dir > 0)
-                               t -= (time_t) 1 << bits;
-                       else    t += (time_t) 1 << bits;
+                               t -= ((time_t) 1) << bits;
+                       else    t += ((time_t) 1) << bits;
                        continue;
                }
                if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
index 684547c..bd04a66 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: private.h,v 1.4 1996/01/08 22:50:57 jtc Exp $  */
+/*     $NetBSD: private.h,v 1.5 1996/01/20 02:31:20 jtc Exp $  */
 
 #ifndef PRIVATE_H
 #define PRIVATE_H
@@ -23,7 +23,7 @@
 
 #ifndef lint
 #ifndef NOID
-static char    privatehid[] = "@(#)private.h   7.35";
+static char    privatehid[] = "@(#)private.h   7.39";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -44,6 +44,10 @@ static char  privatehid[] = "@(#)private.h   7.35";
 #define HAVE_UNISTD_H          1
 #endif /* !defined HAVE_UNISTD_H */
 
+#ifndef HAVE_UTMPX_H
+#define HAVE_UTMPX_H           0
+#endif /* !defined HAVE_UTMPX_H */
+
 #ifndef LOCALE_HOME
 #define LOCALE_HOME            "/usr/lib/locale"
 #endif /* !defined LOCALE_HOME */
@@ -161,22 +165,23 @@ extern int        unlink P((const char * filename));
 #define FALSE  0
 #endif /* !defined FALSE */
 
+#ifndef TYPE_BIT
+#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
+#endif /* !defined TYPE_BIT */
+
+#ifndef TYPE_SIGNED
+#define TYPE_SIGNED(type) (((type) -1) < 0)
+#endif /* !defined TYPE_SIGNED */
+
 #ifndef INT_STRLEN_MAXIMUM
 /*
 ** 302 / 1000 is log10(2.0) rounded up.
-** If type is signed:
-**     subtract one for the sign bit;
-**     add one for integer division truncation;
-**     add one more for a minus sign.
-** If type is unsigned:
-**     do not subtract one since there is no sign bit;
-**     add one for integer division truncation;
-**     do not add one more for a minus sign.
+** Subtract one for the sign bit if the type is signed;
+** add one for integer division truncation;
+** add one more for a minus sign if the type is signed.
 */
 #define INT_STRLEN_MAXIMUM(type) \
-               ((((type) -1) < 0) ? \
-                       ((sizeof(type) * CHAR_BIT - 1) * 302 / 1000 + 2) : \
-                       ((sizeof(type) * CHAR_BIT) * 302 / 1000 + 1))
+    ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 100 + 1 + TYPE_SIGNED(type))
 #endif /* !defined INT_STRLEN_MAXIMUM */
 
 /*
index 2510244..c1fe12f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: tzfile.h,v 1.3 1995/03/09 23:41:24 jtc Exp $   */
+/*     $NetBSD: tzfile.h,v 1.4 1996/01/20 02:31:34 jtc Exp $   */
 
 #ifndef TZFILE_H
 #define TZFILE_H
@@ -17,7 +17,7 @@
 
 #ifndef lint
 #ifndef NOID
-static char    tzfilehid[] = "@(#)tzfile.h     7.6";
+static char    tzfilehid[] = "@(#)tzfile.h     7.7";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -154,7 +154,7 @@ struct tzhead {
 ** that will probably do.
 */
 
-#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
 
 #ifndef USG
 
index ece2e3e..898c840 100644 (file)
@@ -1,8 +1,8 @@
-/*     $NetBSD: zic.c,v 1.3 1996/01/08 22:51:01 jtc Exp $      */
+/*     $NetBSD: zic.c,v 1.4 1996/01/20 02:31:50 jtc Exp $      */
 
 #ifndef lint
 #ifndef NOID
-static char    elsieid[] = "@(#)zic.c  7.57";
+static char    elsieid[] = "@(#)zic.c  7.59";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -587,9 +587,6 @@ const char * const  tofile;
 #define INT_MIN        ((int) ~(((unsigned)~0)>>1))
 #endif /* !defined INT_MIN */
 
-#define TIME_T_SIGNED (((time_t) -1) < 0)
-#define TIME_T_BIT (sizeof (time_t) * CHAR_BIT)
-
 /*
 ** The tz file format currently allows at most 32-bit quantities.
 ** This restriction should be removed before signed 32-bit values
@@ -598,13 +595,13 @@ const char * const        tofile;
 */
 
 #define MAX_BITS_IN_FILE       32
-#define TIME_T_BITS_IN_FILE    ((TIME_T_BIT < MAX_BITS_IN_FILE) ? \
-                                       TIME_T_BIT : MAX_BITS_IN_FILE)
+#define TIME_T_BITS_IN_FILE    ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? \
+                                       TYPE_BIT(time_t) : MAX_BITS_IN_FILE)
 
 static void
 setboundaries P((void))
 {
-       if (TIME_T_SIGNED) {
+       if (TYPE_SIGNED(time_t)) {
                min_time = ~ (time_t) 0;
                min_time <<= TIME_T_BITS_IN_FILE - 1;
                max_time = ~ (time_t) 0 - min_time;
@@ -1052,7 +1049,7 @@ const int         nfields;
                        return;
        }
        dayoff = oadd(dayoff, eitol(day - 1));
-       if (dayoff < 0 && !TIME_T_SIGNED) {
+       if (dayoff < 0 && !TYPE_SIGNED(time_t)) {
                error("time before zero");
                return;
        }
@@ -1928,7 +1925,7 @@ register const int                        wantedy;
                        (void) exit(EXIT_FAILURE);
                }
        }
-       if (dayoff < 0 && !TIME_T_SIGNED)
+       if (dayoff < 0 && !TYPE_SIGNED(time_t))
                return min_time;
        t = (time_t) dayoff * SECSPERDAY;
        /*
@@ -1971,7 +1968,7 @@ char * const      argname;
                ** DOS drive specifier?
                */
                if (isalpha((unsigned char) name[0]) &&
-                       name[1] == ':' && name[2] != '\0') {
+                       name[1] == ':' && name[2] == '\0') {
                                *cp = '/';
                                continue;
                }