mirror of https://github.com/mongodb/mongo
SERVER-90147 Upgrade timelib.h to 2022.10 and timezone files to 2024a
Updates timelib.h to the latest available named version. Additionally modifies the import script such that it always downloads the latest tz dbs. Changes from the original commit to `master`: * `sbom.json` - deleted - does not exist at this point in time * `BUILD.bazel` - deleted - changes we're translated to `SConscript` No changes from `v8.0`. GitOrigin-RevId: 93858dfa4829f700932447e54bc13543a5fb256e
This commit is contained in:
parent
9be8e57f39
commit
c8e9f20da4
|
|
@ -52,7 +52,7 @@ a notice will be included in
|
|||
| [schemastore.org] | Apache-2.0 | 6847cfc3a1 | | |
|
||||
| [scons] | MIT | 3.1.2 | | |
|
||||
| [Snappy] | BSD-3-Clause | 1.1.7 | ✗ | ✗ |
|
||||
| [timelib] | MIT | 2022.04 | | ✗ |
|
||||
| [timelib] | MIT | 2022.10 | | ✗ |
|
||||
| [TomCrypt] | Public Domain | 1.18.2 | ✗ | ✗ |
|
||||
| [Unicode] | Unicode-DFS-2015 | 8.0.0 | ✗ | ✗ |
|
||||
| [libunwind] | MIT | 1.6.2 + changes | | ✗ |
|
||||
|
|
@ -62,6 +62,7 @@ a notice will be included in
|
|||
| [Zlib] | Zlib | 1.3 | ✗ | ✗ |
|
||||
| [Zstandard] | BSD-3-Clause | 1.5.5 | ✗ | ✗ |
|
||||
|
||||
|
||||
[abseil-cpp]: https://github.com/abseil/abseil-cpp
|
||||
[ASIO]: https://github.com/chriskohlhoff/asio
|
||||
[benchmark]: https://github.com/google/benchmark
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ functions:
|
|||
params:
|
||||
working_dir: src
|
||||
script: |
|
||||
cd src/third_party/timelib/zones
|
||||
cd src/third_party/timelib/dist/zones
|
||||
make timezonedb.zip CFLAGS=-DHAVE_SNPRINTF=1
|
||||
cp timezonedb.zip timezonedb-latest.zip
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ functions:
|
|||
aws_key: ${aws_key}
|
||||
aws_secret: ${aws_secret}
|
||||
local_files_include_filter:
|
||||
- src/src/third_party/timelib/zones/timezonedb-*.zip
|
||||
- src/src/third_party/timelib/dist/zones/timezonedb-*.zip
|
||||
remote_file: olson_tz_db/
|
||||
bucket: downloads.mongodb.org
|
||||
permissions: public-read
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ thirdPartyEnvironmentModifications = {
|
|||
# SAFEINT_USE_INTRINSICS=0 for overflow-safe constexpr multiply. See comment in SafeInt.hpp.
|
||||
'CPPDEFINES': [('SAFEINT_USE_INTRINSICS', 0)],
|
||||
},
|
||||
'timelib': {'CPPPATH': ['#/src/third_party/timelib'], },
|
||||
'timelib': {'CPPPATH': ['#/src/third_party/timelib/dist'], },
|
||||
'unwind': {},
|
||||
'mozjs': {
|
||||
'CPPPATH': [
|
||||
|
|
|
|||
|
|
@ -1,141 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -o verbose
|
||||
set -o errexit
|
||||
|
||||
# This script downloads and imports timelib
|
||||
# timelib does not use any autotools/cmake/config system to it is a simple import.
|
||||
|
||||
# This script is designed to run on Linux or Mac OS X
|
||||
#
|
||||
|
||||
VERSION=2022.04
|
||||
NAME=timelib
|
||||
TARBALL=$VERSION.tar.gz
|
||||
TARBALL_DIR=$NAME-$VERSION
|
||||
if grep -q Microsoft /proc/version; then
|
||||
TEMP_DIR=$(wslpath -u $(powershell.exe -Command "Get-ChildItem Env:TEMP | Get-Content | Write-Host"))
|
||||
else
|
||||
TEMP_DIR="/tmp"
|
||||
fi
|
||||
TEMP_DIR=$(mktemp -d $TEMP_DIR/$NAME.XXXXXX)
|
||||
DEST_DIR=`git rev-parse --show-toplevel`/src/third_party/$NAME
|
||||
|
||||
# Check prerequisites: re2c, wget
|
||||
if ! [ -x "$(command -v re2c)" ]; then
|
||||
echo 'Error: re2c is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v wget)" ]; then
|
||||
echo 'Error: wget is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Derick may not upload a tarball for a release. In that case, better to create a tarball manually.
|
||||
# Can create $TARBALL manually using the following commands. For example,
|
||||
# $ cd ~
|
||||
# $ VERSION=2022.04
|
||||
# $ TARBALL=$VERSION.tar.gz
|
||||
# $ git clone git@github.com:derickr/timelib.git
|
||||
# $ cd timelib
|
||||
# Derick made the change to v2022 branch for 2022.04 version
|
||||
# $ git checkout v2022
|
||||
# .git sub-directory is unnecessary in the tarball
|
||||
# $ rm -rf .git
|
||||
# $ cd ..
|
||||
# tarball directory should be in the directory timelib-$VERSION
|
||||
# $ mv timelib timelib-$VERSION
|
||||
# $ tar czvf $TARBALL timelib-$VERSION
|
||||
# $ mv $TARBALL ~/mongo/src/third_party/scripts
|
||||
if [ ! -f $TARBALL ]; then
|
||||
echo "Get tarball"
|
||||
wget https://github.com/derickr/timelib/archive/$TARBALL
|
||||
fi
|
||||
|
||||
echo $TARBALL
|
||||
tar -zxvf $TARBALL
|
||||
|
||||
rm -rf $TEMP_DIR
|
||||
mv $TARBALL_DIR $TEMP_DIR
|
||||
mkdir $DEST_DIR || true
|
||||
|
||||
cp -r $TEMP_DIR/* $DEST_DIR
|
||||
|
||||
cd $DEST_DIR
|
||||
|
||||
# Prune files
|
||||
rm -rf $DEST_DIR/tests
|
||||
rm $DEST_DIR/zones/old-tzcode-32-bit-output.tar.gz || true
|
||||
|
||||
# Create parsers
|
||||
echo "Creating parsers"
|
||||
make parse_date.c parse_iso_intervals.c
|
||||
|
||||
# Create SConscript file
|
||||
cat <<EOF > SConscript
|
||||
# This is a generated file, please do not modify. It is generated by
|
||||
# timelib_get_sources.sh
|
||||
|
||||
Import('env')
|
||||
|
||||
env = env.Clone()
|
||||
|
||||
try:
|
||||
env.AppendUnique(CCFLAGS=[
|
||||
'-DHAVE_GETTIMEOFDAY',
|
||||
'-DHAVE_STRING_H',
|
||||
])
|
||||
if env.TargetOSIs('windows'):
|
||||
env.AppendUnique(CCFLAGS=[
|
||||
'-DHAVE_IO_H',
|
||||
'-DHAVE_WINSOCK2_H',
|
||||
])
|
||||
|
||||
# C4996: '...': was declared deprecated
|
||||
env.Append(CCFLAGS=['/wd4996'])
|
||||
elif env.TargetOSIs('solaris'):
|
||||
env.AppendUnique(CCFLAGS=[
|
||||
'-DHAVE_DIRENT_H',
|
||||
'-DHAVE_STRINGS_H',
|
||||
'-DHAVE_UNISTD_H',
|
||||
'-D_POSIX_C_SOURCE=200112L',
|
||||
])
|
||||
elif env.TargetOSIs('darwin'):
|
||||
env.AppendUnique(CCFLAGS=[
|
||||
'-DHAVE_DIRENT_H',
|
||||
'-DHAVE_SYS_TIME_H',
|
||||
'-DHAVE_UNISTD_H',
|
||||
])
|
||||
else:
|
||||
env.AppendUnique(CCFLAGS=[
|
||||
'-DHAVE_DIRENT_H',
|
||||
'-DHAVE_SYS_TIME_H',
|
||||
'-DHAVE_UNISTD_H',
|
||||
'-D_GNU_SOURCE',
|
||||
])
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
env.Library(
|
||||
target='timelib',
|
||||
source=[
|
||||
'astro.c',
|
||||
'dow.c',
|
||||
'interval.c',
|
||||
'parse_date.c',
|
||||
'parse_iso_intervals.c',
|
||||
'parse_tz.c',
|
||||
'parse_posix.c',
|
||||
'parse_zoneinfo.c',
|
||||
'timelib.c',
|
||||
'tm2unixtime.c',
|
||||
'unixtime2tm.c',
|
||||
],
|
||||
LIBDEPS_TAGS=[
|
||||
'init-no-global-side-effects',
|
||||
],
|
||||
)
|
||||
EOF
|
||||
|
||||
echo "Done"
|
||||
|
|
@ -16,8 +16,10 @@ try:
|
|||
'-DHAVE_WINSOCK2_H',
|
||||
])
|
||||
|
||||
# C4996: '...': was declared deprecated
|
||||
env.Append(CCFLAGS=['/wd4996'])
|
||||
env.Append(CCFLAGS=[
|
||||
'/wd4067', # C4067: '...': expected a newline
|
||||
'/wd4996', # C4996: '...': was declared deprecated
|
||||
])
|
||||
elif env.TargetOSIs('solaris'):
|
||||
env.AppendUnique(CCFLAGS=[
|
||||
'-DHAVE_DIRENT_H',
|
||||
|
|
@ -44,17 +46,17 @@ except ValueError:
|
|||
env.Library(
|
||||
target='timelib',
|
||||
source=[
|
||||
'astro.c',
|
||||
'dow.c',
|
||||
'interval.c',
|
||||
'parse_date.c',
|
||||
'parse_iso_intervals.c',
|
||||
'parse_tz.c',
|
||||
'parse_posix.c',
|
||||
'parse_zoneinfo.c',
|
||||
'timelib.c',
|
||||
'tm2unixtime.c',
|
||||
'unixtime2tm.c',
|
||||
'dist/astro.c',
|
||||
'dist/dow.c',
|
||||
'dist/interval.c',
|
||||
'dist/parse_date.c',
|
||||
'dist/parse_iso_intervals.c',
|
||||
'dist/parse_tz.c',
|
||||
'dist/parse_posix.c',
|
||||
'dist/parse_zoneinfo.c',
|
||||
'dist/timelib.c',
|
||||
'dist/tm2unixtime.c',
|
||||
'dist/unixtime2tm.c',
|
||||
],
|
||||
LIBDEPS_TAGS=[
|
||||
'init-no-global-side-effects',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
FLAGS=-O0 -ggdb3 \
|
||||
-fPIC \
|
||||
-Wall -Werror -Wextra \
|
||||
-Wempty-body \
|
||||
-Wenum-compare \
|
||||
|
|
@ -24,23 +25,25 @@ FLAGS=-O0 -ggdb3 \
|
|||
-fno-exceptions \
|
||||
-fno-omit-frame-pointer \
|
||||
-fno-optimize-sibling-calls \
|
||||
-fsanitize=address \
|
||||
-fsanitize=undefined \
|
||||
-fstack-protector \
|
||||
-pedantic \
|
||||
-DHAVE_STDINT_H -DHAVE_GETTIMEOFDAY -DHAVE_UNISTD_H -DHAVE_DIRENT_H -I.# -DDEBUG_PARSER
|
||||
|
||||
CFLAGS=-Wdeclaration-after-statement ${FLAGS}
|
||||
CFLAGS_BASE=-Wdeclaration-after-statement ${FLAGS}
|
||||
CFLAGS=-fsanitize=address -fsanitize=undefined ${CFLAGS_BASE}
|
||||
|
||||
CPPFLAGS=${FLAGS}
|
||||
CPPFLAGS=-fsanitize=address -fsanitize=undefined ${FLAGS}
|
||||
|
||||
LDFLAGS=-lm -fsanitize=undefined -l:libubsan.so
|
||||
LDFLAGS_BASE=-lm
|
||||
LDFLAGS=${LDFLAGS_BASE} -fsanitize=undefined -l:libubsan.so
|
||||
|
||||
TEST_LDFLAGS=-lCppUTest
|
||||
|
||||
CC=gcc
|
||||
CXX=g++
|
||||
|
||||
FILES=parse_iso_intervals.o parse_date.o unixtime2tm.o tm2unixtime.o dow.o parse_tz.o parse_zoneinfo.o timelib.o astro.o interval.o parse_posix.o
|
||||
|
||||
MANUAL_TESTS=tests/tester-parse-interval \
|
||||
tests/tester-iso-week tests/test-abbr-to-id \
|
||||
tests/enumerate-timezones tests/date_from_isodate
|
||||
|
|
@ -58,13 +61,13 @@ C_TESTS=tests/c/timelib_get_current_offset_test.o tests/c/timelib_decimal_hour.o
|
|||
tests/c/timelib_hmsf_to_decimal_hour.o tests/c/dow.o \
|
||||
tests/c/timelib_get_offset_info_test.o tests/c/add.o tests/c/sub.o
|
||||
|
||||
TEST_BINARIES=${MANUAL_TESTS} ${AUTO_TESTS}
|
||||
TEST_BINARIES=${MANUAL_TESTS} ${AUTO_TESTS} ctest
|
||||
|
||||
EXAMPLE_BINARIES=docs/date-from-iso-parts docs/date-from-parts docs/date-from-string \
|
||||
docs/date-to-parts docs/show-tzinfo
|
||||
|
||||
all: parse_date.o tm2unixtime.o unixtime2tm.o dow.o astro.o interval.o \
|
||||
${TEST_BINARIES} ${EXAMPLE_BINARIES} ctest
|
||||
all: parse_date.o tm2unixtime.o unixtime2tm.o dow.o astro.o interval.o timelib.a timelib.so \
|
||||
${TEST_BINARIES} ${EXAMPLE_BINARIES}
|
||||
|
||||
parse_date.c: timezonemap.h parse_date.re
|
||||
re2c -d -b parse_date.re > parse_date.c
|
||||
|
|
@ -72,8 +75,11 @@ parse_date.c: timezonemap.h parse_date.re
|
|||
parse_iso_intervals.c: parse_iso_intervals.re
|
||||
re2c -d -b parse_iso_intervals.re > parse_iso_intervals.c
|
||||
|
||||
timelib.a: parse_iso_intervals.o parse_date.o unixtime2tm.o tm2unixtime.o dow.o parse_tz.o parse_zoneinfo.o timelib.o astro.o interval.o parse_posix.o
|
||||
ar -rc timelib.a parse_iso_intervals.o parse_date.o unixtime2tm.o tm2unixtime.o dow.o parse_tz.o parse_zoneinfo.o timelib.o astro.o interval.o parse_posix.o
|
||||
timelib.a: ${FILES}
|
||||
ar -rc timelib.a ${FILES}
|
||||
|
||||
timelib.so: ${FILES}
|
||||
$(CC) $(CFLAGS_BASE) -shared -o timelib.so ${FILES} $(LDFLAGS_BASE)
|
||||
|
||||
tests/tester-diff: timelib.a tests/tester-diff.c
|
||||
$(CC) $(CFLAGS) -o tests/tester-diff tests/tester-diff.c timelib.a $(LDFLAGS)
|
||||
|
|
@ -136,13 +142,13 @@ clean-all: clean
|
|||
rm -f timezonemap.h
|
||||
|
||||
clean:
|
||||
rm -f parse_iso_intervals.c parse_date.c *.o tests/c/*.o timelib.a ${TEST_BINARIES}
|
||||
rm -f parse_iso_intervals.c parse_date.c *.o tests/c/*.o timelib.a timelib.so ${TEST_BINARIES}
|
||||
|
||||
#%.o: %.cpp timelib.a
|
||||
# $(CXX) -c $(CPPFLAGS) $(LDFLAGS) $< -o $@
|
||||
|
||||
ctest: tests/c/all_tests.cpp timelib.a ${C_TESTS}
|
||||
$(CXX) $(CPPFLAGS) $(LDFLAGS) tests/c/all_tests.cpp ${C_TESTS} timelib.a $(TEST_LDFLAGS) -o ctest
|
||||
$(CXX) $(CPPFLAGS) $(LDFLAGS) tests/c/all_tests.cpp ${C_TESTS} $(TEST_LDFLAGS) timelib.a -o ctest
|
||||
|
||||
test: ctest
|
||||
@./ctest -c
|
||||
|
|
@ -36,25 +36,6 @@ static void swap_times(timelib_time **one, timelib_time **two, timelib_rel_time
|
|||
rt->invert = 1;
|
||||
}
|
||||
|
||||
static void swap_if_negative(timelib_rel_time *rt)
|
||||
{
|
||||
if (rt->y == 0 && rt->m == 0 && rt->d == 0 && rt->h == 0 && rt->i == 0 && rt->s == 0 && rt->us == 0) {
|
||||
return;
|
||||
}
|
||||
if (rt->y >= 0 && rt->m >= 0 && rt->d >= 0 && rt->h >= 0 && rt->i >= 0 && rt->s >= 0 && rt->us >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
rt->invert = 1 - rt->invert;
|
||||
rt->y = 0 - rt->y;
|
||||
rt->m = 0 - rt->m;
|
||||
rt->d = 0 - rt->d;
|
||||
rt->h = 0 - rt->h;
|
||||
rt->i = 0 - rt->i;
|
||||
rt->s = 0 - rt->s;
|
||||
rt->us = 0 - rt->us;
|
||||
}
|
||||
|
||||
static void sort_old_to_new(timelib_time **one, timelib_time **two, timelib_rel_time *rt)
|
||||
{
|
||||
/* Check whether date/times need to be inverted. If both times are
|
||||
|
|
@ -115,80 +96,48 @@ static timelib_rel_time *timelib_diff_with_tzid(timelib_time *one, timelib_time
|
|||
rt->days = timelib_diff_days(one, two);
|
||||
|
||||
/* Fall Back: Cater for transition period, where rt->invert is 0, but there are negative numbers */
|
||||
if (one->dst == 1 && two->dst == 0) {
|
||||
/* First for two "Type 3" times */
|
||||
if (one->zone_type == TIMELIB_ZONETYPE_ID && two->zone_type == TIMELIB_ZONETYPE_ID) {
|
||||
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL);
|
||||
if (
|
||||
success &&
|
||||
one->sse < trans_transition_time &&
|
||||
one->sse >= trans_transition_time + dst_corr
|
||||
) {
|
||||
timelib_sll flipped = SECS_PER_HOUR + (rt->i * 60) + (rt->s);
|
||||
rt->h = flipped / SECS_PER_HOUR;
|
||||
rt->i = (flipped - rt->h * SECS_PER_HOUR) / 60;
|
||||
rt->s = flipped % 60;
|
||||
}
|
||||
} else if (rt->h == 0 && (rt->i < 0 || rt->s < 0)) {
|
||||
/* Then for all the others */
|
||||
timelib_sll flipped = SECS_PER_HOUR + (rt->i * 60) + (rt->s);
|
||||
rt->h = flipped / SECS_PER_HOUR;
|
||||
rt->i = (flipped - rt->h * SECS_PER_HOUR) / 60;
|
||||
rt->s = flipped % 60;
|
||||
dst_corr += SECS_PER_HOUR;
|
||||
dst_h_corr++;
|
||||
}
|
||||
if (two->sse < one->sse) {
|
||||
timelib_sll flipped = llabs((rt->i * 60) + (rt->s) - dst_corr);
|
||||
rt->h = flipped / SECS_PER_HOUR;
|
||||
rt->i = (flipped - rt->h * SECS_PER_HOUR) / 60;
|
||||
rt->s = flipped % 60;
|
||||
|
||||
rt->invert = 1 - rt->invert;
|
||||
}
|
||||
|
||||
timelib_do_rel_normalize(rt->invert ? one : two, rt);
|
||||
|
||||
/* Do corrections for "Type 3" times with the same TZID */
|
||||
if (one->zone_type == TIMELIB_ZONETYPE_ID && two->zone_type == TIMELIB_ZONETYPE_ID && strcmp(one->tz_info->name, two->tz_info->name) == 0) {
|
||||
if (one->dst == 1 && two->dst == 0) { /* Fall Back */
|
||||
if (two->tz_info) {
|
||||
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL);
|
||||
|
||||
if (
|
||||
success &&
|
||||
two->sse >= trans_transition_time &&
|
||||
((two->sse - one->sse + dst_corr) % SECS_PER_DAY) > (two->sse - trans_transition_time)
|
||||
) {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
}
|
||||
}
|
||||
} else if (one->dst == 0 && two->dst == 1) { /* Spring Forward */
|
||||
if (two->tz_info) {
|
||||
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL);
|
||||
|
||||
if (
|
||||
success &&
|
||||
!((one->sse + SECS_PER_DAY > trans_transition_time) && (one->sse + SECS_PER_DAY <= (trans_transition_time + dst_corr))) &&
|
||||
two->sse >= trans_transition_time &&
|
||||
((two->sse - one->sse + dst_corr) % SECS_PER_DAY) > (two->sse - trans_transition_time)
|
||||
) {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
}
|
||||
}
|
||||
} else if (two->sse - one->sse >= SECS_PER_DAY) {
|
||||
/* Check whether we're in the period to the next transition time */
|
||||
if (timelib_get_time_zone_offset_info(two->sse - two->z, two->tz_info, &trans_offset, &trans_transition_time, NULL)) {
|
||||
dst_corr = one->z - trans_offset;
|
||||
|
||||
if (two->sse >= trans_transition_time - dst_corr && two->sse < trans_transition_time) {
|
||||
rt->d--;
|
||||
rt->h = 24;
|
||||
}
|
||||
if (one->dst == 1 && two->dst == 0) { /* Fall Back */
|
||||
if (two->tz_info) {
|
||||
if ((two->sse - one->sse + dst_corr) < SECS_PER_DAY) {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
} else if (one->dst == 0 && two->dst == 1) { /* Spring Forward */
|
||||
if (two->tz_info) {
|
||||
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL);
|
||||
|
||||
swap_if_negative(rt);
|
||||
if (
|
||||
success &&
|
||||
!((one->sse + SECS_PER_DAY > trans_transition_time) && (one->sse + SECS_PER_DAY <= (trans_transition_time + dst_corr))) &&
|
||||
two->sse >= trans_transition_time &&
|
||||
((two->sse - one->sse + dst_corr) % SECS_PER_DAY) > (two->sse - trans_transition_time)
|
||||
) {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
}
|
||||
}
|
||||
} else if (two->sse - one->sse >= SECS_PER_DAY) {
|
||||
/* Check whether we're in the period to the next transition time */
|
||||
if (timelib_get_time_zone_offset_info(two->sse - two->z, two->tz_info, &trans_offset, &trans_transition_time, NULL)) {
|
||||
dst_corr = one->z - trans_offset;
|
||||
|
||||
timelib_do_rel_normalize(rt->invert ? one : two, rt);
|
||||
if (two->sse >= trans_transition_time - dst_corr && two->sse < trans_transition_time) {
|
||||
rt->d--;
|
||||
rt->h = 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rt;
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2019 Derick Rethans
|
||||
* Copyright (c) 2015-2023 Derick Rethans
|
||||
* Copyright (c) 2018 MongoDB, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
#include "timelib_private.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
|
@ -580,7 +581,13 @@ static timelib_ull timelib_get_signed_nr(Scanner *s, const char **ptr, int max_l
|
|||
++len;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
tmp_nr = strtoll(str, NULL, 10);
|
||||
if (errno == ERANGE) {
|
||||
timelib_free(str);
|
||||
add_error(s, TIMELIB_ERR_NUMBER_OUT_OF_RANGE, "Number out of range");
|
||||
return 0;
|
||||
}
|
||||
|
||||
timelib_free(str);
|
||||
|
||||
|
|
@ -654,9 +661,21 @@ static timelib_long timelib_get_month(const char **ptr)
|
|||
|
||||
static void timelib_eat_spaces(const char **ptr)
|
||||
{
|
||||
while (**ptr == ' ' || **ptr == '\t') {
|
||||
++*ptr;
|
||||
}
|
||||
do {
|
||||
if (**ptr == ' ' || **ptr == '\t') {
|
||||
++*ptr;
|
||||
continue;
|
||||
}
|
||||
if ((*ptr)[0] == '\xe2' && (*ptr)[1] == '\x80' && (*ptr)[2] == '\xaf') { // NNBSP
|
||||
*ptr += 3;
|
||||
continue;
|
||||
}
|
||||
if ((*ptr)[0] == '\xc2' && (*ptr)[1] == '\xa0') { // NBSP
|
||||
*ptr += 2;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
static void timelib_eat_until_separator(const char **ptr)
|
||||
|
|
@ -692,6 +711,17 @@ static const timelib_relunit* timelib_lookup_relunit(const char **ptr)
|
|||
return value;
|
||||
}
|
||||
|
||||
static void add_with_overflow(Scanner *s, timelib_sll *e, timelib_sll amount, int multiplier)
|
||||
{
|
||||
#if defined(__has_builtin) && __has_builtin(__builtin_saddll_overflow)
|
||||
if (__builtin_saddll_overflow(*e, amount * multiplier, e)) {
|
||||
add_error(s, TIMELIB_ERR_NUMBER_OUT_OF_RANGE, "Number out of range");
|
||||
}
|
||||
#else
|
||||
*e += (amount * multiplier);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The time_part parameter is a flag. It can be TIMELIB_TIME_PART_KEEP in case
|
||||
* the time portion should not be reset to midnight, or
|
||||
|
|
@ -707,13 +737,13 @@ static void timelib_set_relative(const char **ptr, timelib_sll amount, int behav
|
|||
}
|
||||
|
||||
switch (relunit->unit) {
|
||||
case TIMELIB_MICROSEC: s->time->relative.us += amount * relunit->multiplier; break;
|
||||
case TIMELIB_SECOND: s->time->relative.s += amount * relunit->multiplier; break;
|
||||
case TIMELIB_MINUTE: s->time->relative.i += amount * relunit->multiplier; break;
|
||||
case TIMELIB_HOUR: s->time->relative.h += amount * relunit->multiplier; break;
|
||||
case TIMELIB_DAY: s->time->relative.d += amount * relunit->multiplier; break;
|
||||
case TIMELIB_MONTH: s->time->relative.m += amount * relunit->multiplier; break;
|
||||
case TIMELIB_YEAR: s->time->relative.y += amount * relunit->multiplier; break;
|
||||
case TIMELIB_MICROSEC: add_with_overflow(s, &s->time->relative.us, amount, relunit->multiplier); break;
|
||||
case TIMELIB_SECOND: add_with_overflow(s, &s->time->relative.s, amount, relunit->multiplier); break;
|
||||
case TIMELIB_MINUTE: add_with_overflow(s, &s->time->relative.i, amount, relunit->multiplier); break;
|
||||
case TIMELIB_HOUR: add_with_overflow(s, &s->time->relative.h, amount, relunit->multiplier); break;
|
||||
case TIMELIB_DAY: add_with_overflow(s, &s->time->relative.d, amount, relunit->multiplier); break;
|
||||
case TIMELIB_MONTH: add_with_overflow(s, &s->time->relative.m, amount, relunit->multiplier); break;
|
||||
case TIMELIB_YEAR: add_with_overflow(s, &s->time->relative.y, amount, relunit->multiplier); break;
|
||||
|
||||
case TIMELIB_WEEKDAY:
|
||||
TIMELIB_HAVE_WEEKDAY_RELATIVE();
|
||||
|
|
@ -985,7 +1015,9 @@ std:
|
|||
/*!re2c
|
||||
any = [\000-\377];
|
||||
|
||||
space = [ \t]+;
|
||||
nbsp = [\302][\240];
|
||||
nnbsp = [\342][\200][\257];
|
||||
space = [ \t]+ | nbsp+ | nnbsp+;
|
||||
frac = "."[0-9]+;
|
||||
|
||||
ago = 'ago';
|
||||
|
|
@ -1312,6 +1344,7 @@ weekdayof = (reltextnumber|reltexttext) space (dayfulls|dayfull|dayabbr)
|
|||
s->time->s = timelib_get_nr(&ptr, 2);
|
||||
}
|
||||
}
|
||||
timelib_eat_spaces(&ptr);
|
||||
s->time->h += timelib_meridian(&ptr, s->time->h);
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_TIME12;
|
||||
|
|
@ -1739,6 +1772,9 @@ weekdayof = (reltextnumber|reltexttext) space (dayfulls|dayfull|dayabbr)
|
|||
s->time->h = timelib_get_nr(&ptr, 2);
|
||||
s->time->i = timelib_get_nr(&ptr, 2);
|
||||
s->time->s = timelib_get_nr(&ptr, 2);
|
||||
|
||||
timelib_eat_spaces(&ptr);
|
||||
|
||||
s->time->z = timelib_parse_zone(&ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
|
||||
if (tz_not_found) {
|
||||
add_error(s, TIMELIB_ERR_TZID_NOT_FOUND, "The timezone could not be found in the database");
|
||||
|
|
@ -1852,6 +1888,7 @@ weekdayof = (reltextnumber|reltexttext) space (dayfulls|dayfull|dayabbr)
|
|||
DEBUG_OUTPUT("tzcorrection | tz");
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_TZ();
|
||||
timelib_eat_spaces(&ptr);
|
||||
s->time->z = timelib_parse_zone(&ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb, tz_get_wrapper);
|
||||
if (tz_not_found) {
|
||||
add_error(s, TIMELIB_ERR_TZID_NOT_FOUND, "The timezone could not be found in the database");
|
||||
|
|
@ -1930,7 +1967,12 @@ weekdayof = (reltextnumber|reltexttext) space (dayfulls|dayfull|dayabbr)
|
|||
return TIMELIB_RELATIVE;
|
||||
}
|
||||
|
||||
[ .,\t]
|
||||
[.,]
|
||||
{
|
||||
goto std;
|
||||
}
|
||||
|
||||
space
|
||||
{
|
||||
goto std;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -187,14 +187,22 @@ timelib_long timelib_date_to_int(timelib_time *d, int *error)
|
|||
|
||||
void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec)
|
||||
{
|
||||
if (h > 0) {
|
||||
*hour = floor(h);
|
||||
*min = floor((h - *hour) * 60);
|
||||
*sec = (h - *hour - ((float) *min / 60)) * 3600;
|
||||
} else {
|
||||
*hour = ceil(h);
|
||||
*min = 0 - ceil((h - *hour) * 60);
|
||||
*sec = 0 - (h - *hour - ((float) *min / -60)) * 3600;
|
||||
bool swap = false;
|
||||
int seconds;
|
||||
|
||||
if (h < 0) {
|
||||
swap = true;
|
||||
h = fabs(h);
|
||||
}
|
||||
|
||||
*hour = floor(h);
|
||||
seconds = floor((h - *hour) * 3600);
|
||||
|
||||
*min = seconds / 60;
|
||||
*sec = seconds % 60;
|
||||
|
||||
if (swap) {
|
||||
*hour = 0 - *hour;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2022 Derick Rethans
|
||||
* Copyright (c) 2015-2023 Derick Rethans
|
||||
* Copyright (c) 2018,2021 MongoDB, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
@ -30,9 +30,9 @@
|
|||
# include "timelib_config.h"
|
||||
#endif
|
||||
|
||||
#define TIMELIB_VERSION 202204
|
||||
#define TIMELIB_EXTENDED_VERSION 20220401
|
||||
#define TIMELIB_ASCII_VERSION "2022.04"
|
||||
#define TIMELIB_VERSION 202210
|
||||
#define TIMELIB_EXTENDED_VERSION 20221001
|
||||
#define TIMELIB_ASCII_VERSION "2022.10"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
|
@ -321,6 +321,7 @@ typedef struct _timelib_abbr_info {
|
|||
#define TIMELIB_ERR_INVALID_TZ_OFFSET 0x223
|
||||
#define TIMELIB_ERR_FORMAT_LITERAL_MISMATCH 0x224
|
||||
#define TIMELIB_ERR_MIX_ISO_WITH_NATURAL 0x225
|
||||
#define TIMELIB_ERR_NUMBER_OUT_OF_RANGE 0x226
|
||||
|
||||
#define TIMELIB_ZONETYPE_NONE 0
|
||||
#define TIMELIB_ZONETYPE_OFFSET 1
|
||||
|
|
@ -378,7 +379,7 @@ typedef struct _timelib_tzdb {
|
|||
#define TIMELIB_OVERRIDE_TIME 0x01
|
||||
#define TIMELIB_NO_CLONE 0x02
|
||||
|
||||
#define TIMELIB_UNSET -99999
|
||||
#define TIMELIB_UNSET -9999999
|
||||
|
||||
/* An entry for each of these error codes is also in the
|
||||
* timelib_error_messages array in timelib.c.
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -32,8 +32,16 @@ static int days_in_month[13] = { 31, 31, 28, 31, 30, 31, 30, 31, 3
|
|||
static void do_range_limit(timelib_sll start, timelib_sll end, timelib_sll adj, timelib_sll *a, timelib_sll *b)
|
||||
{
|
||||
if (*a < start) {
|
||||
*b -= (start - *a - 1) / adj + 1;
|
||||
*a += adj * ((start - *a - 1) / adj + 1);
|
||||
/* We calculate 'a + 1' first as 'start - *a - 1' causes an int64_t overflows if *a is
|
||||
* LONG_MIN. 'start' is 0 in this context, and '0 - LONG_MIN > LONG_MAX'. */
|
||||
timelib_sll a_plus_1 = *a + 1;
|
||||
|
||||
*b -= (start - a_plus_1) / adj + 1;
|
||||
|
||||
/* This code add the extra 'adj' separately, as otherwise this can overflow int64_t in
|
||||
* situations where *b is near LONG_MIN. */
|
||||
*a += adj * ((start - a_plus_1) / adj);
|
||||
*a += adj;
|
||||
}
|
||||
if (*a >= end) {
|
||||
*b += *a / adj;
|
||||
|
|
@ -462,9 +470,15 @@ void timelib_update_ts(timelib_time* time, timelib_tzinfo* tzi)
|
|||
do_adjust_relative(time);
|
||||
do_adjust_special(time);
|
||||
|
||||
time->sse =
|
||||
(timelib_epoch_days_from_time(time) * SECS_PER_DAY) +
|
||||
timelib_hms_to_seconds(time->h, time->i, time->s);
|
||||
/* You might be wondering, why this code does this in two steps. This is because
|
||||
* timelib_epoch_days_from_time(time) * SECS_PER_DAY with the lowest limit of
|
||||
* timelib_epoch_days_from_time() is less than the range of an int64_t. This then overflows. In
|
||||
* order to be able to still allow for any time in that day that only halfly fits in the int64_t
|
||||
* range, we add the time element first, which is always positive, and then twice half the value
|
||||
* of the earliest day as expressed as unix timestamp. */
|
||||
time->sse = timelib_hms_to_seconds(time->h, time->i, time->s);
|
||||
time->sse += timelib_epoch_days_from_time(time) * (SECS_PER_DAY / 2);
|
||||
time->sse += timelib_epoch_days_from_time(time) * (SECS_PER_DAY / 2);
|
||||
|
||||
// This modifies time->sse, if needed
|
||||
do_adjust_timezone(time, tzi);
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,67 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# The script fetches the sources for 'derickr/timelib', downloads the latest Olson timezone
|
||||
# database and generates the necessary sources for the imports. The sources will be generated
|
||||
# inside 'src/third_party/timelib/dist/' and should be commited to the repository.
|
||||
#
|
||||
# The library does not use any autotools/cmake/config system to it, as it is a simple import.
|
||||
# This script is designed to run on Linux or Mac OS X.
|
||||
#
|
||||
# Usage: ./src/third_party/timelib/scripts/import.sh
|
||||
|
||||
VERSION=2022.10
|
||||
NAME=timelib
|
||||
|
||||
set -o verbose
|
||||
set -o errexit
|
||||
|
||||
if grep -q Microsoft /proc/version; then
|
||||
TEMP_DIR=$(wslpath -u $(powershell.exe -Command "Get-ChildItem Env:TEMP | Get-Content | Write-Host"))
|
||||
else
|
||||
TEMP_DIR="/tmp"
|
||||
fi
|
||||
TEMP_DIR=$(mktemp -d $TEMP_DIR/$NAME.XXXXXX)
|
||||
DEST_DIR=`git rev-parse --show-toplevel`/src/third_party/$NAME/dist
|
||||
|
||||
if [[ -d $DEST_DIR ]]; then
|
||||
echo "You must remove '$DEST_DIR' before running $0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check prerequisites: re2c, wget and php.
|
||||
if ! [ -x "$(command -v re2c)" ]; then
|
||||
echo 'Error: re2c is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v wget)" ]; then
|
||||
echo 'Error: wget is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v php)" ]; then
|
||||
echo 'Error: php is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $DEST_DIR
|
||||
pushd $TEMP_DIR
|
||||
git clone --branch $VERSION --depth 1 git@github.com:derickr/timelib.git .
|
||||
|
||||
# Avoid embedding the git repository itself.
|
||||
rm -rf .git*
|
||||
|
||||
# Prune unneeded files.
|
||||
rm -rf tests/
|
||||
|
||||
# Download the latest Olson timezone database and generate 'timezonedb.h'.
|
||||
make -C zones
|
||||
|
||||
# Generate the parsers.
|
||||
make parse_date.c parse_iso_intervals.c
|
||||
|
||||
# Clean up the build artifacts and copy the end sources to the destination directory.
|
||||
make -C zones clean
|
||||
cp -r * $DEST_DIR
|
||||
popd
|
||||
echo "Done"
|
||||
Loading…
Reference in New Issue