summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Hood <jadoxa@yahoo.com.au>2019-02-14 18:39:23 +1000
committerNico Williams <nico@cryptonector.com>2019-02-16 20:41:41 -0600
commit0fc8200ab42ea2b629fa0852987cfd4f6346b2dc (patch)
tree47cf7abd2bf76a668fb642e196b6487a6ee573f9
parent87594f81d6f63556f2644fff4ed493aaac97974c (diff)
Add ISO 8601-specific strptime
Implement `strptime` for systems lacking it, but only supporting the ISO 8601 format string.
-rw-r--r--src/builtin.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/src/builtin.c b/src/builtin.c
index 5d44b1d3..3cde61a3 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -1308,7 +1308,25 @@ static void set_tm_yday(struct tm *tm) {
tm->tm_yday = yday;
}
-#ifdef HAVE_STRPTIME
+#ifndef HAVE_STRPTIME
+static char *strptime(const char *s, const char *format, struct tm *tm) {
+ if (strcmp(format, "%Y-%m-%dT%H:%M:%SZ"))
+ return NULL;
+
+ int count, end;
+ count = sscanf(s, "%d-%d-%dT%d:%d:%d%n",
+ &tm->tm_year, &tm->tm_mon, &tm->tm_mday,
+ &tm->tm_hour, &tm->tm_min, &tm->tm_sec,
+ &end );
+ if (count == 6 && s[end] == 'Z') {
+ tm->tm_year -= 1900;
+ tm->tm_mon--;
+ return (char*)s + end + 1;
+ }
+ return NULL;
+}
+#endif
+
static jv f_strptime(jq_state *jq, jv a, jv b) {
if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING) {
return ret_error2(a, b, jv_string("strptime/1 requires string inputs and arguments"));
@@ -1320,8 +1338,13 @@ static jv f_strptime(jq_state *jq, jv a, jv b) {
tm.tm_yday = 367; // sentinel
const char *input = jv_string_value(a);
const char *fmt = jv_string_value(b);
- const char *end = strptime(input, fmt, &tm);
+#ifndef HAVE_STRPTIME
+ if (strcmp(fmt, "%Y-%m-%dT%H:%M:%SZ")) {
+ return ret_error2(a, b, jv_string("strptime/1 only supports ISO 8601 on this platform"));
+ }
+#endif
+ const char *end = strptime(input, fmt, &tm);
if (end == NULL || (*end != '\0' && !isspace(*end))) {
return ret_error2(a, b, jv_string_fmt("date \"%s\" does not match format \"%s\"", input, fmt));
}
@@ -1358,13 +1381,6 @@ static jv f_strptime(jq_state *jq, jv a, jv b) {
jv_free(a); // must come after `*end` because `end` is a pointer into `a`'s string
return r;
}
-#else
-static jv f_strptime(jq_state *jq, jv a, jv b) {
- jv_free(a);
- jv_free(b);
- return jv_invalid_with_msg(jv_string("strptime/1 not implemented on this platform"));
-}
-#endif
#define TO_TM_FIELD(t, j, i) \
do { \