diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/SConscript | 3 | ||||
-rw-r--r-- | src/mongo/util/time_support.cpp | 7 | ||||
-rw-r--r-- | src/mongo/util/time_support_test.cpp | 424 | ||||
-rw-r--r-- | src/third_party/SConscript | 9 | ||||
-rw-r--r-- | src/third_party/shim_tz.cpp | 2 | ||||
-rw-r--r-- | src/third_party/tz/SConscript | 3 | ||||
-rw-r--r-- | src/third_party/tz/timegm.c | 713 | ||||
-rw-r--r-- | src/third_party/tz/timegm_private.h | 181 | ||||
-rw-r--r-- | src/third_party/tz/timegm_tzfile.h | 93 |
9 files changed, 1433 insertions, 2 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index f543ac4c65c..65e09ed92aa 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -58,7 +58,8 @@ env.Library('foundation', '$BUILD_DIR/mongo/platform/platform', '$BUILD_DIR/mongo/util/concurrency/thread_name', '$BUILD_DIR/third_party/shim_allocator', - '$BUILD_DIR/third_party/shim_boost']) + '$BUILD_DIR/third_party/shim_boost', + '$BUILD_DIR/third_party/shim_tz']) env.CppUnitTest('text_test', 'util/text_test.cpp', LIBDEPS=['foundation']) env.CppUnitTest('util/time_support_test', 'util/time_support_test.cpp', LIBDEPS=['foundation']) diff --git a/src/mongo/util/time_support.cpp b/src/mongo/util/time_support.cpp index 01101aed21c..146d5ad02a4 100644 --- a/src/mongo/util/time_support.cpp +++ b/src/mongo/util/time_support.cpp @@ -40,6 +40,13 @@ #define snprintf _snprintf #endif +#ifdef __sunos__ +// Some versions of Solaris do not have timegm defined, so fall back to our implementation when +// building on Solaris. See SERVER-13446. +extern "C" time_t +timegm(struct tm *const tmp); +#endif + namespace mongo { // jsTime_virtual_skew is just for testing. a test command manipulates it. diff --git a/src/mongo/util/time_support_test.cpp b/src/mongo/util/time_support_test.cpp index d0fd28a8f39..318125c7fdb 100644 --- a/src/mongo/util/time_support_test.cpp +++ b/src/mongo/util/time_support_test.cpp @@ -321,5 +321,429 @@ namespace { ASSERT_NOT_OK(dateFromISOString("1970-01-01T00:00:00.x00Z").getStatus()); } + TEST(TimeParsing, LeapYears) { + StatusWith<Date_t> swull = dateFromISOString("1972-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 68169600000ULL); + + swull = dateFromISOString("1976-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 194400000000ULL); + + swull = dateFromISOString("1980-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 320630400000ULL); + + swull = dateFromISOString("1984-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 446860800000ULL); + + swull = dateFromISOString("1988-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 573091200000ULL); + + swull = dateFromISOString("1992-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 699321600000ULL); + + swull = dateFromISOString("1996-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 825552000000ULL); + + swull = dateFromISOString("2000-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 951782400000ULL); + + swull = dateFromISOString("2004-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 1078012800000ULL); + + swull = dateFromISOString("2008-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 1204243200000ULL); + + swull = dateFromISOString("2012-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 1330473600000ULL); + + swull = dateFromISOString("2016-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 1456704000000ULL); + + swull = dateFromISOString("2020-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 1582934400000ULL); + + swull = dateFromISOString("2024-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 1709164800000ULL); + + swull = dateFromISOString("2028-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 1835395200000ULL); + + swull = dateFromISOString("2032-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 1961625600000ULL); + + swull = dateFromISOString("2036-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 2087856000000ULL); + + if (!isTimeTSmall) { + swull = dateFromISOString("2040-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 2214086400000ULL); + + swull = dateFromISOString("2044-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 2340316800000ULL); + + swull = dateFromISOString("2048-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 2466547200000ULL); + + swull = dateFromISOString("2052-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 2592777600000ULL); + + swull = dateFromISOString("2056-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 2719008000000ULL); + + swull = dateFromISOString("2060-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 2845238400000ULL); + + swull = dateFromISOString("2064-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 2971468800000ULL); + + swull = dateFromISOString("2068-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 3097699200000ULL); + + swull = dateFromISOString("2072-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 3223929600000ULL); + + swull = dateFromISOString("2076-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 3350160000000ULL); + + swull = dateFromISOString("2080-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 3476390400000ULL); + + swull = dateFromISOString("2084-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 3602620800000ULL); + + swull = dateFromISOString("2088-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 3728851200000ULL); + + swull = dateFromISOString("2092-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 3855081600000ULL); + + swull = dateFromISOString("2096-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 3981312000000ULL); + + swull = dateFromISOString("2104-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 4233686400000ULL); + + swull = dateFromISOString("2108-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 4359916800000ULL); + + swull = dateFromISOString("2112-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 4486147200000ULL); + + swull = dateFromISOString("2116-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 4612377600000ULL); + + swull = dateFromISOString("2120-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 4738608000000ULL); + + swull = dateFromISOString("2124-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 4864838400000ULL); + + swull = dateFromISOString("2128-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 4991068800000ULL); + + swull = dateFromISOString("2132-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 5117299200000ULL); + + swull = dateFromISOString("2136-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 5243529600000ULL); + + swull = dateFromISOString("2140-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 5369760000000ULL); + + swull = dateFromISOString("2144-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 5495990400000ULL); + + swull = dateFromISOString("2148-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 5622220800000ULL); + + swull = dateFromISOString("2152-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 5748451200000ULL); + + swull = dateFromISOString("2156-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 5874681600000ULL); + + swull = dateFromISOString("2160-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 6000912000000ULL); + + swull = dateFromISOString("2164-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 6127142400000ULL); + + swull = dateFromISOString("2168-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 6253372800000ULL); + + swull = dateFromISOString("2172-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 6379603200000ULL); + + swull = dateFromISOString("2176-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 6505833600000ULL); + + swull = dateFromISOString("2180-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 6632064000000ULL); + + swull = dateFromISOString("2184-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 6758294400000ULL); + + swull = dateFromISOString("2188-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 6884524800000ULL); + + swull = dateFromISOString("2192-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 7010755200000ULL); + + swull = dateFromISOString("2196-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 7136985600000ULL); + + swull = dateFromISOString("2204-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 7389360000000ULL); + + swull = dateFromISOString("2208-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 7515590400000ULL); + + swull = dateFromISOString("2212-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 7641820800000ULL); + + swull = dateFromISOString("2216-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 7768051200000ULL); + + swull = dateFromISOString("2220-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 7894281600000ULL); + + swull = dateFromISOString("2224-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 8020512000000ULL); + + swull = dateFromISOString("2228-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 8146742400000ULL); + + swull = dateFromISOString("2232-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 8272972800000ULL); + + swull = dateFromISOString("2236-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 8399203200000ULL); + + swull = dateFromISOString("2240-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 8525433600000ULL); + + swull = dateFromISOString("2244-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 8651664000000ULL); + + swull = dateFromISOString("2248-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 8777894400000ULL); + + swull = dateFromISOString("2252-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 8904124800000ULL); + + swull = dateFromISOString("2256-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 9030355200000ULL); + + swull = dateFromISOString("2260-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 9156585600000ULL); + + swull = dateFromISOString("2264-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 9282816000000ULL); + + swull = dateFromISOString("2268-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 9409046400000ULL); + + swull = dateFromISOString("2272-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 9535276800000ULL); + + swull = dateFromISOString("2276-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 9661507200000ULL); + + swull = dateFromISOString("2280-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 9787737600000ULL); + + swull = dateFromISOString("2284-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 9913968000000ULL); + + swull = dateFromISOString("2288-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 10040198400000ULL); + + swull = dateFromISOString("2292-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 10166428800000ULL); + + swull = dateFromISOString("2296-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 10292659200000ULL); + + swull = dateFromISOString("2304-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 10545033600000ULL); + + swull = dateFromISOString("2308-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 10671264000000ULL); + + swull = dateFromISOString("2312-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 10797494400000ULL); + + swull = dateFromISOString("2316-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 10923724800000ULL); + + swull = dateFromISOString("2320-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 11049955200000ULL); + + swull = dateFromISOString("2324-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 11176185600000ULL); + + swull = dateFromISOString("2328-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 11302416000000ULL); + + swull = dateFromISOString("2332-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 11428646400000ULL); + + swull = dateFromISOString("2336-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 11554876800000ULL); + + swull = dateFromISOString("2340-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 11681107200000ULL); + + swull = dateFromISOString("2344-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 11807337600000ULL); + + swull = dateFromISOString("2348-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 11933568000000ULL); + + swull = dateFromISOString("2352-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 12059798400000ULL); + + swull = dateFromISOString("2356-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 12186028800000ULL); + + swull = dateFromISOString("2360-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 12312259200000ULL); + + swull = dateFromISOString("2364-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 12438489600000ULL); + + swull = dateFromISOString("2368-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 12564720000000ULL); + + swull = dateFromISOString("2372-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 12690950400000ULL); + + swull = dateFromISOString("2376-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 12817180800000ULL); + + swull = dateFromISOString("2380-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 12943411200000ULL); + + swull = dateFromISOString("2384-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 13069641600000ULL); + + swull = dateFromISOString("2388-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 13195872000000ULL); + + swull = dateFromISOString("2392-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 13322102400000ULL); + + swull = dateFromISOString("2396-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 13448332800000ULL); + + swull = dateFromISOString("2400-02-29T00:00:00.000Z"); + ASSERT_OK(swull.getStatus()); + ASSERT_EQUALS(swull.getValue(), 13574563200000ULL); + } + } + } // namespace } // namespace mongo diff --git a/src/third_party/SConscript b/src/third_party/SConscript index 2d368b87977..0040188156b 100644 --- a/src/third_party/SConscript +++ b/src/third_party/SConscript @@ -1,6 +1,6 @@ # -*- mode: python -*- -Import("env use_system_version_of_library windows darwin usev8") +Import("env use_system_version_of_library windows darwin usev8 solaris") env.SConscript( [ "murmurhash3/SConscript", @@ -92,3 +92,10 @@ else: env.SConscript('yaml-cpp-0.5.1/SConscript') env.Library("shim_yaml", ['shim_yaml.cpp'], LIBDEPS=['yaml-cpp-0.5.1/yaml']) + +if solaris: + env.Append(CPPPATH='$BUILD_DIR/third_party/tz') + env.SConscript('tz/SConscript') + env.Library('shim_tz', ['shim_tz.cpp'], LIBDEPS=['tz/tz']) +else: + env.Library('shim_tz', ['shim_tz.cpp'], LIBDEPS=[]) diff --git a/src/third_party/shim_tz.cpp b/src/third_party/shim_tz.cpp new file mode 100644 index 00000000000..f0aae0c9755 --- /dev/null +++ b/src/third_party/shim_tz.cpp @@ -0,0 +1,2 @@ +// This file intentionally blank. shim_tz.cpp is part of the third_party/tz library, which is just +// a placeholder for forwarding library dependencies. diff --git a/src/third_party/tz/SConscript b/src/third_party/tz/SConscript new file mode 100644 index 00000000000..b3449b6f513 --- /dev/null +++ b/src/third_party/tz/SConscript @@ -0,0 +1,3 @@ +Import("env") + +env.Library("tz", [ "timegm.c" ]) diff --git a/src/third_party/tz/timegm.c b/src/third_party/tz/timegm.c new file mode 100644 index 00000000000..e9227430010 --- /dev/null +++ b/src/third_party/tz/timegm.c @@ -0,0 +1,713 @@ +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** Leap second handling from Bradley White. +** POSIX-style TZ environment variable handling from Guy Harris. +*/ + +/*LINTLIBRARY*/ + +#include "timegm_private.h" +#include "timegm_tzfile.h" + +#ifndef TZ_ABBR_MAX_LEN +#define TZ_ABBR_MAX_LEN 16 +#endif /* !defined TZ_ABBR_MAX_LEN */ + +#ifndef TZ_ABBR_CHAR_SET +#define TZ_ABBR_CHAR_SET \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" +#endif /* !defined TZ_ABBR_CHAR_SET */ + +#ifndef TZ_ABBR_ERR_CHAR +#define TZ_ABBR_ERR_CHAR '_' +#endif /* !defined TZ_ABBR_ERR_CHAR */ + +/* +** SunOS 4.1.1 headers lack O_BINARY. +*/ + +#ifdef O_BINARY +#define OPEN_MODE (O_RDONLY | O_BINARY) +#endif /* defined O_BINARY */ +#ifndef O_BINARY +#define OPEN_MODE O_RDONLY +#endif /* !defined O_BINARY */ + +#ifndef WILDABBR +/* +** Someone might make incorrect use of a time zone abbreviation: +** 1. They might reference tzname[0] before calling tzset (explicitly +** or implicitly). +** 2. They might reference tzname[1] before calling tzset (explicitly +** or implicitly). +** 3. They might reference tzname[1] after setting to a time zone +** in which Daylight Saving Time is never observed. +** 4. They might reference tzname[0] after setting to a time zone +** in which Standard Time is never observed. +** 5. They might reference tm.TM_ZONE after calling offtime. +** What's best to do in the above cases is open to debate; +** for now, we just set things up so that in any of the five cases +** WILDABBR is used. Another possibility: initialize tzname[0] to the +** string "tzname[0] used before set", and similarly for the other cases. +** And another: initialize tzname[0] to "ERA", with an explanation in the +** manual page of what this "time zone abbreviation" means (doing this so +** that tzname[0] has the "normal" length of three characters). +*/ +#define WILDABBR " " +#endif /* !defined WILDABBR */ + +static const char wildabbr[] = WILDABBR; + +static const char gmt[] = "GMT"; + +struct ttinfo { /* time type information */ + int_fast32_t tt_gmtoff; /* UT offset in seconds */ + int tt_isdst; /* used to set tm_isdst */ + int tt_abbrind; /* abbreviation list index */ + int tt_ttisstd; /* TRUE if transition is std time */ + int tt_ttisgmt; /* TRUE if transition is UT */ +}; + +struct lsinfo { /* leap second information */ + time_t ls_trans; /* transition time */ + int_fast64_t ls_corr; /* correction to apply */ +}; + +#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) + +#ifdef TZNAME_MAX +#define MY_TZNAME_MAX TZNAME_MAX +#endif /* defined TZNAME_MAX */ +#ifndef TZNAME_MAX +#define MY_TZNAME_MAX 255 +#endif /* !defined TZNAME_MAX */ + +struct state { + int leapcnt; + int timecnt; + int typecnt; + int charcnt; + int goback; + int goahead; + time_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; + struct ttinfo ttis[TZ_MAX_TYPES]; + char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), + (2 * (MY_TZNAME_MAX + 1)))]; + struct lsinfo lsis[TZ_MAX_LEAPS]; + int defaulttype; /* for early times or if no transitions */ +}; + +struct rule { + int r_type; /* type of rule--see below */ + int r_day; /* day number of rule */ + int r_week; /* week number of rule */ + int r_mon; /* month number of rule */ + int_fast32_t r_time; /* transition time of rule */ +}; + +#define JULIAN_DAY 0 /* Jn - Julian day */ +#define DAY_OF_YEAR 1 /* n - day of year */ +#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ + +/* +** Prototypes for static functions. +*/ + +static void gmtload(struct state * sp); +static struct tm * gmtsub(const time_t * timep, int_fast32_t offset, + struct tm * tmp); +static int increment_overflow(int * number, int delta); +static int leaps_thru_end_of(int y) ATTRIBUTE_PURE; +static int increment_overflow32(int_fast32_t * number, int delta); +static int increment_overflow_time(time_t *t, int_fast32_t delta); +static int normalize_overflow32(int_fast32_t * tensptr, + int * unitsptr, int base); +static int normalize_overflow(int * tensptr, int * unitsptr, + int base); +static time_t time1(struct tm * tmp, + struct tm * (*funcp)(const time_t *, + int_fast32_t, struct tm *), + int_fast32_t offset); +static time_t time2(struct tm *tmp, + struct tm * (*funcp)(const time_t *, + int_fast32_t, struct tm*), + int_fast32_t offset, int * okayp); +static time_t time2sub(struct tm *tmp, + struct tm * (*funcp)(const time_t *, + int_fast32_t, struct tm*), + int_fast32_t offset, int * okayp, int do_norm_secs); +static struct tm * timesub(const time_t * timep, int_fast32_t offset, + const struct state * sp, struct tm * tmp); +static int tmcomp(const struct tm * atmp, + const struct tm * btmp); + +static struct state gmtmem; +#define gmtptr (&gmtmem) + +static int gmt_is_set; + +static const int mon_lengths[2][MONSPERYEAR] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static const int year_lengths[2] = { + DAYSPERNYEAR, DAYSPERLYEAR +}; + +static void +gmtload(struct state *const sp) +{ + memset(sp, 0, sizeof(struct state)); + sp->typecnt = 1; + sp->charcnt = 4; + sp->chars[0] = 'G'; + sp->chars[1] = 'M'; + sp->chars[2] = 'T'; +} + +/* +** gmtsub is to gmtime as localsub is to localtime. +*/ + +static struct tm * +gmtsub(const time_t *const timep, const int_fast32_t offset, + struct tm *const tmp) +{ + register struct tm * result; + + if (!gmt_is_set) { + gmt_is_set = TRUE; + if (gmtptr != NULL) + gmtload(gmtptr); + } + result = timesub(timep, offset, gmtptr, tmp); +#ifdef TM_ZONE + /* + ** Could get fancy here and deliver something such as + ** "UT+xxxx" or "UT-xxxx" if offset is non-zero, + ** but this is no time for a treasure hunt. + */ + tmp->TM_ZONE = offset ? wildabbr : gmtptr ? gmtptr->chars : gmt; +#endif /* defined TM_ZONE */ + return result; +} + +/* +** Return the number of leap years through the end of the given year +** where, to make the math easy, the answer for year zero is defined as zero. +*/ + +static int +leaps_thru_end_of(register const int y) +{ + return (y >= 0) ? (y / 4 - y / 100 + y / 400) : + -(leaps_thru_end_of(-(y + 1)) + 1); +} + +static struct tm * +timesub(const time_t *const timep, const int_fast32_t offset, + register const struct state *const sp, + register struct tm *const tmp) +{ + register const struct lsinfo * lp; + register time_t tdays; + register int idays; /* unsigned would be so 2003 */ + register int_fast64_t rem; + int y; + register const int * ip; + register int_fast64_t corr; + register int hit; + register int i; + + corr = 0; + hit = 0; + i = (sp == NULL) ? 0 : sp->leapcnt; + while (--i >= 0) { + lp = &sp->lsis[i]; + if (*timep >= lp->ls_trans) { + if (*timep == lp->ls_trans) { + hit = ((i == 0 && lp->ls_corr > 0) || + lp->ls_corr > sp->lsis[i - 1].ls_corr); + if (hit) + while (i > 0 && + sp->lsis[i].ls_trans == + sp->lsis[i - 1].ls_trans + 1 && + sp->lsis[i].ls_corr == + sp->lsis[i - 1].ls_corr + 1) { + ++hit; + --i; + } + } + corr = lp->ls_corr; + break; + } + } + y = EPOCH_YEAR; + tdays = *timep / SECSPERDAY; + rem = *timep - tdays * SECSPERDAY; + while (tdays < 0 || tdays >= year_lengths[isleap(y)]) { + int newy; + register time_t tdelta; + register int idelta; + register int leapdays; + + tdelta = tdays / DAYSPERLYEAR; + if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta) + && tdelta <= INT_MAX)) + return NULL; + idelta = tdelta; + if (idelta == 0) + idelta = (tdays < 0) ? -1 : 1; + newy = y; + if (increment_overflow(&newy, idelta)) + return NULL; + leapdays = leaps_thru_end_of(newy - 1) - + leaps_thru_end_of(y - 1); + tdays -= ((time_t) newy - y) * DAYSPERNYEAR; + tdays -= leapdays; + y = newy; + } + { + register int_fast32_t seconds; + + seconds = tdays * SECSPERDAY; + tdays = seconds / SECSPERDAY; + rem += seconds - tdays * SECSPERDAY; + } + /* + ** Given the range, we can now fearlessly cast... + */ + idays = tdays; + rem += offset - corr; + while (rem < 0) { + rem += SECSPERDAY; + --idays; + } + while (rem >= SECSPERDAY) { + rem -= SECSPERDAY; + ++idays; + } + while (idays < 0) { + if (increment_overflow(&y, -1)) + return NULL; + idays += year_lengths[isleap(y)]; + } + while (idays >= year_lengths[isleap(y)]) { + idays -= year_lengths[isleap(y)]; + if (increment_overflow(&y, 1)) + return NULL; + } + tmp->tm_year = y; + if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) + return NULL; + tmp->tm_yday = idays; + /* + ** The "extra" mods below avoid overflow problems. + */ + tmp->tm_wday = EPOCH_WDAY + + ((y - EPOCH_YEAR) % DAYSPERWEEK) * + (DAYSPERNYEAR % DAYSPERWEEK) + + leaps_thru_end_of(y - 1) - + leaps_thru_end_of(EPOCH_YEAR - 1) + + idays; + tmp->tm_wday %= DAYSPERWEEK; + if (tmp->tm_wday < 0) + tmp->tm_wday += DAYSPERWEEK; + tmp->tm_hour = (int) (rem / SECSPERHOUR); + rem %= SECSPERHOUR; + tmp->tm_min = (int) (rem / SECSPERMIN); + /* + ** A positive leap second requires a special + ** representation. This uses "... ??:59:60" et seq. + */ + tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; + ip = mon_lengths[isleap(y)]; + for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) + idays -= ip[tmp->tm_mon]; + tmp->tm_mday = (int) (idays + 1); + tmp->tm_isdst = 0; +#ifdef TM_GMTOFF + tmp->TM_GMTOFF = offset; +#endif /* defined TM_GMTOFF */ + return tmp; +} + +/* +** Adapted from code provided by Robert Elz, who writes: +** The "best" way to do mktime I think is based on an idea of Bob +** Kridle's (so its said...) from a long time ago. +** It does a binary search of the time_t space. Since time_t's are +** just 32 bits, its a max of 32 iterations (even at 64 bits it +** would still be very reasonable). +*/ + +#ifndef WRONG +#define WRONG (-1) +#endif /* !defined WRONG */ + +/* +** Normalize logic courtesy Paul Eggert. +*/ + +static int +increment_overflow(int *const ip, int j) +{ + register int const i = *ip; + + /* + ** If i >= 0 there can only be overflow if i + j > INT_MAX + ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. + ** If i < 0 there can only be overflow if i + j < INT_MIN + ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. + */ + if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) + return TRUE; + *ip += j; + return FALSE; +} + +static int +increment_overflow32(int_fast32_t *const lp, int const m) +{ + register int_fast32_t const l = *lp; + + if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) + return TRUE; + *lp += m; + return FALSE; +} + +static int +increment_overflow_time(time_t *tp, int_fast32_t j) +{ + /* + ** This is like + ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...', + ** except that it does the right thing even if *tp + j would overflow. + */ + if (! (j < 0 + ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp) + : *tp <= time_t_max - j)) + return TRUE; + *tp += j; + return FALSE; +} + +static int +normalize_overflow(int *const tensptr, int *const unitsptr, const int base) +{ + register int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return increment_overflow(tensptr, tensdelta); +} + +static int +normalize_overflow32(int_fast32_t *const tensptr, int *const unitsptr, + const int base) +{ + register int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return increment_overflow32(tensptr, tensdelta); +} + +static int +tmcomp(register const struct tm *const atmp, + register const struct tm *const btmp) +{ + register int result; + + if (atmp->tm_year != btmp->tm_year) + return atmp->tm_year < btmp->tm_year ? -1 : 1; + if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && + (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && + (result = (atmp->tm_min - btmp->tm_min)) == 0) + result = atmp->tm_sec - btmp->tm_sec; + return result; +} + +static time_t +time2sub(struct tm *const tmp, + struct tm *(*const funcp)(const time_t *, int_fast32_t, struct tm *), + const int_fast32_t offset, + int *const okayp, + const int do_norm_secs) +{ + register const struct state * sp; + register int dir; + register int i, j; + register int saved_seconds; + register int_fast32_t li; + register time_t lo; + register time_t hi; + int_fast32_t y; + time_t newt; + time_t t; + struct tm yourtm, mytm; + + *okayp = FALSE; + yourtm = *tmp; + if (do_norm_secs) { + if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, + SECSPERMIN)) + return WRONG; + } + if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) + return WRONG; + if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) + return WRONG; + y = yourtm.tm_year; + if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR)) + return WRONG; + /* + ** Turn y into an actual year number for now. + ** It is converted back to an offset from TM_YEAR_BASE later. + */ + if (increment_overflow32(&y, TM_YEAR_BASE)) + return WRONG; + while (yourtm.tm_mday <= 0) { + if (increment_overflow32(&y, -1)) + return WRONG; + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday += year_lengths[isleap(li)]; + } + while (yourtm.tm_mday > DAYSPERLYEAR) { + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday -= year_lengths[isleap(li)]; + if (increment_overflow32(&y, 1)) + return WRONG; + } + for ( ; ; ) { + i = mon_lengths[isleap(y)][yourtm.tm_mon]; + if (yourtm.tm_mday <= i) + break; + yourtm.tm_mday -= i; + if (++yourtm.tm_mon >= MONSPERYEAR) { + yourtm.tm_mon = 0; + if (increment_overflow32(&y, 1)) + return WRONG; + } + } + if (increment_overflow32(&y, -TM_YEAR_BASE)) + return WRONG; + yourtm.tm_year = y; + if (yourtm.tm_year != y) + return WRONG; + if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) + saved_seconds = 0; + else if (y + TM_YEAR_BASE < EPOCH_YEAR) { + /* + ** We can't set tm_sec to 0, because that might push the + ** time below the minimum representable time. + ** Set tm_sec to 59 instead. + ** This assumes that the minimum representable time is + ** not in the same minute that a leap second was deleted from, + ** which is a safer assumption than using 58 would be. + */ + if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) + return WRONG; + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = SECSPERMIN - 1; + } else { + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = 0; + } + /* + ** Do a binary search (this works whatever time_t's type is). + */ + if (!TYPE_SIGNED(time_t)) { + lo = 0; + hi = lo - 1; + } else { + lo = 1; + for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) + lo *= 2; + hi = -(lo + 1); + } + for ( ; ; ) { + t = lo / 2 + hi / 2; + if (t < lo) + t = lo; + else if (t > hi) + t = hi; + if ((*funcp)(&t, offset, &mytm) == NULL) { + /* + ** Assume that t is too extreme to be represented in + ** a struct tm; arrange things so that it is less + ** extreme on the next pass. + */ + dir = (t > 0) ? 1 : -1; + } else dir = tmcomp(&mytm, &yourtm); + if (dir != 0) { + if (t == lo) { + if (t == time_t_max) + return WRONG; + ++t; + ++lo; + } else if (t == hi) { + if (t == time_t_min) + return WRONG; + --t; + --hi; + } + if (lo > hi) + return WRONG; + if (dir > 0) + hi = t; + else lo = t; + continue; + } + if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) + break; + /* + ** Right time, wrong type. + ** Hunt for right time, right type. + ** It's okay to guess wrong since the guess + ** gets checked. + */ + sp = (const struct state *) gmtptr; + if (sp == NULL) + return WRONG; + for (i = sp->typecnt - 1; i >= 0; --i) { + if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) + continue; + for (j = sp->typecnt - 1; j >= 0; --j) { + if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) + continue; + newt = t + sp->ttis[j].tt_gmtoff - + sp->ttis[i].tt_gmtoff; + if ((*funcp)(&newt, offset, &mytm) == NULL) + continue; + if (tmcomp(&mytm, &yourtm) != 0) + continue; + if (mytm.tm_isdst != yourtm.tm_isdst) + continue; + /* + ** We have a match. + */ + t = newt; + goto label; + } + } + return WRONG; + } +label: + newt = t + saved_seconds; + if ((newt < t) != (saved_seconds < 0)) + return WRONG; + t = newt; + if ((*funcp)(&t, offset, tmp)) + *okayp = TRUE; + return t; +} + +static time_t +time2(struct tm * const tmp, + struct tm * (*const funcp)(const time_t *, int_fast32_t, struct tm *), + const int_fast32_t offset, + int *const okayp) +{ + time_t t; + + /* + ** First try without normalization of seconds + ** (in case tm_sec contains a value associated with a leap second). + ** If that fails, try with normalization of seconds. + */ + t = time2sub(tmp, funcp, offset, okayp, FALSE); + return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE); +} + +static time_t +time1(struct tm *const tmp, + struct tm *(*const funcp) (const time_t *, int_fast32_t, struct tm *), + const int_fast32_t offset) +{ + register time_t t; + register const struct state * sp; + register int samei, otheri; + register int sameind, otherind; + register int i; + register int nseen; + int seen[TZ_MAX_TYPES]; + int types[TZ_MAX_TYPES]; + int okay; + + if (tmp == NULL) { + errno = EINVAL; + return WRONG; + } + if (tmp->tm_isdst > 1) + tmp->tm_isdst = 1; + t = time2(tmp, funcp, offset, &okay); + if (okay) + return t; + if (tmp->tm_isdst < 0) +#ifdef PCTS + /* + ** POSIX Conformance Test Suite code courtesy Grant Sullivan. + */ + tmp->tm_isdst = 0; /* reset to std and try again */ +#else + return t; +#endif /* !defined PCTS */ + /* + ** We're supposed to assume that somebody took a time of one type + ** and did some math on it that yielded a "struct tm" that's bad. + ** We try to divine the type they started from and adjust to the + ** type they need. + */ + sp = (const struct state *) gmtptr; + if (sp == NULL) + return WRONG; + for (i = 0; i < sp->typecnt; ++i) + seen[i] = FALSE; + nseen = 0; + for (i = sp->timecnt - 1; i >= 0; --i) + if (!seen[sp->types[i]]) { + seen[sp->types[i]] = TRUE; + types[nseen++] = sp->types[i]; + } + for (sameind = 0; sameind < nseen; ++sameind) { + samei = types[sameind]; + if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) + continue; + for (otherind = 0; otherind < nseen; ++otherind) { + otheri = types[otherind]; + if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) + continue; + tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + t = time2(tmp, funcp, offset, &okay); + if (okay) + return t; + tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + } + } + return WRONG; +} + +time_t +timegm(struct tm *const tmp) +{ + if (tmp != NULL) + tmp->tm_isdst = 0; + return time1(tmp, gmtsub, 0L); +} diff --git a/src/third_party/tz/timegm_private.h b/src/third_party/tz/timegm_private.h new file mode 100644 index 00000000000..c5ed516f838 --- /dev/null +++ b/src/third_party/tz/timegm_private.h @@ -0,0 +1,181 @@ +#ifndef PRIVATE_H + +#define PRIVATE_H + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H 1 +#endif + +#define GRANDPARENTED "Local time zone must be set--see zic manual page" + +/* +** Nested includes +*/ + +#include "errno.h" +#include "string.h" +#include "limits.h" /* for CHAR_BIT et al. */ +#include "time.h" + +/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +#define is_digit(c) ((unsigned)(c) - '0' <= 9) + +/* +** Define HAVE_STDINT_H's default value here, rather than at the +** start, since __GLIBC__'s value depends on previously-included +** files. +** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.) +*/ +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H \ + (199901 <= __STDC_VERSION__ || \ + 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__))) +#endif /* !defined HAVE_STDINT_H */ + +#if HAVE_STDINT_H +#include "stdint.h" +#endif /* !HAVE_STDINT_H */ + +#ifndef HAVE_INTTYPES_H +# define HAVE_INTTYPES_H HAVE_STDINT_H +#endif +#if HAVE_INTTYPES_H +# include <inttypes.h> +#endif + +#ifndef INT_FAST64_MAX +/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */ +#if defined LLONG_MAX || defined __LONG_LONG_MAX__ +typedef long long int_fast64_t; +# ifdef LLONG_MAX +# define INT_FAST64_MIN LLONG_MIN +# define INT_FAST64_MAX LLONG_MAX +# else +# define INT_FAST64_MIN __LONG_LONG_MIN__ +# define INT_FAST64_MAX __LONG_LONG_MAX__ +# endif +# define SCNdFAST64 "lld" +#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#if (LONG_MAX >> 31) < 0xffffffff +Please use a compiler that supports a 64-bit integer type (or wider); +you may need to compile with "-DHAVE_STDINT_H". +#endif /* (LONG_MAX >> 31) < 0xffffffff */ +typedef long int_fast64_t; +# define INT_FAST64_MIN LONG_MIN +# define INT_FAST64_MAX LONG_MAX +# define SCNdFAST64 "ld" +#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#endif /* !defined INT_FAST64_MAX */ + +#ifndef INT_FAST32_MAX +# if INT_MAX >> 31 == 0 +typedef long int_fast32_t; +# else +typedef int int_fast32_t; +# endif +#endif + +#ifndef INTMAX_MAX +# if defined LLONG_MAX || defined __LONG_LONG_MAX__ +typedef long long intmax_t; +# define strtoimax strtoll +# define PRIdMAX "lld" +# ifdef LLONG_MAX +# define INTMAX_MAX LLONG_MAX +# define INTMAX_MIN LLONG_MIN +# else +# define INTMAX_MAX __LONG_LONG_MAX__ +# define INTMAX_MIN __LONG_LONG_MIN__ +# endif +# else +typedef long intmax_t; +# define strtoimax strtol +# define PRIdMAX "ld" +# define INTMAX_MAX LONG_MAX +# define INTMAX_MIN LONG_MIN +# endif +#endif + +#ifndef UINTMAX_MAX +# if defined ULLONG_MAX || defined __LONG_LONG_MAX__ +typedef unsigned long long uintmax_t; +# define PRIuMAX "llu" +# else +typedef unsigned long uintmax_t; +# define PRIuMAX "lu" +# endif +#endif + +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif /* !defined INT32_MAX */ +#ifndef INT32_MIN +#define INT32_MIN (-1 - INT32_MAX) +#endif /* !defined INT32_MIN */ + +#ifndef SIZE_MAX +#define SIZE_MAX ((size_t) -1) +#endif + +#if 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define ATTRIBUTE_CONST __attribute__ ((const)) +# define ATTRIBUTE_PURE __attribute__ ((__pure__)) +# define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define ATTRIBUTE_CONST /* empty */ +# define ATTRIBUTE_PURE /* empty */ +# define ATTRIBUTE_FORMAT(spec) /* empty */ +#endif + +#if !defined _Noreturn && __STDC_VERSION__ < 201112 +# if 2 < __GNUC__ + (8 <= __GNUC_MINOR__) +# define _Noreturn __attribute__ ((__noreturn__)) +# else +# define _Noreturn +# endif +#endif + +#if __STDC_VERSION__ < 199901 && !defined restrict +# define restrict /* empty */ +#endif + +#ifndef TRUE +#define TRUE 1 +#endif /* !defined TRUE */ + +#ifndef FALSE +#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 */ + +/* The minimum and maximum finite time values. */ +static time_t const time_t_min = + (TYPE_SIGNED(time_t) + ? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1) + : 0); +static time_t const time_t_max = + (TYPE_SIGNED(time_t) + ? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)) + : -1); + +#endif /* !defined PRIVATE_H */ diff --git a/src/third_party/tz/timegm_tzfile.h b/src/third_party/tz/timegm_tzfile.h new file mode 100644 index 00000000000..f1819d68bf9 --- /dev/null +++ b/src/third_party/tz/timegm_tzfile.h @@ -0,0 +1,93 @@ +#ifndef TZFILE_H + +#define TZFILE_H + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** In the current implementation, "tzset()" refuses to deal with files that +** exceed any of the limits below. +*/ + +#ifndef TZ_MAX_TIMES +#define TZ_MAX_TIMES 2000 +#endif /* !defined TZ_MAX_TIMES */ + +#ifndef TZ_MAX_TYPES +/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */ +#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ +#endif /* !defined TZ_MAX_TYPES */ + +#ifndef TZ_MAX_CHARS +#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ + /* (limited by what unsigned chars can hold) */ +#endif /* !defined TZ_MAX_CHARS */ + +#ifndef TZ_MAX_LEAPS +#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ +#endif /* !defined TZ_MAX_LEAPS */ + +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define HOURSPERDAY 24 +#define DAYSPERWEEK 7 +#define DAYSPERNYEAR 365 +#define DAYSPERLYEAR 366 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY) +#define MONSPERYEAR 12 + +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define TM_TUESDAY 2 +#define TM_WEDNESDAY 3 +#define TM_THURSDAY 4 +#define TM_FRIDAY 5 +#define TM_SATURDAY 6 + +#define TM_JANUARY 0 +#define TM_FEBRUARY 1 +#define TM_MARCH 2 +#define TM_APRIL 3 +#define TM_MAY 4 +#define TM_JUNE 5 +#define TM_JULY 6 +#define TM_AUGUST 7 +#define TM_SEPTEMBER 8 +#define TM_OCTOBER 9 +#define TM_NOVEMBER 10 +#define TM_DECEMBER 11 + +#define TM_YEAR_BASE 1900 + +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY TM_THURSDAY + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + +/* +** Since everything in isleap is modulo 400 (or a factor of 400), we know that +** isleap(y) == isleap(y % 400) +** and so +** isleap(a + b) == isleap((a + b) % 400) +** or +** isleap(a + b) == isleap(a % 400 + b % 400) +** This is true even if % means modulo rather than Fortran remainder +** (which is allowed by C89 but not C99). +** We use this to avoid addition overflow problems. +*/ + +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) + +#endif /* !defined TZFILE_H */ |