Revision: 75340
          http://sourceforge.net/p/brlcad/code/75340
Author:   starseeker
Date:     2020-04-10 18:29:58 +0000 (Fri, 10 Apr 2020)
Log Message:
-----------
Make a stab at merging upstream y2038 changes

Modified Paths:
--------------
    brlcad/trunk/src/libbu/y2038/time64.c
    brlcad/trunk/src/libbu/y2038/time64.h

Modified: brlcad/trunk/src/libbu/y2038/time64.c
===================================================================
--- brlcad/trunk/src/libbu/y2038/time64.c       2020-04-10 17:46:43 UTC (rev 
75339)
+++ brlcad/trunk/src/libbu/y2038/time64.c       2020-04-10 18:29:58 UTC (rev 
75340)
@@ -1,4 +1,4 @@
-/*
+/* 
 
 Copyright (c) 2007-2010  Michael G Schwern
 
@@ -30,7 +30,7 @@
 
 Programmers who have available to them 64-bit time values as a 'long
 long' type can use localtime64_r() and gmtime64_r() which correctly
-converts the time even on 32-bit systems. Whether you have 64-bit time
+converts the time even on 32-bit systems. Whether you have 64-bit time 
 values will depend on the operating system.
 
 localtime64_r() is a 64-bit equivalent of localtime_r().
@@ -181,9 +181,13 @@
 #define CHEAT_DAYS  (1199145600 / 24 / 60 / 60)
 #define CHEAT_YEARS 108
 
-#define IS_LEAP(n)      ((!(((n) + 1900) % 400) || (!(((n) + 1900) % 4) && 
(((n) + 1900) % 100))) != 0)
-#define WRAP(a,b,m)     ((a) = ((a) <  0  ) ? ((b)--, (a) + (m)) : (a))
+/* IS_LEAP is used all over the place to index on arrays, so make sure it 
always returns 0 or 1. */
+#define IS_LEAP(n)  ( (!(((n) + 1900) % 400) || (!(((n) + 1900) % 4) && (((n) 
+ 1900) % 100))) ? 1 : 0 )
+#define IS_LEAP_ABS(n)  (!((n) % 400) || (!((n) % 4) && ((n) % 100) && ((n) > 
0)))
 
+/* Allegedly, some <termios.h> define a macro called WRAP, so use a longer 
name like WRAP_TIME64. */
+#define WRAP_TIME64(a,b,m)     ((a) = ((a) <  0  ) ? ((b)--, (a) + (m)) : (a))
+
 #ifdef USE_SYSTEM_LOCALTIME
 #    define SHOULD_USE_SYSTEM_LOCALTIME(a)  (       \
     (a) <= SYSTEM_LOCALTIME_MAX &&              \
@@ -229,7 +233,7 @@
    The result is like cmp.
    Ignores things like gmtoffset and dst
 */
-int cmp_date( const struct TM* left, const struct tm* right ) {
+static int cmp_date( const struct TM* left, const struct tm* right ) {
     if( left->tm_year > right->tm_year )
         return 1;
     else if( left->tm_year < right->tm_year )
@@ -265,9 +269,9 @@
 
 
 /* Check if a date is safely inside a range.
-   The intention is to check if it's a few days inside.
+   The intention is to check if its a few days inside.
 */
-int date_in_safe_range( const struct TM* date, const struct tm* min, const 
struct tm* max ) {
+static int date_in_safe_range( const struct TM* date, const struct tm* min, 
const struct tm* max ) {
     if( cmp_date(date, min) == -1 )
         return 0;
 
@@ -287,19 +291,19 @@
     Time64_T seconds = 0;
     Year     year;
     Year     orig_year = (Year)date->tm_year;
-    int      cycles  = 0;
+    Year     cycles  = 0;
 
     if( orig_year > 100 ) {
         cycles = (orig_year - 100) / 400;
         orig_year -= cycles * 400;
-        days      += (Time64_T)cycles * days_in_gregorian_cycle;
+        days      += cycles * days_in_gregorian_cycle;
     }
     else if( orig_year < -300 ) {
         cycles = (orig_year - 100) / 400;
         orig_year -= cycles * 400;
-        days      += (Time64_T)cycles * days_in_gregorian_cycle;
+        days      += cycles * days_in_gregorian_cycle;
     }
-    TIME64_TRACE3("# timegm/ cycles: %d, days: %lld, orig_year: %lld\n", 
cycles, days, orig_year);
+    TIME64_TRACE3("# timegm/ cycles: %"PRId64", days: %"PRId64", orig_year: 
%"PRId64"\n", cycles, days, orig_year);
 
     if( orig_year > 70 ) {
         year = 70;
@@ -343,7 +347,7 @@
     exceptions  = year_diff / 100;
     exceptions -= year_diff / 400;
 
-    TIME64_TRACE3("# year: %lld, exceptions: %lld, year_diff: %lld\n",
+    TIME64_TRACE3("# year: %"PRId64", exceptions: %"PRId64", year_diff: 
%"PRId64"\n",
           year, exceptions, year_diff);
 
     return exceptions * 16;
@@ -371,7 +375,7 @@
 */
 static int safe_year(const Year year)
 {
-    int ret = 0;
+    int safe_year;
     Year year_cycle;
 
     if( year >= MIN_SAFE_YEAR && year <= MAX_SAFE_YEAR ) {
@@ -393,28 +397,28 @@
         year_cycle += 17;
 
     year_cycle %= SOLAR_CYCLE_LENGTH;
-    if( year_cycle < 0 )
+    if( year_cycle < 0 ) 
         year_cycle = SOLAR_CYCLE_LENGTH + year_cycle;
 
     BU_ASSERT( year_cycle >= 0 );
     BU_ASSERT( year_cycle < SOLAR_CYCLE_LENGTH );
     if( year < MIN_SAFE_YEAR )
-        ret = safe_years_low[year_cycle];
+        safe_year = safe_years_low[year_cycle];
     else if( year > MAX_SAFE_YEAR )
-        ret = safe_years_high[year_cycle];
+        safe_year = safe_years_high[year_cycle];
     else
         bu_bomb("unexpected value for year");
 
-    TIME64_TRACE3("# year: %lld, year_cycle: %lld, safe_year: %d\n",
-          year, year_cycle, ret);
+    TIME64_TRACE3("# year: %"PRId64", year_cycle: %"PRId64", safe_year: %d\n",
+          year, year_cycle, safe_year);
 
-    BU_ASSERT(ret <= MAX_SAFE_YEAR && ret >= MIN_SAFE_YEAR);
+    BU_ASSERT(safe_year <= MAX_SAFE_YEAR && safe_year >= MIN_SAFE_YEAR);
 
-    return ret;
+    return safe_year;
 }
 
 
-void copy_tm_to_TM64(const struct tm *src, struct TM *dest) {
+static void copy_tm_to_TM64(const struct tm *src, struct TM *dest) {
     if( src == NULL ) {
         memset(dest, 0, sizeof(*dest));
     }
@@ -515,7 +519,7 @@
 static Time64_T seconds_between_years(Year left_year, Year right_year) {
     int increment = (left_year > right_year) ? 1 : -1;
     Time64_T seconds = 0;
-    int cycles;
+    Year cycles;
 
     if( left_year > 2400 ) {
         cycles = (left_year - 2400) / 400;
@@ -528,12 +532,23 @@
         seconds   += cycles * seconds_in_gregorian_cycle;
     }
 
-    while( left_year != right_year ) {
-        seconds += length_of_year[IS_LEAP(right_year - 1900)] * 60 * 60 * 24;
-        right_year += increment;
+    if (increment > 0) {
+        TIME64_TRACE2("year %"PRId64" > safe_year %"PRId64"\n", left_year, 
right_year);
+        while( left_year != right_year ) {
+            seconds += length_of_year[IS_LEAP_ABS(right_year)] * 60 * 60 * 24;
+            right_year++;
+        }
+        TIME64_TRACE1("adjust by %"PRId64" days\n", seconds / (60 * 60 * 24));
+        return seconds;
+    } else {
+        TIME64_TRACE2("year %"PRId64" < safe_year %"PRId64"\n", left_year, 
right_year);
+        while( left_year != right_year ) {
+            seconds -= length_of_year[IS_LEAP_ABS(right_year)] * 60 * 60 * 24;
+            right_year--;
+        }
+        TIME64_TRACE1("adjust by %"PRId64" days\n", seconds / (60 * 60 * 24));
+        return seconds;
     }
-
-    return seconds * increment;
 }
 
 
@@ -565,13 +580,14 @@
     date = *input_date;
     date.tm_year = safe_year(year) - 1900;
     copy_TM64_to_tm(&date, &safe_date);
-
     ytime = (Time64_T)mktime(&safe_date);
+    TIME64_TRACE1("mktime64: %"PRId64" seconds\n", time);
 
     /* Correct the user's possibly out of bound input date */
     copy_tm_to_TM64(&safe_date, input_date);
 
     ytime += seconds_between_years(year, (Year)(safe_date.tm_year + 1900));
+    TIME64_TRACE1("mktime64 => %"PRId64" seconds\n", time);
 
     return ytime;
 }
@@ -591,7 +607,7 @@
     Time64_T m;
     Time64_T ytime = *in_time;
     Year year = 70;
-    int cycles = 0;
+    Year cycles = 0;
 
     BU_ASSERT(p != NULL);
 
@@ -623,9 +639,9 @@
     ytime /= 24;
     v_tm_tday = ytime;
 
-    WRAP (v_tm_sec, v_tm_min, 60);
-    WRAP (v_tm_min, v_tm_hour, 60);
-    WRAP (v_tm_hour, v_tm_tday, 24);
+    WRAP_TIME64 (v_tm_sec, v_tm_min, 60);
+    WRAP_TIME64 (v_tm_min, v_tm_hour, 60);
+    WRAP_TIME64 (v_tm_hour, v_tm_tday, 24);
 
     v_tm_wday = (int)((v_tm_tday + 4) % 7);
     if (v_tm_wday < 0)
@@ -639,10 +655,10 @@
 
     if (m >= 0) {
         /* Gregorian cycles, this is huge optimization for distant times */
-        cycles = (int)(m / (Time64_T) days_in_gregorian_cycle);
+        cycles = m / (Time64_T) days_in_gregorian_cycle;
         if( cycles ) {
-            m -= (cycles * (Time64_T) days_in_gregorian_cycle);
-            year += (cycles * years_in_gregorian_cycle);
+            m -= cycles * (Time64_T) days_in_gregorian_cycle;
+            year += cycles * years_in_gregorian_cycle;
         }
 
         /* Years */
@@ -663,10 +679,10 @@
         year--;
 
         /* Gregorian cycles */
-        cycles = (int)((m / (Time64_T) days_in_gregorian_cycle) + 1);
+        cycles = (m / (Time64_T) days_in_gregorian_cycle) + 1;
         if( cycles ) {
-            m -= (cycles * (Time64_T) days_in_gregorian_cycle);
-            year += (cycles * years_in_gregorian_cycle);
+            m -= cycles * (Time64_T) days_in_gregorian_cycle;
+            year += cycles * years_in_gregorian_cycle;
         }
 
         /* Years */
@@ -686,7 +702,7 @@
         m += (Time64_T) days_in_month[leap][v_tm_mon];
     }
 
-    p->tm_year = year;
+      p->tm_year = year;
     if( p->tm_year != year ) {
 #ifdef EOVERFLOW
         errno = EOVERFLOW;
@@ -702,7 +718,7 @@
     p->tm_hour = v_tm_hour;
     p->tm_mon  = v_tm_mon;
     p->tm_wday = v_tm_wday;
-
+    
     return p;
 }
 
@@ -741,7 +757,7 @@
         gm_tm.tm_year < (1970 - 1900)
        )
     {
-        TIME64_TRACE1("Mapping tm_year %lld to safe_year\n", 
(Year)gm_tm.tm_year);
+        TIME64_TRACE1("Mapping tm_year %"PRId64" to safe_year\n", 
(Year)gm_tm.tm_year);
         gm_tm.tm_year = safe_year((Year)(gm_tm.tm_year + 1900)) - 1900;
     }
 
@@ -753,9 +769,9 @@
 
     copy_tm_to_TM64(&safe_date, local_tm);
 
-    local_tm->tm_year = orig_year;
+      local_tm->tm_year = orig_year;
     if( local_tm->tm_year != orig_year ) {
-        TIME64_TRACE2("tm_year overflow: tm_year %lld, orig_year %lld\n",
+        TIME64_TRACE2("tm_year overflow: tm_year %"PRId64", orig_year 
%"PRId64"\n",
               (Year)local_tm->tm_year, (Year)orig_year);
 
 #ifdef EOVERFLOW
@@ -781,7 +797,7 @@
         local_tm->tm_year++;
     }
 
-    /* GMT is Jan 1st, xx01 year, but localtime is still Dec 31st
+    /* GMT is Jan 1st, xx01 year, but localtime is still Dec 31st 
        in a non-leap xx00.  There is one point in the cycle
        we can't account for which the safe xx00 year is a leap
        year.  So we need to correct for Dec 31st coming out as

Modified: brlcad/trunk/src/libbu/y2038/time64.h
===================================================================
--- brlcad/trunk/src/libbu/y2038/time64.h       2020-04-10 17:46:43 UTC (rev 
75339)
+++ brlcad/trunk/src/libbu/y2038/time64.h       2020-04-10 18:29:58 UTC (rev 
75340)
@@ -20,12 +20,23 @@
 #include <time.h>
 #include "time64_config.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-
 /* Set our custom types */
-typedef INT_64_T       Time64_T;
-typedef INT_64_T       Year;
+typedef INT_64_T        Int64;
+typedef Int64           Time64_T;
+typedef Int64           Year;
 
+#ifndef PRId64
+# if (__WORDSIZE == 64) && !defined(__APPLE__)
+#  define PRId64 "ld"
+# else
+#  define PRId64 "lld"
+# endif
+#endif
+
 /* A copy of the tm struct but with a 64 bit year */
 struct TM64 {
         int     tm_sec;
@@ -43,7 +54,7 @@
 #endif
 
 #ifdef HAS_TM_TM_ZONE
-        char    *tm_zone;
+        const char *tm_zone;
 #endif
 };
 
@@ -52,7 +63,7 @@
 #define TM      TM64
 #else
 #define TM      tm
-#endif
+#endif   
 
 /* Declare public functions */
 Y2038_EXPORT struct TM *gmtime64_r    (const Time64_T *, struct TM *);
@@ -86,10 +97,13 @@
 
 /* Use a different asctime format depending on how big the year is */
 #ifdef USE_TM64
-    #define TM64_ASCTIME_FORMAT "%.3s %.3s%3d %.2d:%.2d:%.2d %lld\n"
+    #define TM64_ASCTIME_FORMAT "%.3s %.3s%3d %.2d:%.2d:%.2d %"PRId64"\n"
 #else
     #define TM64_ASCTIME_FORMAT "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n"
 #endif
 
+#ifdef __cplusplus
+  };
+#endif
 
 #endif

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to