5 # define _XOPEN_SOURCE_EXTENDED 1
8 # define __EXTENSIONS__
17 # define alloca __builtin_alloca
18 # elif defined _MSC_VER
20 # define alloca _alloca
21 # elif !defined HAVE_ALLOCA
25 void *alloca (size_t);
33 #include <oniguruma.h>
42 #include "jq_parser.h"
46 #include "jv_unicode.h"
50 static jv type_error(jv bad, const char* msg) {
52 jv err = jv_invalid_with_msg(jv_string_fmt("%s (%s) %s",
53 jv_kind_name(jv_get_kind(bad)),
54 jv_dump_string_trunc(jv_copy(bad), errbuf, sizeof(errbuf)),
60 static jv type_error2(jv bad1, jv bad2, const char* msg) {
61 char errbuf1[15],errbuf2[15];
62 jv err = jv_invalid_with_msg(jv_string_fmt("%s (%s) and %s (%s) %s",
63 jv_kind_name(jv_get_kind(bad1)),
64 jv_dump_string_trunc(jv_copy(bad1), errbuf1, sizeof(errbuf1)),
65 jv_kind_name(jv_get_kind(bad2)),
66 jv_dump_string_trunc(jv_copy(bad2), errbuf2, sizeof(errbuf2)),
73 static inline jv ret_error(jv bad, jv msg) {
75 return jv_invalid_with_msg(msg);
78 static inline jv ret_error2(jv bad1, jv bad2, jv msg) {
81 return jv_invalid_with_msg(msg);
84 static jv f_plus(jq_state *jq, jv input, jv a, jv b) {
86 if (jv_get_kind(a) == JV_KIND_NULL) {
89 } else if (jv_get_kind(b) == JV_KIND_NULL) {
92 } else if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
93 return jv_number(jv_number_value(a) +
95 } else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) {
96 return jv_string_concat(a, b);
97 } else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) {
98 return jv_array_concat(a, b);
99 } else if (jv_get_kind(a) == JV_KIND_OBJECT && jv_get_kind(b) == JV_KIND_OBJECT) {
100 return jv_object_merge(a, b);
102 return type_error2(a, b, "cannot be added");
106 #define LIBM_DD(name) \
107 static jv f_ ## name(jq_state *jq, jv input) { \
108 if (jv_get_kind(input) != JV_KIND_NUMBER) { \
109 return type_error(input, "number required"); \
111 jv ret = jv_number(name(jv_number_value(input))); \
115 #define LIBM_DD_NO(name)
117 #define LIBM_DDD(name) \
118 static jv f_ ## name(jq_state *jq, jv input, jv a, jv b) { \
120 if (jv_get_kind(a) != JV_KIND_NUMBER) { \
122 return type_error(a, "number required"); \
124 if (jv_get_kind(b) != JV_KIND_NUMBER) { \
126 return type_error(b, "number required"); \
128 jv ret = jv_number(name(jv_number_value(a), jv_number_value(b))); \
133 #define LIBM_DDD_NO(name)
135 #define LIBM_DDDD(name) \
136 static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \
138 if (jv_get_kind(a) != JV_KIND_NUMBER) { \
141 return type_error(a, "number required"); \
143 if (jv_get_kind(b) != JV_KIND_NUMBER) { \
146 return type_error(b, "number required"); \
148 if (jv_get_kind(c) != JV_KIND_NUMBER) { \
151 return type_error(c, "number required"); \
153 jv ret = jv_number(name(jv_number_value(a), jv_number_value(b), jv_number_value(c))); \
159 #define LIBM_DDDD_NO(name)
169 static jv f_frexp(jq_state *jq, jv input) {
170 if (jv_get_kind(input) != JV_KIND_NUMBER) {
171 return type_error(input, "number required");
174 double d = frexp(jv_number_value(input), &exp);
175 jv ret = JV_ARRAY(jv_number(d), jv_number(exp));
181 static jv f_modf(jq_state *jq, jv input) {
182 if (jv_get_kind(input) != JV_KIND_NUMBER) {
183 return type_error(input, "number required");
186 jv ret = JV_ARRAY(jv_number(modf(jv_number_value(input), &i)));
188 return jv_array_append(ret, jv_number(i));
192 static jv f_lgamma_r(jq_state *jq, jv input) {
193 if (jv_get_kind(input) != JV_KIND_NUMBER) {
194 return type_error(input, "number required");
197 jv ret = JV_ARRAY(jv_number(lgamma_r(jv_number_value(input), &sign)));
199 return jv_array_append(ret, jv_number(sign));
203 static jv f_negate(jq_state *jq, jv input) {
204 if (jv_get_kind(input) != JV_KIND_NUMBER) {
205 return type_error(input, "cannot be negated");
207 jv ret = jv_number(-jv_number_value(input));
212 static jv f_startswith(jq_state *jq, jv a, jv b) {
213 if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING)
214 return ret_error2(a, b, jv_string("startswith() requires string inputs"));
215 int alen = jv_string_length_bytes(jv_copy(a));
216 int blen = jv_string_length_bytes(jv_copy(b));
219 if (blen <= alen && memcmp(jv_string_value(a), jv_string_value(b), blen) == 0)
228 static jv f_endswith(jq_state *jq, jv a, jv b) {
229 if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING)
230 return ret_error2(a, b, jv_string("endswith() requires string inputs"));
231 const char *astr = jv_string_value(a);
232 const char *bstr = jv_string_value(b);
233 size_t alen = jv_string_length_bytes(jv_copy(a));
234 size_t blen = jv_string_length_bytes(jv_copy(b));
238 memcmp(astr + (alen - blen), bstr, blen) != 0)
247 static jv f_ltrimstr(jq_state *jq, jv input, jv left) {
248 if (jv_get_kind(f_startswith(jq, jv_copy(input), jv_copy(left))) != JV_KIND_TRUE) {
253 * FIXME It'd be better to share the suffix with the original input --
254 * that we could do, we just can't share prefixes.
256 int prefixlen = jv_string_length_bytes(left);
257 jv res = jv_string_sized(jv_string_value(input) + prefixlen,
258 jv_string_length_bytes(jv_copy(input)) - prefixlen);
263 static jv f_rtrimstr(jq_state *jq, jv input, jv right) {
264 if (jv_get_kind(f_endswith(jq, jv_copy(input), jv_copy(right))) == JV_KIND_TRUE) {
265 jv res = jv_string_sized(jv_string_value(input),
266 jv_string_length_bytes(jv_copy(input)) - jv_string_length_bytes(right));
274 static jv f_minus(jq_state *jq, jv input, jv a, jv b) {
276 if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
277 return jv_number(jv_number_value(a) - jv_number_value(b));
278 } else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) {
280 jv_array_foreach(a, i, x) {
282 jv_array_foreach(b, j, y) {
283 if (jv_equal(jv_copy(x), y)) {
289 out = jv_array_append(out, jv_copy(x));
296 return type_error2(a, b, "cannot be subtracted");
300 static jv f_multiply(jq_state *jq, jv input, jv a, jv b) {
301 jv_kind ak = jv_get_kind(a);
302 jv_kind bk = jv_get_kind(b);
304 if (ak == JV_KIND_NUMBER && bk == JV_KIND_NUMBER) {
305 return jv_number(jv_number_value(a) * jv_number_value(b));
306 } else if ((ak == JV_KIND_STRING && bk == JV_KIND_NUMBER) ||
307 (ak == JV_KIND_NUMBER && bk == JV_KIND_STRING)) {
310 if (ak == JV_KIND_NUMBER) {
315 size_t alen = jv_string_length_bytes(jv_copy(str));
318 for (n = jv_number_value(num) - 1; n > 0; n--)
319 res = jv_string_append_buf(res, jv_string_value(str), alen);
327 } else if (ak == JV_KIND_OBJECT && bk == JV_KIND_OBJECT) {
328 return jv_object_merge_recursive(a, b);
330 return type_error2(a, b, "cannot be multiplied");
334 static jv f_divide(jq_state *jq, jv input, jv a, jv b) {
336 if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
337 if (jv_number_value(b) == 0.0)
338 return type_error2(a, b, "cannot be divided because the divisor is zero");
339 return jv_number(jv_number_value(a) / jv_number_value(b));
340 } else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) {
341 return jv_string_split(a, b);
343 return type_error2(a, b, "cannot be divided");
347 static jv f_mod(jq_state *jq, jv input, jv a, jv b) {
349 if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
350 if ((intmax_t)jv_number_value(b) == 0)
351 return type_error2(a, b, "cannot be divided (remainder) because the divisor is zero");
352 return jv_number((intmax_t)jv_number_value(a) % (intmax_t)jv_number_value(b));
354 return type_error2(a, b, "cannot be divided (remainder)");
358 static jv f_equal(jq_state *jq, jv input, jv a, jv b) {
360 return jv_bool(jv_equal(a, b));
363 static jv f_notequal(jq_state *jq, jv input, jv a, jv b) {
365 return jv_bool(!jv_equal(a, b));
375 static jv order_cmp(jv input, jv a, jv b, enum cmp_op op) {
377 int r = jv_cmp(a, b);
378 return jv_bool((op == CMP_OP_LESS && r < 0) ||
379 (op == CMP_OP_LESSEQ && r <= 0) ||
380 (op == CMP_OP_GREATEREQ && r >= 0) ||
381 (op == CMP_OP_GREATER && r > 0));
384 static jv f_less(jq_state *jq, jv input, jv a, jv b) {
385 return order_cmp(input, a, b, CMP_OP_LESS);
388 static jv f_greater(jq_state *jq, jv input, jv a, jv b) {
389 return order_cmp(input, a, b, CMP_OP_GREATER);
392 static jv f_lesseq(jq_state *jq, jv input, jv a, jv b) {
393 return order_cmp(input, a, b, CMP_OP_LESSEQ);
396 static jv f_greatereq(jq_state *jq, jv input, jv a, jv b) {
397 return order_cmp(input, a, b, CMP_OP_GREATEREQ);
400 static jv f_contains(jq_state *jq, jv a, jv b) {
401 if (jv_get_kind(a) == jv_get_kind(b)) {
402 return jv_bool(jv_contains(a, b));
404 return type_error2(a, b, "cannot have their containment checked");
408 static jv f_dump(jq_state *jq, jv input) {
409 return jv_dump_string(input, 0);
412 static jv f_json_parse(jq_state *jq, jv input) {
413 if (jv_get_kind(input) != JV_KIND_STRING)
414 return type_error(input, "only strings can be parsed");
415 jv res = jv_parse_sized(jv_string_value(input),
416 jv_string_length_bytes(jv_copy(input)));
421 static jv f_tonumber(jq_state *jq, jv input) {
422 if (jv_get_kind(input) == JV_KIND_NUMBER) {
425 if (jv_get_kind(input) == JV_KIND_STRING) {
426 jv parsed = jv_parse(jv_string_value(input));
427 if (!jv_is_valid(parsed) || jv_get_kind(parsed) == JV_KIND_NUMBER) {
432 return type_error(input, "cannot be parsed as a number");
435 static jv f_length(jq_state *jq, jv input) {
436 if (jv_get_kind(input) == JV_KIND_ARRAY) {
437 return jv_number(jv_array_length(input));
438 } else if (jv_get_kind(input) == JV_KIND_OBJECT) {
439 return jv_number(jv_object_length(input));
440 } else if (jv_get_kind(input) == JV_KIND_STRING) {
441 return jv_number(jv_string_length_codepoints(input));
442 } else if (jv_get_kind(input) == JV_KIND_NUMBER) {
443 return jv_number(fabs(jv_number_value(input)));
444 } else if (jv_get_kind(input) == JV_KIND_NULL) {
448 return type_error(input, "has no length");
452 static jv f_tostring(jq_state *jq, jv input) {
453 if (jv_get_kind(input) == JV_KIND_STRING) {
456 return jv_dump_string(input, 0);
460 static jv f_utf8bytelength(jq_state *jq, jv input) {
461 if (jv_get_kind(input) != JV_KIND_STRING)
462 return type_error(input, "only strings have UTF-8 byte length");
463 return jv_number(jv_string_length_bytes(input));
466 #define CHARS_ALPHANUM "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
468 static const unsigned char BASE64_ENCODE_TABLE[64 + 1] = CHARS_ALPHANUM "+/";
469 static const unsigned char BASE64_INVALID_ENTRY = 0xFF;
470 static const unsigned char BASE64_DECODE_TABLE[255] = {
471 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
475 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // 0-9
479 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // A-Z
480 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
481 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // a-z
482 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
486 static jv escape_string(jv input, const char* escapings) {
488 assert(jv_get_kind(input) == JV_KIND_STRING);
489 const char* lookup[128] = {0};
490 const char* p = escapings;
493 lookup[(int)*p] = p+1;
499 jv ret = jv_string("");
500 const char* i = jv_string_value(input);
501 const char* end = i + jv_string_length_bytes(jv_copy(input));
504 while ((i = jvp_utf8_next((cstart = i), end, &c))) {
505 if (c < 128 && lookup[c]) {
506 ret = jv_string_append_str(ret, lookup[c]);
508 ret = jv_string_append_buf(ret, cstart, i - cstart);
516 static jv f_format(jq_state *jq, jv input, jv fmt) {
517 if (jv_get_kind(fmt) != JV_KIND_STRING) {
519 return type_error(fmt, "is not a valid format");
521 const char* fmt_s = jv_string_value(fmt);
522 if (!strcmp(fmt_s, "json")) {
524 return jv_dump_string(input, 0);
525 } else if (!strcmp(fmt_s, "text")) {
527 return f_tostring(jq, input);
528 } else if (!strcmp(fmt_s, "csv") || !strcmp(fmt_s, "tsv")) {
529 const char *quotes, *sep, *escapings;
531 if (!strcmp(fmt_s, "csv")) {
532 msg = "cannot be csv-formatted, only array";
535 escapings = "\"\"\"\0";
537 msg = "cannot be tsv-formatted, only array";
538 assert(!strcmp(fmt_s, "tsv"));
541 escapings = "\t\\t\0\r\\r\0\n\\n\0\\\\\\\0";
544 if (jv_get_kind(input) != JV_KIND_ARRAY)
545 return type_error(input, msg);
546 jv line = jv_string("");
547 jv_array_foreach(input, i, x) {
548 if (i) line = jv_string_append_str(line, sep);
549 switch (jv_get_kind(x)) {
551 /* null rendered as empty string */
556 line = jv_string_concat(line, jv_dump_string(x, 0));
559 if (jv_number_value(x) != jv_number_value(x)) {
560 /* NaN, render as empty string */
563 line = jv_string_concat(line, jv_dump_string(x, 0));
566 case JV_KIND_STRING: {
567 line = jv_string_append_str(line, quotes);
568 line = jv_string_concat(line, escape_string(x, escapings));
569 line = jv_string_append_str(line, quotes);
575 return type_error(x, "is not valid in a csv row");
580 } else if (!strcmp(fmt_s, "html")) {
582 return escape_string(f_tostring(jq, input), "&&\0<<\0>>\0''\0\""\0");
583 } else if (!strcmp(fmt_s, "uri")) {
585 input = f_tostring(jq, input);
587 int unreserved[128] = {0};
588 const char* p = CHARS_ALPHANUM "-_.!~*'()";
589 while (*p) unreserved[(int)*p++] = 1;
591 jv line = jv_string("");
592 const char* s = jv_string_value(input);
593 for (int i=0; i<jv_string_length_bytes(jv_copy(input)); i++) {
594 unsigned ch = (unsigned)(unsigned char)*s;
595 if (ch < 128 && unreserved[ch]) {
596 line = jv_string_append_buf(line, s, 1);
598 line = jv_string_concat(line, jv_string_fmt("%%%02X", ch));
604 } else if (!strcmp(fmt_s, "sh")) {
606 if (jv_get_kind(input) != JV_KIND_ARRAY)
607 input = jv_array_set(jv_array(), 0, input);
608 jv line = jv_string("");
609 jv_array_foreach(input, i, x) {
610 if (i) line = jv_string_append_str(line, " ");
611 switch (jv_get_kind(x)) {
616 line = jv_string_concat(line, jv_dump_string(x, 0));
619 case JV_KIND_STRING: {
620 line = jv_string_append_str(line, "'");
621 line = jv_string_concat(line, escape_string(x, "''\\''\0"));
622 line = jv_string_append_str(line, "'");
629 return type_error(x, "can not be escaped for shell");
634 } else if (!strcmp(fmt_s, "base64")) {
636 input = f_tostring(jq, input);
637 jv line = jv_string("");
638 const unsigned char* data = (const unsigned char*)jv_string_value(input);
639 int len = jv_string_length_bytes(jv_copy(input));
640 for (int i=0; i<len; i+=3) {
642 int n = len - i >= 3 ? 3 : len-i;
643 for (int j=0; j<3; j++) {
645 code |= j < n ? (unsigned)data[i+j] : 0;
648 for (int j=0; j<4; j++) {
649 buf[j] = BASE64_ENCODE_TABLE[(code >> (18 - j*6)) & 0x3f];
651 if (n < 3) buf[3] = '=';
652 if (n < 2) buf[2] = '=';
653 line = jv_string_append_buf(line, buf, sizeof(buf));
657 } else if (!strcmp(fmt_s, "base64d")) {
659 input = f_tostring(jq, input);
660 const unsigned char* data = (const unsigned char*)jv_string_value(input);
661 int len = jv_string_length_bytes(jv_copy(input));
662 size_t decoded_len = (3 * len) / 4; // 3 usable bytes for every 4 bytes of input
663 char *result = jv_mem_calloc(decoded_len, sizeof(char));
664 memset(result, 0, decoded_len * sizeof(char));
666 int input_bytes_read=0;
668 for (int i=0; i<len && data[i] != '='; i++) {
669 if (BASE64_DECODE_TABLE[data[i]] == BASE64_INVALID_ENTRY) {
671 return type_error(input, "is not valid base64 data");
675 code |= BASE64_DECODE_TABLE[data[i]];
678 if (input_bytes_read == 4) {
679 result[ri++] = (code >> 16) & 0xFF;
680 result[ri++] = (code >> 8) & 0xFF;
681 result[ri++] = code & 0xFF;
682 input_bytes_read = 0;
686 if (input_bytes_read == 3) {
687 result[ri++] = (code >> 10) & 0xFF;
688 result[ri++] = (code >> 2) & 0xFF;
689 } else if (input_bytes_read == 2) {
690 result[ri++] = (code >> 4) & 0xFF;
691 } else if (input_bytes_read == 1) {
693 return type_error(input, "trailing base64 byte found");
696 jv line = jv_string_sized(result, ri);
702 return jv_invalid_with_msg(jv_string_concat(fmt, jv_string(" is not a valid format")));
706 static jv f_keys(jq_state *jq, jv input) {
707 if (jv_get_kind(input) == JV_KIND_OBJECT || jv_get_kind(input) == JV_KIND_ARRAY) {
708 return jv_keys(input);
710 return type_error(input, "has no keys");
714 static jv f_keys_unsorted(jq_state *jq, jv input) {
715 if (jv_get_kind(input) == JV_KIND_OBJECT || jv_get_kind(input) == JV_KIND_ARRAY) {
716 return jv_keys_unsorted(input);
718 return type_error(input, "has no keys");
722 static jv f_sort(jq_state *jq, jv input){
723 if (jv_get_kind(input) == JV_KIND_ARRAY) {
724 return jv_sort(input, jv_copy(input));
726 return type_error(input, "cannot be sorted, as it is not an array");
730 static jv f_sort_by_impl(jq_state *jq, jv input, jv keys) {
731 if (jv_get_kind(input) == JV_KIND_ARRAY &&
732 jv_get_kind(keys) == JV_KIND_ARRAY &&
733 jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) {
734 return jv_sort(input, keys);
736 return type_error2(input, keys, "cannot be sorted, as they are not both arrays");
740 static jv f_group_by_impl(jq_state *jq, jv input, jv keys) {
741 if (jv_get_kind(input) == JV_KIND_ARRAY &&
742 jv_get_kind(keys) == JV_KIND_ARRAY &&
743 jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) {
744 return jv_group(input, keys);
746 return type_error2(input, keys, "cannot be sorted, as they are not both arrays");
751 static int f_match_name_iter(const UChar* name, const UChar *name_end, int ngroups,
752 int *groups, regex_t *reg, void *arg) {
753 jv captures = *(jv*)arg;
754 for (int i = 0; i < ngroups; ++i) {
755 jv cap = jv_array_get(jv_copy(captures),groups[i]-1);
756 if (jv_get_kind(cap) == JV_KIND_OBJECT) {
757 cap = jv_object_set(cap, jv_string("name"), jv_string_sized((const char*)name, name_end-name));
758 captures = jv_array_set(captures,groups[i]-1,cap);
763 *(jv *)arg = captures;
767 static jv f_match(jq_state *jq, jv input, jv regex, jv modifiers, jv testmode) {
768 int test = jv_equal(testmode, jv_true());
776 if (jv_get_kind(input) != JV_KIND_STRING) {
779 return type_error(input, "cannot be matched, as it is not a string");
782 if (jv_get_kind(regex) != JV_KIND_STRING) {
785 return type_error(regex, "is not a string");
788 OnigOptionType options = ONIG_OPTION_CAPTURE_GROUP;
790 if (jv_get_kind(modifiers) == JV_KIND_STRING) {
791 jv modarray = jv_string_explode(jv_copy(modifiers));
792 jv_array_foreach(modarray, i, mod) {
793 switch ((int)jv_number_value(mod)) {
798 options |= ONIG_OPTION_IGNORECASE;
801 options |= ONIG_OPTION_EXTEND;
804 options |= ONIG_OPTION_MULTILINE;
807 options |= ONIG_OPTION_SINGLELINE;
810 options |= ONIG_OPTION_MULTILINE | ONIG_OPTION_SINGLELINE;
813 options |= ONIG_OPTION_FIND_LONGEST;
816 options |= ONIG_OPTION_FIND_NOT_EMPTY;
822 return jv_invalid_with_msg(jv_string_concat(modifiers,
823 jv_string(" is not a valid modifier string")));
827 } else if (jv_get_kind(modifiers) != JV_KIND_NULL) {
828 // If it isn't a string or null, then it is the wrong type...
831 return type_error(modifiers, "is not a string");
836 onigret = onig_new(®, (const UChar*)jv_string_value(regex),
837 (const UChar*)(jv_string_value(regex) + jv_string_length_bytes(jv_copy(regex))),
838 options, ONIG_ENCODING_UTF8, ONIG_SYNTAX_PERL_NG, &einfo);
839 if (onigret != ONIG_NORMAL) {
840 UChar ebuf[ONIG_MAX_ERROR_MESSAGE_LEN];
841 onig_error_code_to_str(ebuf, onigret, &einfo);
844 return jv_invalid_with_msg(jv_string_concat(jv_string("Regex failure: "),
845 jv_string((char*)ebuf)));
847 result = test ? jv_false() : jv_array();
848 const char *input_string = jv_string_value(input);
849 const UChar* start = (const UChar*)jv_string_value(input);
850 const unsigned long length = jv_string_length_bytes(jv_copy(input));
851 const UChar* end = start + length;
852 region = onig_region_new();
854 onigret = onig_search(reg,
855 (const UChar*)jv_string_value(input), end, /* string boundaries */
856 start, end, /* search boundaries */
857 region, ONIG_OPTION_NONE);
865 if (region->end[0] == region->beg[0]) {
867 const char *fr = (const char*)input_string;
868 for (idx = 0; fr != input_string+region->beg[0]; idx++) {
869 fr += jvp_utf8_decode_length(*fr);
871 jv match = jv_object_set(jv_object(), jv_string("offset"), jv_number(idx));
872 match = jv_object_set(match, jv_string("length"), jv_number(0));
873 match = jv_object_set(match, jv_string("string"), jv_string(""));
874 match = jv_object_set(match, jv_string("captures"), jv_array());
875 result = jv_array_append(result, match);
882 const char *fr = (const char*)input_string;
884 for (idx = len = 0; fr < input_string+region->end[0]; len++) {
885 if (fr == input_string+region->beg[0]) idx = len, len=0;
886 fr += jvp_utf8_decode_length(*fr);
889 jv match = jv_object_set(jv_object(), jv_string("offset"), jv_number(idx));
891 unsigned long blen = region->end[0]-region->beg[0];
892 match = jv_object_set(match, jv_string("length"), jv_number(len));
893 match = jv_object_set(match, jv_string("string"), jv_string_sized(input_string+region->beg[0],blen));
894 jv captures = jv_array();
895 for (int i = 1; i < region->num_regs; ++i) {
897 if (region->beg[i] == region->end[i]) {
900 if (region->beg[i] == -1) {
901 cap = jv_object_set(jv_object(), jv_string("offset"), jv_number(-1));
902 cap = jv_object_set(cap, jv_string("string"), jv_null());
905 for (idx = 0; fr != input_string+region->beg[i]; idx++) {
906 fr += jvp_utf8_decode_length(*fr);
908 cap = jv_object_set(jv_object(), jv_string("offset"), jv_number(idx));
909 cap = jv_object_set(cap, jv_string("string"), jv_string(""));
911 cap = jv_object_set(cap, jv_string("length"), jv_number(0));
912 cap = jv_object_set(cap, jv_string("name"), jv_null());
913 captures = jv_array_append(captures, cap);
917 for (idx = len = 0; fr != input_string+region->end[i]; len++) {
918 if (fr == input_string+region->beg[i]) idx = len, len=0;
919 fr += jvp_utf8_decode_length(*fr);
922 blen = region->end[i]-region->beg[i];
923 jv cap = jv_object_set(jv_object(), jv_string("offset"), jv_number(idx));
924 cap = jv_object_set(cap, jv_string("length"), jv_number(len));
925 cap = jv_object_set(cap, jv_string("string"), jv_string_sized(input_string+region->beg[i],blen));
926 cap = jv_object_set(cap, jv_string("name"), jv_null());
927 captures = jv_array_append(captures,cap);
929 onig_foreach_name(reg,f_match_name_iter,&captures);
930 match = jv_object_set(match, jv_string("captures"), captures);
931 result = jv_array_append(result, match);
932 start = (const UChar*)(input_string+region->end[0]);
933 onig_region_free(region,0);
934 } else if (onigret == ONIG_MISMATCH) {
937 UChar ebuf[ONIG_MAX_ERROR_MESSAGE_LEN];
938 onig_error_code_to_str(ebuf, onigret, einfo);
940 result = jv_invalid_with_msg(jv_string_concat(jv_string("Regex failure: "),
941 jv_string((char*)ebuf)));
944 } while (global && start != end);
945 onig_region_free(region,1);
948 onig_region_free(region,1);
954 #else /* !HAVE_LIBONIG */
955 static jv f_match(jq_state *jq, jv input, jv regex, jv modifiers, jv testmode) {
956 return jv_invalid_with_msg(jv_string("jq was compiled without ONIGURUMA regex libary. match/test/sub and related functions are not available."));
958 #endif /* HAVE_LIBONIG */
960 static jv minmax_by(jv values, jv keys, int is_min) {
961 if (jv_get_kind(values) != JV_KIND_ARRAY)
962 return type_error2(values, keys, "cannot be iterated over");
963 if (jv_get_kind(keys) != JV_KIND_ARRAY)
964 return type_error2(values, keys, "cannot be iterated over");
965 if (jv_array_length(jv_copy(values)) != jv_array_length(jv_copy(keys)))
966 return type_error2(values, keys, "have wrong length");
968 if (jv_array_length(jv_copy(values)) == 0) {
973 jv ret = jv_array_get(jv_copy(values), 0);
974 jv retkey = jv_array_get(jv_copy(keys), 0);
975 for (int i=1; i<jv_array_length(jv_copy(values)); i++) {
976 jv item = jv_array_get(jv_copy(keys), i);
977 int cmp = jv_cmp(jv_copy(item), jv_copy(retkey));
978 if ((cmp < 0) == (is_min == 1)) {
982 ret = jv_array_get(jv_copy(values), i);
993 static jv f_min(jq_state *jq, jv x) {
994 return minmax_by(x, jv_copy(x), 1);
997 static jv f_max(jq_state *jq, jv x) {
998 return minmax_by(x, jv_copy(x), 0);
1001 static jv f_min_by_impl(jq_state *jq, jv x, jv y) {
1002 return minmax_by(x, y, 1);
1005 static jv f_max_by_impl(jq_state *jq, jv x, jv y) {
1006 return minmax_by(x, y, 0);
1010 static jv f_type(jq_state *jq, jv input) {
1011 jv out = jv_string(jv_kind_name(jv_get_kind(input)));
1016 static jv f_isinfinite(jq_state *jq, jv input) {
1017 jv_kind k = jv_get_kind(input);
1018 if (k != JV_KIND_NUMBER) {
1022 double n = jv_number_value(input);
1024 return isinf(n) ? jv_true() : jv_false();
1027 static jv f_isnan(jq_state *jq, jv input) {
1028 jv_kind k = jv_get_kind(input);
1029 if (k != JV_KIND_NUMBER) {
1033 double n = jv_number_value(input);
1035 return isnan(n) ? jv_true() : jv_false();
1038 static jv f_isnormal(jq_state *jq, jv input) {
1039 jv_kind k = jv_get_kind(input);
1040 if (k != JV_KIND_NUMBER) {
1044 double n = jv_number_value(input);
1046 return isnormal(n) ? jv_true() : jv_false();
1049 static jv f_infinite(jq_state *jq, jv input) {
1051 return jv_number(INFINITY);
1054 static jv f_nan(jq_state *jq, jv input) {
1056 return jv_number(NAN);
1059 static jv f_error(jq_state *jq, jv input, jv msg) {
1061 return jv_invalid_with_msg(msg);
1064 // FIXME Should autoconf check for this!
1066 extern char **environ;
1069 static jv f_env(jq_state *jq, jv input) {
1071 jv env = jv_object();
1072 const char *var, *val;
1073 for (char **e = environ; *e != NULL; e++) {
1075 val = strchr(e[0], '=');
1077 env = jv_object_set(env, jv_string(var), jv_null());
1078 else if (var - val < INT_MAX)
1079 env = jv_object_set(env, jv_string_sized(var, val - var), jv_string(val + 1));
1084 static jv f_halt(jq_state *jq, jv input) {
1086 jq_halt(jq, jv_invalid(), jv_invalid());
1090 static jv f_halt_error(jq_state *jq, jv input, jv a) {
1091 if (jv_get_kind(a) != JV_KIND_NUMBER) {
1093 return type_error(input, "halt_error/1: number required");
1095 jq_halt(jq, a, input);
1099 static jv f_get_search_list(jq_state *jq, jv input) {
1101 return jq_get_lib_dirs(jq);
1104 static jv f_get_prog_origin(jq_state *jq, jv input) {
1106 return jq_get_prog_origin(jq);
1109 static jv f_get_jq_origin(jq_state *jq, jv input) {
1111 return jq_get_jq_origin(jq);
1114 static jv f_string_split(jq_state *jq, jv a, jv b) {
1115 if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING) {
1116 return ret_error2(a, b, jv_string("split input and separator must be strings"));
1118 return jv_string_split(a, b);
1121 static jv f_string_explode(jq_state *jq, jv a) {
1122 if (jv_get_kind(a) != JV_KIND_STRING) {
1123 return ret_error(a, jv_string("explode input must be a string"));
1125 return jv_string_explode(a);
1128 static jv f_string_indexes(jq_state *jq, jv a, jv b) {
1129 return jv_string_indexes(a, b);
1132 static jv f_string_implode(jq_state *jq, jv a) {
1133 if (jv_get_kind(a) != JV_KIND_ARRAY) {
1134 return ret_error(a, jv_string("implode input must be an array"));
1136 return jv_string_implode(a);
1139 static jv f_setpath(jq_state *jq, jv a, jv b, jv c) { return jv_setpath(a, b, c); }
1140 extern jv _jq_path_append(jq_state *, jv, jv, jv);
1141 static jv f_getpath(jq_state *jq, jv a, jv b) {
1142 return _jq_path_append(jq, a, b, jv_getpath(jv_copy(a), jv_copy(b)));
1144 static jv f_delpaths(jq_state *jq, jv a, jv b) { return jv_delpaths(a, b); }
1145 static jv f_has(jq_state *jq, jv a, jv b) { return jv_has(a, b); }
1147 static jv f_modulemeta(jq_state *jq, jv a) {
1148 if (jv_get_kind(a) != JV_KIND_STRING) {
1149 return ret_error(a, jv_string("modulemeta input module name must be a string"));
1151 return load_module_meta(jq, a);
1154 static jv f_input(jq_state *jq, jv input) {
1158 jq_get_input_cb(jq, &cb, &data);
1160 return jv_invalid_with_msg(jv_string("break"));
1161 jv v = cb(jq, data);
1162 if (jv_is_valid(v) || jv_invalid_has_msg(jv_copy(v)))
1164 return jv_invalid_with_msg(jv_string("break"));
1167 static jv f_debug(jq_state *jq, jv input) {
1170 jq_get_debug_cb(jq, &cb, &data);
1172 cb(data, jv_copy(input));
1176 static jv f_stderr(jq_state *jq, jv input) {
1177 jv_dumpf(jv_copy(input), stderr, 0);
1181 static jv tm2jv(struct tm *tm) {
1182 return JV_ARRAY(jv_number(tm->tm_year + 1900),
1183 jv_number(tm->tm_mon),
1184 jv_number(tm->tm_mday),
1185 jv_number(tm->tm_hour),
1186 jv_number(tm->tm_min),
1187 jv_number(tm->tm_sec),
1188 jv_number(tm->tm_wday),
1189 jv_number(tm->tm_yday));
1192 #if defined(WIN32) && !defined(HAVE_SETENV)
1193 static int setenv(const char *var, const char *val, int ovr)
1200 d = GetEnvironmentVariableA (var, c, 2);
1201 if (0 != d && GetLastError () != ERROR_ENVVAR_NOT_FOUND) {
1205 b = SetEnvironmentVariableA (var, val);
1214 * mktime() has side-effects and anyways, returns time in the local
1215 * timezone, not UTC. We want timegm(), which isn't standard.
1217 * To make things worse, mktime() tells you what the timezone
1218 * adjustment is, but you have to #define _BSD_SOURCE to get this
1219 * field of struct tm on some systems.
1221 * This is all to blame on POSIX, of course.
1223 * Our wrapper tries to use timegm() if available, or mktime() and
1224 * correct for its side-effects if possible.
1226 * Returns (time_t)-2 if mktime()'s side-effects cannot be corrected.
1228 static time_t my_mktime(struct tm *tm) {
1231 #elif HAVE_TM_TM_GMT_OFF
1233 time_t t = mktime(tm);
1234 if (t == (time_t)-1)
1236 return t + tm->tm_gmtoff;
1237 #elif HAVE_TM___TM_GMT_OFF
1238 time_t t = mktime(tm);
1239 if (t == (time_t)-1)
1241 return t + tm->__tm_gmtoff;
1245 tz = (tz = getenv("TZ")) != NULL ? strdup(tz) : NULL;
1247 setenv("TZ", "", 1);
1248 time_t t = mktime(tm);
1250 setenv("TZ", tz, 1);
1255 /* Compute and set tm_wday */
1256 static void set_tm_wday(struct tm *tm) {
1258 * https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Gauss.27s_algorithm
1259 * https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html
1261 * Tested with dates from 1900-01-01 through 2100-01-01. This
1262 * algorithm produces the wrong day-of-the-week number for dates in
1263 * the range 1900-01-01..1900-02-28, and for 2100-01-01..2100-02-28.
1264 * Since this is only needed on OS X and *BSD, we might just document
1267 int century = (1900 + tm->tm_year) / 100;
1268 int year = (1900 + tm->tm_year) % 100;
1272 * The month value in the wday computation below is shifted so that
1273 * March is 1, April is 2, .., January is 11, and February is 12.
1275 int mon = tm->tm_mon - 1;
1279 (tm->tm_mday + (int)floor((2.6 * mon - 0.2)) + year + (int)floor(year / 4.0) + (int)floor(century / 4.0) - 2 * century) % 7;
1283 /* See commentary above */
1284 assert(wday == tm->tm_wday || tm->tm_wday == 8);
1289 * Compute and set tm_yday.
1292 static void set_tm_yday(struct tm *tm) {
1293 static const int d[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
1294 int mon = tm->tm_mon;
1295 int year = 1900 + tm->tm_year;
1297 if (tm->tm_mon > 1 &&
1298 ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
1301 /* Bound check index into d[] */
1307 int yday = d[mon] + leap_day + tm->tm_mday - 1;
1308 assert(yday == tm->tm_yday || tm->tm_yday == 367);
1312 #ifdef HAVE_STRPTIME
1313 static jv f_strptime(jq_state *jq, jv a, jv b) {
1314 if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING) {
1315 return ret_error2(a, b, jv_string("strptime/1 requires string inputs and arguments"));
1319 memset(&tm, 0, sizeof(tm));
1320 tm.tm_wday = 8; // sentinel
1321 tm.tm_yday = 367; // sentinel
1322 const char *input = jv_string_value(a);
1323 const char *fmt = jv_string_value(b);
1324 const char *end = strptime(input, fmt, &tm);
1326 if (end == NULL || (*end != '\0' && !isspace(*end))) {
1327 return ret_error2(a, b, jv_string_fmt("date \"%s\" does not match format \"%s\"", input, fmt));
1331 * This is OS X or some *BSD whose strptime() is just not that
1334 * We don't know that the format string did involve parsing a
1335 * year, or a month (if tm->tm_mon == 0). But with our invalid
1336 * day-of-week and day-of-year sentinel checks above, the worst
1337 * this can do is produce garbage.
1341 * Apple has made it worse, and different versions of the OS have different
1342 * behaviors. Some versions just don't touch the fields, but others do, and
1343 * sometimes provide wrong answers, at that! We can't tell at compile-time
1344 * which behavior the target system will have, so instead we always use our
1345 * functions to set these on OS X, and document that %u and %j are
1346 * unsupported on OS X.
1351 if (tm.tm_wday == 8 && tm.tm_mday != 0 && tm.tm_mon >= 0 && tm.tm_mon <= 11)
1353 if (tm.tm_yday == 367 && tm.tm_mday != 0 && tm.tm_mon >= 0 && tm.tm_mon <= 11)
1358 r = jv_array_append(r, jv_string(end));
1359 jv_free(a); // must come after `*end` because `end` is a pointer into `a`'s string
1363 static jv f_strptime(jq_state *jq, jv a, jv b) {
1366 return jv_invalid_with_msg(jv_string("strptime/1 not implemented on this platform"));
1370 #define TO_TM_FIELD(t, j, i) \
1372 jv n = jv_array_get(jv_copy(j), (i)); \
1373 if (jv_get_kind(n) != (JV_KIND_NUMBER)) { \
1377 t = jv_number_value(n); \
1381 static int jv2tm(jv a, struct tm *tm) {
1382 memset(tm, 0, sizeof(*tm));
1383 TO_TM_FIELD(tm->tm_year, a, 0);
1384 tm->tm_year -= 1900;
1385 TO_TM_FIELD(tm->tm_mon, a, 1);
1386 TO_TM_FIELD(tm->tm_mday, a, 2);
1387 TO_TM_FIELD(tm->tm_hour, a, 3);
1388 TO_TM_FIELD(tm->tm_min, a, 4);
1389 TO_TM_FIELD(tm->tm_sec, a, 5);
1390 TO_TM_FIELD(tm->tm_wday, a, 6);
1391 TO_TM_FIELD(tm->tm_yday, a, 7);
1394 // We use UTC everywhere (gettimeofday, gmtime) and UTC does not do DST.
1395 // Setting tm_isdst to 0 is done by the memset.
1396 // tm->tm_isdst = 0;
1398 // The standard permits the tm structure to contain additional members. We
1399 // hope it is okay to initialize them to zero, because the standard does not
1400 // provide an alternative.
1407 static jv f_mktime(jq_state *jq, jv a) {
1408 if (jv_get_kind(a) != JV_KIND_ARRAY)
1409 return ret_error(a, jv_string("mktime requires array inputs"));
1410 if (jv_array_length(jv_copy(a)) < 6)
1411 return ret_error(a, jv_string("mktime requires parsed datetime inputs"));
1414 return jv_invalid_with_msg(jv_string("mktime requires parsed datetime inputs"));
1415 time_t t = my_mktime(&tm);
1416 if (t == (time_t)-1)
1417 return jv_invalid_with_msg(jv_string("invalid gmtime representation"));
1418 if (t == (time_t)-2)
1419 return jv_invalid_with_msg(jv_string("mktime not supported on this platform"));
1420 return jv_number(t);
1423 #ifdef HAVE_GMTIME_R
1424 static jv f_gmtime(jq_state *jq, jv a) {
1425 if (jv_get_kind(a) != JV_KIND_NUMBER)
1426 return ret_error(a, jv_string("gmtime() requires numeric inputs"));
1428 memset(&tm, 0, sizeof(tm));
1429 double fsecs = jv_number_value(a);
1430 time_t secs = fsecs;
1432 tmp = gmtime_r(&secs, &tm);
1434 return jv_invalid_with_msg(jv_string("errror converting number of seconds since epoch to datetime"));
1436 return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1438 #elif defined HAVE_GMTIME
1439 static jv f_gmtime(jq_state *jq, jv a) {
1440 if (jv_get_kind(a) != JV_KIND_NUMBER)
1441 return ret_error(a, jv_string("gmtime requires numeric inputs"));
1443 memset(&tm, 0, sizeof(tm));
1444 double fsecs = jv_number_value(a);
1445 time_t secs = fsecs;
1447 tmp = gmtime(&secs);
1449 return jv_invalid_with_msg(jv_string("errror converting number of seconds since epoch to datetime"));
1451 return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1454 static jv f_gmtime(jq_state *jq, jv a) {
1456 return jv_invalid_with_msg(jv_string("gmtime not implemented on this platform"));
1460 #ifdef HAVE_LOCALTIME_R
1461 static jv f_localtime(jq_state *jq, jv a) {
1462 if (jv_get_kind(a) != JV_KIND_NUMBER)
1463 return ret_error(a, jv_string("localtime() requires numeric inputs"));
1465 memset(&tm, 0, sizeof(tm));
1466 double fsecs = jv_number_value(a);
1467 time_t secs = fsecs;
1469 tmp = localtime_r(&secs, &tm);
1471 return jv_invalid_with_msg(jv_string("error converting number of seconds since epoch to datetime"));
1473 return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1475 #elif defined HAVE_GMTIME
1476 static jv f_localtime(jq_state *jq, jv a) {
1477 if (jv_get_kind(a) != JV_KIND_NUMBER)
1478 return ret_error(a, jv_string("localtime requires numeric inputs"));
1480 memset(&tm, 0, sizeof(tm));
1481 double fsecs = jv_number_value(a);
1482 time_t secs = fsecs;
1484 tmp = localtime(&secs);
1486 return jv_invalid_with_msg(jv_string("error converting number of seconds since epoch to datetime"));
1488 return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1491 static jv f_localtime(jq_state *jq, jv a) {
1493 return jv_invalid_with_msg(jv_string("localtime not implemented on this platform"));
1497 #ifdef HAVE_STRFTIME
1498 static jv f_strftime(jq_state *jq, jv a, jv b) {
1499 if (jv_get_kind(a) == JV_KIND_NUMBER) {
1500 a = f_gmtime(jq, a);
1501 } else if (jv_get_kind(a) != JV_KIND_ARRAY) {
1502 return ret_error2(a, b, jv_string("strftime/1 requires parsed datetime inputs"));
1503 } else if (jv_get_kind(b) != JV_KIND_STRING) {
1504 return ret_error2(a, b, jv_string("strftime/1 requires a string format"));
1508 return ret_error(b, jv_string("strftime/1 requires parsed datetime inputs"));
1510 const char *fmt = jv_string_value(b);
1511 size_t alloced = strlen(fmt) + 100;
1512 char *buf = alloca(alloced);
1513 size_t n = strftime(buf, alloced, fmt, &tm);
1515 /* POSIX doesn't provide errno values for strftime() failures; weird */
1516 if (n == 0 || n > alloced)
1517 return jv_invalid_with_msg(jv_string("strftime/1: unknown system failure"));
1518 return jv_string(buf);
1521 static jv f_strftime(jq_state *jq, jv a, jv b) {
1524 return jv_invalid_with_msg(jv_string("strftime/1 not implemented on this platform"));
1528 #ifdef HAVE_STRFTIME
1529 static jv f_strflocaltime(jq_state *jq, jv a, jv b) {
1530 if (jv_get_kind(a) == JV_KIND_NUMBER) {
1531 a = f_localtime(jq, a);
1532 } else if (jv_get_kind(a) != JV_KIND_ARRAY) {
1533 return ret_error2(a, b, jv_string("strflocaltime/1 requires parsed datetime inputs"));
1534 } else if (jv_get_kind(b) != JV_KIND_STRING) {
1535 return ret_error2(a, b, jv_string("strflocaltime/1 requires a string format"));
1539 return jv_invalid_with_msg(jv_string("strflocaltime/1 requires parsed datetime inputs"));
1540 const char *fmt = jv_string_value(b);
1541 size_t alloced = strlen(fmt) + 100;
1542 char *buf = alloca(alloced);
1543 size_t n = strftime(buf, alloced, fmt, &tm);
1545 /* POSIX doesn't provide errno values for strftime() failures; weird */
1546 if (n == 0 || n > alloced)
1547 return jv_invalid_with_msg(jv_string("strflocaltime/1: unknown system failure"));
1548 return jv_string(buf);
1551 static jv f_strflocaltime(jq_state *jq, jv a, jv b) {
1554 return jv_invalid_with_msg(jv_string("strflocaltime/1 not implemented on this platform"));
1558 #ifdef HAVE_GETTIMEOFDAY
1559 static jv f_now(jq_state *jq, jv a) {
1562 if (gettimeofday(&tv, NULL) == -1)
1563 return jv_number(time(NULL));
1564 return jv_number(tv.tv_sec + tv.tv_usec / 1000000.0);
1567 static jv f_now(jq_state *jq, jv a) {
1569 return jv_number(time(NULL));
1573 static jv f_current_filename(jq_state *jq, jv a) {
1576 jv r = jq_util_input_get_current_filename(jq);
1582 static jv f_current_line(jq_state *jq, jv a) {
1584 return jq_util_input_get_current_line(jq);
1587 #define LIBM_DD(name) \
1588 {(cfunction_ptr)f_ ## name, #name, 1},
1589 #define LIBM_DD_NO(name)
1591 #define LIBM_DDD(name) \
1592 {(cfunction_ptr)f_ ## name, #name, 3},
1593 #define LIBM_DDD_NO(name)
1595 #define LIBM_DDDD(name) \
1596 {(cfunction_ptr)f_ ## name, #name, 4},
1597 #define LIBM_DDDD_NO(name)
1599 static const struct cfunction function_list[] = {
1602 {(cfunction_ptr)f_frexp,"frexp", 1},
1605 {(cfunction_ptr)f_modf,"modf", 1},
1607 #ifdef HAVE_LGAMMA_R
1608 {(cfunction_ptr)f_lgamma_r,"lgamma_r", 1},
1610 {(cfunction_ptr)f_plus, "_plus", 3},
1611 {(cfunction_ptr)f_negate, "_negate", 1},
1612 {(cfunction_ptr)f_minus, "_minus", 3},
1613 {(cfunction_ptr)f_multiply, "_multiply", 3},
1614 {(cfunction_ptr)f_divide, "_divide", 3},
1615 {(cfunction_ptr)f_mod, "_mod", 3},
1616 {(cfunction_ptr)f_dump, "tojson", 1},
1617 {(cfunction_ptr)f_json_parse, "fromjson", 1},
1618 {(cfunction_ptr)f_tonumber, "tonumber", 1},
1619 {(cfunction_ptr)f_tostring, "tostring", 1},
1620 {(cfunction_ptr)f_keys, "keys", 1},
1621 {(cfunction_ptr)f_keys_unsorted, "keys_unsorted", 1},
1622 {(cfunction_ptr)f_startswith, "startswith", 2},
1623 {(cfunction_ptr)f_endswith, "endswith", 2},
1624 {(cfunction_ptr)f_ltrimstr, "ltrimstr", 2},
1625 {(cfunction_ptr)f_rtrimstr, "rtrimstr", 2},
1626 {(cfunction_ptr)f_string_split, "split", 2},
1627 {(cfunction_ptr)f_string_explode, "explode", 1},
1628 {(cfunction_ptr)f_string_implode, "implode", 1},
1629 {(cfunction_ptr)f_string_indexes, "_strindices", 2},
1630 {(cfunction_ptr)f_setpath, "setpath", 3}, // FIXME typechecking
1631 {(cfunction_ptr)f_getpath, "getpath", 2},
1632 {(cfunction_ptr)f_delpaths, "delpaths", 2},
1633 {(cfunction_ptr)f_has, "has", 2},
1634 {(cfunction_ptr)f_equal, "_equal", 3},
1635 {(cfunction_ptr)f_notequal, "_notequal", 3},
1636 {(cfunction_ptr)f_less, "_less", 3},
1637 {(cfunction_ptr)f_greater, "_greater", 3},
1638 {(cfunction_ptr)f_lesseq, "_lesseq", 3},
1639 {(cfunction_ptr)f_greatereq, "_greatereq", 3},
1640 {(cfunction_ptr)f_contains, "contains", 2},
1641 {(cfunction_ptr)f_length, "length", 1},
1642 {(cfunction_ptr)f_utf8bytelength, "utf8bytelength", 1},
1643 {(cfunction_ptr)f_type, "type", 1},
1644 {(cfunction_ptr)f_isinfinite, "isinfinite", 1},
1645 {(cfunction_ptr)f_isnan, "isnan", 1},
1646 {(cfunction_ptr)f_isnormal, "isnormal", 1},
1647 {(cfunction_ptr)f_infinite, "infinite", 1},
1648 {(cfunction_ptr)f_nan, "nan", 1},
1649 {(cfunction_ptr)f_sort, "sort", 1},
1650 {(cfunction_ptr)f_sort_by_impl, "_sort_by_impl", 2},
1651 {(cfunction_ptr)f_group_by_impl, "_group_by_impl", 2},
1652 {(cfunction_ptr)f_min, "min", 1},
1653 {(cfunction_ptr)f_max, "max", 1},
1654 {(cfunction_ptr)f_min_by_impl, "_min_by_impl", 2},
1655 {(cfunction_ptr)f_max_by_impl, "_max_by_impl", 2},
1656 {(cfunction_ptr)f_error, "error", 2},
1657 {(cfunction_ptr)f_format, "format", 2},
1658 {(cfunction_ptr)f_env, "env", 1},
1659 {(cfunction_ptr)f_halt, "halt", 1},
1660 {(cfunction_ptr)f_halt_error, "halt_error", 2},
1661 {(cfunction_ptr)f_get_search_list, "get_search_list", 1},
1662 {(cfunction_ptr)f_get_prog_origin, "get_prog_origin", 1},
1663 {(cfunction_ptr)f_get_jq_origin, "get_jq_origin", 1},
1664 {(cfunction_ptr)f_match, "_match_impl", 4},
1665 {(cfunction_ptr)f_modulemeta, "modulemeta", 1},
1666 {(cfunction_ptr)f_input, "_input", 1},
1667 {(cfunction_ptr)f_debug, "debug", 1},
1668 {(cfunction_ptr)f_stderr, "stderr", 1},
1669 {(cfunction_ptr)f_strptime, "strptime", 2},
1670 {(cfunction_ptr)f_strftime, "strftime", 2},
1671 {(cfunction_ptr)f_strflocaltime, "strflocaltime", 2},
1672 {(cfunction_ptr)f_mktime, "mktime", 1},
1673 {(cfunction_ptr)f_gmtime, "gmtime", 1},
1674 {(cfunction_ptr)f_localtime, "localtime", 1},
1675 {(cfunction_ptr)f_now, "now", 1},
1676 {(cfunction_ptr)f_current_filename, "input_filename", 1},
1677 {(cfunction_ptr)f_current_line, "input_line_number", 1},
1686 struct bytecoded_builtin { const char* name; block code; };
1687 static block bind_bytecoded_builtins(block b) {
1688 block builtins = gen_noop();
1690 struct bytecoded_builtin builtin_defs[] = {
1691 {"empty", gen_op_simple(BACKTRACK)},
1692 {"not", gen_condbranch(gen_const(jv_false()),
1693 gen_const(jv_true()))}
1695 for (unsigned i=0; i<sizeof(builtin_defs)/sizeof(builtin_defs[0]); i++) {
1696 builtins = BLOCK(builtins, gen_function(builtin_defs[i].name, gen_noop(),
1697 builtin_defs[i].code));
1701 struct bytecoded_builtin builtin_def_1arg[] = {
1702 {"path", BLOCK(gen_op_simple(PATH_BEGIN),
1703 gen_call("arg", gen_noop()),
1704 gen_op_simple(PATH_END))},
1706 for (unsigned i=0; i<sizeof(builtin_def_1arg)/sizeof(builtin_def_1arg[0]); i++) {
1707 builtins = BLOCK(builtins, gen_function(builtin_def_1arg[i].name,
1709 builtin_def_1arg[i].code));
1713 // Note that we can now define `range` as a jq-coded function
1714 block rangevar = gen_op_var_fresh(STOREV, "rangevar");
1715 block rangestart = gen_op_var_fresh(STOREV, "rangestart");
1716 block range = BLOCK(gen_op_simple(DUP),
1717 gen_call("start", gen_noop()),
1719 gen_call("end", gen_noop()),
1721 gen_op_bound(LOADV, rangestart),
1722 // Reset rangevar for every value generated by "end"
1724 gen_op_bound(RANGE, rangevar));
1725 builtins = BLOCK(builtins, gen_function("range",
1726 BLOCK(gen_param("start"), gen_param("end")),
1729 return block_bind(builtins, b, OP_IS_CALL_PSEUDO);
1734 static const char* const jq_builtins =
1735 /* Include jq-coded builtins */
1736 #include "src/builtin.inc"
1738 /* Include unsupported math functions next */
1739 #define LIBM_DD(name)
1740 #define LIBM_DDD(name)
1741 #define LIBM_DDDD(name)
1742 #define LIBM_DD_NO(name) "def " #name ": \"Error: " #name "/0 not found at build time\"|error;"
1743 #define LIBM_DDD_NO(name) "def " #name "(a;b): \"Error: " #name "/2 not found at build time\"|error;"
1744 #define LIBM_DDDD_NO(name) "def " #name "(a;b;c): \"Error: " #name "/3 not found at build time\"|error;"
1747 "def frexp: \"Error: frexp/0 not found found at build time\"|error;"
1750 "def modf: \"Error: modf/0 not found found at build time\"|error;"
1752 #ifndef HAVE_LGAMMA_R
1753 "def lgamma_r: \"Error: lgamma_r/0 not found found at build time\"|error;"
1765 static block gen_builtin_list(block builtins) {
1766 jv list = jv_array_append(block_list_funcs(builtins, 1), jv_string("builtins/0"));
1767 return BLOCK(builtins, gen_function("builtins", gen_noop(), gen_const(list)));
1770 static int builtins_bind_one(jq_state *jq, block* bb, const char* code) {
1771 struct locfile* src;
1772 src = locfile_init(jq, "<builtin>", code, strlen(code));
1774 int nerrors = jq_parse_library(src, &funcs);
1776 *bb = block_bind(funcs, *bb, OP_IS_CALL_PSEUDO);
1782 static int slurp_lib(jq_state *jq, block* bb) {
1784 char* home = getenv("HOME");
1785 if (home) { // silently ignore no $HOME
1786 jv filename = jv_string_append_str(jv_string(home), "/.jq");
1787 jv data = jv_load_file(jv_string_value(filename), 1);
1788 if (jv_is_valid(data)) {
1789 nerrors = builtins_bind_one(jq, bb, jv_string_value(data) );
1797 int builtins_bind(jq_state *jq, block* bb) {
1798 block builtins = gen_noop();
1799 int nerrors = slurp_lib(jq, bb);
1804 nerrors = builtins_bind_one(jq, &builtins, jq_builtins);
1806 builtins = bind_bytecoded_builtins(builtins);
1807 builtins = gen_cbinding(function_list, sizeof(function_list)/sizeof(function_list[0]), builtins);
1808 builtins = gen_builtin_list(builtins);
1809 *bb = block_bind(builtins, *bb, OP_IS_CALL_PSEUDO);
1810 *bb = block_drop_unreferenced(*bb);