aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-05-13 12:43:58 -0400
committerChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-05-13 12:43:58 -0400
commit71026ea3ecb33b923f513f1e36cedbd89d6b7dc4 (patch)
tree164885af945a25fef0f63303263522848238285d /src
parentbetter tests that also serve as temporary docs (diff)
add TM_GMTOFF and TM_ZONE
I might want to be able to write to them, but that seems very error-prone.
Diffstat (limited to 'src')
-rw-r--r--src/polyfill.h20
-rw-r--r--src/tm.c47
2 files changed, 62 insertions, 5 deletions
diff --git a/src/polyfill.h b/src/polyfill.h
index 5fa72ac..ecc3a0d 100644
--- a/src/polyfill.h
+++ b/src/polyfill.h
@@ -18,5 +18,23 @@ const char *janet_optcbytes(const Janet *argv, int32_t argc, int32_t n, const ch
static const int32_t CNAME##_sourceline_ = __LINE__; \
Janet CNAME (int32_t argc, Janet *argv)
#endif // !defined(JANET_NO_SOURCEMAPS)
-
#endif // JANET_VERSION_MAJOR < 2 && JANET_VERSION_MINOR < 28
+
+// ===
+
+// public domain code from
+// https://github.com/eggert/tz.git
+
+/* Infer TM_ZONE on systems where this information is known, but suppress
+ guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
+#if (defined __GLIBC__ \
+ || defined __tm_zone /* musl */ \
+ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
+ || (defined __APPLE__ && defined __MACH__))
+# if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
+# define TM_GMTOFF tm_gmtoff
+# endif
+# if !defined TM_ZONE && !defined NO_TM_ZONE
+# define TM_ZONE tm_zone
+# endif
+#endif
diff --git a/src/tm.c b/src/tm.c
index 6f245eb..ce19ea3 100644
--- a/src/tm.c
+++ b/src/tm.c
@@ -40,6 +40,12 @@ static const struct jd_tm_key jd_tm_keys[] = {
{"wday", offsetof(struct tm, tm_wday)},
{"yday", offsetof(struct tm, tm_yday)},
{"isdst", offsetof(struct tm, tm_isdst)},
+#ifdef TM_GMTOFF
+ {"gmtoff", offsetof(struct tm, TM_GMTOFF)},
+#endif
+#ifdef TM_ZONE
+ {"zone", offsetof(struct tm, TM_ZONE)},
+#endif
{NULL, 0},
};
@@ -56,6 +62,21 @@ static int jd_tm_get(void *p, Janet key, Janet *out) {
const struct jd_tm_key *ptr = jd_tm_keys;
while (ptr->key) {
if (janet_keyeq(key, ptr->key)) {
+#ifdef TM_GMTOFF
+ if (janet_keyeq(key, "gmtoff")) {
+ long val = *((long*)(p + ptr->off));
+ *out = janet_wrap_s64(val);
+ return 1;
+ }
+#endif
+#ifdef TM_ZONE
+ if (janet_keyeq(key, "zone")) {
+ const char *val = *((const char **)(p + ptr->off));
+ *out = janet_ckeywordv(val);
+ return 1;
+ }
+#endif
+
int val = *((int*)(p + ptr->off));
// exceptional values
@@ -87,6 +108,16 @@ static Janet jd_tm_next(void *p, Janet key) {
}
static void jd_tm_put(void *data, Janet key, Janet value) {
+ if (0
+#ifdef TM_GMTOFF
+ || janet_keyeq(key, "gmtoff")
+#endif
+#ifdef TM_ZONE
+ || janet_keyeq(key, "zone")
+#endif
+ ) {
+ janet_panicf("%s is read-only", key);
+ }
// note that keyword, boolean are only valid for isdst
if (!janet_checktypes(value, JANET_TFLAG_NUMBER | JANET_TFLAG_KEYWORD | JANET_TFLAG_BOOLEAN)) {
janet_panicf("expected function or number, got %t", value);
@@ -117,18 +148,26 @@ static void jd_tm_tostring(void *p, JanetBuffer *buffer) {
const struct jd_tm_key *ptr = jd_tm_keys;
while (ptr->key) {
- int *loc = (int*)(p + ptr->off);
+ void *loc = (void*)(p + ptr->off);
janet_buffer_push_cstring(buffer, ":");
janet_buffer_push_cstring(buffer, ptr->key);
janet_buffer_push_cstring(buffer, " ");
// exceptional values
if (!strcmp(ptr->key, "year")) {
- snprintf(buf, MAX_INT_STRLEN, "%d", *loc + 1900);
+ snprintf(buf, MAX_INT_STRLEN, "%d", *(int*)loc + 1900);
} else if (!strcmp(ptr->key, "isdst")) {
- strcpy(buf, *loc ? (*loc > 0 ? "true" : ":detect") : "false");
+ strcpy(buf, *(int*)loc ? (*(int*)loc > 0 ? "true" : ":detect") : "false");
+#ifdef TM_ZONE
+ } else if (!strcmp(ptr->key, "zone")) {
+ strcpy(buf, *(char**)loc);
+#endif
+#ifdef TM_GMTOFF
+ } else if (!strcmp(ptr->key, "gmtoff")) {
+ snprintf(buf, MAX_INT_STRLEN, "%ld", *(long*)loc);
+#endif
} else {
- snprintf(buf, MAX_INT_STRLEN, "%d", *loc);
+ snprintf(buf, MAX_INT_STRLEN, "%d", *(int*)loc);
}
janet_buffer_push_cstring(buffer, buf);