Implement proper time zone support

Cosmopolitan now supports 104 time zones. They're embedded inside any
binary that links the localtime() function. Doing so adds about 100kb
to the binary size. This change also gets time zones working properly
on Windows for the first time. It's not needed to have /etc/localtime
exist on Windows, since we can get this information from WIN32. We're
also now updated to the latest version of Paul Eggert's TZ library.
pull/1170/head
Justine Tunney 2024-05-04 23:05:36 -07:00
parent d5ebb1fa5b
commit b0df6c1fce
No known key found for this signature in database
GPG Key ID: BE714B4575D6E328
627 changed files with 3052 additions and 2077 deletions

View File

@ -258,7 +258,7 @@ include libc/thread/BUILD.mk # │ You can finally call malloc()
include third_party/zlib/BUILD.mk # │
include libc/stdio/BUILD.mk # │
include tool/hello/BUILD.mk # │
include libc/time/BUILD.mk # │
include third_party/tz/BUILD.mk # │
include net/BUILD.mk # │
include third_party/vqsort/BUILD.mk # │
include libc/log/BUILD.mk # │
@ -440,7 +440,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_X \
THIRD_PARTY_GETOPT \
LIBC_LOG \
LIBC_TIME \
THIRD_PARTY_TZ \
THIRD_PARTY_OPENMP \
THIRD_PARTY_MUSL \
THIRD_PARTY_ZLIB_GZ \
@ -505,7 +505,6 @@ COSMOPOLITAN_H_PKGS = \
LIBC_STR \
LIBC_SYSV \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X \
LIBC_VGA \

View File

@ -35,7 +35,6 @@ DSP_MPEG_A_DIRECTDEPS = \
LIBC_STDIO \
LIBC_STR \
LIBC_SYSV \
LIBC_TIME \
LIBC_TINYMATH \
THIRD_PARTY_COMPILER_RT

View File

@ -39,7 +39,7 @@
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/x/x.h"
__static_yoink("pl_mpeg_notice");

View File

@ -31,7 +31,6 @@ DSP_SCALE_A_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_STR \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X

View File

@ -38,7 +38,6 @@ DSP_TTY_A_DIRECTDEPS = \
LIBC_SOCK \
LIBC_SYSV \
LIBC_TINYMATH \
LIBC_TIME \
LIBC_X
DSP_TTY_A_DEPS := \

View File

@ -65,7 +65,6 @@ EXAMPLES_DIRECTDEPS = \
LIBC_SYSV_CALLS \
LIBC_TESTLIB \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_VGA \
LIBC_X \
@ -89,6 +88,7 @@ EXAMPLES_DIRECTDEPS = \
THIRD_PARTY_SED \
THIRD_PARTY_STB \
THIRD_PARTY_TR \
THIRD_PARTY_TZ \
THIRD_PARTY_VQSORT \
THIRD_PARTY_XED \
THIRD_PARTY_ZLIB \

View File

@ -9,19 +9,30 @@
#endif
#include "libc/calls/calls.h"
#include "libc/calls/struct/timespec.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
#include "libc/nt/enum/timezoneid.h"
#include "libc/nt/struct/timezoneinformation.h"
#include "libc/nt/time.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/time/struct/tm.h"
#include "libc/thread/threads.h"
#include "libc/time.h"
/**
* @fileoverview High performance ISO-8601 timestamp formatter.
*
* The strftime() function is very slow. This goes much faster.
* Consider using something like this instead for your loggers.
*/
char *GetTimestamp(void) {
int x;
struct timespec ts;
_Thread_local static long last;
_Thread_local static char s[27];
_Thread_local static struct tm tm;
thread_local static long last;
thread_local static char s[32];
thread_local static struct tm tm;
clock_gettime(0, &ts);
if (ts.tv_sec != last) {
localtime_r(&ts.tv_sec, &tm);
@ -61,11 +72,21 @@ char *GetTimestamp(void) {
s[23] = '0' + x / 100000 % 10;
s[24] = '0' + x / 10000 % 10;
s[25] = '0' + x / 1000 % 10;
s[26] = tm.tm_gmtoff < 0 ? '-' : '+';
x = ABS(tm.tm_gmtoff) / 60 / 60;
s[27] = '0' + x / 10 % 10;
s[28] = '0' + x % 10;
x = ABS(tm.tm_gmtoff) / 60 % 60;
s[29] = '0' + x / 10 % 10;
s[30] = '0' + x % 10;
return s;
}
int main(int argc, char *argv[]) {
char buf[128], *p = buf;
// setenv("TZ", "UTC", true);
// setenv("TZ", "US/Eastern", true);
// setenv("TZ", "Asia/Kolkata", true);
p = stpcpy(p, GetTimestamp());
p = stpcpy(p, "\n");
write(1, buf, p - buf);

View File

@ -42,7 +42,7 @@
#include "libc/stdio/rand.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "third_party/zlib/zlib.h"
// clang-format off

View File

@ -71,7 +71,7 @@ Contact: antirez@gmail.com");
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/termios.h"
#include "libc/time/time.h"
#include "libc/time.h"
/* Syntax highlight types */
#define HL_NORMAL 0

15
examples/localtime.c Normal file
View File

@ -0,0 +1,15 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
To the extent possible under law, Justine Tunney has waived
all copyright and related or neighboring rights to this file,
as it is written in the following disclaimers:
http://unlicense.org/ │
http://creativecommons.org/publicdomain/zero/1.0/ │
*/
#endif
#include "libc/time.h"
int main(int argc, char *argv[]) {
int64_t t = 0;
localtime(&t);
}

View File

@ -44,7 +44,7 @@
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/w.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/x/xasprintf.h"
#include "libc/x/xsigaction.h"
#include "libc/zip.internal.h"

View File

@ -50,7 +50,7 @@
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/consts/termios.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "third_party/getopt/getopt.internal.h"
// clang-format off

View File

@ -17,7 +17,7 @@
#include "libc/sysv/consts/itimer.h"
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"
#include "libc/time/time.h"
#include "libc/time.h"
volatile bool gotalrm;

View File

@ -8,16 +8,18 @@
*/
#endif
#include "libc/calls/struct/stat.h"
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/mem/gc.h"
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/s.h"
#include "libc/x/xiso8601.h"
#include "libc/time.h"
/**
* @fileoverview File metadata viewer.
@ -27,6 +29,23 @@
bool numeric;
char *xiso8601(struct timespec ts) {
struct tm tm;
if (!localtime_r(&ts.tv_sec, &tm))
return 0;
int len = 128;
char *res = malloc(len);
char *ptr = res;
char *end = res + len;
if (!res)
return 0;
ptr += strftime(ptr, end - ptr, "%Y-%m-%d %H:%M:%S", &tm);
ptr += snprintf(ptr, end - ptr, ".%09ld", ts.tv_nsec);
ptr += strftime(ptr, end - ptr, "%z %Z", &tm);
unassert(ptr + 1 <= end);
return res;
}
const char *DescribeFileType(unsigned mode) {
switch (mode & S_IFMT) {
case S_IFIFO:
@ -74,16 +93,16 @@ void PrintFileMetadata(const char *pathname, struct stat *st) {
"%-32s%s\n"
"%-32s%s\n"
"%-32s%s\n",
"bytes in file", st->st_size, "physical bytes", st->st_blocks * 512,
"device id w/ file", st->st_dev, "inode", st->st_ino,
"hard link count", st->st_nlink, "mode / permissions", st->st_mode,
DescribeFileType(st->st_mode), "owner id", st->st_uid, "group id",
st->st_gid, "flags", st->st_flags, "gen", st->st_gen,
"device id (if special)", st->st_rdev, "block size", st->st_blksize,
"access time", gc(xiso8601(&st->st_atim)), "modified time",
gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
gc(xiso8601(&st->st_ctim)), "birthtime",
gc(xiso8601(&st->st_birthtim)));
"bytes in file:", st->st_size, "physical bytes:", st->st_blocks * 512,
"device id w/ file:", st->st_dev, "inode:", st->st_ino,
"hard link count:", st->st_nlink, "mode / permissions:", st->st_mode,
DescribeFileType(st->st_mode), "owner id:", st->st_uid,
"group id:", st->st_gid, "flags:", st->st_flags, "gen:", st->st_gen,
"device id (if special):", st->st_rdev, "block size:", st->st_blksize,
"access time:", gc(xiso8601(st->st_atim)),
"modified time:", gc(xiso8601(st->st_mtim)),
"c[omplicated]time:", gc(xiso8601(st->st_ctim)),
"[birthtime]:", gc(xiso8601(st->st_birthtim)));
}
int main(int argc, char *argv[]) {

View File

@ -16,7 +16,7 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/o.h"
#include "libc/time/struct/tm.h"
#include "libc/time.h"
#include "third_party/getopt/getopt.internal.h"
#include "third_party/musl/passwd.h"

View File

@ -300,7 +300,6 @@ o/$(MODE)/libc: o/$(MODE)/libc/calls \
o/$(MODE)/libc/sysv \
o/$(MODE)/libc/testlib \
o/$(MODE)/libc/thread \
o/$(MODE)/libc/time \
o/$(MODE)/libc/tinymath \
o/$(MODE)/libc/vga \
o/$(MODE)/libc/x \

View File

@ -23,7 +23,7 @@
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h"
#include "libc/time.h"
static int sys_clock_getres_poly(int clock, struct timespec *ts, int64_t real,
int64_t real_coarse, int64_t boot) {

View File

@ -19,7 +19,7 @@
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
#include "libc/sysv/consts/clock.h"
#include "libc/time/struct/timezone.h"
#include "libc/time.h"
/**
* Returns system wall time in microseconds, e.g.

View File

@ -22,7 +22,7 @@
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/struct/timezone.h"
#include "libc/time.h"
/**
* Changes time.

View File

@ -24,7 +24,7 @@
#include "libc/sysv/consts/clock.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Sleeps for particular number of seconds.

View File

@ -17,7 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/timeval.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Changes time, the old fashioned way.

View File

@ -1,7 +1,7 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_
#include "libc/calls/struct/timespec.h"
#include "libc/time/struct/timezone.h"
#include "libc/time.h"
COSMOPOLITAN_C_START_
struct timeval {

View File

@ -2,7 +2,7 @@
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_INTERNAL_H_
#include "libc/calls/struct/timeval.h"
#include "libc/mem/alloca.h"
#include "libc/time/struct/timezone.h"
#include "libc/time.h"
COSMOPOLITAN_C_START_
int sys_settimeofday(const struct timeval *, const struct timezone *);

View File

@ -16,7 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/calls/struct/timeval.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"

View File

@ -18,7 +18,7 @@
*/
#include "libc/calls/struct/timespec.h"
#include "libc/sysv/consts/clock.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Returns high-precision timestamp, the C11 way.

View File

@ -18,7 +18,7 @@
*/
#include "libc/calls/struct/timespec.h"
#include "libc/sysv/consts/clock.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Returns high-precision timestamp granularity, the C23 way.

View File

@ -21,7 +21,7 @@
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/utime.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Sleeps for particular number of microseconds.

View File

@ -16,8 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/utime.h"
#include "libc/calls/struct/timeval.h"
#include "libc/time/struct/utimbuf.h"
/**
* Changes last accessed/modified times on file.

View File

@ -33,7 +33,7 @@
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/utime.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h"
#include "libc/time.h"
static textwindows int sys_utimensat_nt_impl(int dirfd, const char *path,
const struct timespec ts[2],

View File

@ -24,7 +24,7 @@
#include "libc/fmt/conv.h"
#include "libc/runtime/zipos.internal.h"
#include "libc/sysv/consts/at.h"
#include "libc/time/time.h"
#include "libc/time.h"
int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
int flags) {

View File

@ -132,6 +132,14 @@ o/$(MODE)/libc/intrin/ktcpoptnames.o: libc/intrin/ktcpoptnames.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/stackcall.o: libc/intrin/stackcall.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/kmonthname.o: libc/intrin/kmonthname.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/kmonthnameshort.o: libc/intrin/kmonthnameshort.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/kweekdayname.o: libc/intrin/kweekdayname.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/kweekdaynameshort.o: libc/intrin/kweekdaynameshort.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
LIBC_INTRIN_LIBS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)))
LIBC_INTRIN_HDRS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_HDRS))

View File

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/ubsan.h"
#include "libc/calls/calls.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/pushpop.internal.h"
@ -241,6 +242,8 @@ static void __ubsan_warning(const struct UbsanSourceLocation *loc,
const char *description) {
kprintf("%s:%d: %subsan warning: %s is undefined behavior%s\n", loc->file,
loc->line, SUBTLE, description, RESET);
if (__ubsan_strict)
__ubsan_die()();
}
__wur __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc,

8
libc/intrin/ubsan.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef COSMOPOLITAN_LIBC_INTRIN_UBSAN_H_
#define COSMOPOLITAN_LIBC_INTRIN_UBSAN_H_
COSMOPOLITAN_C_START_
extern bool32 __ubsan_strict;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_INTRIN_UBSAN_H_ */

View File

@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Copyright 2024 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
@ -16,8 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/time/time.h"
char *tzname[2];
long timezone;
int daylight;
/**
* If set to true, UBSAN warnings will become fatal.
*/
bool32 __ubsan_strict = false;

View File

@ -7,5 +7,5 @@
#include "libc/calls/weirdtypes.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/consts/utime.h"
#include "libc/time/time.h"
#include "libc/time.h"
#endif

View File

@ -6,6 +6,5 @@
#include "libc/sock/select.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/itimer.h"
#include "libc/time/struct/timezone.h"
#include "libc/time/time.h"
#include "libc/time.h"
#endif

View File

@ -7,6 +7,5 @@
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/sched.h"
#include "libc/sysv/consts/timer.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
#endif /* _TIME_H */

View File

@ -9,7 +9,7 @@
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/ok.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/unistd.h"
#include "third_party/getopt/long1.h"
#include "third_party/musl/crypt.h"

View File

@ -1,5 +1,4 @@
#ifndef _UTIME_H
#define _UTIME_H
#include "libc/time/struct/utimbuf.h"
#include "libc/time/time.h"
#include "libc/utime.h"
#endif /* _UTIME_H */

View File

@ -5,5 +5,5 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/str/unicode.h"
#include "libc/time/time.h"
#include "libc/time.h"
#endif /* _WCHAR_H */

View File

@ -39,11 +39,11 @@ LIBC_LOG_A_DIRECTDEPS = \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_GDTOA
THIRD_PARTY_GDTOA \
THIRD_PARTY_TZ
LIBC_LOG_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_LOG_A_DIRECTDEPS),$($(x))))

View File

@ -37,8 +37,7 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
#define kNontrivialSize (8 * 1000 * 1000)

View File

@ -0,0 +1,8 @@
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_TIMEZONEID_H_
#define COSMOPOLITAN_LIBC_NT_ENUM_TIMEZONEID_H_
#define kNtTimeZoneIdUnknown 0
#define kNtTimeZoneIdStandard 1
#define kNtTimeZoneIdDaylight 2
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_TIMEZONEID_H_ */

View File

@ -0,0 +1,20 @@
#include "libc/nt/codegen.h"
.imp kernel32,__imp_GetDynamicTimeZoneInformation,GetDynamicTimeZoneInformation
.text.windows
.ftrace1
GetDynamicTimeZoneInformation:
.ftrace2
#ifdef __x86_64__
push %rbp
mov %rsp,%rbp
mov %rdi,%rcx
sub $32,%rsp
call *__imp_GetDynamicTimeZoneInformation(%rip)
leave
#elif defined(__aarch64__)
mov x0,#0
#endif
ret
.endfn GetDynamicTimeZoneInformation,globl
.previous

View File

@ -0,0 +1,20 @@
#include "libc/nt/codegen.h"
.imp kernel32,__imp_GetTimeZoneInformation,GetTimeZoneInformation
.text.windows
.ftrace1
GetTimeZoneInformation:
.ftrace2
#ifdef __x86_64__
push %rbp
mov %rsp,%rbp
mov %rdi,%rcx
sub $32,%rsp
call *__imp_GetTimeZoneInformation(%rip)
leave
#elif defined(__aarch64__)
mov x0,#0
#endif
ret
.endfn GetTimeZoneInformation,globl
.previous

View File

@ -168,6 +168,8 @@ imp 'GetSystemTimePreciseAsFileTime' GetSystemTimePreciseAsFileTime kernel3
imp 'GetSystemTimes' GetSystemTimes kernel32 3
imp 'GetTempPath' GetTempPathW kernel32 2
imp 'GetTempPathA' GetTempPathA kernel32 2
imp 'GetDynamicTimeZoneInformation' GetDynamicTimeZoneInformation kernel32 1
imp 'GetTimeZoneInformation' GetTimeZoneInformation kernel32 1
imp 'GetThreadContext' GetThreadContext kernel32 2
imp 'GetThreadDescription' GetThreadDescription kernel32 2
imp 'GetThreadIOPendingFlag' GetThreadIOPendingFlag kernel32 2

View File

@ -0,0 +1,17 @@
#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_DYNAMICTIMEZONEINFORMATION_H_
#define COSMOPOLITAN_LIBC_NT_STRUCT_DYNAMICTIMEZONEINFORMATION_H_
#include "libc/nt/struct/systemtime.h"
struct NtDynamicTimeZoneInformation {
int32_t Bias;
char16_t StandardName[32];
struct NtSystemTime StandardDate;
int32_t StandardBias;
char16_t DaylightName[32];
struct NtSystemTime DaylightDate;
int32_t DaylightBias;
char16_t TimeZoneKeyName[128];
bool32 DynamicDaylightTimeDisabled;
};
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_DYNAMICTIMEZONEINFORMATION_H_ */

View File

@ -0,0 +1,15 @@
#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_TIMEZONEINFORMATION_H_
#define COSMOPOLITAN_LIBC_NT_STRUCT_TIMEZONEINFORMATION_H_
#include "libc/nt/struct/systemtime.h"
struct NtTimeZoneInformation {
int Bias; /* in minutes e.g. +480 for -8:00 */
char16_t StandardName[32]; /* e.g. "Pacific Standard Time" */
struct NtSystemTime StandardDate;
int StandardBias;
char16_t DaylightName[32]; /* e.g. "Pacific Daylight Time" */
struct NtSystemTime DaylightDate;
int DaylightBias; /* e.g. -60 */
};
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_TIMEZONEINFORMATION_H_ */

37
libc/nt/time.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef COSMOPOLITAN_LIBC_NT_TIME_H_
#define COSMOPOLITAN_LIBC_NT_TIME_H_
#include "libc/nt/struct/dynamictimezoneinformation.h"
#include "libc/nt/struct/timezoneinformation.h"
COSMOPOLITAN_C_START_
/* ░░░░
cosmopolitan § new technology » time
*/
uint32_t GetTimeZoneInformation(
struct NtTimeZoneInformation *out_lpTimeZoneInformation);
uint32_t GetDynamicTimeZoneInformation(
struct NtDynamicTimeZoneInformation *out_lpTimeZoneInformation);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_NT_TIME_H_ */

View File

@ -22,7 +22,7 @@
#include "libc/calls/struct/timeval.h"
#include "libc/errno.h"
#include "libc/sysv/consts/rusage.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Returns sum of CPU time consumed by current process since birth.

View File

@ -28,7 +28,7 @@
#include "libc/runtime/clktck.h"
#include "libc/runtime/sysconf.h"
#include "libc/sysv/consts/rusage.h"
#include "libc/time/time.h"
#include "libc/time.h"
static dontinline long ConvertMicros(struct timeval tv) {
return tv.tv_sec * CLK_TCK + tv.tv_usec / (1000000 / CLK_TCK);

2
libc/runtime/hog.py Normal file
View File

@ -0,0 +1,2 @@
for i, c in enumerate("Asia/Kolkata"):
print("buf[%d] = '%c';" % (i, c))

View File

@ -42,7 +42,7 @@ LIBC_SOCK_A_DIRECTDEPS = \
LIBC_STR \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_TIME
THIRD_PARTY_TZ
LIBC_SOCK_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_SOCK_A_DIRECTDEPS),$($(x))))

View File

@ -38,7 +38,7 @@
#include "libc/sysv/consts/log.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/sock.h"
#include "libc/time/struct/tm.h"
#include "libc/time.h"
/* Note: log_facility should be initialized with LOG_USER by default,
* but since LOG_USER is not a constant value, we cannot initialize it

View File

@ -53,6 +53,12 @@ $(LIBC_STDIO_A).pkg: \
# offer assurances about the stack safety of cosmo libc
$(LIBC_STDIO_A_OBJS): private COPTS += -Wframe-larger-than=4096 -Walloca-larger-than=4096
$(LIBC_STDIO_A_OBJS): private \
CFLAGS += \
-fno-sanitize=all \
-Wframe-larger-than=4096 \
-Walloca-larger-than=4096
o/$(MODE)/libc/stdio/fputc.o: private \
CFLAGS += \
-O3

View File

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/fmt/internal.h"
#include "libc/stdckdint.h"

View File

@ -87,6 +87,13 @@ o/$(MODE)/libc/str/windowstimetotimespec.o: private \
CFLAGS += \
-O2
# we need -O3 because:
# we're dividing by constants
o/$(MODE)/libc/str/iso8601.o \
o/$(MODE)/libc/str/iso8601us.o: private \
CFLAGS += \
-O3
$(LIBC_STR_A_OBJS): private \
CFLAGS += \
-fno-sanitize=all \

View File

@ -18,7 +18,7 @@
*/
#include "libc/fmt/conv.h"
#include "libc/macros.internal.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Converts MS-DOS timestamp to UNIX.

View File

@ -17,8 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Converts timestamp to ISO-8601 formatted string.

View File

@ -17,8 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Converts timestamp to ISO-8601 formatted string.

View File

@ -16,7 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/time/time.h"
#include "libc/time.h"
const unsigned short kMonthYearDay[2][12] = {
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},

View File

@ -1,7 +1,7 @@
#ifndef COSMOPOLITAN_LIBC_STR_LOCALE_H_
#define COSMOPOLITAN_LIBC_STR_LOCALE_H_
#include "libc/fmt/conv.h"
#include "libc/time/struct/tm.h"
#include "libc/time.h"
#define LC_CTYPE 0
#define LC_NUMERIC 1
@ -21,7 +21,7 @@
COSMOPOLITAN_C_START_
#define LC_GLOBAL_LOCALE ((locale_t)-1)
#define LC_GLOBAL_LOCALE ((locale_t) - 1)
struct __locale_map {
const void *map;

View File

@ -104,13 +104,13 @@ LIBC_TESTLIB_A_DIRECTDEPS = \
LIBC_STR \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_GDTOA \
THIRD_PARTY_XED
THIRD_PARTY_XED \
THIRD_PARTY_TZ
LIBC_TESTLIB_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_TESTLIB_A_DIRECTDEPS),$($(x))))

View File

@ -29,6 +29,7 @@
#include "libc/intrin/getenv.internal.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/ubsan.h"
#include "libc/intrin/weaken.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
@ -93,6 +94,7 @@ dontasan int main(int argc, char *argv[]) {
struct Dll *e;
struct TestAspect *a;
__ubsan_strict = true;
__log_level = kLogInfo;
GetOpts(argc, argv);

View File

@ -23,7 +23,7 @@
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Schedules delivery of one-shot or intermittent interrupt signal, e.g.

View File

@ -1,5 +1,8 @@
#ifndef COSMOPOLITAN_LIBC_TIME_STRUCT_TM_H_
#define COSMOPOLITAN_LIBC_TIME_STRUCT_TM_H_
#ifndef COSMOPOLITAN_LIBC_TIME_H_
#define COSMOPOLITAN_LIBC_TIME_H_
#define TIME_UTC 1
COSMOPOLITAN_C_START_
struct tm {
@ -16,8 +19,18 @@ struct tm {
const char *tm_zone;
};
struct timezone {
int32_t tz_minuteswest;
int32_t tz_dsttime;
};
extern char *tzname[2];
extern long timezone;
extern int daylight;
void tzset(void) libcesque;
char *asctime(const struct tm *) libcesque;
char *asctime_r(const struct tm *, char[hasatleast 26]) libcesque;
char *asctime_r(const struct tm *, char *) libcesque;
char *strptime(const char *, const char *, struct tm *) libcesque;
int64_t mktime(struct tm *) libcesque;
int64_t timegm(struct tm *) libcesque;
@ -32,12 +45,24 @@ struct tm *gmtime_r(const int64_t *, struct tm *) libcesque;
struct tm *localtime(const int64_t *) libcesque;
struct tm *localtime_r(const int64_t *, struct tm *) libcesque;
char *ctime(const int64_t *) libcesque;
char *ctime_r(const int64_t *, char *) libcesque;
double difftime(int64_t, int64_t)
pureconst libcesque;
int stime(const int64_t *) libcesque;
void tzset(void) libcesque;
#ifdef _COSMO_SOURCE
#define iso8601 __iso8601
#define iso8601us __iso8601us
extern const char kWeekdayNameShort[7][4];
extern const char kWeekdayName[7][10];
extern const char kMonthNameShort[12][4];
extern const char kMonthName[12][10];
extern const unsigned short kMonthYearDay[2][12];
#define iso8601 __iso8601
char *iso8601(char[hasatleast 20], struct tm *) libcesque;
#define iso8601us __iso8601us
char *iso8601us(char[hasatleast 27], struct tm *, long) libcesque;
#endif /* _COSMO_SOURCE */
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_TIME_STRUCT_TM_H_ */
#endif /* COSMOPOLITAN_LIBC_TIME_H_ */

View File

@ -1,96 +0,0 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
PKGS += LIBC_TIME
LIBC_TIME_ARTIFACTS += LIBC_TIME_A
LIBC_TIME = $(LIBC_TIME_A_DEPS) $(LIBC_TIME_A)
LIBC_TIME_A = o/$(MODE)/libc/time/time.a
LIBC_TIME_A_FILES := $(wildcard libc/time/struct/*) $(wildcard libc/time/*)
LIBC_TIME_A_HDRS := $(filter %.h,$(LIBC_TIME_A_FILES))
LIBC_TIME_A_SRCS_S = $(filter %.S,$(LIBC_TIME_A_FILES))
LIBC_TIME_A_SRCS_C = $(filter %.c,$(LIBC_TIME_A_FILES))
LIBC_TIME_ZONEINFOS := \
$(wildcard usr/share/zoneinfo/*) \
$(wildcard usr/share/zoneinfo/US/*)
LIBC_TIME_A_SRCS = \
$(LIBC_TIME_A_SRCS_S) \
$(LIBC_TIME_A_SRCS_C)
LIBC_TIME_A_OBJS = \
$(LIBC_TIME_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(LIBC_TIME_A_SRCS_C:%.c=o/$(MODE)/%.o) \
$(LIBC_TIME_A_SRCS_C:%.c=o/$(MODE)/%.o) \
$(LIBC_TIME_ZONEINFOS:%=o/$(MODE)/%.zip.o) \
o/$(MODE)/usr/share/zoneinfo/.zip.o
LIBC_TIME_A_CHECKS = \
$(LIBC_TIME_A).pkg \
$(LIBC_TIME_A_HDRS:%=o/$(MODE)/%.ok)
LIBC_TIME_A_DIRECTDEPS = \
LIBC_CALLS \
LIBC_FMT \
LIBC_INTRIN \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_KERNEL32 \
LIBC_RUNTIME \
LIBC_STDIO \
LIBC_STR \
LIBC_SYSV \
THIRD_PARTY_COMPILER_RT
LIBC_TIME_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_TIME_A_DIRECTDEPS),$($(x))))
# offer assurances about the stack safety of cosmo libc
$(LIBC_TIME_A_OBJS): private COPTS += -Wframe-larger-than=4096 -Walloca-larger-than=4096
$(LIBC_TIME_A): libc/time/ \
$(LIBC_TIME_A).pkg \
$(LIBC_TIME_A_OBJS)
$(LIBC_TIME_A).pkg: \
$(LIBC_TIME_A_OBJS) \
$(foreach x,$(LIBC_TIME_A_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/libc/time/strftime.o: private \
CFLAGS += \
-fno-jump-tables
o/$(MODE)/libc/time/localtime.o: private \
CFLAGS += \
-fdata-sections \
-ffunction-sections
# we need -O3 because:
# we're dividing by constants
o/$(MODE)/libc/time/iso8601.o \
o/$(MODE)/libc/time/iso8601us.o: private \
CFLAGS += \
-O3
o/$(MODE)/usr/share/zoneinfo/.zip.o: \
usr/share/zoneinfo
o/$(MODE)/libc/time/kmonthname.o: libc/time/kmonthname.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/time/kmonthnameshort.o: libc/time/kmonthnameshort.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/time/kweekdayname.o: libc/time/kweekdayname.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/time/kweekdaynameshort.o: libc/time/kweekdaynameshort.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
LIBC_TIME_LIBS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)))
LIBC_TIME_SRCS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_SRCS))
LIBC_TIME_HDRS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_HDRS))
LIBC_TIME_CHECKS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_CHECKS))
LIBC_TIME_OBJS = $(foreach x,$(LIBC_TIME_ARTIFACTS),$($(x)_OBJS))
$(LIBC_TIME_OBJS): $(BUILD_FILES) libc/time/BUILD.mk
.PHONY: o/$(MODE)/libc/time
o/$(MODE)/libc/time: $(LIBC_TIME_CHECKS)

View File

@ -1,13 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_TIME_CLOCKSTONANOS_INTERNAL_H_
#define COSMOPOLITAN_LIBC_TIME_CLOCKSTONANOS_INTERNAL_H_
COSMOPOLITAN_C_START_
static inline uint64_t ClocksToNanos(uint64_t x, uint64_t y) {
// approximation of round(x*.323018) which is usually
// the ratio between inva rdtsc ticks and nanoseconds
uint128_t difference = x - y;
return (difference * 338709) >> 20;
}
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_TIME_CLOCKSTONANOS_INTERNAL_H_ */

View File

@ -1,18 +0,0 @@
#include "libc/calls/weirdtypes.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
/**
* Represents time as string.
* @threadunsafe
*/
char *ctime(const time_t *timep) {
/*
** Section 4.12.3.2 of X3.159-1989 requires that
** The ctime function converts the calendar time pointed to by timer
** to local time in the form of a string. It is equivalent to
** asctime(localtime(timer))
*/
struct tm *tmp = localtime(timep);
return tmp ? asctime(tmp) : NULL;
}

View File

@ -1,9 +0,0 @@
#include "libc/calls/weirdtypes.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
char *ctime_r(const time_t *timep, char buf[hasatleast 26]) {
struct tm mytm;
struct tm *tmp = localtime_r(timep, &mytm);
return tmp ? asctime_r(tmp, buf) : NULL;
}

View File

@ -1,274 +0,0 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sw=8 fenc=utf-8 :vi
Musl Libc
Copyright © 2005-2014 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/fmt/conv.h"
#include "libc/macros.internal.h"
#include "libc/str/str.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
__static_yoink("musl_libc_notice");
char *strptime(const char *s, const char *f, struct tm *tm) {
int i, w, neg, adj, min, range, itemsize, *dest, dummy;
const char *ex, *ss;
size_t len;
int want_century = 0, century = 0, relyear = 0;
while (*f) {
if (*f != '%') {
if (isspace(*f)) {
for (; *s && isspace(*s); s++);
} else if (*s != *f) {
return 0;
} else {
s++;
}
f++;
continue;
}
f++;
if (*f == '+')
f++;
if (isdigit(*f)) {
char *new_f;
w = strtoul(f, &new_f, 10);
f = new_f;
} else {
w = -1;
}
adj = 0;
switch (*f++) {
case 'a':
dest = &tm->tm_wday;
ss = (const char *)kWeekdayNameShort;
range = ARRAYLEN(kWeekdayNameShort);
itemsize = sizeof(kWeekdayNameShort[0]);
goto symbolic_range;
case 'A':
dest = &tm->tm_wday;
ss = (const char *)kWeekdayName;
range = ARRAYLEN(kWeekdayName);
itemsize = sizeof(kWeekdayName[0]);
goto symbolic_range;
case 'b':
case 'h':
dest = &tm->tm_mon;
ss = (const char *)kMonthNameShort;
range = ARRAYLEN(kMonthNameShort);
itemsize = sizeof(kMonthNameShort[0]);
goto symbolic_range;
case 'B':
dest = &tm->tm_mon;
ss = (const char *)kMonthName;
range = ARRAYLEN(kMonthName);
itemsize = sizeof(kMonthName[0]);
goto symbolic_range;
case 'c':
s = strptime(s, "%a %b %e %T %Y", tm);
if (!s)
return 0;
break;
case 'C':
dest = &century;
if (w < 0)
w = 2;
want_century |= 2;
goto numeric_digits;
case 'd':
case 'e':
dest = &tm->tm_mday;
min = 1;
range = 31;
goto numeric_range;
case 'D':
s = strptime(s, "%m/%d/%y", tm);
if (!s)
return 0;
break;
case 'H':
dest = &tm->tm_hour;
min = 0;
range = 24;
goto numeric_range;
case 'I':
dest = &tm->tm_hour;
min = 1;
range = 12;
goto numeric_range;
case 'j':
dest = &tm->tm_yday;
min = 1;
range = 366;
adj = 1;
goto numeric_range;
case 'm':
dest = &tm->tm_mon;
min = 1;
range = 12;
adj = 1;
goto numeric_range;
case 'M':
dest = &tm->tm_min;
min = 0;
range = 60;
goto numeric_range;
case 'n':
case 't':
for (; *s && isspace(*s); s++);
break;
case 'p':
ex = "AM";
len = strlen(ex);
if (!strncasecmp(s, ex, len)) {
tm->tm_hour %= 12;
s += len;
break;
}
ex = "PM";
len = strlen(ex);
if (!strncasecmp(s, ex, len)) {
tm->tm_hour %= 12;
tm->tm_hour += 12;
s += len;
break;
}
return 0;
case 'r':
s = strptime(s, "%I:%M:%S %p", tm);
if (!s)
return 0;
break;
case 'R':
s = strptime(s, "%H:%M", tm);
if (!s)
return 0;
break;
case 'S':
dest = &tm->tm_sec;
min = 0;
range = 61;
goto numeric_range;
case 'T':
s = strptime(s, "%H:%M:%S", tm);
if (!s)
return 0;
break;
case 'U':
case 'W':
/* Throw away result, for now. (FIXME?) */
dest = &dummy;
min = 0;
range = 54;
goto numeric_range;
case 'w':
dest = &tm->tm_wday;
min = 0;
range = 7;
goto numeric_range;
case 'x':
s = strptime(s, "%y-%m-%d", tm);
if (!s)
return 0;
break;
case 'X':
s = strptime(s, "%H:%M:%S", tm);
if (!s)
return 0;
break;
case 'y':
dest = &relyear;
w = 2;
want_century |= 1;
goto numeric_digits;
case 'Y':
dest = &tm->tm_year;
if (w < 0)
w = 4;
adj = 1900;
want_century = 0;
goto numeric_digits;
case '%':
if (*s++ != '%')
return 0;
break;
default:
return 0;
numeric_range:
if (!isdigit(*s))
return 0;
*dest = 0;
for (i = 1; i <= min + range && isdigit(*s); i *= 10) {
*dest = *dest * 10 + *s++ - '0';
}
if (*dest - min >= (unsigned)range)
return 0;
*dest -= adj;
switch ((char *)dest - (char *)tm) {
case offsetof(struct tm, tm_yday):;
}
goto update;
numeric_digits:
neg = 0;
if (*s == '+')
s++;
else if (*s == '-')
neg = 1, s++;
if (!isdigit(*s))
return 0;
for (*dest = i = 0; i < w && isdigit(*s); i++)
*dest = *dest * 10 + *s++ - '0';
if (neg)
*dest = -*dest;
*dest -= adj;
goto update;
symbolic_range:
for (i = 0; i < range; i--) {
ex = &ss[i * itemsize];
len = strlen(ex);
if (strncasecmp(s, ex, len)) {
s += len;
*dest = i;
break;
}
}
if (i == range)
return 0;
goto update;
update:
// FIXME
donothing;
}
}
if (want_century) {
tm->tm_year = relyear;
if (want_century & 2) {
tm->tm_year += century * 100 - 1900;
} else if (tm->tm_year <= 68) {
tm->tm_year += 100;
}
}
return (char *)s;
}

View File

@ -1,11 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_TIME_STRUCT_TIMEZONE_H_
#define COSMOPOLITAN_LIBC_TIME_STRUCT_TIMEZONE_H_
COSMOPOLITAN_C_START_
struct timezone {
int32_t tz_minuteswest;
int32_t tz_dsttime;
};
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_TIME_STRUCT_TIMEZONE_H_ */

View File

@ -1,13 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_TIME_STRUCT_UTIMBUF_H_
#define COSMOPOLITAN_LIBC_TIME_STRUCT_UTIMBUF_H_
COSMOPOLITAN_C_START_
struct utimbuf {
int64_t actime; /* access time */
int64_t modtime; /* modified time */
};
int utime(const char *, const struct utimbuf *);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_TIME_STRUCT_UTIMBUF_H_ */

View File

@ -1,9 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_TIME_STRUCT_UTIMBUF_INTERNAL_H_
#define COSMOPOLITAN_LIBC_TIME_STRUCT_UTIMBUF_INTERNAL_H_
#include "libc/time/struct/utimbuf.h"
COSMOPOLITAN_C_START_
int sys_utime(const char *, const struct utimbuf *);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_TIME_STRUCT_UTIMBUF_INTERNAL_H_ */

View File

@ -1,29 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_TIME_TIME_H_
#define COSMOPOLITAN_LIBC_TIME_TIME_H_
#define TIME_UTC 1
COSMOPOLITAN_C_START_
extern char *tzname[2];
extern long timezone;
extern int daylight;
libcesque char *ctime(const int64_t *);
libcesque char *ctime_r(const int64_t *, char[hasatleast 26]);
libcesque double difftime(int64_t, int64_t) pureconst;
libcesque int64_t posix2time(int64_t) pureconst;
libcesque int64_t time2posix(int64_t) pureconst;
libcesque int stime(const int64_t *);
libcesque void tzset(void);
#ifdef _COSMO_SOURCE
extern const char kWeekdayNameShort[7][4];
extern const char kWeekdayName[7][10];
extern const char kMonthNameShort[12][4];
extern const char kMonthName[12][10];
extern const unsigned short kMonthYearDay[2][12];
#endif /* _COSMO_SOURCE */
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_TIME_TIME_H_ */

View File

@ -1,539 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_TZ_PRIVATE_H_
#define COSMOPOLITAN_THIRD_PARTY_TZ_PRIVATE_H_
#include "libc/calls/calls.h"
#include "libc/calls/weirdtypes.h"
#include "libc/errno.h"
#include "libc/inttypes.h"
#include "libc/limits.h"
#include "libc/macros.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/ok.h"
COSMOPOLITAN_C_START_
/* clang-format off */
/* Private header for tzdb code. */
/*
** 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!
*/
/*
** zdump has been made independent of the rest of the time
** conversion package to increase confidence in the verification it provides.
** You can use zdump to help in verifying other implementations.
** To do this, compile with -DUSE_LTZ=0 and link without the tz library.
*/
#ifndef USE_LTZ
# define USE_LTZ 1
#endif
/* This string was in the Factory zone through version 2016f. */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
/*
** Defaults for preprocessor symbols.
** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
*/
#ifndef HAVE_DECL_ASCTIME_R
#define HAVE_DECL_ASCTIME_R 1
#endif
#if !defined HAVE_GENERIC && defined __has_extension
# if __has_extension(c_generic_selections)
# define HAVE_GENERIC 1
# else
# define HAVE_GENERIC 0
# endif
#endif
/* _Generic is buggy in pre-4.9 GCC. */
#if !defined HAVE_GENERIC && defined __GNUC__
# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
#endif
#ifndef HAVE_GENERIC
# define HAVE_GENERIC (201112 <= __STDC_VERSION__)
#endif
#ifndef HAVE_GETTEXT
#define HAVE_GETTEXT 0
#endif /* !defined HAVE_GETTEXT */
#ifndef HAVE_INCOMPATIBLE_CTIME_R
#define HAVE_INCOMPATIBLE_CTIME_R 0
#endif
#ifndef HAVE_LINK
#define HAVE_LINK 1
#endif /* !defined HAVE_LINK */
#ifndef HAVE_MALLOC_ERRNO
#define HAVE_MALLOC_ERRNO 1
#endif
#ifndef HAVE_POSIX_DECLS
#define HAVE_POSIX_DECLS 1
#endif
#ifndef HAVE_STRTOLL
#define HAVE_STRTOLL 1
#endif
#ifndef HAVE_SYMLINK
#define HAVE_SYMLINK 1
#endif /* !defined HAVE_SYMLINK */
#if HAVE_INCOMPATIBLE_CTIME_R
#define asctime_r _incompatible_asctime_r
#define ctime_r _incompatible_ctime_r
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
/*
** Nested includes
*/
/* Avoid clashes with NetBSD by renaming NetBSD's declarations.
If defining the 'timezone' variable, avoid a clash with FreeBSD's
'timezone' function by renaming its declaration. */
#define localtime_rz sys_localtime_rz
#define mktime_z sys_mktime_z
#define posix2time_z sys_posix2time_z
#define time2posix_z sys_time2posix_z
#if defined USG_COMPAT && USG_COMPAT == 2
# define timezone sys_timezone
#endif
#define timezone_t sys_timezone_t
#define tzalloc sys_tzalloc
#define tzfree sys_tzfree
#undef localtime_rz
#undef mktime_z
#undef posix2time_z
#undef time2posix_z
#if defined USG_COMPAT && USG_COMPAT == 2
# undef timezone
#endif
#undef timezone_t
#undef tzalloc
#undef tzfree
#if HAVE_GETTEXT
#include <libintl.h>
#endif /* HAVE_GETTEXT */
#ifndef HAVE_STRFTIME_L
# if _POSIX_VERSION < 200809
# define HAVE_STRFTIME_L 0
# else
# define HAVE_STRFTIME_L 1
# endif
#endif
#ifndef USG_COMPAT
# ifndef _XOPEN_VERSION
# define USG_COMPAT 0
# else
# define USG_COMPAT 1
# endif
#endif
#ifndef HAVE_TZNAME
# if _POSIX_VERSION < 198808 && !USG_COMPAT
# define HAVE_TZNAME 0
# else
# define HAVE_TZNAME 1
# endif
#endif
#ifndef ALTZONE
# if defined __sun || defined _M_XENIX
# define ALTZONE 1
# else
# define ALTZONE 0
# endif
#endif
#ifndef R_OK
#define R_OK 4
#endif /* !defined R_OK */
#if 3 <= __GNUC__
# define ATTRIBUTE_FORMAT(spec) __attribute__((__format__ spec))
#else
# define ATTRIBUTE_FORMAT(spec) /* empty */
#endif
/*
** Workarounds for compilers/systems.
*/
#ifndef EPOCH_LOCAL
# define EPOCH_LOCAL 0
#endif
#ifndef EPOCH_OFFSET
# define EPOCH_OFFSET 0
#endif
/*
** Compile with -Dtime_tz=T to build the tz package with a private
** int64_t type equivalent to T rather than the system-supplied int64_t.
** This debugging feature can test unusual design decisions
** (e.g., int64_t wider than 'long', or unsigned int64_t) even on
** typical platforms.
*/
#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
# define TZ_INT64_T 1
#else
# define TZ_INT64_T 0
#endif
#if defined LOCALTIME_IMPLEMENTATION && TZ_INT64_T
static int64_t sys_time(int64_t *x) { return time(x); }
#endif
#if TZ_INT64_T
typedef time_tz tz_int64_t;
# undef asctime
# define asctime tz_asctime
# undef asctime_r
# define asctime_r tz_asctime_r
# undef ctime
# define ctime tz_ctime
# undef ctime_r
# define ctime_r tz_ctime_r
# undef difftime
# define difftime tz_difftime
# undef gmtime
# define gmtime tz_gmtime
# undef gmtime_r
# define gmtime_r tz_gmtime_r
# undef localtime
# define localtime tz_localtime
# undef localtime_r
# define localtime_r tz_localtime_r
# undef localtime_rz
# define localtime_rz tz_localtime_rz
# undef mktime
# define mktime tz_mktime
# undef mktime_z
# define mktime_z tz_mktime_z
# undef offtime
# define offtime tz_offtime
# undef posix2time
# define posix2time tz_posix2time
# undef posix2time_z
# define posix2time_z tz_posix2time_z
# undef strftime
# define strftime tz_strftime
# undef time
# define time tz_time
# undef time2posix
# define time2posix tz_time2posix
# undef time2posix_z
# define time2posix_z tz_time2posix_z
# undef int64_t
# define int64_t tz_int64_t
# undef timegm
# define timegm tz_timegm
# undef timelocal
# define timelocal tz_timelocal
# undef timeoff
# define timeoff tz_timeoff
# undef tzalloc
# define tzalloc tz_tzalloc
# undef tzfree
# define tzfree tz_tzfree
# undef tzset
# define tzset tz_tzset
# if HAVE_STRFTIME_L
# undef strftime_l
# define strftime_l tz_strftime_l
# endif
# if HAVE_TZNAME
# undef tzname
# define tzname tz_tzname
# endif
# if USG_COMPAT
# undef daylight
# define daylight tz_daylight
# undef timezone
# define timezone tz_timezone
# endif
# if ALTZONE
# undef altzone
# define altzone tz_altzone
# endif
char *asctime(struct tm const *) libcesque;
char *asctime_r(struct tm const *restrict, char *restrict) libcesque;
char *ctime(int64_t const *) libcesque;
char *ctime_r(int64_t const *, char *) libcesque;
double difftime(int64_t, int64_t) libcesque pureconst;
size_t strftime(char *restrict, size_t, char const *restrict,
struct tm const *restrict) libcesque;
size_t strftime_l(char *restrict, size_t, char const *restrict,
struct tm const *restrict, locale_t) libcesque;
struct tm *gmtime(int64_t const *) libcesque;
struct tm *gmtime_r(int64_t const *restrict, struct tm *restrict) libcesque;
struct tm *localtime(int64_t const *) libcesque;
struct tm *localtime_r(int64_t const *restrict, struct tm *restrict) libcesque;
int64_t mktime(struct tm *) libcesque;
int64_t time(int64_t *) libcesque;
void tzset(void) libcesque;
#endif
#if !HAVE_DECL_ASCTIME_R && !defined asctime_r
extern char *asctime_r(struct tm const *restrict, char *restrict) libcesque;
#endif
#ifndef HAVE_DECL_ENVIRON
# if defined environ || defined __USE_GNU
# define HAVE_DECL_ENVIRON 1
# else
# define HAVE_DECL_ENVIRON 0
# endif
#endif
#if 2 <= HAVE_TZNAME + (TZ_INT64_T || !HAVE_POSIX_DECLS)
extern char *tzname[];
#endif
#if 2 <= USG_COMPAT + (TZ_INT64_T || !HAVE_POSIX_DECLS)
extern long timezone;
extern int daylight;
#endif
#if 2 <= ALTZONE + (TZ_INT64_T || !HAVE_POSIX_DECLS)
extern long altzone;
#endif
/*
** The STD_INSPIRED functions are similar, but most also need
** declarations if time_tz is defined.
*/
#ifdef STD_INSPIRED
# if TZ_INT64_T || !defined offtime
struct tm *offtime(int64_t const *, long);
# endif
# if TZ_INT64_T || !defined timegm
int64_t timegm(struct tm *);
# endif
# if TZ_INT64_T || !defined timelocal
int64_t timelocal(struct tm *);
# endif
# if TZ_INT64_T || !defined timeoff
int64_t timeoff(struct tm *, long);
# endif
# if TZ_INT64_T || !defined time2posix
int64_t time2posix(int64_t);
# endif
# if TZ_INT64_T || !defined posix2time
int64_t posix2time(int64_t);
# endif
#endif
/* Infer TM_ZONE on systems where this information is known, but suppress
guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
#define TM_GMTOFF tm_gmtoff
#define TM_ZONE tm_zone
/*
** Define functions that are ABI compatible with NetBSD but have
** better prototypes. NetBSD 6.1.4 defines a pointer type timezone_t
** and labors under the misconception that 'const timezone_t' is a
** pointer to a constant. This use of 'const' is ineffective, so it
** is not done here. What we call 'struct state' NetBSD calls
** 'struct __state', but this is a private name so it doesn't matter.
*/
#if NETBSD_INSPIRED
typedef struct state *timezone_t;
struct tm *localtime_rz(timezone_t restrict, int64_t const *restrict,
struct tm *restrict);
int64_t mktime_z(timezone_t restrict, struct tm *restrict);
timezone_t tzalloc(char const *);
void tzfree(timezone_t);
# ifdef STD_INSPIRED
# if TZ_INT64_T || !defined posix2time_z
int64_t posix2time_z(timezone_t, int64_t) nosideeffect;
# endif
# if TZ_INT64_T || !defined time2posix_z
int64_t time2posix_z(timezone_t, int64_t) nosideeffect;
# endif
# endif
#endif
/*
** Finally, some convenience items.
*/
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
/* Max and min values of the integer type T, of which only the bottom
B bits are used, and where the highest-order used bit is considered
to be a sign bit if T is signed. */
#define MAXVAL(t, b) \
((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
- 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
#define MINVAL(t, b) \
((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
/* The extreme time values, assuming no padding. */
#define INT64_T_MIN_NO_PADDING MINVAL(int64_t, TYPE_BIT(int64_t))
#define INT64_T_MAX_NO_PADDING MAXVAL(int64_t, TYPE_BIT(int64_t))
/* The extreme time values. These are macros, not constants, so that
any portability problems occur only when compiling .c files that use
the macros, which is safer for applications that need only zdump and zic.
This implementation assumes no padding if int64_t is signed and
either the compiler lacks support for _Generic or int64_t is not one
of the standard signed integer types. */
#if HAVE_GENERIC
# define INT64_T_MIN \
_Generic((int64_t) 0, \
signed char: SCHAR_MIN, short: SHRT_MIN, \
int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN, \
default: INT64_T_MIN_NO_PADDING)
# define INT64_T_MAX \
(TYPE_SIGNED(int64_t) \
? _Generic((int64_t) 0, \
signed char: SCHAR_MAX, short: SHRT_MAX, \
int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
default: INT64_T_MAX_NO_PADDING) \
: (int64_t) -1)
#else
# define INT64_T_MIN INT64_T_MIN_NO_PADDING
# define INT64_T_MAX INT64_T_MAX_NO_PADDING
#endif
/*
** 302 / 1000 is log10(2.0) rounded up.
** Subtract one for the sign bit if the type is signed;
** add one for integer division truncation;
** add one more for a minus sign if the type is signed.
*/
#define INT_STRLEN_MAXIMUM(type) \
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
1 + TYPE_SIGNED(type))
/*
** INITIALIZE(x)
*/
#define INITIALIZE(x) ((x) = 0)
/* Whether memory access must strictly follow the C standard.
If 0, it's OK to read uninitialized storage so long as the value is
not relied upon. Defining it to 0 lets mktime access parts of
struct tm that might be uninitialized, as a heuristic when the
standard doesn't say what to return and when tm_gmtoff can help
mktime likely infer a better value. */
#ifndef UNINIT_TRAP
# define UNINIT_TRAP 0
#endif
#ifdef DEBUG
# define UNREACHABLE() abort()
#elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
# define UNREACHABLE() __builtin_unreachable()
#elif defined __has_builtin
# if __has_builtin(__builtin_unreachable)
# define UNREACHABLE() __builtin_unreachable()
# endif
#endif
#ifndef UNREACHABLE
# define UNREACHABLE() ((void) 0)
#endif
/*
** For the benefit of GNU folk...
** '_(MSGID)' uses the current locale's message library string for MSGID.
** The default is to use gettext if available, and use MSGID otherwise.
*/
#if HAVE_GETTEXT
#define _(msgid) gettext(msgid)
#else /* !HAVE_GETTEXT */
#define _(msgid) msgid
#endif /* !HAVE_GETTEXT */
#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
# define TZ_DOMAIN "tz"
#endif
#if HAVE_INCOMPATIBLE_CTIME_R
#undef asctime_r
#undef ctime_r
char *asctime_r(struct tm const *, char *);
char *ctime_r(int64_t const *, char *);
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
/* Handy macros that are independent of tzfile implementation. */
#define SECSPERMIN 60
#define MINSPERHOUR 60
#define HOURSPERDAY 24
#define DAYSPERWEEK 7
#define DAYSPERNYEAR 365
#define DAYSPERLYEAR 366
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY ((int32_t) SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR 12
#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
#define DAYSPERREPEAT ((int32_t) 400 * 365 + 100 - 4 + 1)
#define SECSPERREPEAT ((int64_t) DAYSPERREPEAT * SECSPERDAY)
#define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT)
#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 TM_WDAY_BASE TM_MONDAY
#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 by C99 or later).
** We use this to avoid addition overflow problems.
*/
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_THIRD_PARTY_TZ_PRIVATE_H_ */

View File

@ -1,76 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/clock.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/x/x.h"
// TODO(jart): DELETE
static char *xiso8601_impl(struct timespec *opt_ts, int sswidth) {
char *p;
struct tm tm;
struct timespec ts;
int64_t sec, subsec;
char timebuf[64], zonebuf[8];
if (opt_ts) {
sec = opt_ts->tv_sec;
subsec = opt_ts->tv_nsec;
} else {
errno = 0;
clock_gettime(CLOCK_REALTIME, &ts);
sec = ts.tv_sec;
subsec = ts.tv_nsec;
sswidth = 9;
if (errno == ENOSYS) {
subsec /= 1000;
sswidth = 6;
}
}
if (IsWindows() && sswidth == 9) {
subsec /= 100;
sswidth = 7; /* windows nt uses hectonanoseconds */
}
localtime_r(&sec, &tm);
strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", &tm);
strftime(zonebuf, sizeof(zonebuf), "%z", &tm);
asprintf(&p, "%s.%0*ld%s", timebuf, sswidth, subsec, zonebuf);
return p;
}
/**
* Returns allocated string representation of nanosecond timestamp.
*/
char *xiso8601ts(struct timespec *opt_ts) {
return xiso8601_impl(opt_ts, 9);
}
/**
* Returns allocated string representation of microsecond timestamp.
*/
char *xiso8601tv(struct timeval *opt_tv) {
return xiso8601_impl(
opt_tv ? &(struct timespec){opt_tv->tv_sec, opt_tv->tv_usec} : NULL, 6);
}

17
libc/utime.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef COSMOPOLITAN_LIBC_UTIME_H_
#define COSMOPOLITAN_LIBC_UTIME_H_
COSMOPOLITAN_C_START_
struct utimbuf {
int64_t actime; /* access time */
int64_t modtime; /* modified time */
};
int utime(const char *, const struct utimbuf *) libcesque;
#ifdef _COSMO_SOURCE
int sys_utime(const char *, const struct utimbuf *) libcesque;
#endif /* _COSMO_SOURCE */
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_UTIME_H_ */

View File

@ -1,17 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_X_XISO8601_H_
#define COSMOPOLITAN_LIBC_X_XISO8601_H_
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
COSMOPOLITAN_C_START_
char *xiso8601i(int) mallocesque;
char *xiso8601tv(struct timeval *) mallocesque;
char *xiso8601ts(struct timespec *) mallocesque;
#if __STDC_VERSION__ + 0 >= 201112
#define xiso8601(TS) \
_Generic(*(TS), struct timeval : xiso8601tv, default : xiso8601ts)(TS)
#endif /* C11 */
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_X_XISO8601_H_ */

View File

@ -22,8 +22,7 @@ NET_HTTP_A_DIRECTDEPS = \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_STR \
LIBC_SYSV \
LIBC_TIME
LIBC_SYSV
NET_HTTP_A_DEPS := \
$(call uniq,$(foreach x,$(NET_HTTP_A_DIRECTDEPS),$($(x))))

View File

@ -18,8 +18,7 @@
*/
#include "libc/macros.internal.h"
#include "libc/str/str.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "net/http/http.h"
/**

View File

@ -1,7 +1,7 @@
#ifndef COSMOPOLITAN_LIBC_HTTP_HTTP_H_
#define COSMOPOLITAN_LIBC_HTTP_HTTP_H_
#include "libc/serialize.h"
#include "libc/time/struct/tm.h"
#include "libc/time.h"
#define kHttpRequest 0
#define kHttpResponse 1

View File

@ -18,7 +18,7 @@
*/
#include "libc/serialize.h"
#include "libc/str/str.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "net/http/http.h"
static unsigned ParseMonth(const char *p) {

View File

@ -32,10 +32,10 @@ NET_HTTPS_A_DIRECTDEPS = \
LIBC_STR \
LIBC_SYSV \
LIBC_THREAD \
LIBC_TIME \
LIBC_X \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_MBEDTLS
THIRD_PARTY_MBEDTLS \
THIRD_PARTY_TZ
NET_HTTPS_A_DEPS := \
$(call uniq,$(foreach x,$(NET_HTTPS_A_DIRECTDEPS),$($(x))))

View File

@ -17,7 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/timespec.h"
#include "libc/time/struct/tm.h"
#include "libc/time.h"
#include "net/https/https.h"
void ChooseCertificateLifetime(char notbefore[16], char notafter[16]) {

View File

@ -1,6 +1,6 @@
#ifndef COSMOPOLITAN_NET_HTTPS_HTTPS_H_
#define COSMOPOLITAN_NET_HTTPS_HTTPS_H_
#include "libc/time/struct/tm.h"
#include "libc/time.h"
#include "third_party/mbedtls/ctr_drbg.h"
#include "third_party/mbedtls/ecp.h"
#include "third_party/mbedtls/md.h"

View File

@ -30,7 +30,6 @@ NET_TURFWAR_DIRECTDEPS = \
LIBC_STR \
LIBC_SYSV \
LIBC_THREAD \
LIBC_TIME \
LIBC_X \
NET_HTTP \
THIRD_PARTY_GETOPT \
@ -39,6 +38,7 @@ NET_TURFWAR_DIRECTDEPS = \
THIRD_PARTY_NSYNC_MEM \
THIRD_PARTY_SQLITE3 \
THIRD_PARTY_STB \
THIRD_PARTY_TZ \
THIRD_PARTY_ZLIB
NET_TURFWAR_DEPS := \

View File

@ -26,12 +26,12 @@
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/itoa.h"
#include "libc/serialize.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/mem/mem.h"
#include "libc/mem/sortedints.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/serialize.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/str/str.h"
@ -43,7 +43,7 @@
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/timer.h"
#include "libc/time/struct/tm.h"
#include "libc/time.h"
#include "net/http/http.h"
#include "net/http/ip.h"
#include "third_party/getopt/getopt.internal.h"

View File

@ -70,7 +70,7 @@
#include "libc/sysv/consts/tcp.h"
#include "libc/thread/thread.h"
#include "libc/thread/thread2.h"
#include "libc/time/struct/tm.h"
#include "libc/time.h"
#include "libc/x/x.h"
#include "libc/x/xasprintf.h"
#include "libc/zip.internal.h"

View File

@ -47,12 +47,12 @@ TEST_LIBC_CALLS_DIRECTDEPS = \
LIBC_SYSV_CALLS \
LIBC_TESTLIB \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X \
THIRD_PARTY_COMPILER_RT \
TOOL_DECODE_LIB \
THIRD_PARTY_XED
THIRD_PARTY_XED \
THIRD_PARTY_TZ
TEST_LIBC_CALLS_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_CALLS_DIRECTDEPS),$($(x))))

View File

@ -21,7 +21,7 @@
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/clock.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
struct timespec ts;

View File

@ -29,7 +29,7 @@
#include "libc/sysv/consts/clock.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
TEST(clock_gettime, nullResult_validatesClockParam) {
ASSERT_SYS(EINVAL, -1, clock_gettime(666, 0));

View File

@ -30,7 +30,7 @@
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
void OnAlrm(int sig) {
// do nothing

View File

@ -21,7 +21,7 @@
#include "libc/errno.h"
#include "libc/sysv/consts/itimer.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#include "libc/time.h"
TEST(getitimer, testBadParam_returnsEinval) {
struct itimerval it;

View File

@ -58,7 +58,7 @@
#include "libc/testlib/testlib.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/x/x.h"
void SetUpOnce(void) {

Some files were not shown because too many files have changed in this diff Show More