]> granicus.if.org Git - jq/blob - src/builtin.c
baa689156937ad4d1694d9cabad6c844e97c0ef9
[jq] / src / builtin.c
1 #define _BSD_SOURCE
2 #define _GNU_SOURCE
3 #ifndef __sun__
4 # define _XOPEN_SOURCE
5 # define _XOPEN_SOURCE_EXTENDED 1
6 #else
7 # define _XPG6
8 # define __EXTENSIONS__
9 #endif
10 #include <sys/time.h>
11 #include <stdlib.h>
12 #include <stddef.h>
13 #ifdef HAVE_ALLOCA_H
14 # include <alloca.h>
15 #elif !defined alloca
16 # ifdef __GNUC__
17 #  define alloca __builtin_alloca
18 # elif defined _MSC_VER
19 #  include <malloc.h>
20 #  define alloca _alloca
21 # elif !defined HAVE_ALLOCA
22 #  ifdef  __cplusplus
23 extern "C"
24 #  endif
25 void *alloca (size_t);
26 # endif
27 #endif
28 #include <assert.h>
29 #include <ctype.h>
30 #include <limits.h>
31 #include <math.h>
32 #ifdef HAVE_LIBONIG
33 #include <oniguruma.h>
34 #endif
35 #include <string.h>
36 #include <time.h>
37 #ifdef WIN32
38 #include <windows.h>
39 #endif
40 #include "builtin.h"
41 #include "compile.h"
42 #include "jq_parser.h"
43 #include "bytecode.h"
44 #include "linker.h"
45 #include "locfile.h"
46 #include "jv_unicode.h"
47 #include "jv_alloc.h"
48
49
50 static jv type_error(jv bad, const char* msg) {
51   char errbuf[15];
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)),
55                                              msg));
56   jv_free(bad);
57   return err;
58 }
59
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)),
67                                              msg));
68   jv_free(bad1);
69   jv_free(bad2);
70   return err;
71 }
72
73 static inline jv ret_error(jv bad, jv msg) {
74   jv_free(bad);
75   return jv_invalid_with_msg(msg);
76 }
77
78 static inline jv ret_error2(jv bad1, jv bad2, jv msg) {
79   jv_free(bad1);
80   jv_free(bad2);
81   return jv_invalid_with_msg(msg);
82 }
83
84 static jv f_plus(jq_state *jq, jv input, jv a, jv b) {
85   jv_free(input);
86   if (jv_get_kind(a) == JV_KIND_NULL) {
87     jv_free(a);
88     return b;
89   } else if (jv_get_kind(b) == JV_KIND_NULL) {
90     jv_free(b);
91     return a;
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) +
94                      jv_number_value(b));
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);
101   } else {
102     return type_error2(a, b, "cannot be added");
103   }
104 }
105
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"); \
110   } \
111   jv ret = jv_number(name(jv_number_value(input))); \
112   jv_free(input); \
113   return ret; \
114 }
115 #define LIBM_DD_NO(name)
116
117 #define LIBM_DDD(name) \
118 static jv f_ ## name(jq_state *jq, jv input, jv a, jv b) { \
119   jv_free(input); \
120   if (jv_get_kind(a) != JV_KIND_NUMBER) { \
121     jv_free(b); \
122     return type_error(a, "number required"); \
123   } \
124   if (jv_get_kind(b) != JV_KIND_NUMBER) { \
125     jv_free(a); \
126     return type_error(b, "number required"); \
127   } \
128   jv ret = jv_number(name(jv_number_value(a), jv_number_value(b))); \
129   jv_free(a); \
130   jv_free(b); \
131   return ret; \
132 }
133 #define LIBM_DDD_NO(name)
134
135 #define LIBM_DDDD(name) \
136 static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \
137   jv_free(input); \
138   if (jv_get_kind(a) != JV_KIND_NUMBER) { \
139     jv_free(b); \
140     jv_free(c); \
141     return type_error(a, "number required"); \
142   } \
143   if (jv_get_kind(b) != JV_KIND_NUMBER) { \
144     jv_free(a); \
145     jv_free(c); \
146     return type_error(b, "number required"); \
147   } \
148   if (jv_get_kind(c) != JV_KIND_NUMBER) { \
149     jv_free(a); \
150     jv_free(b); \
151     return type_error(c, "number required"); \
152   } \
153   jv ret = jv_number(name(jv_number_value(a), jv_number_value(b), jv_number_value(c))); \
154   jv_free(a); \
155   jv_free(b); \
156   jv_free(c); \
157   return ret; \
158 }
159 #define LIBM_DDDD_NO(name)
160 #include "libm.h"
161 #undef LIBM_DDDD_NO
162 #undef LIBM_DDD_NO
163 #undef LIBM_DD_NO
164 #undef LIBM_DDDD
165 #undef LIBM_DDD
166 #undef LIBM_DD
167
168 #ifdef HAVE_FREXP
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");
172   }
173   int exp;
174   double d = frexp(jv_number_value(input), &exp);
175   jv ret = JV_ARRAY(jv_number(d), jv_number(exp));
176   jv_free(input);
177   return ret;
178 }
179 #endif
180 #ifdef HAVE_MODF
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");
184   }
185   double i;
186   jv ret = JV_ARRAY(jv_number(modf(jv_number_value(input), &i)));
187   jv_free(input);
188   return jv_array_append(ret, jv_number(i));
189 }
190 #endif
191 #ifdef HAVE_LGAMMA_R
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");
195   }
196   int sign;
197   jv ret = JV_ARRAY(jv_number(lgamma_r(jv_number_value(input), &sign)));
198   jv_free(input);
199   return jv_array_append(ret, jv_number(sign));
200 }
201 #endif
202
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");
206   }
207   jv ret = jv_number(-jv_number_value(input));
208   jv_free(input);
209   return ret;
210 }
211
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));
217   jv ret;
218
219   if (blen <= alen && memcmp(jv_string_value(a), jv_string_value(b), blen) == 0)
220     ret = jv_true();
221   else
222     ret = jv_false();
223   jv_free(a);
224   jv_free(b);
225   return ret;
226 }
227
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));
235   jv ret;;
236
237   if (alen < blen ||
238      memcmp(astr + (alen - blen), bstr, blen) != 0)
239     ret = jv_false();
240   else
241     ret = jv_true();
242   jv_free(a);
243   jv_free(b);
244   return ret;
245 }
246
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) {
249     jv_free(left);
250     return input;
251   }
252   /*
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.
255    */
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);
259   jv_free(input);
260   return res;
261 }
262
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));
267     jv_free(input);
268     return res;
269   }
270   jv_free(right);
271   return input;
272 }
273
274 static jv f_minus(jq_state *jq, jv input, jv a, jv b) {
275   jv_free(input);
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) {
279     jv out = jv_array();
280     jv_array_foreach(a, i, x) {
281       int include = 1;
282       jv_array_foreach(b, j, y) {
283         if (jv_equal(jv_copy(x), y)) {
284           include = 0;
285           break;
286         }
287       }
288       if (include)
289         out = jv_array_append(out, jv_copy(x));
290       jv_free(x);
291     }
292     jv_free(a);
293     jv_free(b);
294     return out;
295   } else {
296     return type_error2(a, b, "cannot be subtracted");
297   }
298 }
299
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);
303   jv_free(input);
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)) {
308     jv str = a;
309     jv num = b;
310     if (ak == JV_KIND_NUMBER) {
311       str = b;
312       num = a;
313     }
314     int n;
315     size_t alen = jv_string_length_bytes(jv_copy(str));
316     jv res = str;
317
318     for (n = jv_number_value(num) - 1; n > 0; n--)
319       res = jv_string_append_buf(res, jv_string_value(str), alen);
320
321     jv_free(num);
322     if (n < 0) {
323       jv_free(str);
324       return jv_null();
325     }
326     return res;
327   } else if (ak == JV_KIND_OBJECT && bk == JV_KIND_OBJECT) {
328     return jv_object_merge_recursive(a, b);
329   } else {
330     return type_error2(a, b, "cannot be multiplied");
331   }
332 }
333
334 static jv f_divide(jq_state *jq, jv input, jv a, jv b) {
335   jv_free(input);
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);
342   } else {
343     return type_error2(a, b, "cannot be divided");
344   }
345 }
346
347 static jv f_mod(jq_state *jq, jv input, jv a, jv b) {
348   jv_free(input);
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));
353   } else {
354     return type_error2(a, b, "cannot be divided (remainder)");
355   }
356 }
357
358 static jv f_equal(jq_state *jq, jv input, jv a, jv b) {
359   jv_free(input);
360   return jv_bool(jv_equal(a, b));
361 }
362
363 static jv f_notequal(jq_state *jq, jv input, jv a, jv b) {
364   jv_free(input);
365   return jv_bool(!jv_equal(a, b));
366 }
367
368 enum cmp_op {
369   CMP_OP_LESS,
370   CMP_OP_GREATER,
371   CMP_OP_LESSEQ,
372   CMP_OP_GREATEREQ
373 };
374
375 static jv order_cmp(jv input, jv a, jv b, enum cmp_op op) {
376   jv_free(input);
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));
382 }
383
384 static jv f_less(jq_state *jq, jv input, jv a, jv b) {
385   return order_cmp(input, a, b, CMP_OP_LESS);
386 }
387
388 static jv f_greater(jq_state *jq, jv input, jv a, jv b) {
389   return order_cmp(input, a, b, CMP_OP_GREATER);
390 }
391
392 static jv f_lesseq(jq_state *jq, jv input, jv a, jv b) {
393   return order_cmp(input, a, b, CMP_OP_LESSEQ);
394 }
395
396 static jv f_greatereq(jq_state *jq, jv input, jv a, jv b) {
397   return order_cmp(input, a, b, CMP_OP_GREATEREQ);
398 }
399
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));
403   } else {
404     return type_error2(a, b, "cannot have their containment checked");
405   }
406 }
407
408 static jv f_dump(jq_state *jq, jv input) {
409   return jv_dump_string(input, 0);
410 }
411
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)));
417   jv_free(input);
418   return res;
419 }
420
421 static jv f_tonumber(jq_state *jq, jv input) {
422   if (jv_get_kind(input) == JV_KIND_NUMBER) {
423     return input;
424   }
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) {
428       jv_free(input);
429       return parsed;
430     }
431   }
432   return type_error(input, "cannot be parsed as a number");
433 }
434
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) {
445     jv_free(input);
446     return jv_number(0);
447   } else {
448     return type_error(input, "has no length");
449   }
450 }
451
452 static jv f_tostring(jq_state *jq, jv input) {
453   if (jv_get_kind(input) == JV_KIND_STRING) {
454     return input;
455   } else {
456     return jv_dump_string(input, 0);
457   }
458 }
459
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));
464 }
465
466 #define CHARS_ALPHANUM "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
467
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,
472   62, // +
473   0xFF, 0xFF, 0xFF,
474   63, // /
475   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // 0-9
476   0xFF, 0xFF, 0xFF,
477   99, // =
478   0xFF, 0xFF, 0xFF,
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
483 };
484
485
486 static jv escape_string(jv input, const char* escapings) {
487
488   assert(jv_get_kind(input) == JV_KIND_STRING);
489   const char* lookup[128] = {0};
490   const char* p = escapings;
491   lookup[0] = "\\0";
492   while (*p) {
493     lookup[(int)*p] = p+1;
494     p++;
495     p += strlen(p);
496     p++;
497   }
498
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));
502   const char* cstart;
503   int c = 0;
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]);
507     } else {
508       ret = jv_string_append_buf(ret, cstart, i - cstart);
509     }
510   }
511   jv_free(input);
512   return ret;
513
514 }
515
516 static jv f_format(jq_state *jq, jv input, jv fmt) {
517   if (jv_get_kind(fmt) != JV_KIND_STRING) {
518     jv_free(input);
519     return type_error(fmt, "is not a valid format");
520   }
521   const char* fmt_s = jv_string_value(fmt);
522   if (!strcmp(fmt_s, "json")) {
523     jv_free(fmt);
524     return jv_dump_string(input, 0);
525   } else if (!strcmp(fmt_s, "text")) {
526     jv_free(fmt);
527     return f_tostring(jq, input);
528   } else if (!strcmp(fmt_s, "csv") || !strcmp(fmt_s, "tsv")) {
529     const char *quotes, *sep, *escapings;
530     const char *msg;
531     if (!strcmp(fmt_s, "csv")) {
532       msg = "cannot be csv-formatted, only array";
533       quotes = "\"";
534       sep = ",";
535       escapings = "\"\"\"\0";
536     } else {
537       msg = "cannot be tsv-formatted, only array";
538       assert(!strcmp(fmt_s, "tsv"));
539       quotes = "";
540       sep = "\t";
541       escapings = "\t\\t\0\r\\r\0\n\\n\0\\\\\\\0";
542     }
543     jv_free(fmt);
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)) {
550       case JV_KIND_NULL:
551         /* null rendered as empty string */
552         jv_free(x);
553         break;
554       case JV_KIND_TRUE:
555       case JV_KIND_FALSE:
556         line = jv_string_concat(line, jv_dump_string(x, 0));
557         break;
558       case JV_KIND_NUMBER:
559         if (jv_number_value(x) != jv_number_value(x)) {
560           /* NaN, render as empty string */
561           jv_free(x);
562         } else {
563           line = jv_string_concat(line, jv_dump_string(x, 0));
564         }
565         break;
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);
570         break;
571       }
572       default:
573         jv_free(input);
574         jv_free(line);
575         return type_error(x, "is not valid in a csv row");
576       }
577     }
578     jv_free(input);
579     return line;
580   } else if (!strcmp(fmt_s, "html")) {
581     jv_free(fmt);
582     return escape_string(f_tostring(jq, input), "&&amp;\0<&lt;\0>&gt;\0'&apos;\0\"&quot;\0");
583   } else if (!strcmp(fmt_s, "uri")) {
584     jv_free(fmt);
585     input = f_tostring(jq, input);
586
587     int unreserved[128] = {0};
588     const char* p = CHARS_ALPHANUM "-_.!~*'()";
589     while (*p) unreserved[(int)*p++] = 1;
590
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);
597       } else {
598         line = jv_string_concat(line, jv_string_fmt("%%%02X", ch));
599       }
600       s++;
601     }
602     jv_free(input);
603     return line;
604   } else if (!strcmp(fmt_s, "sh")) {
605     jv_free(fmt);
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)) {
612       case JV_KIND_NULL:
613       case JV_KIND_TRUE:
614       case JV_KIND_FALSE:
615       case JV_KIND_NUMBER:
616         line = jv_string_concat(line, jv_dump_string(x, 0));
617         break;
618
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, "'");
623         break;
624       }
625
626       default:
627         jv_free(input);
628         jv_free(line);
629         return type_error(x, "can not be escaped for shell");
630       }
631     }
632     jv_free(input);
633     return line;
634   } else if (!strcmp(fmt_s, "base64")) {
635     jv_free(fmt);
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) {
641       uint32_t code = 0;
642       int n = len - i >= 3 ? 3 : len-i;
643       for (int j=0; j<3; j++) {
644         code <<= 8;
645         code |= j < n ? (unsigned)data[i+j] : 0;
646       }
647       char buf[4];
648       for (int j=0; j<4; j++) {
649         buf[j] = BASE64_ENCODE_TABLE[(code >> (18 - j*6)) & 0x3f];
650       }
651       if (n < 3) buf[3] = '=';
652       if (n < 2) buf[2] = '=';
653       line = jv_string_append_buf(line, buf, sizeof(buf));
654     }
655     jv_free(input);
656     return line;
657   } else if (!strcmp(fmt_s, "base64d")) {
658     jv_free(fmt);
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));
665     uint32_t ri = 0;
666     int input_bytes_read=0;
667     uint32_t code = 0;
668     for (int i=0; i<len && data[i] != '='; i++) {
669       if (BASE64_DECODE_TABLE[data[i]] == BASE64_INVALID_ENTRY) {
670         free(result);
671         return type_error(input, "is not valid base64 data");
672       }
673
674       code <<= 6;
675       code |= BASE64_DECODE_TABLE[data[i]];
676       input_bytes_read++;
677
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;
683         code = 0;
684       }
685     }
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) {
692       free(result);
693       return type_error(input, "trailing base64 byte found");
694     }
695
696     jv line = jv_string_sized(result, ri);
697     jv_free(input);
698     free(result);
699     return line;
700   } else {
701     jv_free(input);
702     return jv_invalid_with_msg(jv_string_concat(fmt, jv_string(" is not a valid format")));
703   }
704 }
705
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);
709   } else {
710     return type_error(input, "has no keys");
711   }
712 }
713
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);
717   } else {
718     return type_error(input, "has no keys");
719   }
720 }
721
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));
725   } else {
726     return type_error(input, "cannot be sorted, as it is not an array");
727   }
728 }
729
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);
735   } else {
736     return type_error2(input, keys, "cannot be sorted, as they are not both arrays");
737   }
738 }
739
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);
745   } else {
746     return type_error2(input, keys, "cannot be sorted, as they are not both arrays");
747   }
748 }
749
750 #ifdef HAVE_LIBONIG
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);
759     } else {
760       jv_free(cap);
761     }
762   }
763   *(jv *)arg = captures;
764   return 0;
765 }
766
767 static jv f_match(jq_state *jq, jv input, jv regex, jv modifiers, jv testmode) {
768   int test = jv_equal(testmode, jv_true());
769   jv result;
770   int onigret;
771   int global = 0;
772   regex_t *reg;
773   OnigErrorInfo einfo;
774   OnigRegion* region;
775
776   if (jv_get_kind(input) != JV_KIND_STRING) {
777     jv_free(regex);
778     jv_free(modifiers);
779     return type_error(input, "cannot be matched, as it is not a string");
780   }
781
782   if (jv_get_kind(regex) != JV_KIND_STRING) {
783     jv_free(input);
784     jv_free(modifiers);
785     return type_error(regex, "is not a string");
786   }
787
788   OnigOptionType options = ONIG_OPTION_CAPTURE_GROUP;
789
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)) {
794         case 'g':
795           global = 1;
796           break;
797         case 'i':
798           options |= ONIG_OPTION_IGNORECASE;
799           break;
800         case 'x':
801           options |= ONIG_OPTION_EXTEND;
802           break;
803         case 'm':
804           options |= ONIG_OPTION_MULTILINE;
805           break;
806         case 's':
807           options |= ONIG_OPTION_SINGLELINE;
808           break;
809         case 'p':
810           options |= ONIG_OPTION_MULTILINE | ONIG_OPTION_SINGLELINE;
811           break;
812         case 'l':
813           options |= ONIG_OPTION_FIND_LONGEST;
814           break;
815         case 'n':
816           options |= ONIG_OPTION_FIND_NOT_EMPTY;
817           break;
818         default:
819           jv_free(input);
820           jv_free(regex);
821           jv_free(modarray);
822           return jv_invalid_with_msg(jv_string_concat(modifiers,
823                 jv_string(" is not a valid modifier string")));
824       }
825     }
826     jv_free(modarray);
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...
829     jv_free(input);
830     jv_free(regex);
831     return type_error(modifiers, "is not a string");
832   }
833
834   jv_free(modifiers);
835
836   onigret = onig_new(&reg, (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);
842     jv_free(input);
843     jv_free(regex);
844     return jv_invalid_with_msg(jv_string_concat(jv_string("Regex failure: "),
845           jv_string((char*)ebuf)));
846   }
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();
853   do {
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);
858     if (onigret >= 0) {
859       if (test) {
860         result = jv_true();
861         break;
862       }
863
864       // Zero-width match
865       if (region->end[0] == region->beg[0]) {
866         unsigned long idx;
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);
870         }
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);
876         start += 1;
877         continue;
878       }
879
880       unsigned long idx;
881       unsigned long len;
882       const char *fr = (const char*)input_string;
883
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);
887       }
888
889       jv match = jv_object_set(jv_object(), jv_string("offset"), jv_number(idx));
890
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) {
896         // Empty capture.
897         if (region->beg[i] == region->end[i]) {
898           // Didn't match.
899           jv cap;
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());
903           } else {
904             fr = input_string;
905             for (idx = 0; fr != input_string+region->beg[i]; idx++) {
906               fr += jvp_utf8_decode_length(*fr);
907             }
908             cap = jv_object_set(jv_object(), jv_string("offset"), jv_number(idx));
909             cap = jv_object_set(cap, jv_string("string"), jv_string(""));
910           }
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);
914           continue;
915         }
916         fr = input_string;
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);
920         }
921
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);
928       }
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) {
935       break;
936     } else { /* Error */
937       UChar ebuf[ONIG_MAX_ERROR_MESSAGE_LEN];
938       onig_error_code_to_str(ebuf, onigret, einfo);
939       jv_free(result);
940       result = jv_invalid_with_msg(jv_string_concat(jv_string("Regex failure: "),
941             jv_string((char*)ebuf)));
942       break;
943     }
944   } while (global && start != end);
945   onig_region_free(region,1);
946   region = NULL;
947   if (region)
948     onig_region_free(region,1);
949   onig_free(reg);
950   jv_free(input);
951   jv_free(regex);
952   return result;
953 }
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."));
957 }
958 #endif /* HAVE_LIBONIG */
959
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");
967
968   if (jv_array_length(jv_copy(values)) == 0) {
969     jv_free(values);
970     jv_free(keys);
971     return jv_null();
972   }
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)) {
979       jv_free(retkey);
980       retkey = item;
981       jv_free(ret);
982       ret = jv_array_get(jv_copy(values), i);
983     } else {
984       jv_free(item);
985     }
986   }
987   jv_free(values);
988   jv_free(keys);
989   jv_free(retkey);
990   return ret;
991 }
992
993 static jv f_min(jq_state *jq, jv x) {
994   return minmax_by(x, jv_copy(x), 1);
995 }
996
997 static jv f_max(jq_state *jq, jv x) {
998   return minmax_by(x, jv_copy(x), 0);
999 }
1000
1001 static jv f_min_by_impl(jq_state *jq, jv x, jv y) {
1002   return minmax_by(x, y, 1);
1003 }
1004
1005 static jv f_max_by_impl(jq_state *jq, jv x, jv y) {
1006   return minmax_by(x, y, 0);
1007 }
1008
1009
1010 static jv f_type(jq_state *jq, jv input) {
1011   jv out = jv_string(jv_kind_name(jv_get_kind(input)));
1012   jv_free(input);
1013   return out;
1014 }
1015
1016 static jv f_isinfinite(jq_state *jq, jv input) {
1017   jv_kind k = jv_get_kind(input);
1018   if (k != JV_KIND_NUMBER) {
1019     jv_free(input);
1020     return jv_false();
1021   }
1022   double n = jv_number_value(input);
1023   jv_free(input);
1024   return isinf(n) ? jv_true() : jv_false();
1025 }
1026
1027 static jv f_isnan(jq_state *jq, jv input) {
1028   jv_kind k = jv_get_kind(input);
1029   if (k != JV_KIND_NUMBER) {
1030     jv_free(input);
1031     return jv_false();
1032   }
1033   double n = jv_number_value(input);
1034   jv_free(input);
1035   return isnan(n) ? jv_true() : jv_false();
1036 }
1037
1038 static jv f_isnormal(jq_state *jq, jv input) {
1039   jv_kind k = jv_get_kind(input);
1040   if (k != JV_KIND_NUMBER) {
1041     jv_free(input);
1042     return jv_false();
1043   }
1044   double n = jv_number_value(input);
1045   jv_free(input);
1046   return isnormal(n) ? jv_true() : jv_false();
1047 }
1048
1049 static jv f_infinite(jq_state *jq, jv input) {
1050   jv_free(input);
1051   return jv_number(INFINITY);
1052 }
1053
1054 static jv f_nan(jq_state *jq, jv input) {
1055   jv_free(input);
1056   return jv_number(NAN);
1057 }
1058
1059 static jv f_error(jq_state *jq, jv input, jv msg) {
1060   jv_free(input);
1061   return jv_invalid_with_msg(msg);
1062 }
1063
1064 // FIXME Should autoconf check for this!
1065 #ifndef WIN32
1066 extern char **environ;
1067 #endif
1068
1069 static jv f_env(jq_state *jq, jv input) {
1070   jv_free(input);
1071   jv env = jv_object();
1072   const char *var, *val;
1073   for (char **e = environ; *e != NULL; e++) {
1074     var = e[0];
1075     val = strchr(e[0], '=');
1076     if (val == NULL)
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));
1080   }
1081   return env;
1082 }
1083
1084 static jv f_halt(jq_state *jq, jv input) {
1085   jv_free(input);
1086   jq_halt(jq, jv_invalid(), jv_invalid());
1087   return jv_true();
1088 }
1089
1090 static jv f_halt_error(jq_state *jq, jv input, jv a) {
1091   if (jv_get_kind(a) != JV_KIND_NUMBER) {
1092     jv_free(a);
1093     return type_error(input, "halt_error/1: number required");
1094   }
1095   jq_halt(jq, a, input);
1096   return jv_true();
1097 }
1098
1099 static jv f_get_search_list(jq_state *jq, jv input) {
1100   jv_free(input);
1101   return jq_get_lib_dirs(jq);
1102 }
1103
1104 static jv f_get_prog_origin(jq_state *jq, jv input) {
1105   jv_free(input);
1106   return jq_get_prog_origin(jq);
1107 }
1108
1109 static jv f_get_jq_origin(jq_state *jq, jv input) {
1110   jv_free(input);
1111   return jq_get_jq_origin(jq);
1112 }
1113
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"));
1117   }
1118   return jv_string_split(a, b);
1119 }
1120
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"));
1124   }
1125   return jv_string_explode(a);
1126 }
1127
1128 static jv f_string_indexes(jq_state *jq, jv a, jv b) {
1129   return jv_string_indexes(a, b);
1130 }
1131
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"));
1135   }
1136   return jv_string_implode(a);
1137 }
1138
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)));
1143 }
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); }
1146
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"));
1150   }
1151   return load_module_meta(jq, a);
1152 }
1153
1154 static jv f_input(jq_state *jq, jv input) {
1155   jv_free(input);
1156   jq_input_cb cb;
1157   void *data;
1158   jq_get_input_cb(jq, &cb, &data);
1159   if (cb == NULL)
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)))
1163     return v;
1164   return jv_invalid_with_msg(jv_string("break"));
1165 }
1166
1167 static jv f_debug(jq_state *jq, jv input) {
1168   jq_msg_cb cb;
1169   void *data;
1170   jq_get_debug_cb(jq, &cb, &data);
1171   if (cb != NULL)
1172     cb(data, jv_copy(input));
1173   return input;
1174 }
1175
1176 static jv f_stderr(jq_state *jq, jv input) {
1177   jv_dumpf(jv_copy(input), stderr, 0);
1178   return input;
1179 }
1180
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));
1190 }
1191
1192 #if defined(WIN32) && !defined(HAVE_SETENV)
1193 static int setenv(const char *var, const char *val, int ovr)
1194 {
1195   BOOL b;
1196   char c[2];
1197   if (!ovr)
1198   {
1199     DWORD d;
1200     d = GetEnvironmentVariableA (var, c, 2);
1201     if (0 != d && GetLastError () != ERROR_ENVVAR_NOT_FOUND) {
1202       return d;
1203     }
1204   }
1205   b = SetEnvironmentVariableA (var, val);
1206   if (b) {
1207     return 0;
1208   }
1209   return 1;
1210 }
1211 #endif
1212
1213 /*
1214  * mktime() has side-effects and anyways, returns time in the local
1215  * timezone, not UTC.  We want timegm(), which isn't standard.
1216  *
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.
1220  *
1221  * This is all to blame on POSIX, of course.
1222  *
1223  * Our wrapper tries to use timegm() if available, or mktime() and
1224  * correct for its side-effects if possible.
1225  *
1226  * Returns (time_t)-2 if mktime()'s side-effects cannot be corrected.
1227  */
1228 static time_t my_mktime(struct tm *tm) {
1229 #ifdef HAVE_TIMEGM
1230   return timegm(tm);
1231 #elif HAVE_TM_TM_GMT_OFF
1232
1233   time_t t = mktime(tm);
1234   if (t == (time_t)-1)
1235     return t;
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)
1240     return t;
1241   return t + tm->__tm_gmtoff;
1242 #else
1243   char *tz;
1244
1245   tz = (tz = getenv("TZ")) != NULL ? strdup(tz) : NULL;
1246   if (tz != NULL)
1247     setenv("TZ", "", 1);
1248   time_t t = mktime(tm);
1249   if (tz != NULL)
1250     setenv("TZ", tz, 1);
1251   return t;
1252 #endif
1253 }
1254
1255 /* Compute and set tm_wday */
1256 static void set_tm_wday(struct tm *tm) {
1257   /*
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
1260    *
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
1265    * this.
1266    */
1267   int century = (1900 + tm->tm_year) / 100;
1268   int year = (1900 + tm->tm_year) % 100;
1269   if (tm->tm_mon < 2)
1270     year--;
1271   /*
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.
1274    */
1275   int mon = tm->tm_mon - 1;
1276   if (mon < 1)
1277     mon += 12;
1278   int wday =
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;
1280   if (wday < 0)
1281     wday += 7;
1282 #if 0
1283   /* See commentary above */
1284   assert(wday == tm->tm_wday || tm->tm_wday == 8);
1285 #endif
1286   tm->tm_wday = wday;
1287 }
1288 /*
1289  * Compute and set tm_yday.
1290  *
1291  */
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;
1296   int leap_day = 0;
1297   if (tm->tm_mon > 1 &&
1298       ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
1299     leap_day = 1;
1300
1301   /* Bound check index into d[] */
1302   if (mon < 0)
1303     mon = -mon;
1304   if (mon > 11)
1305     mon %= 12;
1306
1307   int yday = d[mon] + leap_day + tm->tm_mday - 1;
1308   assert(yday == tm->tm_yday || tm->tm_yday == 367);
1309   tm->tm_yday = yday;
1310 }
1311
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"));
1316   }
1317
1318   struct tm tm;
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);
1325
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));
1328   }
1329   jv_free(b);
1330   /*
1331    * This is OS X or some *BSD whose strptime() is just not that
1332    * helpful!
1333    *
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.
1338    */
1339 #ifdef __APPLE__
1340   /*
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.
1347    */
1348   set_tm_wday(&tm);
1349   set_tm_yday(&tm);
1350 #else
1351   if (tm.tm_wday == 8 && tm.tm_mday != 0 && tm.tm_mon >= 0 && tm.tm_mon <= 11)
1352     set_tm_wday(&tm);
1353   if (tm.tm_yday == 367 && tm.tm_mday != 0 && tm.tm_mon >= 0 && tm.tm_mon <= 11)
1354     set_tm_yday(&tm);
1355 #endif
1356   jv r = tm2jv(&tm);
1357   if (*end != '\0')
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
1360   return r;
1361 }
1362 #else
1363 static jv f_strptime(jq_state *jq, jv a, jv b) {
1364   jv_free(a);
1365   jv_free(b);
1366   return jv_invalid_with_msg(jv_string("strptime/1 not implemented on this platform"));
1367 }
1368 #endif
1369
1370 #define TO_TM_FIELD(t, j, i)                    \
1371     do {                                        \
1372       jv n = jv_array_get(jv_copy(j), (i));     \
1373       if (jv_get_kind(n) != (JV_KIND_NUMBER)) { \
1374         jv_free(j);                             \
1375         return 0;                               \
1376       }                                         \
1377       t = jv_number_value(n);                   \
1378       jv_free(n);                               \
1379     } while (0)
1380
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);
1392   jv_free(a);
1393
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;
1397
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.
1401
1402   return 1;
1403 }
1404
1405 #undef TO_TM_FIELD
1406
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"));
1412   struct tm tm;
1413   if (!jv2tm(a, &tm))
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);
1421 }
1422
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"));
1427   struct tm tm, *tmp;
1428   memset(&tm, 0, sizeof(tm));
1429   double fsecs = jv_number_value(a);
1430   time_t secs = fsecs;
1431   jv_free(a);
1432   tmp = gmtime_r(&secs, &tm);
1433   if (tmp == NULL)
1434     return jv_invalid_with_msg(jv_string("errror converting number of seconds since epoch to datetime"));
1435   a = tm2jv(tmp);
1436   return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1437 }
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"));
1442   struct tm tm, *tmp;
1443   memset(&tm, 0, sizeof(tm));
1444   double fsecs = jv_number_value(a);
1445   time_t secs = fsecs;
1446   jv_free(a);
1447   tmp = gmtime(&secs);
1448   if (tmp == NULL)
1449     return jv_invalid_with_msg(jv_string("errror converting number of seconds since epoch to datetime"));
1450   a = tm2jv(tmp);
1451   return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1452 }
1453 #else
1454 static jv f_gmtime(jq_state *jq, jv a) {
1455   jv_free(a);
1456   return jv_invalid_with_msg(jv_string("gmtime not implemented on this platform"));
1457 }
1458 #endif
1459
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"));
1464   struct tm tm, *tmp;
1465   memset(&tm, 0, sizeof(tm));
1466   double fsecs = jv_number_value(a);
1467   time_t secs = fsecs;
1468   jv_free(a);
1469   tmp = localtime_r(&secs, &tm);
1470   if (tmp == NULL)
1471     return jv_invalid_with_msg(jv_string("error converting number of seconds since epoch to datetime"));
1472   a = tm2jv(tmp);
1473   return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1474 }
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"));
1479   struct tm tm, *tmp;
1480   memset(&tm, 0, sizeof(tm));
1481   double fsecs = jv_number_value(a);
1482   time_t secs = fsecs;
1483   jv_free(a);
1484   tmp = localtime(&secs);
1485   if (tmp == NULL)
1486     return jv_invalid_with_msg(jv_string("error converting number of seconds since epoch to datetime"));
1487   a = tm2jv(tmp);
1488   return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1489 }
1490 #else
1491 static jv f_localtime(jq_state *jq, jv a) {
1492   jv_free(a);
1493   return jv_invalid_with_msg(jv_string("localtime not implemented on this platform"));
1494 }
1495 #endif
1496
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"));
1505   }
1506   struct tm tm;
1507   if (!jv2tm(a, &tm))
1508     return ret_error(b, jv_string("strftime/1 requires parsed datetime inputs"));
1509
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);
1514   jv_free(b);
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);
1519 }
1520 #else
1521 static jv f_strftime(jq_state *jq, jv a, jv b) {
1522   jv_free(a);
1523   jv_free(b);
1524   return jv_invalid_with_msg(jv_string("strftime/1 not implemented on this platform"));
1525 }
1526 #endif
1527
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"));
1536   }
1537   struct tm tm;
1538   if (!jv2tm(a, &tm))
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);
1544   jv_free(b);
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);
1549 }
1550 #else
1551 static jv f_strflocaltime(jq_state *jq, jv a, jv b) {
1552   jv_free(a);
1553   jv_free(b);
1554   return jv_invalid_with_msg(jv_string("strflocaltime/1 not implemented on this platform"));
1555 }
1556 #endif
1557
1558 #ifdef HAVE_GETTIMEOFDAY
1559 static jv f_now(jq_state *jq, jv a) {
1560   jv_free(a);
1561   struct timeval tv;
1562   if (gettimeofday(&tv, NULL) == -1)
1563     return jv_number(time(NULL));
1564   return jv_number(tv.tv_sec + tv.tv_usec / 1000000.0);
1565 }
1566 #else
1567 static jv f_now(jq_state *jq, jv a) {
1568   jv_free(a);
1569   return jv_number(time(NULL));
1570 }
1571 #endif
1572
1573 static jv f_current_filename(jq_state *jq, jv a) {
1574   jv_free(a);
1575
1576   jv r = jq_util_input_get_current_filename(jq);
1577   if (jv_is_valid(r))
1578     return r;
1579   jv_free(r);
1580   return jv_null();
1581 }
1582 static jv f_current_line(jq_state *jq, jv a) {
1583   jv_free(a);
1584   return jq_util_input_get_current_line(jq);
1585 }
1586
1587 #define LIBM_DD(name) \
1588   {(cfunction_ptr)f_ ## name,  #name, 1},
1589 #define LIBM_DD_NO(name)
1590
1591 #define LIBM_DDD(name) \
1592   {(cfunction_ptr)f_ ## name, #name, 3},
1593 #define LIBM_DDD_NO(name)
1594
1595 #define LIBM_DDDD(name) \
1596   {(cfunction_ptr)f_ ## name, #name, 4},
1597 #define LIBM_DDDD_NO(name)
1598
1599 static const struct cfunction function_list[] = {
1600 #include "libm.h"
1601 #ifdef HAVE_FREXP
1602   {(cfunction_ptr)f_frexp,"frexp", 1},
1603 #endif
1604 #ifdef HAVE_MODF
1605   {(cfunction_ptr)f_modf,"modf", 1},
1606 #endif
1607 #ifdef HAVE_LGAMMA_R
1608   {(cfunction_ptr)f_lgamma_r,"lgamma_r", 1},
1609 #endif
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},
1678 };
1679 #undef LIBM_DDDD_NO
1680 #undef LIBM_DDD_NO
1681 #undef LIBM_DD_NO
1682 #undef LIBM_DDDD
1683 #undef LIBM_DDD
1684 #undef LIBM_DD
1685
1686 struct bytecoded_builtin { const char* name; block code; };
1687 static block bind_bytecoded_builtins(block b) {
1688   block builtins = gen_noop();
1689   {
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()))}
1694     };
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));
1698     }
1699   }
1700   {
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))},
1705     };
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,
1708                                               gen_param("arg"),
1709                                               builtin_def_1arg[i].code));
1710     }
1711   }
1712   {
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()),
1718                         rangestart,
1719                         gen_call("end", gen_noop()),
1720                         gen_op_simple(DUP),
1721                         gen_op_bound(LOADV, rangestart),
1722                         // Reset rangevar for every value generated by "end"
1723                         rangevar,
1724                         gen_op_bound(RANGE, rangevar));
1725     builtins = BLOCK(builtins, gen_function("range",
1726                                             BLOCK(gen_param("start"), gen_param("end")),
1727                                             range));
1728   }
1729   return block_bind(builtins, b, OP_IS_CALL_PSEUDO);
1730 }
1731
1732
1733
1734 static const char* const jq_builtins =
1735 /* Include jq-coded builtins */
1736 #include "src/builtin.inc"
1737
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;"
1745 #include "libm.h"
1746 #ifndef HAVE_FREXP
1747   "def frexp: \"Error: frexp/0 not found found at build time\"|error;"
1748 #endif
1749 #ifndef HAVE_MODF
1750   "def modf: \"Error: modf/0 not found found at build time\"|error;"
1751 #endif
1752 #ifndef HAVE_LGAMMA_R
1753   "def lgamma_r: \"Error: lgamma_r/0 not found found at build time\"|error;"
1754 #endif
1755 ;
1756
1757 #undef LIBM_DDDD_NO
1758 #undef LIBM_DDD_NO
1759 #undef LIBM_DD_NO
1760 #undef LIBM_DDDD
1761 #undef LIBM_DDD
1762 #undef LIBM_DD
1763
1764
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)));
1768 }
1769
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));
1773   block funcs;
1774   int nerrors = jq_parse_library(src, &funcs);
1775   if (nerrors == 0) {
1776     *bb = block_bind(funcs, *bb, OP_IS_CALL_PSEUDO);
1777   }
1778   locfile_free(src);
1779   return nerrors;
1780 }
1781
1782 static int slurp_lib(jq_state *jq, block* bb) {
1783   int nerrors = 0;
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) );
1790     }
1791     jv_free(filename);
1792     jv_free(data);
1793   }
1794   return nerrors;
1795 }
1796
1797 int builtins_bind(jq_state *jq, block* bb) {
1798   block builtins = gen_noop();
1799   int nerrors = slurp_lib(jq, bb);
1800   if (nerrors) {
1801     block_free(*bb);
1802     return nerrors;
1803   }
1804   nerrors = builtins_bind_one(jq, &builtins, jq_builtins);
1805   assert(!nerrors);
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);
1811   return nerrors;
1812 }