@port-labs/jq-node-bindings 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/deps/jq/COPYING +1 -9
  2. package/deps/jq/Makefile.am +13 -18
  3. package/deps/jq/NEWS.md +2 -2
  4. package/deps/jq/README.md +3 -18
  5. package/deps/jq/configure.ac +1 -0
  6. package/deps/jq/docs/Pipfile.lock +59 -72
  7. package/deps/jq/docs/README.md +1 -1
  8. package/deps/jq/docs/build_manpage.py +1 -1
  9. package/deps/jq/docs/build_mantests.py +1 -1
  10. package/deps/jq/docs/content/download/default.yml +1 -23
  11. package/deps/jq/docs/content/index.yml +0 -5
  12. package/deps/jq/docs/content/manual/{dev/manual.yml → manual.yml} +36 -162
  13. package/deps/jq/docs/content/manual/v1.3/manual.yml +5 -0
  14. package/deps/jq/docs/content/manual/v1.4/manual.yml +5 -0
  15. package/deps/jq/docs/content/manual/v1.5/manual.yml +8 -3
  16. package/deps/jq/docs/content/manual/v1.6/manual.yml +8 -3
  17. package/deps/jq/docs/content/manual/v1.7/manual.yml +11 -6
  18. package/deps/jq/docs/content/tutorial/default.yml +3 -3
  19. package/deps/jq/docs/manual_schema.yml +3 -0
  20. package/deps/jq/docs/templates/index.html.j2 +6 -6
  21. package/deps/jq/docs/templates/manual.html.j2 +1 -11
  22. package/deps/jq/jq.1.prebuilt +26 -162
  23. package/deps/jq/jq.spec +1 -1
  24. package/deps/jq/src/builtin.c +211 -298
  25. package/deps/jq/src/builtin.jq +7 -13
  26. package/deps/jq/src/bytecode.h +3 -8
  27. package/deps/jq/src/compile.c +2 -2
  28. package/deps/jq/src/decNumber/decBasic.c +1 -1
  29. package/deps/jq/src/decNumber/decCommon.c +1 -1
  30. package/deps/jq/src/decNumber/decNumber.c +4 -4
  31. package/deps/jq/src/execute.c +42 -22
  32. package/deps/jq/src/jq.h +1 -1
  33. package/deps/jq/src/jq_test.c +7 -69
  34. package/deps/jq/src/jv.c +12 -17
  35. package/deps/jq/src/jv.h +0 -3
  36. package/deps/jq/src/jv_aux.c +4 -3
  37. package/deps/jq/src/jv_dtoa.c +1 -1
  38. package/deps/jq/src/jv_parse.c +0 -2
  39. package/deps/jq/src/jv_print.c +27 -21
  40. package/deps/jq/src/jv_unicode.c +0 -18
  41. package/deps/jq/src/jv_unicode.h +0 -2
  42. package/deps/jq/src/lexer.c +262 -283
  43. package/deps/jq/src/lexer.h +2 -3
  44. package/deps/jq/src/lexer.l +1 -7
  45. package/deps/jq/src/libm.h +5 -15
  46. package/deps/jq/src/linker.c +4 -6
  47. package/deps/jq/src/main.c +252 -179
  48. package/deps/jq/src/util.c +35 -41
  49. package/deps/jq/src/util.h +1 -1
  50. package/deps/jq/tests/jq.test +10 -148
  51. package/deps/jq/tests/jq_fuzz_load_file.c +0 -1
  52. package/deps/jq/tests/man.test +8 -26
  53. package/deps/jq/tests/setup +0 -4
  54. package/deps/jq/tests/shtest +39 -150
  55. package/index.d.ts +3 -2
  56. package/lib/jq.js +2 -2
  57. package/lib/templateAsync.js +8 -15
  58. package/package.json +2 -2
  59. package/src/binding.cc +46 -27
  60. package/test/santiy-async.test.js +4 -0
  61. package/deps/jq/sig/v1.7.1/jq-1.7.1.tar.gz.asc +0 -16
  62. package/deps/jq/sig/v1.7.1/jq-1.7.1.zip.asc +0 -16
  63. package/deps/jq/sig/v1.7.1/jq-linux-amd64.asc +0 -16
  64. package/deps/jq/sig/v1.7.1/jq-linux-arm64.asc +0 -16
  65. package/deps/jq/sig/v1.7.1/jq-linux-armel.asc +0 -16
  66. package/deps/jq/sig/v1.7.1/jq-linux-armhf.asc +0 -16
  67. package/deps/jq/sig/v1.7.1/jq-linux-i386.asc +0 -16
  68. package/deps/jq/sig/v1.7.1/jq-linux-mips.asc +0 -16
  69. package/deps/jq/sig/v1.7.1/jq-linux-mips64.asc +0 -16
  70. package/deps/jq/sig/v1.7.1/jq-linux-mips64el.asc +0 -16
  71. package/deps/jq/sig/v1.7.1/jq-linux-mips64r6.asc +0 -16
  72. package/deps/jq/sig/v1.7.1/jq-linux-mips64r6el.asc +0 -16
  73. package/deps/jq/sig/v1.7.1/jq-linux-mipsel.asc +0 -16
  74. package/deps/jq/sig/v1.7.1/jq-linux-mipsr6.asc +0 -16
  75. package/deps/jq/sig/v1.7.1/jq-linux-mipsr6el.asc +0 -16
  76. package/deps/jq/sig/v1.7.1/jq-linux-powerpc.asc +0 -16
  77. package/deps/jq/sig/v1.7.1/jq-linux-ppc64el.asc +0 -16
  78. package/deps/jq/sig/v1.7.1/jq-linux-riscv64.asc +0 -16
  79. package/deps/jq/sig/v1.7.1/jq-linux-s390x.asc +0 -16
  80. package/deps/jq/sig/v1.7.1/jq-linux64.asc +0 -16
  81. package/deps/jq/sig/v1.7.1/jq-macos-amd64.asc +0 -16
  82. package/deps/jq/sig/v1.7.1/jq-macos-arm64.asc +0 -16
  83. package/deps/jq/sig/v1.7.1/jq-osx-amd64.asc +0 -16
  84. package/deps/jq/sig/v1.7.1/jq-win64.exe.asc +0 -16
  85. package/deps/jq/sig/v1.7.1/jq-windows-amd64.exe.asc +0 -16
  86. package/deps/jq/sig/v1.7.1/jq-windows-i386.exe.asc +0 -16
  87. package/deps/jq/sig/v1.7.1/sha256sum.txt +0 -26
  88. package/deps/jq/tests/uri.test +0 -38
  89. package/deps/jq/tests/uritest +0 -5
@@ -43,8 +43,6 @@ void *alloca (size_t);
43
43
  #include "locfile.h"
44
44
  #include "jv_unicode.h"
45
45
  #include "jv_alloc.h"
46
- #include "jv_dtoa.h"
47
- #include "jv_dtoa_tsd.h"
48
46
  #include "jv_private.h"
49
47
  #include "util.h"
50
48
 
@@ -157,11 +155,7 @@ static jv f_ ## name(jq_state *jq, jv input) { \
157
155
  jv_free(input); \
158
156
  return ret; \
159
157
  }
160
- #define LIBM_DD_NO(name) \
161
- static jv f_ ## name(jq_state *jq, jv input) { \
162
- jv error = jv_string("Error: " #name "/0 not found at build time"); \
163
- return ret_error(input, error); \
164
- }
158
+ #define LIBM_DD_NO(name)
165
159
 
166
160
  #define LIBM_DDD(name) \
167
161
  static jv f_ ## name(jq_state *jq, jv input, jv a, jv b) { \
@@ -179,12 +173,7 @@ static jv f_ ## name(jq_state *jq, jv input, jv a, jv b) { \
179
173
  jv_free(b); \
180
174
  return ret; \
181
175
  }
182
- #define LIBM_DDD_NO(name) \
183
- static jv f_ ## name(jq_state *jq, jv input, jv a, jv b) { \
184
- jv_free(b); \
185
- jv error = jv_string("Error: " #name "/2 not found at build time"); \
186
- return ret_error2(input, a, error); \
187
- }
176
+ #define LIBM_DDD_NO(name)
188
177
 
189
178
  #define LIBM_DDDD(name) \
190
179
  static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \
@@ -210,40 +199,14 @@ static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \
210
199
  jv_free(c); \
211
200
  return ret; \
212
201
  }
213
- #define LIBM_DDDD_NO(name) \
214
- static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \
215
- jv_free(c); \
216
- jv_free(b); \
217
- jv error = jv_string("Error: " #name "/3 not found at build time"); \
218
- return ret_error2(input, a, error); \
219
- }
220
-
221
- #define LIBM_DA(name, type) \
222
- static jv f_ ## name(jq_state *jq, jv input) { \
223
- if (jv_get_kind(input) != JV_KIND_NUMBER) { \
224
- return type_error(input, "number required"); \
225
- } \
226
- type value; \
227
- double d = name(jv_number_value(input), &value); \
228
- jv ret = JV_ARRAY(jv_number(d), jv_number(value)); \
229
- jv_free(input); \
230
- return ret; \
231
- }
232
- #define LIBM_DA_NO(name, type) \
233
- static jv f_ ## name(jq_state *jq, jv input) { \
234
- jv error = jv_string("Error: " #name "/0 not found at build time"); \
235
- return ret_error(input, error); \
236
- }
237
-
202
+ #define LIBM_DDDD_NO(name)
238
203
  #include "libm.h"
239
204
  #undef LIBM_DDDD_NO
240
205
  #undef LIBM_DDD_NO
241
206
  #undef LIBM_DD_NO
242
- #undef LIBM_DA_NO
243
207
  #undef LIBM_DDDD
244
208
  #undef LIBM_DDD
245
209
  #undef LIBM_DD
246
- #undef LIBM_DA
247
210
 
248
211
  #ifdef __APPLE__
249
212
  #undef gamma
@@ -252,6 +215,41 @@ static jv f_ ## name(jq_state *jq, jv input) { \
252
215
  #undef exp10
253
216
  #endif
254
217
 
218
+ #ifdef HAVE_FREXP
219
+ static jv f_frexp(jq_state *jq, jv input) {
220
+ if (jv_get_kind(input) != JV_KIND_NUMBER) {
221
+ return type_error(input, "number required");
222
+ }
223
+ int exp;
224
+ double d = frexp(jv_number_value(input), &exp);
225
+ jv ret = JV_ARRAY(jv_number(d), jv_number(exp));
226
+ jv_free(input);
227
+ return ret;
228
+ }
229
+ #endif
230
+ #ifdef HAVE_MODF
231
+ static jv f_modf(jq_state *jq, jv input) {
232
+ if (jv_get_kind(input) != JV_KIND_NUMBER) {
233
+ return type_error(input, "number required");
234
+ }
235
+ double i;
236
+ jv ret = JV_ARRAY(jv_number(modf(jv_number_value(input), &i)));
237
+ jv_free(input);
238
+ return jv_array_append(ret, jv_number(i));
239
+ }
240
+ #endif
241
+ #ifdef HAVE_LGAMMA_R
242
+ static jv f_lgamma_r(jq_state *jq, jv input) {
243
+ if (jv_get_kind(input) != JV_KIND_NUMBER) {
244
+ return type_error(input, "number required");
245
+ }
246
+ int sign;
247
+ jv ret = JV_ARRAY(jv_number(lgamma_r(jv_number_value(input), &sign)));
248
+ jv_free(input);
249
+ return jv_array_append(ret, jv_number(sign));
250
+ }
251
+ #endif
252
+
255
253
  static jv f_negate(jq_state *jq, jv input) {
256
254
  if (jv_get_kind(input) != JV_KIND_NUMBER) {
257
255
  return type_error(input, "cannot be negated");
@@ -296,6 +294,37 @@ static jv f_endswith(jq_state *jq, jv a, jv b) {
296
294
  return ret;
297
295
  }
298
296
 
297
+ static jv f_ltrimstr(jq_state *jq, jv input, jv left) {
298
+ jv startswith = f_startswith(jq, jv_copy(input), jv_copy(left));
299
+ if (jv_get_kind(startswith) != JV_KIND_TRUE) {
300
+ jv_free(startswith);
301
+ jv_free(left);
302
+ return input;
303
+ }
304
+ /*
305
+ * FIXME It'd be better to share the suffix with the original input --
306
+ * that we could do, we just can't share prefixes.
307
+ */
308
+ int prefixlen = jv_string_length_bytes(left);
309
+ jv res = jv_string_sized(jv_string_value(input) + prefixlen,
310
+ jv_string_length_bytes(jv_copy(input)) - prefixlen);
311
+ jv_free(input);
312
+ return res;
313
+ }
314
+
315
+ static jv f_rtrimstr(jq_state *jq, jv input, jv right) {
316
+ jv endswith = f_endswith(jq, jv_copy(input), jv_copy(right));
317
+ if (jv_get_kind(endswith) == JV_KIND_TRUE) {
318
+ jv res = jv_string_sized(jv_string_value(input),
319
+ jv_string_length_bytes(jv_copy(input)) - jv_string_length_bytes(right));
320
+ jv_free(input);
321
+ return res;
322
+ }
323
+ jv_free(endswith);
324
+ jv_free(right);
325
+ return input;
326
+ }
327
+
299
328
  jv binop_minus(jv a, jv b) {
300
329
  if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
301
330
  jv r = jv_number(jv_number_value(a) - jv_number_value(b));
@@ -466,22 +495,11 @@ static jv f_tonumber(jq_state *jq, jv input) {
466
495
  return input;
467
496
  }
468
497
  if (jv_get_kind(input) == JV_KIND_STRING) {
469
- const char* s = jv_string_value(input);
470
- #ifdef USE_DECNUM
471
- jv number = jv_number_with_literal(s);
472
- if (jv_get_kind(number) == JV_KIND_INVALID) {
473
- return type_error(input, "cannot be parsed as a number");
474
- }
475
- #else
476
- char *end = 0;
477
- double d = jvp_strtod(tsd_dtoa_context_get(), s, &end);
478
- if (end == 0 || *end != 0) {
479
- return type_error(input, "cannot be parsed as a number");
498
+ jv parsed = jv_parse(jv_string_value(input));
499
+ if (!jv_is_valid(parsed) || jv_get_kind(parsed) == JV_KIND_NUMBER) {
500
+ jv_free(input);
501
+ return parsed;
480
502
  }
481
- jv number = jv_number(d);
482
- #endif
483
- jv_free(input);
484
- return number;
485
503
  }
486
504
  return type_error(input, "cannot be parsed as a number");
487
505
  }
@@ -657,48 +675,6 @@ static jv f_format(jq_state *jq, jv input, jv fmt) {
657
675
  }
658
676
  jv_free(input);
659
677
  return line;
660
- } else if (!strcmp(fmt_s, "urid")) {
661
- jv_free(fmt);
662
- input = f_tostring(jq, input);
663
-
664
- jv line = jv_string("");
665
- const char *errmsg = "is not a valid uri encoding";
666
- const char *s = jv_string_value(input);
667
- while (*s) {
668
- if (*s != '%') {
669
- line = jv_string_append_buf(line, s++, 1);
670
- } else {
671
- unsigned char unicode[4] = {0};
672
- int b = 0;
673
- // check leading bits of first octet to determine length of unicode character
674
- // (https://datatracker.ietf.org/doc/html/rfc3629#section-3)
675
- while (b == 0 || (b < 4 && unicode[0] >> 7 & 1 && unicode[0] >> (7-b) & 1)) {
676
- if (*(s++) != '%') {
677
- jv_free(line);
678
- return type_error(input, errmsg);
679
- }
680
- for (int i=0; i<2; i++) {
681
- unicode[b] <<= 4;
682
- char c = *(s++);
683
- if ('0' <= c && c <= '9') unicode[b] |= c - '0';
684
- else if ('a' <= c && c <= 'f') unicode[b] |= c - 'a' + 10;
685
- else if ('A' <= c && c <= 'F') unicode[b] |= c - 'A' + 10;
686
- else {
687
- jv_free(line);
688
- return type_error(input, errmsg);
689
- }
690
- }
691
- b++;
692
- }
693
- if (!jvp_utf8_is_valid((const char *)unicode, (const char *)unicode+b)) {
694
- jv_free(line);
695
- return type_error(input, errmsg);
696
- }
697
- line = jv_string_append_buf(line, (const char *)unicode, b);
698
- }
699
- }
700
- jv_free(input);
701
- return line;
702
678
  } else if (!strcmp(fmt_s, "sh")) {
703
679
  jv_free(fmt);
704
680
  if (jv_get_kind(input) != JV_KIND_ARRAY)
@@ -757,7 +733,7 @@ static jv f_format(jq_state *jq, jv input, jv fmt) {
757
733
  input = f_tostring(jq, input);
758
734
  const unsigned char* data = (const unsigned char*)jv_string_value(input);
759
735
  int len = jv_string_length_bytes(jv_copy(input));
760
- size_t decoded_len = (3 * (size_t)len) / 4; // 3 usable bytes for every 4 bytes of input
736
+ size_t decoded_len = (3 * len) / 4; // 3 usable bytes for every 4 bytes of input
761
737
  char *result = jv_mem_calloc(decoded_len, sizeof(char));
762
738
  memset(result, 0, decoded_len * sizeof(char));
763
739
  uint32_t ri = 0;
@@ -1239,58 +1215,6 @@ static jv f_string_indexes(jq_state *jq, jv a, jv b) {
1239
1215
  return jv_string_indexes(a, b);
1240
1216
  }
1241
1217
 
1242
- enum trim_op {
1243
- TRIM_LEFT = 1 << 0,
1244
- TRIM_RIGHT = 1 << 1
1245
- };
1246
-
1247
- static jv string_trim(jv a, int op) {
1248
- if (jv_get_kind(a) != JV_KIND_STRING) {
1249
- return ret_error(a, jv_string("trim input must be a string"));
1250
- }
1251
-
1252
- int len = jv_string_length_bytes(jv_copy(a));
1253
- const char *start = jv_string_value(a);
1254
- const char *trim_start = start;
1255
- const char *end = trim_start + len;
1256
- const char *trim_end = end;
1257
- int c;
1258
-
1259
- if (op & TRIM_LEFT) {
1260
- for (;;) {
1261
- const char *ns = jvp_utf8_next(trim_start, end, &c);
1262
- if (!ns || !jvp_codepoint_is_whitespace(c))
1263
- break;
1264
- trim_start = ns;
1265
- }
1266
- }
1267
-
1268
- // make sure not empty string or start trim has trimmed everything
1269
- if ((op & TRIM_RIGHT) && trim_end > trim_start) {
1270
- for (;;) {
1271
- const char *ns = jvp_utf8_backtrack(trim_end-1, trim_start, NULL);
1272
- jvp_utf8_next(ns, trim_end, &c);
1273
- if (!jvp_codepoint_is_whitespace(c))
1274
- break;
1275
- trim_end = ns;
1276
- if (ns == trim_start)
1277
- break;
1278
- }
1279
- }
1280
-
1281
- // no new string needed if there is nothing to trim
1282
- if (trim_start == start && trim_end == end)
1283
- return a;
1284
-
1285
- jv ts = jv_string_sized(trim_start, trim_end - trim_start);
1286
- jv_free(a);
1287
- return ts;
1288
- }
1289
-
1290
- static jv f_string_trim(jq_state *jq, jv a) { return string_trim(a, TRIM_LEFT | TRIM_RIGHT); }
1291
- static jv f_string_ltrim(jq_state *jq, jv a) { return string_trim(a, TRIM_LEFT); }
1292
- static jv f_string_rtrim(jq_state *jq, jv a) { return string_trim(a, TRIM_RIGHT); }
1293
-
1294
1218
  static jv f_string_implode(jq_state *jq, jv a) {
1295
1219
  if (jv_get_kind(a) != JV_KIND_ARRAY) {
1296
1220
  return ret_error(a, jv_string("implode input must be an array"));
@@ -1516,7 +1440,7 @@ static jv f_strptime(jq_state *jq, jv a, jv b) {
1516
1440
  }
1517
1441
  #endif
1518
1442
  const char *end = strptime(input, fmt, &tm);
1519
- if (end == NULL || (*end != '\0' && !isspace((unsigned char)*end))) {
1443
+ if (end == NULL || (*end != '\0' && !isspace(*end))) {
1520
1444
  return ret_error2(a, b, jv_string_fmt("date \"%s\" does not match format \"%s\"", input, fmt));
1521
1445
  }
1522
1446
  jv_free(b);
@@ -1540,7 +1464,7 @@ static jv f_strptime(jq_state *jq, jv a, jv b) {
1540
1464
  */
1541
1465
  set_tm_wday(&tm);
1542
1466
  set_tm_yday(&tm);
1543
- #elif defined(WIN32) || !defined(HAVE_STRPTIME)
1467
+ #elif defined(WIN32)
1544
1468
  set_tm_wday(&tm);
1545
1469
  #else
1546
1470
  if (tm.tm_wday == 8 && tm.tm_mday != 0 && tm.tm_mon >= 0 && tm.tm_mon <= 11)
@@ -1555,35 +1479,30 @@ static jv f_strptime(jq_state *jq, jv a, jv b) {
1555
1479
  return r;
1556
1480
  }
1557
1481
 
1482
+ #define TO_TM_FIELD(t, j, i) \
1483
+ do { \
1484
+ jv n = jv_array_get(jv_copy(j), (i)); \
1485
+ if (jv_get_kind(n) != (JV_KIND_NUMBER)) { \
1486
+ jv_free(n); \
1487
+ jv_free(j); \
1488
+ return 0; \
1489
+ } \
1490
+ t = jv_number_value(n); \
1491
+ jv_free(n); \
1492
+ } while (0)
1493
+
1558
1494
  static int jv2tm(jv a, struct tm *tm) {
1559
1495
  memset(tm, 0, sizeof(*tm));
1560
- static const size_t offsets[] = {
1561
- offsetof(struct tm, tm_year),
1562
- offsetof(struct tm, tm_mon),
1563
- offsetof(struct tm, tm_mday),
1564
- offsetof(struct tm, tm_hour),
1565
- offsetof(struct tm, tm_min),
1566
- offsetof(struct tm, tm_sec),
1567
- offsetof(struct tm, tm_wday),
1568
- offsetof(struct tm, tm_yday),
1569
- };
1570
-
1571
- for (size_t i = 0; i < (sizeof offsets / sizeof *offsets); ++i) {
1572
- jv n = jv_array_get(jv_copy(a), i);
1573
- if (!jv_is_valid(n))
1574
- break;
1575
- if (jv_get_kind(n) != JV_KIND_NUMBER || jvp_number_is_nan(n)) {
1576
- jv_free(a);
1577
- jv_free(n);
1578
- return 0;
1579
- }
1580
- double d = jv_number_value(n);
1581
- if (i == 0) /* year */
1582
- d -= 1900;
1583
- *(int *)((void *)tm + offsets[i]) = d < INT_MIN ? INT_MIN :
1584
- d > INT_MAX ? INT_MAX : (int)d;
1585
- jv_free(n);
1586
- }
1496
+ TO_TM_FIELD(tm->tm_year, a, 0);
1497
+ tm->tm_year -= 1900;
1498
+ TO_TM_FIELD(tm->tm_mon, a, 1);
1499
+ TO_TM_FIELD(tm->tm_mday, a, 2);
1500
+ TO_TM_FIELD(tm->tm_hour, a, 3);
1501
+ TO_TM_FIELD(tm->tm_min, a, 4);
1502
+ TO_TM_FIELD(tm->tm_sec, a, 5);
1503
+ TO_TM_FIELD(tm->tm_wday, a, 6);
1504
+ TO_TM_FIELD(tm->tm_yday, a, 7);
1505
+ jv_free(a);
1587
1506
 
1588
1507
  // We use UTC everywhere (gettimeofday, gmtime) and UTC does not do DST.
1589
1508
  // Setting tm_isdst to 0 is done by the memset.
@@ -1593,7 +1512,6 @@ static int jv2tm(jv a, struct tm *tm) {
1593
1512
  // hope it is okay to initialize them to zero, because the standard does not
1594
1513
  // provide an alternative.
1595
1514
 
1596
- jv_free(a);
1597
1515
  return 1;
1598
1516
  }
1599
1517
 
@@ -1602,6 +1520,8 @@ static int jv2tm(jv a, struct tm *tm) {
1602
1520
  static jv f_mktime(jq_state *jq, jv a) {
1603
1521
  if (jv_get_kind(a) != JV_KIND_ARRAY)
1604
1522
  return ret_error(a, jv_string("mktime requires array inputs"));
1523
+ if (jv_array_length(jv_copy(a)) < 6)
1524
+ return ret_error(a, jv_string("mktime requires parsed datetime inputs"));
1605
1525
  struct tm tm;
1606
1526
  if (!jv2tm(a, &tm))
1607
1527
  return jv_invalid_with_msg(jv_string("mktime requires parsed datetime inputs"));
@@ -1697,9 +1617,9 @@ static jv f_strftime(jq_state *jq, jv a, jv b) {
1697
1617
  }
1698
1618
  } else if (jv_get_kind(a) != JV_KIND_ARRAY) {
1699
1619
  return ret_error2(a, b, jv_string("strftime/1 requires parsed datetime inputs"));
1700
- }
1701
- if (jv_get_kind(b) != JV_KIND_STRING)
1620
+ } else if (jv_get_kind(b) != JV_KIND_STRING) {
1702
1621
  return ret_error2(a, b, jv_string("strftime/1 requires a string format"));
1622
+ }
1703
1623
  struct tm tm;
1704
1624
  if (!jv2tm(a, &tm))
1705
1625
  return ret_error(b, jv_string("strftime/1 requires parsed datetime inputs"));
@@ -1728,9 +1648,9 @@ static jv f_strflocaltime(jq_state *jq, jv a, jv b) {
1728
1648
  a = f_localtime(jq, a);
1729
1649
  } else if (jv_get_kind(a) != JV_KIND_ARRAY) {
1730
1650
  return ret_error2(a, b, jv_string("strflocaltime/1 requires parsed datetime inputs"));
1731
- }
1732
- if (jv_get_kind(b) != JV_KIND_STRING)
1651
+ } else if (jv_get_kind(b) != JV_KIND_STRING) {
1733
1652
  return ret_error2(a, b, jv_string("strflocaltime/1 requires a string format"));
1653
+ }
1734
1654
  struct tm tm;
1735
1655
  if (!jv2tm(a, &tm))
1736
1656
  return ret_error(b, jv_string("strflocaltime/1 requires parsed datetime inputs"));
@@ -1781,133 +1701,96 @@ static jv f_current_line(jq_state *jq, jv a) {
1781
1701
  return jq_util_input_get_current_line(jq);
1782
1702
  }
1783
1703
 
1784
- static jv f_have_decnum(jq_state *jq, jv a) {
1785
- jv_free(a);
1786
- #ifdef USE_DECNUM
1787
- return jv_true();
1788
- #else
1789
- return jv_false();
1790
- #endif
1791
- }
1792
-
1793
- #define CFUNC(func, name, arity) \
1794
- {.fptr = { .a ## arity = func }, name, arity}
1795
-
1796
1704
  #define LIBM_DD(name) \
1797
- CFUNC(f_ ## name, #name, 1),
1798
- #define LIBM_DD_NO(name) LIBM_DD(name)
1799
- #define LIBM_DA(name, type) LIBM_DD(name)
1800
- #define LIBM_DA_NO(name, type) LIBM_DD(name)
1705
+ {f_ ## name, #name, 1},
1706
+ #define LIBM_DD_NO(name)
1801
1707
 
1802
1708
  #define LIBM_DDD(name) \
1803
- CFUNC(f_ ## name, #name, 3),
1804
- #define LIBM_DDD_NO(name) LIBM_DDD(name)
1709
+ {f_ ## name, #name, 3},
1710
+ #define LIBM_DDD_NO(name)
1805
1711
 
1806
1712
  #define LIBM_DDDD(name) \
1807
- CFUNC(f_ ## name, #name, 4),
1808
- #define LIBM_DDDD_NO(name) LIBM_DDDD(name)
1713
+ {f_ ## name, #name, 4},
1714
+ #define LIBM_DDDD_NO(name)
1809
1715
 
1810
1716
  static const struct cfunction function_list[] = {
1811
1717
  #include "libm.h"
1812
- CFUNC(f_negate, "_negate", 1),
1813
- #define BINOP(name) CFUNC(f_ ## name, "_" #name, 3),
1718
+ #ifdef HAVE_FREXP
1719
+ {f_frexp,"frexp", 1},
1720
+ #endif
1721
+ #ifdef HAVE_MODF
1722
+ {f_modf,"modf", 1},
1723
+ #endif
1724
+ #ifdef HAVE_LGAMMA_R
1725
+ {f_lgamma_r,"lgamma_r", 1},
1726
+ #endif
1727
+ {f_negate, "_negate", 1},
1728
+ #define BINOP(name) {f_ ## name, "_" #name, 3},
1814
1729
  BINOPS
1815
1730
  #undef BINOP
1816
- CFUNC(f_dump, "tojson", 1),
1817
- CFUNC(f_json_parse, "fromjson", 1),
1818
- CFUNC(f_tonumber, "tonumber", 1),
1819
- CFUNC(f_tostring, "tostring", 1),
1820
- CFUNC(f_keys, "keys", 1),
1821
- CFUNC(f_keys_unsorted, "keys_unsorted", 1),
1822
- CFUNC(f_startswith, "startswith", 2),
1823
- CFUNC(f_endswith, "endswith", 2),
1824
- CFUNC(f_string_split, "split", 2),
1825
- CFUNC(f_string_explode, "explode", 1),
1826
- CFUNC(f_string_implode, "implode", 1),
1827
- CFUNC(f_string_indexes, "_strindices", 2),
1828
- CFUNC(f_string_trim, "trim", 1),
1829
- CFUNC(f_string_ltrim, "ltrim", 1),
1830
- CFUNC(f_string_rtrim, "rtrim", 1),
1831
- CFUNC(f_setpath, "setpath", 3),
1832
- CFUNC(f_getpath, "getpath", 2),
1833
- CFUNC(f_delpaths, "delpaths", 2),
1834
- CFUNC(f_has, "has", 2),
1835
- CFUNC(f_contains, "contains", 2),
1836
- CFUNC(f_length, "length", 1),
1837
- CFUNC(f_utf8bytelength, "utf8bytelength", 1),
1838
- CFUNC(f_type, "type", 1),
1839
- CFUNC(f_isinfinite, "isinfinite", 1),
1840
- CFUNC(f_isnan, "isnan", 1),
1841
- CFUNC(f_isnormal, "isnormal", 1),
1842
- CFUNC(f_infinite, "infinite", 1),
1843
- CFUNC(f_nan, "nan", 1),
1844
- CFUNC(f_sort, "sort", 1),
1845
- CFUNC(f_sort_by_impl, "_sort_by_impl", 2),
1846
- CFUNC(f_group_by_impl, "_group_by_impl", 2),
1847
- CFUNC(f_min, "min", 1),
1848
- CFUNC(f_max, "max", 1),
1849
- CFUNC(f_min_by_impl, "_min_by_impl", 2),
1850
- CFUNC(f_max_by_impl, "_max_by_impl", 2),
1851
- CFUNC(f_error, "error", 1),
1852
- CFUNC(f_format, "format", 2),
1853
- CFUNC(f_env, "env", 1),
1854
- CFUNC(f_halt, "halt", 1),
1855
- CFUNC(f_halt_error, "halt_error", 2),
1856
- CFUNC(f_get_search_list, "get_search_list", 1),
1857
- CFUNC(f_get_prog_origin, "get_prog_origin", 1),
1858
- CFUNC(f_get_jq_origin, "get_jq_origin", 1),
1859
- CFUNC(f_match, "_match_impl", 4),
1860
- CFUNC(f_modulemeta, "modulemeta", 1),
1861
- CFUNC(f_input, "input", 1),
1862
- CFUNC(f_debug, "debug", 1),
1863
- CFUNC(f_stderr, "stderr", 1),
1864
- CFUNC(f_strptime, "strptime", 2),
1865
- CFUNC(f_strftime, "strftime", 2),
1866
- CFUNC(f_strflocaltime, "strflocaltime", 2),
1867
- CFUNC(f_mktime, "mktime", 1),
1868
- CFUNC(f_gmtime, "gmtime", 1),
1869
- CFUNC(f_localtime, "localtime", 1),
1870
- CFUNC(f_now, "now", 1),
1871
- CFUNC(f_current_filename, "input_filename", 1),
1872
- CFUNC(f_current_line, "input_line_number", 1),
1873
- CFUNC(f_have_decnum, "have_decnum", 1),
1874
- CFUNC(f_have_decnum, "have_literal_numbers", 1),
1731
+ {f_dump, "tojson", 1},
1732
+ {f_json_parse, "fromjson", 1},
1733
+ {f_tonumber, "tonumber", 1},
1734
+ {f_tostring, "tostring", 1},
1735
+ {f_keys, "keys", 1},
1736
+ {f_keys_unsorted, "keys_unsorted", 1},
1737
+ {f_startswith, "startswith", 2},
1738
+ {f_endswith, "endswith", 2},
1739
+ {f_ltrimstr, "ltrimstr", 2},
1740
+ {f_rtrimstr, "rtrimstr", 2},
1741
+ {f_string_split, "split", 2},
1742
+ {f_string_explode, "explode", 1},
1743
+ {f_string_implode, "implode", 1},
1744
+ {f_string_indexes, "_strindices", 2},
1745
+ {f_setpath, "setpath", 3}, // FIXME typechecking
1746
+ {f_getpath, "getpath", 2},
1747
+ {f_delpaths, "delpaths", 2},
1748
+ {f_has, "has", 2},
1749
+ {f_contains, "contains", 2},
1750
+ {f_length, "length", 1},
1751
+ {f_utf8bytelength, "utf8bytelength", 1},
1752
+ {f_type, "type", 1},
1753
+ {f_isinfinite, "isinfinite", 1},
1754
+ {f_isnan, "isnan", 1},
1755
+ {f_isnormal, "isnormal", 1},
1756
+ {f_infinite, "infinite", 1},
1757
+ {f_nan, "nan", 1},
1758
+ {f_sort, "sort", 1},
1759
+ {f_sort_by_impl, "_sort_by_impl", 2},
1760
+ {f_group_by_impl, "_group_by_impl", 2},
1761
+ {f_min, "min", 1},
1762
+ {f_max, "max", 1},
1763
+ {f_min_by_impl, "_min_by_impl", 2},
1764
+ {f_max_by_impl, "_max_by_impl", 2},
1765
+ {f_error, "error", 1},
1766
+ {f_format, "format", 2},
1767
+ {f_env, "env", 1},
1768
+ {f_halt, "halt", 1},
1769
+ {f_halt_error, "halt_error", 2},
1770
+ {f_get_search_list, "get_search_list", 1},
1771
+ {f_get_prog_origin, "get_prog_origin", 1},
1772
+ {f_get_jq_origin, "get_jq_origin", 1},
1773
+ {f_match, "_match_impl", 4},
1774
+ {f_modulemeta, "modulemeta", 1},
1775
+ {f_input, "input", 1},
1776
+ {f_debug, "debug", 1},
1777
+ {f_stderr, "stderr", 1},
1778
+ {f_strptime, "strptime", 2},
1779
+ {f_strftime, "strftime", 2},
1780
+ {f_strflocaltime, "strflocaltime", 2},
1781
+ {f_mktime, "mktime", 1},
1782
+ {f_gmtime, "gmtime", 1},
1783
+ {f_localtime, "localtime", 1},
1784
+ {f_now, "now", 1},
1785
+ {f_current_filename, "input_filename", 1},
1786
+ {f_current_line, "input_line_number", 1},
1875
1787
  };
1876
1788
  #undef LIBM_DDDD_NO
1877
1789
  #undef LIBM_DDD_NO
1878
1790
  #undef LIBM_DD_NO
1879
- #undef LIBM_DA_NO
1880
1791
  #undef LIBM_DDDD
1881
1792
  #undef LIBM_DDD
1882
1793
  #undef LIBM_DD
1883
- #undef LIBM_DA
1884
-
1885
- // This is a hack to make last(g) yield no output values,
1886
- // if g yields no output values, without using boxing.
1887
- static block gen_last_1() {
1888
- block last_var = gen_op_var_fresh(STOREV, "last");
1889
- block is_empty_var = gen_op_var_fresh(STOREV, "is_empty");
1890
- block init = BLOCK(gen_op_simple(DUP),
1891
- gen_const(jv_null()),
1892
- last_var,
1893
- gen_op_simple(DUP),
1894
- gen_const(jv_true()),
1895
- is_empty_var);
1896
- block call_arg = BLOCK(gen_call("arg", gen_noop()),
1897
- gen_op_simple(DUP),
1898
- gen_op_bound(STOREV, last_var),
1899
- gen_const(jv_false()),
1900
- gen_op_bound(STOREV, is_empty_var),
1901
- gen_op_simple(BACKTRACK));
1902
- block if_empty = gen_op_simple(BACKTRACK);
1903
- return BLOCK(init,
1904
- gen_op_target(FORK, call_arg),
1905
- call_arg,
1906
- BLOCK(gen_op_bound(LOADVN, is_empty_var),
1907
- gen_op_target(JUMP_F, if_empty),
1908
- if_empty,
1909
- gen_op_bound(LOADVN, last_var)));
1910
- }
1911
1794
 
1912
1795
  struct bytecoded_builtin { const char* name; block code; };
1913
1796
  static block bind_bytecoded_builtins(block b) {
@@ -1928,7 +1811,6 @@ static block bind_bytecoded_builtins(block b) {
1928
1811
  {"path", BLOCK(gen_op_simple(PATH_BEGIN),
1929
1812
  gen_call("arg", gen_noop()),
1930
1813
  gen_op_simple(PATH_END))},
1931
- {"last", gen_last_1()},
1932
1814
  };
1933
1815
  for (unsigned i=0; i<sizeof(builtin_def_1arg)/sizeof(builtin_def_1arg[0]); i++) {
1934
1816
  builtins = BLOCK(builtins, gen_function(builtin_def_1arg[i].name,
@@ -1956,11 +1838,42 @@ static block bind_bytecoded_builtins(block b) {
1956
1838
  return BLOCK(builtins, b);
1957
1839
  }
1958
1840
 
1959
- static const char jq_builtins[] = {
1841
+ static const char jq_builtins[] =
1960
1842
  /* Include jq-coded builtins */
1961
1843
  #include "src/builtin.inc"
1962
- '\0',
1963
- };
1844
+
1845
+ /* Include unsupported math functions next */
1846
+ #define LIBM_DD(name)
1847
+ #define LIBM_DDD(name)
1848
+ #define LIBM_DDDD(name)
1849
+ #define LIBM_DD_NO(name) "def " #name ": \"Error: " #name "/0 not found at build time\"|error;"
1850
+ #define LIBM_DDD_NO(name) "def " #name "(a;b): \"Error: " #name "/2 not found at build time\"|error;"
1851
+ #define LIBM_DDDD_NO(name) "def " #name "(a;b;c): \"Error: " #name "/3 not found at build time\"|error;"
1852
+ #include "libm.h"
1853
+ #ifndef HAVE_FREXP
1854
+ "def frexp: \"Error: frexp/0 not found at build time\"|error;"
1855
+ #endif
1856
+ #ifndef HAVE_MODF
1857
+ "def modf: \"Error: modf/0 not found at build time\"|error;"
1858
+ #endif
1859
+ #ifndef HAVE_LGAMMA_R
1860
+ "def lgamma_r: \"Error: lgamma_r/0 not found at build time\"|error;"
1861
+ #endif
1862
+ ;
1863
+
1864
+ #undef LIBM_DDDD_NO
1865
+ #undef LIBM_DDD_NO
1866
+ #undef LIBM_DD_NO
1867
+ #undef LIBM_DDDD
1868
+ #undef LIBM_DDD
1869
+ #undef LIBM_DD
1870
+
1871
+ #ifdef __APPLE__
1872
+ #undef HAVE_GAMMA
1873
+ #undef HAVE_EXP10
1874
+ #undef HAVE_DREM
1875
+ #undef HAVE_SIGNIFICAND
1876
+ #endif
1964
1877
 
1965
1878
  static block gen_builtin_list(block builtins) {
1966
1879
  jv list = jv_array_append(block_list_funcs(builtins, 1), jv_string("builtins/0"));