diff options
author | Jason Hood <jadoxa@yahoo.com.au> | 2019-02-14 18:39:23 +1000 |
---|---|---|
committer | Nico Williams <nico@cryptonector.com> | 2019-02-16 20:41:41 -0600 |
commit | 0fc8200ab42ea2b629fa0852987cfd4f6346b2dc (patch) | |
tree | 47cf7abd2bf76a668fb642e196b6487a6ee573f9 | |
parent | 87594f81d6f63556f2644fff4ed493aaac97974c (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.c | 34 |
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 { \ |