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