diff options
| author | Erick Tryzelaar <erick.tryzelaar@gmail.com> | 2012-04-03 10:32:26 -0700 |
|---|---|---|
| committer | Erick Tryzelaar <erick.tryzelaar@gmail.com> | 2012-04-03 22:43:10 -0700 |
| commit | 4a4889859e84b65617c27a08e129086267b58695 (patch) | |
| tree | e9ef7852519d08de5cc3862c42e5645694ec3757 /src/rt/rust_builtin.cpp | |
| parent | 72444636d32b34743e14bbd25c3ffc579b881af8 (diff) | |
| download | rust-4a4889859e84b65617c27a08e129086267b58695.tar.gz rust-4a4889859e84b65617c27a08e129086267b58695.zip | |
std: add localtime/gmtime support.
Diffstat (limited to 'src/rt/rust_builtin.cpp')
| -rw-r--r-- | src/rt/rust_builtin.cpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 684322a22a8..9c2e2c3276c 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -8,6 +8,8 @@ #include "rust_abi.h" #include "rust_port.h" +#include <time.h> + #ifdef __APPLE__ #include <crt_externs.h> #endif @@ -448,6 +450,127 @@ precise_time_ns(uint64_t *ns) { *ns = t.time_ns(); } +struct rust_tm { + int32_t tm_sec; + int32_t tm_min; + int32_t tm_hour; + int32_t tm_mday; + int32_t tm_mon; + int32_t tm_year; + int32_t tm_wday; + int32_t tm_yday; + int32_t tm_isdst; + int32_t tm_gmtoff; + rust_str *tm_zone; + int32_t tm_nsec; +}; + +void rust_tm_to_tm(rust_tm* in_tm, tm* out_tm) { + memset(out_tm, 0, sizeof(tm)); + out_tm->tm_sec = in_tm->tm_sec; + out_tm->tm_min = in_tm->tm_min; + out_tm->tm_hour = in_tm->tm_hour; + out_tm->tm_mday = in_tm->tm_mday; + out_tm->tm_mon = in_tm->tm_mon; + out_tm->tm_year = in_tm->tm_year; + out_tm->tm_wday = in_tm->tm_wday; + out_tm->tm_yday = in_tm->tm_yday; + out_tm->tm_isdst = in_tm->tm_isdst; +} + +void tm_to_rust_tm(tm* in_tm, rust_tm* out_tm, int32_t gmtoff, + const char *zone, int32_t nsec) { + out_tm->tm_sec = in_tm->tm_sec; + out_tm->tm_min = in_tm->tm_min; + out_tm->tm_hour = in_tm->tm_hour; + out_tm->tm_mday = in_tm->tm_mday; + out_tm->tm_mon = in_tm->tm_mon; + out_tm->tm_year = in_tm->tm_year; + out_tm->tm_wday = in_tm->tm_wday; + out_tm->tm_yday = in_tm->tm_yday; + out_tm->tm_isdst = in_tm->tm_isdst; + out_tm->tm_gmtoff = gmtoff; + out_tm->tm_nsec = nsec; + + if (zone != NULL) { + size_t size = strlen(zone); + str_reserve_shared(&out_tm->tm_zone, size); + memcpy(out_tm->tm_zone->data, zone, size); + out_tm->tm_zone->fill = size + 1; + out_tm->tm_zone->data[size] = '\0'; + } +} + +#if defined(__WIN32__) +#define TZSET() _tzset() +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define GMTIME(clock, result) gmtime_s((result), (clock)) +#define LOCALTIME(clock, result) localtime_s((result), (clock)) +#define TIMEGM(result) _mkgmtime64(result) +#else +struct tm* GMTIME(const time_t *clock, tm *result) { + struct tm* t = gmtime(clock); + if (t == NULL || result == NULL) { return NULL; } + *result = *t; + return result; +} +struct tm* LOCALTIME(const time_t *clock, tm *result) { + struct tm* t = localtime(clock); + if (t == NULL || result == NULL) { return NULL; } + *result = *t; + return result; +} +#define TIMEGM(result) mktime((result)) - _timezone +#endif +#else +#define TZSET() tzset() +#define GMTIME(clock, result) gmtime_r((clock), (result)) +#define LOCALTIME(clock, result) localtime_r((clock), (result)) +#define TIMEGM(result) timegm(result) +#endif + +extern "C" CDECL void +rust_gmtime(int64_t *sec, int32_t *nsec, rust_tm *timeptr) { + tm tm; + time_t s = *sec; + GMTIME(&s, &tm); + + tm_to_rust_tm(&tm, timeptr, 0, "UTC", *nsec); +} + +extern "C" CDECL void +rust_localtime(int64_t *sec, int32_t *nsec, rust_tm *timeptr) { + tm tm; + TZSET(); + time_t s = *sec; + LOCALTIME(&s, &tm); + +#if defined(__WIN32__) + int32_t gmtoff = -timezone; + char zone[64]; + strftime(zone, sizeof(zone), "%Z", &tm); +#else + int32_t gmtoff = tm.tm_gmtoff; + const char *zone = tm.tm_zone; +#endif + + tm_to_rust_tm(&tm, timeptr, gmtoff, zone, *nsec); +} + +extern "C" CDECL void +rust_timegm(rust_tm* timeptr, int64_t *out) { + tm t; + rust_tm_to_tm(timeptr, &t); + *out = TIMEGM(&t); +} + +extern "C" CDECL void +rust_mktime(rust_tm* timeptr, int64_t *out) { + tm t; + rust_tm_to_tm(timeptr, &t); + *out = mktime(&t); +} + extern "C" CDECL rust_sched_id rust_get_sched_id() { rust_task *task = rust_get_current_task(); |
