@port-labs/jq-node-bindings 0.0.4 → 0.0.6

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 (286) hide show
  1. package/binding.gyp +3 -3
  2. package/configure +8 -6
  3. package/deps/jq/.travis.yml +184 -35
  4. package/deps/jq/AUTHORS +31 -30
  5. package/deps/jq/COPYING +2 -2
  6. package/deps/jq/KEYS +8 -0
  7. package/deps/jq/Makefile.am +85 -70
  8. package/deps/jq/NEWS +5 -4
  9. package/deps/jq/README.md +18 -9
  10. package/deps/jq/appveyor.yml +53 -0
  11. package/deps/jq/compile-ios.sh +5 -5
  12. package/deps/jq/config/m4/check-math-func.m4 +7 -2
  13. package/deps/jq/configure.ac +130 -68
  14. package/deps/jq/docs/Rakefile +14 -135
  15. package/deps/jq/docs/Rakefile.manual +49 -0
  16. package/deps/jq/docs/Rakefile.website +76 -0
  17. package/deps/jq/docs/content/2.download/default.yml +115 -39
  18. package/deps/jq/docs/content/3.manual/manual.yml +641 -231
  19. package/deps/jq/docs/content/3.manual/v1.3/manual.yml +130 -130
  20. package/deps/jq/docs/content/3.manual/v1.4/manual.yml +160 -160
  21. package/deps/jq/docs/content/3.manual/v1.5/manual.yml +2878 -0
  22. package/deps/jq/docs/content/3.manual/v1.6/manual.yml +3287 -0
  23. package/deps/jq/docs/content/index/index.yml +28 -6
  24. package/deps/jq/docs/public/.htaccess +2 -2
  25. package/deps/jq/docs/public/css/base.scss +141 -59
  26. package/deps/jq/docs/public/js/manual-search.js +52 -0
  27. package/deps/jq/docs/site.yml +1 -10
  28. package/deps/jq/docs/templates/default.liquid +10 -10
  29. package/deps/jq/docs/templates/index.liquid +45 -32
  30. package/deps/jq/docs/templates/manual.liquid +67 -90
  31. package/deps/jq/docs/templates/shared/_footer.liquid +10 -5
  32. package/deps/jq/docs/templates/shared/_head.liquid +17 -12
  33. package/deps/jq/docs/templates/shared/_navbar.liquid +27 -0
  34. package/deps/jq/jq.1.prebuilt +523 -139
  35. package/deps/jq/modules/oniguruma/AUTHORS +1 -0
  36. package/deps/jq/modules/oniguruma/CMakeLists.txt +86 -0
  37. package/deps/jq/modules/oniguruma/COPYING +28 -0
  38. package/deps/jq/modules/oniguruma/ChangeLog +0 -0
  39. package/deps/jq/modules/oniguruma/HISTORY +2138 -0
  40. package/deps/jq/modules/oniguruma/Makefile.am +33 -0
  41. package/deps/jq/modules/oniguruma/NEWS +0 -0
  42. package/deps/jq/modules/oniguruma/README +189 -0
  43. package/deps/jq/modules/oniguruma/README.ja +195 -0
  44. package/deps/jq/modules/oniguruma/README.md +203 -0
  45. package/deps/jq/modules/oniguruma/cmake/dist.cmake +321 -0
  46. package/deps/jq/modules/oniguruma/compile +348 -0
  47. package/deps/jq/modules/oniguruma/config.guess +1754 -0
  48. package/deps/jq/modules/oniguruma/config.sub +1890 -0
  49. package/deps/jq/modules/oniguruma/configure.ac +87 -0
  50. package/deps/jq/modules/oniguruma/contributed/libfuzzer-onig.cpp +31 -0
  51. package/deps/jq/modules/oniguruma/depcomp +791 -0
  52. package/deps/jq/modules/oniguruma/dist.info +10 -0
  53. package/deps/jq/modules/oniguruma/doc/API +660 -0
  54. package/deps/jq/modules/oniguruma/doc/API.ja +667 -0
  55. package/deps/jq/modules/oniguruma/doc/FAQ +12 -0
  56. package/deps/jq/modules/oniguruma/doc/FAQ.ja +22 -0
  57. package/deps/jq/modules/oniguruma/doc/RE +436 -0
  58. package/deps/jq/modules/oniguruma/doc/RE.ja +448 -0
  59. package/deps/jq/modules/oniguruma/doc/UNICODE_PROPERTIES +698 -0
  60. package/deps/jq/modules/oniguruma/index.html +181 -0
  61. package/deps/jq/modules/oniguruma/index_ja.html +184 -0
  62. package/deps/jq/modules/oniguruma/install-sh +541 -0
  63. package/deps/jq/modules/oniguruma/m4/.whatever +0 -0
  64. package/deps/jq/modules/oniguruma/make_win32.bat +3 -0
  65. package/deps/jq/modules/oniguruma/make_win64.bat +3 -0
  66. package/deps/jq/modules/oniguruma/missing +215 -0
  67. package/deps/jq/modules/oniguruma/onig-config.in +78 -0
  68. package/deps/jq/modules/oniguruma/oniguruma.pc.cmake.in +13 -0
  69. package/deps/jq/modules/oniguruma/oniguruma.pc.in +14 -0
  70. package/deps/jq/modules/oniguruma/sample/CMakeLists.txt +28 -0
  71. package/deps/jq/modules/oniguruma/sample/Makefile.am +34 -0
  72. package/deps/jq/modules/oniguruma/sample/bug_fix.c +131 -0
  73. package/deps/jq/modules/oniguruma/sample/crnl.c +127 -0
  74. package/deps/jq/modules/oniguruma/sample/encode.c +308 -0
  75. package/deps/jq/modules/oniguruma/sample/listcap.c +110 -0
  76. package/deps/jq/modules/oniguruma/sample/names.c +75 -0
  77. package/deps/jq/modules/oniguruma/sample/posix.c +96 -0
  78. package/deps/jq/modules/oniguruma/sample/scan.c +88 -0
  79. package/deps/jq/modules/oniguruma/sample/simple.c +59 -0
  80. package/deps/jq/modules/oniguruma/sample/sql.c +76 -0
  81. package/deps/jq/modules/oniguruma/sample/syntax.c +76 -0
  82. package/deps/jq/modules/oniguruma/sample/user_property.c +87 -0
  83. package/deps/jq/modules/oniguruma/src/Makefile.am +58 -0
  84. package/deps/jq/modules/oniguruma/src/Makefile.windows +183 -0
  85. package/deps/jq/modules/oniguruma/src/ascii.c +61 -0
  86. package/deps/jq/modules/oniguruma/src/big5.c +190 -0
  87. package/deps/jq/modules/oniguruma/src/config.h.cmake.in +71 -0
  88. package/deps/jq/modules/oniguruma/src/config.h.win32 +84 -0
  89. package/deps/jq/modules/oniguruma/src/config.h.win64 +84 -0
  90. package/deps/jq/modules/oniguruma/src/cp1251.c +203 -0
  91. package/deps/jq/modules/oniguruma/src/euc_jp.c +310 -0
  92. package/deps/jq/modules/oniguruma/src/euc_jp_prop.c +158 -0
  93. package/deps/jq/modules/oniguruma/src/euc_jp_prop.gperf +27 -0
  94. package/deps/jq/modules/oniguruma/src/euc_kr.c +188 -0
  95. package/deps/jq/modules/oniguruma/src/euc_tw.c +171 -0
  96. package/deps/jq/modules/oniguruma/src/gb18030.c +538 -0
  97. package/deps/jq/modules/oniguruma/src/gperf_fold_key_conv.py +67 -0
  98. package/deps/jq/modules/oniguruma/src/gperf_unfold_key_conv.py +55 -0
  99. package/deps/jq/modules/oniguruma/src/iso8859_1.c +275 -0
  100. package/deps/jq/modules/oniguruma/src/iso8859_10.c +242 -0
  101. package/deps/jq/modules/oniguruma/src/iso8859_11.c +99 -0
  102. package/deps/jq/modules/oniguruma/src/iso8859_13.c +231 -0
  103. package/deps/jq/modules/oniguruma/src/iso8859_14.c +244 -0
  104. package/deps/jq/modules/oniguruma/src/iso8859_15.c +238 -0
  105. package/deps/jq/modules/oniguruma/src/iso8859_16.c +240 -0
  106. package/deps/jq/modules/oniguruma/src/iso8859_2.c +238 -0
  107. package/deps/jq/modules/oniguruma/src/iso8859_3.c +238 -0
  108. package/deps/jq/modules/oniguruma/src/iso8859_4.c +240 -0
  109. package/deps/jq/modules/oniguruma/src/iso8859_5.c +229 -0
  110. package/deps/jq/modules/oniguruma/src/iso8859_6.c +99 -0
  111. package/deps/jq/modules/oniguruma/src/iso8859_7.c +225 -0
  112. package/deps/jq/modules/oniguruma/src/iso8859_8.c +99 -0
  113. package/deps/jq/modules/oniguruma/src/iso8859_9.c +231 -0
  114. package/deps/jq/modules/oniguruma/src/koi8.c +253 -0
  115. package/deps/jq/modules/oniguruma/src/koi8_r.c +215 -0
  116. package/deps/jq/modules/oniguruma/src/make_unicode_fold.sh +22 -0
  117. package/deps/jq/modules/oniguruma/src/make_unicode_fold_data.py +306 -0
  118. package/deps/jq/modules/oniguruma/src/make_unicode_property.sh +18 -0
  119. package/deps/jq/modules/oniguruma/src/make_unicode_property_data.py +545 -0
  120. package/deps/jq/modules/oniguruma/src/mktable.c +1184 -0
  121. package/deps/jq/modules/oniguruma/src/onig_init.c +45 -0
  122. package/deps/jq/modules/oniguruma/src/oniggnu.h +85 -0
  123. package/deps/jq/modules/oniguruma/src/onigposix.h +169 -0
  124. package/deps/jq/modules/oniguruma/src/oniguruma.h +841 -0
  125. package/deps/jq/modules/oniguruma/src/regcomp.c +6300 -0
  126. package/deps/jq/modules/oniguruma/src/regenc.c +917 -0
  127. package/deps/jq/modules/oniguruma/src/regenc.h +243 -0
  128. package/deps/jq/modules/oniguruma/src/regerror.c +393 -0
  129. package/deps/jq/modules/oniguruma/src/regexec.c +3856 -0
  130. package/deps/jq/modules/oniguruma/src/regext.c +202 -0
  131. package/deps/jq/modules/oniguruma/src/reggnu.c +147 -0
  132. package/deps/jq/modules/oniguruma/src/regint.h +779 -0
  133. package/deps/jq/modules/oniguruma/src/regparse.c +5403 -0
  134. package/deps/jq/modules/oniguruma/src/regparse.h +351 -0
  135. package/deps/jq/modules/oniguruma/src/regposerr.c +105 -0
  136. package/deps/jq/modules/oniguruma/src/regposix.c +306 -0
  137. package/deps/jq/modules/oniguruma/src/regsyntax.c +315 -0
  138. package/deps/jq/modules/oniguruma/src/regtrav.c +76 -0
  139. package/deps/jq/modules/oniguruma/src/regversion.c +57 -0
  140. package/deps/jq/modules/oniguruma/src/sjis.c +341 -0
  141. package/deps/jq/modules/oniguruma/src/sjis_prop.c +158 -0
  142. package/deps/jq/modules/oniguruma/src/sjis_prop.gperf +27 -0
  143. package/deps/jq/modules/oniguruma/src/st.c +589 -0
  144. package/deps/jq/modules/oniguruma/src/st.h +68 -0
  145. package/deps/jq/modules/oniguruma/src/unicode-7.0/unicode_fold1_key.c +2250 -0
  146. package/deps/jq/modules/oniguruma/src/unicode-7.0/unicode_fold2_key.c +203 -0
  147. package/deps/jq/modules/oniguruma/src/unicode-7.0/unicode_fold3_key.c +113 -0
  148. package/deps/jq/modules/oniguruma/src/unicode-7.0/unicode_fold_data.c +1225 -0
  149. package/deps/jq/modules/oniguruma/src/unicode-7.0/unicode_property_data.c +24742 -0
  150. package/deps/jq/modules/oniguruma/src/unicode-7.0/unicode_property_data_posix.c +4846 -0
  151. package/deps/jq/modules/oniguruma/src/unicode-7.0/unicode_unfold_key.c +2571 -0
  152. package/deps/jq/modules/oniguruma/src/unicode.c +664 -0
  153. package/deps/jq/modules/oniguruma/src/unicode_fold1_key.c +2548 -0
  154. package/deps/jq/modules/oniguruma/src/unicode_fold2_key.c +203 -0
  155. package/deps/jq/modules/oniguruma/src/unicode_fold3_key.c +113 -0
  156. package/deps/jq/modules/oniguruma/src/unicode_fold_data.c +1366 -0
  157. package/deps/jq/modules/oniguruma/src/unicode_property_data.c +25306 -0
  158. package/deps/jq/modules/oniguruma/src/unicode_property_data_posix.c +4940 -0
  159. package/deps/jq/modules/oniguruma/src/unicode_unfold_key.c +2854 -0
  160. package/deps/jq/modules/oniguruma/src/utf16_be.c +235 -0
  161. package/deps/jq/modules/oniguruma/src/utf16_le.c +245 -0
  162. package/deps/jq/modules/oniguruma/src/utf32_be.c +194 -0
  163. package/deps/jq/modules/oniguruma/src/utf32_le.c +194 -0
  164. package/deps/jq/modules/oniguruma/src/utf8.c +335 -0
  165. package/deps/jq/modules/oniguruma/test/Makefile.am +28 -0
  166. package/deps/jq/modules/oniguruma/test/testc.c +874 -0
  167. package/deps/jq/modules/oniguruma/test/testu.c +916 -0
  168. package/deps/jq/modules/oniguruma/test-driver +153 -0
  169. package/deps/jq/modules/oniguruma/windows/testc.c +869 -0
  170. package/deps/jq/scripts/crosscompile +2 -1
  171. package/deps/jq/scripts/gen_utf8_tables.py +2 -3
  172. package/deps/jq/scripts/update-website +29 -0
  173. package/deps/jq/scripts/version +7 -2
  174. package/deps/jq/sig/jq-release.key +41 -0
  175. package/deps/jq/sig/v1.3/jq-linux-x86.asc +17 -0
  176. package/deps/jq/sig/v1.3/jq-linux-x86_64.asc +17 -0
  177. package/deps/jq/sig/v1.3/jq-osx-x86.asc +17 -0
  178. package/deps/jq/sig/v1.3/jq-osx-x86_64.asc +17 -0
  179. package/deps/jq/sig/v1.3/jq-win32.exe.asc +17 -0
  180. package/deps/jq/sig/v1.3/jq-win64.exe.asc +17 -0
  181. package/deps/jq/sig/v1.3/sha256sum.txt +6 -0
  182. package/deps/jq/sig/v1.4/jq-linux-x86.asc +17 -0
  183. package/deps/jq/sig/v1.4/jq-linux-x86_64.asc +17 -0
  184. package/deps/jq/sig/v1.4/jq-osx-x86.asc +17 -0
  185. package/deps/jq/sig/v1.4/jq-osx-x86_64.asc +17 -0
  186. package/deps/jq/sig/v1.4/jq-solaris11-32.asc +17 -0
  187. package/deps/jq/sig/v1.4/jq-solaris11-64.asc +17 -0
  188. package/deps/jq/sig/v1.4/jq-win32.exe.asc +17 -0
  189. package/deps/jq/sig/v1.4/jq-win64.exe.asc +17 -0
  190. package/deps/jq/sig/v1.4/sha256sum.txt +8 -0
  191. package/deps/jq/sig/v1.5/jq-linux32-no-oniguruma.asc +17 -0
  192. package/deps/jq/sig/v1.5/jq-linux32.asc +17 -0
  193. package/deps/jq/sig/v1.5/jq-linux64.asc +17 -0
  194. package/deps/jq/sig/v1.5/jq-osx-amd64.asc +17 -0
  195. package/deps/jq/sig/v1.5/jq-win32.exe.asc +17 -0
  196. package/deps/jq/sig/v1.5/jq-win64.exe.asc +17 -0
  197. package/deps/jq/sig/v1.5/sha256sum.txt +5 -0
  198. package/deps/jq/sig/v1.5rc1/jq-linux-x86_64-static.asc +17 -0
  199. package/deps/jq/sig/v1.5rc1/jq-win32.exe.asc +17 -0
  200. package/deps/jq/sig/v1.5rc1/jq-win64.exe.asc +17 -0
  201. package/deps/jq/sig/v1.5rc1/sha256sum.txt +3 -0
  202. package/deps/jq/sig/v1.5rc2/jq-linux-x86.asc +17 -0
  203. package/deps/jq/sig/v1.5rc2/jq-linux-x86_64.asc +17 -0
  204. package/deps/jq/sig/v1.5rc2/jq-osx-x86_64.asc +17 -0
  205. package/deps/jq/sig/v1.5rc2/jq-win32.exe.asc +17 -0
  206. package/deps/jq/sig/v1.5rc2/jq-win64.exe.asc +17 -0
  207. package/deps/jq/sig/v1.5rc2/sha256sum.txt +5 -0
  208. package/deps/jq/sig/v1.6/jq-linux32.asc +16 -0
  209. package/deps/jq/sig/v1.6/jq-linux64.asc +16 -0
  210. package/deps/jq/sig/v1.6/jq-osx-amd64.asc +16 -0
  211. package/deps/jq/sig/v1.6/jq-win32.exe.asc +16 -0
  212. package/deps/jq/sig/v1.6/jq-win64.exe.asc +16 -0
  213. package/deps/jq/sig/v1.6/sha256sum.txt +5 -0
  214. package/deps/jq/{builtin.c → src/builtin.c} +449 -344
  215. package/deps/jq/{builtin.h → src/builtin.h} +0 -0
  216. package/deps/jq/src/builtin.jq +311 -0
  217. package/deps/jq/{bytecode.c → src/bytecode.c} +0 -0
  218. package/deps/jq/{bytecode.h → src/bytecode.h} +0 -0
  219. package/deps/jq/{compile.c → src/compile.c} +213 -37
  220. package/deps/jq/{compile.h → src/compile.h} +7 -2
  221. package/deps/jq/{exec_stack.h → src/exec_stack.h} +0 -0
  222. package/deps/jq/{execute.c → src/execute.c} +127 -24
  223. package/deps/jq/{inject_errors.c → src/inject_errors.c} +0 -0
  224. package/deps/jq/{jq.h → src/jq.h} +13 -2
  225. package/deps/jq/{jq_parser.h → src/jq_parser.h} +0 -0
  226. package/deps/jq/{jq_test.c → src/jq_test.c} +1 -1
  227. package/deps/jq/{jv.c → src/jv.c} +24 -5
  228. package/deps/jq/{jv.h → src/jv.h} +46 -11
  229. package/deps/jq/{jv_alloc.c → src/jv_alloc.c} +0 -0
  230. package/deps/jq/{jv_alloc.h → src/jv_alloc.h} +0 -0
  231. package/deps/jq/{jv_aux.c → src/jv_aux.c} +38 -14
  232. package/deps/jq/{jv_dtoa.c → src/jv_dtoa.c} +4 -5
  233. package/deps/jq/{jv_dtoa.h → src/jv_dtoa.h} +0 -0
  234. package/deps/jq/src/jv_file.c +81 -0
  235. package/deps/jq/{jv_parse.c → src/jv_parse.c} +8 -2
  236. package/deps/jq/{jv_print.c → src/jv_print.c} +80 -27
  237. package/deps/jq/{jv_unicode.c → src/jv_unicode.c} +28 -4
  238. package/deps/jq/{jv_unicode.h → src/jv_unicode.h} +1 -0
  239. package/deps/jq/{jv_utf8_tables.h → src/jv_utf8_tables.h} +0 -0
  240. package/deps/jq/{lexer.c → src/lexer.c} +317 -292
  241. package/deps/jq/{lexer.h → src/lexer.h} +16 -12
  242. package/deps/jq/{lexer.l → src/lexer.l} +5 -4
  243. package/deps/jq/src/libm.h +291 -0
  244. package/deps/jq/{linker.c → src/linker.c} +5 -3
  245. package/deps/jq/{linker.h → src/linker.h} +0 -0
  246. package/deps/jq/{locfile.c → src/locfile.c} +1 -1
  247. package/deps/jq/{locfile.h → src/locfile.h} +0 -0
  248. package/deps/jq/{main.c → src/main.c} +202 -100
  249. package/deps/jq/{opcode_list.h → src/opcode_list.h} +4 -0
  250. package/deps/jq/{parser.c → src/parser.c} +1149 -1069
  251. package/deps/jq/{parser.h → src/parser.h} +28 -24
  252. package/deps/jq/{parser.y → src/parser.y} +108 -52
  253. package/deps/jq/{util.c → src/util.c} +12 -9
  254. package/deps/jq/{util.h → src/util.h} +0 -0
  255. package/deps/jq/tests/base64.test +35 -0
  256. package/deps/jq/tests/base64test +5 -0
  257. package/deps/jq/tests/jq-f-test.sh +4 -0
  258. package/deps/jq/tests/jq.test +305 -21
  259. package/deps/jq/tests/jqtest +1 -1
  260. package/deps/jq/tests/mantest +1 -1
  261. package/deps/jq/tests/onig.test +13 -0
  262. package/deps/jq/tests/onigtest +1 -1
  263. package/deps/jq/tests/optional.test +20 -0
  264. package/deps/jq/tests/optionaltest +5 -0
  265. package/deps/jq/tests/setup +7 -1
  266. package/deps/jq/tests/shtest +133 -29
  267. package/deps/jq/tests/utf8-truncate.jq +3 -0
  268. package/deps/jq/tests/utf8test +10 -0
  269. package/lib/index.js +7 -1
  270. package/package.json +3 -3
  271. package/test/santiy.test.js +24 -0
  272. package/deps/jq/docs/default_manpage.md +0 -22
  273. package/deps/jq/docs/public/bootstrap/css/bootstrap-responsive.css +0 -1058
  274. package/deps/jq/docs/public/bootstrap/css/bootstrap-responsive.min.css +0 -9
  275. package/deps/jq/docs/public/bootstrap/css/bootstrap.css +0 -5224
  276. package/deps/jq/docs/public/bootstrap/css/bootstrap.min.css +0 -9
  277. package/deps/jq/docs/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
  278. package/deps/jq/docs/public/bootstrap/img/glyphicons-halflings.png +0 -0
  279. package/deps/jq/docs/public/bootstrap/js/bootstrap.js +0 -2027
  280. package/deps/jq/docs/public/bootstrap/js/bootstrap.min.js +0 -6
  281. package/deps/jq/docs/templates/shared/_header.liquid +0 -26
  282. package/deps/jq/jq.1.default +0 -39
  283. package/deps/jq/jv_file.c +0 -49
  284. package/deps/jq/libm.h +0 -160
  285. package/deps/jq/setup.sh +0 -33
  286. package/reports/jest-port-api.xml +0 -35
@@ -1,6 +1,12 @@
1
1
  #define _BSD_SOURCE
2
2
  #define _GNU_SOURCE
3
- #define _XOPEN_SOURCE
3
+ #ifndef __sun__
4
+ # define _XOPEN_SOURCE
5
+ # define _XOPEN_SOURCE_EXTENDED 1
6
+ #else
7
+ # define _XPG6
8
+ # define __EXTENSIONS__
9
+ #endif
4
10
  #include <sys/time.h>
5
11
  #include <stdlib.h>
6
12
  #include <stddef.h>
@@ -23,7 +29,7 @@ void *alloca (size_t);
23
29
  #include <ctype.h>
24
30
  #include <limits.h>
25
31
  #include <math.h>
26
- #ifdef HAVE_ONIGURUMA
32
+ #ifdef HAVE_LIBONIG
27
33
  #include <oniguruma.h>
28
34
  #endif
29
35
  #include <string.h>
@@ -35,6 +41,7 @@ void *alloca (size_t);
35
41
  #include "linker.h"
36
42
  #include "locfile.h"
37
43
  #include "jv_unicode.h"
44
+ #include "jv_alloc.h"
38
45
 
39
46
 
40
47
  static jv type_error(jv bad, const char* msg) {
@@ -60,6 +67,17 @@ static jv type_error2(jv bad1, jv bad2, const char* msg) {
60
67
  return err;
61
68
  }
62
69
 
70
+ static inline jv ret_error(jv bad, jv msg) {
71
+ jv_free(bad);
72
+ return jv_invalid_with_msg(msg);
73
+ }
74
+
75
+ static inline jv ret_error2(jv bad1, jv bad2, jv msg) {
76
+ jv_free(bad1);
77
+ jv_free(bad2);
78
+ return jv_invalid_with_msg(msg);
79
+ }
80
+
63
81
  static jv f_plus(jq_state *jq, jv input, jv a, jv b) {
64
82
  jv_free(input);
65
83
  if (jv_get_kind(a) == JV_KIND_NULL) {
@@ -95,21 +113,90 @@ static jv f_ ## name(jq_state *jq, jv input) { \
95
113
 
96
114
  #define LIBM_DDD(name) \
97
115
  static jv f_ ## name(jq_state *jq, jv input, jv a, jv b) { \
98
- if (jv_get_kind(a) != JV_KIND_NUMBER || jv_get_kind(b) != JV_KIND_NUMBER) \
99
- return type_error(input, "number required"); \
100
116
  jv_free(input); \
117
+ if (jv_get_kind(a) != JV_KIND_NUMBER) { \
118
+ jv_free(b); \
119
+ return type_error(a, "number required"); \
120
+ } \
121
+ if (jv_get_kind(b) != JV_KIND_NUMBER) { \
122
+ jv_free(a); \
123
+ return type_error(b, "number required"); \
124
+ } \
101
125
  jv ret = jv_number(name(jv_number_value(a), jv_number_value(b))); \
102
126
  jv_free(a); \
103
127
  jv_free(b); \
104
128
  return ret; \
105
129
  }
106
130
  #define LIBM_DDD_NO(name)
131
+
132
+ #define LIBM_DDDD(name) \
133
+ static jv f_ ## name(jq_state *jq, jv input, jv a, jv b, jv c) { \
134
+ jv_free(input); \
135
+ if (jv_get_kind(a) != JV_KIND_NUMBER) { \
136
+ jv_free(b); \
137
+ jv_free(c); \
138
+ return type_error(a, "number required"); \
139
+ } \
140
+ if (jv_get_kind(b) != JV_KIND_NUMBER) { \
141
+ jv_free(a); \
142
+ jv_free(c); \
143
+ return type_error(b, "number required"); \
144
+ } \
145
+ if (jv_get_kind(c) != JV_KIND_NUMBER) { \
146
+ jv_free(a); \
147
+ jv_free(b); \
148
+ return type_error(c, "number required"); \
149
+ } \
150
+ jv ret = jv_number(name(jv_number_value(a), jv_number_value(b), jv_number_value(c))); \
151
+ jv_free(a); \
152
+ jv_free(b); \
153
+ jv_free(c); \
154
+ return ret; \
155
+ }
156
+ #define LIBM_DDDD_NO(name)
107
157
  #include "libm.h"
158
+ #undef LIBM_DDDD_NO
108
159
  #undef LIBM_DDD_NO
109
160
  #undef LIBM_DD_NO
161
+ #undef LIBM_DDDD
110
162
  #undef LIBM_DDD
111
163
  #undef LIBM_DD
112
164
 
165
+ #ifdef HAVE_FREXP
166
+ static jv f_frexp(jq_state *jq, jv input) {
167
+ if (jv_get_kind(input) != JV_KIND_NUMBER) {
168
+ return type_error(input, "number required");
169
+ }
170
+ int exp;
171
+ double d = frexp(jv_number_value(input), &exp);
172
+ jv ret = JV_ARRAY(jv_number(d), jv_number(exp));
173
+ jv_free(input);
174
+ return ret;
175
+ }
176
+ #endif
177
+ #ifdef HAVE_MODF
178
+ static jv f_modf(jq_state *jq, jv input) {
179
+ if (jv_get_kind(input) != JV_KIND_NUMBER) {
180
+ return type_error(input, "number required");
181
+ }
182
+ double i;
183
+ jv ret = JV_ARRAY(jv_number(modf(jv_number_value(input), &i)));
184
+ jv_free(input);
185
+ return jv_array_append(ret, jv_number(i));
186
+ }
187
+ #endif
188
+ #ifdef HAVE_LGAMMA_R
189
+ static jv f_lgamma_r(jq_state *jq, jv input) {
190
+ if (jv_get_kind(input) != JV_KIND_NUMBER) {
191
+ return type_error(input, "number required");
192
+ }
193
+ int sign;
194
+ jv ret = JV_ARRAY(jv_number(lgamma_r(jv_number_value(input), &sign)));
195
+ jv_free(input);
196
+ return jv_array_append(ret, jv_number(sign));
197
+ }
198
+ #endif
199
+
113
200
  static jv f_negate(jq_state *jq, jv input) {
114
201
  if (jv_get_kind(input) != JV_KIND_NUMBER) {
115
202
  return type_error(input, "cannot be negated");
@@ -121,7 +208,7 @@ static jv f_negate(jq_state *jq, jv input) {
121
208
 
122
209
  static jv f_startswith(jq_state *jq, jv a, jv b) {
123
210
  if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING)
124
- return jv_invalid_with_msg(jv_string("startswith() requires string inputs"));
211
+ return ret_error2(a, b, jv_string("startswith() requires string inputs"));
125
212
  int alen = jv_string_length_bytes(jv_copy(a));
126
213
  int blen = jv_string_length_bytes(jv_copy(b));
127
214
  jv ret;
@@ -137,7 +224,7 @@ static jv f_startswith(jq_state *jq, jv a, jv b) {
137
224
 
138
225
  static jv f_endswith(jq_state *jq, jv a, jv b) {
139
226
  if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING)
140
- return jv_invalid_with_msg(jv_string("endswith() requires string inputs"));
227
+ return ret_error2(a, b, jv_string("endswith() requires string inputs"));
141
228
  const char *astr = jv_string_value(a);
142
229
  const char *bstr = jv_string_value(b);
143
230
  size_t alen = jv_string_length_bytes(jv_copy(a));
@@ -367,8 +454,32 @@ static jv f_tostring(jq_state *jq, jv input) {
367
454
  }
368
455
  }
369
456
 
457
+ static jv f_utf8bytelength(jq_state *jq, jv input) {
458
+ if (jv_get_kind(input) != JV_KIND_STRING)
459
+ return type_error(input, "only strings have UTF-8 byte length");
460
+ return jv_number(jv_string_length_bytes(input));
461
+ }
462
+
370
463
  #define CHARS_ALPHANUM "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
371
464
 
465
+ static const unsigned char BASE64_ENCODE_TABLE[64 + 1] = CHARS_ALPHANUM "+/";
466
+ static const unsigned char BASE64_INVALID_ENTRY = 0xFF;
467
+ static const unsigned char BASE64_DECODE_TABLE[255] = {
468
+ 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,
469
+ 62, // +
470
+ 0xFF, 0xFF, 0xFF,
471
+ 63, // /
472
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // 0-9
473
+ 0xFF, 0xFF, 0xFF,
474
+ 99, // =
475
+ 0xFF, 0xFF, 0xFF,
476
+ 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
477
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
478
+ 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
479
+ 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
480
+ };
481
+
482
+
372
483
  static jv escape_string(jv input, const char* escapings) {
373
484
 
374
485
  assert(jv_get_kind(input) == JV_KIND_STRING);
@@ -521,7 +632,6 @@ static jv f_format(jq_state *jq, jv input, jv fmt) {
521
632
  jv_free(fmt);
522
633
  input = f_tostring(jq, input);
523
634
  jv line = jv_string("");
524
- const char b64[64 + 1] = CHARS_ALPHANUM "+/";
525
635
  const unsigned char* data = (const unsigned char*)jv_string_value(input);
526
636
  int len = jv_string_length_bytes(jv_copy(input));
527
637
  for (int i=0; i<len; i+=3) {
@@ -533,7 +643,7 @@ static jv f_format(jq_state *jq, jv input, jv fmt) {
533
643
  }
534
644
  char buf[4];
535
645
  for (int j=0; j<4; j++) {
536
- buf[j] = b64[(code >> (18 - j*6)) & 0x3f];
646
+ buf[j] = BASE64_ENCODE_TABLE[(code >> (18 - j*6)) & 0x3f];
537
647
  }
538
648
  if (n < 3) buf[3] = '=';
539
649
  if (n < 2) buf[2] = '=';
@@ -541,6 +651,49 @@ static jv f_format(jq_state *jq, jv input, jv fmt) {
541
651
  }
542
652
  jv_free(input);
543
653
  return line;
654
+ } else if (!strcmp(fmt_s, "base64d")) {
655
+ jv_free(fmt);
656
+ input = f_tostring(jq, input);
657
+ const unsigned char* data = (const unsigned char*)jv_string_value(input);
658
+ int len = jv_string_length_bytes(jv_copy(input));
659
+ size_t decoded_len = (3 * len) / 4; // 3 usable bytes for every 4 bytes of input
660
+ char *result = jv_mem_calloc(decoded_len, sizeof(char));
661
+ memset(result, 0, decoded_len * sizeof(char));
662
+ uint32_t ri = 0;
663
+ int input_bytes_read=0;
664
+ uint32_t code = 0;
665
+ for (int i=0; i<len && data[i] != '='; i++) {
666
+ if (BASE64_DECODE_TABLE[data[i]] == BASE64_INVALID_ENTRY) {
667
+ free(result);
668
+ return type_error(input, "is not valid base64 data");
669
+ }
670
+
671
+ code <<= 6;
672
+ code |= BASE64_DECODE_TABLE[data[i]];
673
+ input_bytes_read++;
674
+
675
+ if (input_bytes_read == 4) {
676
+ result[ri++] = (code >> 16) & 0xFF;
677
+ result[ri++] = (code >> 8) & 0xFF;
678
+ result[ri++] = code & 0xFF;
679
+ input_bytes_read = 0;
680
+ code = 0;
681
+ }
682
+ }
683
+ if (input_bytes_read == 3) {
684
+ result[ri++] = (code >> 10) & 0xFF;
685
+ result[ri++] = (code >> 2) & 0xFF;
686
+ } else if (input_bytes_read == 2) {
687
+ result[ri++] = (code >> 4) & 0xFF;
688
+ } else if (input_bytes_read == 1) {
689
+ free(result);
690
+ return type_error(input, "trailing base64 byte found");
691
+ }
692
+
693
+ jv line = jv_string_sized(result, ri);
694
+ jv_free(input);
695
+ free(result);
696
+ return line;
544
697
  } else {
545
698
  jv_free(input);
546
699
  return jv_invalid_with_msg(jv_string_concat(fmt, jv_string(" is not a valid format")));
@@ -591,7 +744,7 @@ static jv f_group_by_impl(jq_state *jq, jv input, jv keys) {
591
744
  }
592
745
  }
593
746
 
594
- #ifdef HAVE_ONIGURUMA
747
+ #ifdef HAVE_LIBONIG
595
748
  static int f_match_name_iter(const UChar* name, const UChar *name_end, int ngroups,
596
749
  int *groups, regex_t *reg, void *arg) {
597
750
  jv captures = *(jv*)arg;
@@ -795,11 +948,11 @@ static jv f_match(jq_state *jq, jv input, jv regex, jv modifiers, jv testmode) {
795
948
  jv_free(regex);
796
949
  return result;
797
950
  }
798
- #else /* ! HAVE_ONIGURUMA */
951
+ #else /* !HAVE_LIBONIG */
799
952
  static jv f_match(jq_state *jq, jv input, jv regex, jv modifiers, jv testmode) {
800
953
  return jv_invalid_with_msg(jv_string("jq was compiled without ONIGURUMA regex libary. match/test/sub and related functions are not available."));
801
954
  }
802
- #endif /* HAVE_ONIGURUMA */
955
+ #endif /* HAVE_LIBONIG */
803
956
 
804
957
  static jv minmax_by(jv values, jv keys, int is_min) {
805
958
  if (jv_get_kind(values) != JV_KIND_ARRAY)
@@ -907,14 +1060,14 @@ static jv f_error(jq_state *jq, jv input, jv msg) {
907
1060
 
908
1061
  // FIXME Should autoconf check for this!
909
1062
  #ifndef WIN32
910
- extern const char **environ;
1063
+ extern char **environ;
911
1064
  #endif
912
1065
 
913
1066
  static jv f_env(jq_state *jq, jv input) {
914
1067
  jv_free(input);
915
1068
  jv env = jv_object();
916
1069
  const char *var, *val;
917
- for (const char **e = environ; *e != NULL; e++) {
1070
+ for (char **e = environ; *e != NULL; e++) {
918
1071
  var = e[0];
919
1072
  val = strchr(e[0], '=');
920
1073
  if (val == NULL)
@@ -925,6 +1078,21 @@ static jv f_env(jq_state *jq, jv input) {
925
1078
  return env;
926
1079
  }
927
1080
 
1081
+ static jv f_halt(jq_state *jq, jv input) {
1082
+ jv_free(input);
1083
+ jq_halt(jq, jv_invalid(), jv_invalid());
1084
+ return jv_true();
1085
+ }
1086
+
1087
+ static jv f_halt_error(jq_state *jq, jv input, jv a) {
1088
+ if (jv_get_kind(a) != JV_KIND_NUMBER) {
1089
+ jv_free(a);
1090
+ return type_error(input, "halt_error/1: number required");
1091
+ }
1092
+ jq_halt(jq, a, input);
1093
+ return jv_true();
1094
+ }
1095
+
928
1096
  static jv f_get_search_list(jq_state *jq, jv input) {
929
1097
  jv_free(input);
930
1098
  return jq_get_lib_dirs(jq);
@@ -942,17 +1110,14 @@ static jv f_get_jq_origin(jq_state *jq, jv input) {
942
1110
 
943
1111
  static jv f_string_split(jq_state *jq, jv a, jv b) {
944
1112
  if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING) {
945
- jv_free(a);
946
- jv_free(b);
947
- return jv_invalid_with_msg(jv_string("split input and separator must be strings"));
1113
+ return ret_error2(a, b, jv_string("split input and separator must be strings"));
948
1114
  }
949
1115
  return jv_string_split(a, b);
950
1116
  }
951
1117
 
952
1118
  static jv f_string_explode(jq_state *jq, jv a) {
953
1119
  if (jv_get_kind(a) != JV_KIND_STRING) {
954
- jv_free(a);
955
- return jv_invalid_with_msg(jv_string("explode input must be a string"));
1120
+ return ret_error(a, jv_string("explode input must be a string"));
956
1121
  }
957
1122
  return jv_string_explode(a);
958
1123
  }
@@ -963,21 +1128,22 @@ static jv f_string_indexes(jq_state *jq, jv a, jv b) {
963
1128
 
964
1129
  static jv f_string_implode(jq_state *jq, jv a) {
965
1130
  if (jv_get_kind(a) != JV_KIND_ARRAY) {
966
- jv_free(a);
967
- return jv_invalid_with_msg(jv_string("implode input must be an array"));
1131
+ return ret_error(a, jv_string("implode input must be an array"));
968
1132
  }
969
1133
  return jv_string_implode(a);
970
1134
  }
971
1135
 
972
1136
  static jv f_setpath(jq_state *jq, jv a, jv b, jv c) { return jv_setpath(a, b, c); }
973
- static jv f_getpath(jq_state *jq, jv a, jv b) { return jv_getpath(a, b); }
1137
+ extern jv _jq_path_append(jq_state *, jv, jv, jv);
1138
+ static jv f_getpath(jq_state *jq, jv a, jv b) {
1139
+ return _jq_path_append(jq, a, b, jv_getpath(jv_copy(a), jv_copy(b)));
1140
+ }
974
1141
  static jv f_delpaths(jq_state *jq, jv a, jv b) { return jv_delpaths(a, b); }
975
1142
  static jv f_has(jq_state *jq, jv a, jv b) { return jv_has(a, b); }
976
1143
 
977
1144
  static jv f_modulemeta(jq_state *jq, jv a) {
978
1145
  if (jv_get_kind(a) != JV_KIND_STRING) {
979
- jv_free(a);
980
- return jv_invalid_with_msg(jv_string("modulemeta input module name must be a string"));
1146
+ return ret_error(a, jv_string("modulemeta input module name must be a string"));
981
1147
  }
982
1148
  return load_module_meta(jq, a);
983
1149
  }
@@ -1006,7 +1172,6 @@ static jv f_debug(jq_state *jq, jv input) {
1006
1172
 
1007
1173
  static jv f_stderr(jq_state *jq, jv input) {
1008
1174
  jv_dumpf(jv_copy(input), stderr, 0);
1009
- fprintf(stderr, "\n");
1010
1175
  return input;
1011
1176
  }
1012
1177
 
@@ -1036,45 +1201,135 @@ static jv tm2jv(struct tm *tm) {
1036
1201
  *
1037
1202
  * Returns (time_t)-2 if mktime()'s side-effects cannot be corrected.
1038
1203
  */
1039
- static time_t my_mktime(struct tm *tm) {
1204
+ static time_t my_timegm(struct tm *tm) {
1040
1205
  #ifdef HAVE_TIMEGM
1041
1206
  return timegm(tm);
1042
1207
  #else /* HAVE_TIMEGM */
1208
+ char *tz;
1209
+
1210
+ tz = (tz = getenv("TZ")) != NULL ? strdup(tz) : NULL;
1211
+ if (tz != NULL)
1212
+ setenv("TZ", "", 1);
1213
+ time_t t = mktime(tm);
1214
+ if (tz != NULL)
1215
+ setenv("TZ", tz, 1);
1216
+ return t;
1217
+ #endif /* !HAVE_TIMEGM */
1218
+ }
1219
+ static time_t my_mktime(struct tm *tm) {
1043
1220
  time_t t = mktime(tm);
1044
1221
  if (t == (time_t)-1)
1045
1222
  return t;
1046
1223
  #ifdef HAVE_TM_TM_GMT_OFF
1047
- return t + tm.tm_gmtoff;
1048
- #elif defined(HAVE_TM_TM_GMT_OFF)
1049
- return t + tm.__tm_gmtoff;
1224
+ return t + tm->tm_gmtoff;
1225
+ #elif HAVE_TM___TM_GMT_OFF
1226
+ return t + tm->__tm_gmtoff;
1050
1227
  #else
1051
1228
  return (time_t)-2; /* Not supported */
1052
1229
  #endif
1053
- #endif /* !HAVE_TIMEGM */
1230
+ }
1231
+
1232
+ /* Compute and set tm_wday */
1233
+ static void set_tm_wday(struct tm *tm) {
1234
+ /*
1235
+ * https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Gauss.27s_algorithm
1236
+ * https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html
1237
+ *
1238
+ * Tested with dates from 1900-01-01 through 2100-01-01. This
1239
+ * algorithm produces the wrong day-of-the-week number for dates in
1240
+ * the range 1900-01-01..1900-02-28, and for 2100-01-01..2100-02-28.
1241
+ * Since this is only needed on OS X and *BSD, we might just document
1242
+ * this.
1243
+ */
1244
+ int century = (1900 + tm->tm_year) / 100;
1245
+ int year = (1900 + tm->tm_year) % 100;
1246
+ if (tm->tm_mon < 2)
1247
+ year--;
1248
+ /*
1249
+ * The month value in the wday computation below is shifted so that
1250
+ * March is 1, April is 2, .., January is 11, and February is 12.
1251
+ */
1252
+ int mon = tm->tm_mon - 1;
1253
+ if (mon < 1)
1254
+ mon += 12;
1255
+ int wday =
1256
+ (tm->tm_mday + (int)floor((2.6 * mon - 0.2)) + year + (int)floor(year / 4.0) + (int)floor(century / 4.0) - 2 * century) % 7;
1257
+ if (wday < 0)
1258
+ wday += 7;
1259
+ #if 0
1260
+ /* See commentary above */
1261
+ assert(wday == tm->tm_wday || tm->tm_wday == 8);
1262
+ #endif
1263
+ tm->tm_wday = wday;
1264
+ }
1265
+ /*
1266
+ * Compute and set tm_yday.
1267
+ *
1268
+ */
1269
+ static void set_tm_yday(struct tm *tm) {
1270
+ static const int d[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
1271
+ int mon = tm->tm_mon;
1272
+ int year = 1900 + tm->tm_year;
1273
+ int leap_day = 0;
1274
+ if (tm->tm_mon > 1 &&
1275
+ ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
1276
+ leap_day = 1;
1277
+
1278
+ /* Bound check index into d[] */
1279
+ if (mon < 0)
1280
+ mon = -mon;
1281
+ if (mon > 11)
1282
+ mon %= 12;
1283
+
1284
+ int yday = d[mon] + leap_day + tm->tm_mday - 1;
1285
+ assert(yday == tm->tm_yday || tm->tm_yday == 367);
1286
+ tm->tm_yday = yday;
1054
1287
  }
1055
1288
 
1056
1289
  #ifdef HAVE_STRPTIME
1057
1290
  static jv f_strptime(jq_state *jq, jv a, jv b) {
1058
- if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING)
1059
- return jv_invalid_with_msg(jv_string("strptime/1 requires string inputs and arguments"));
1291
+ if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING) {
1292
+ return ret_error2(a, b, jv_string("strptime/1 requires string inputs and arguments"));
1293
+ }
1060
1294
 
1061
1295
  struct tm tm;
1062
1296
  memset(&tm, 0, sizeof(tm));
1297
+ tm.tm_wday = 8; // sentinel
1298
+ tm.tm_yday = 367; // sentinel
1063
1299
  const char *input = jv_string_value(a);
1064
1300
  const char *fmt = jv_string_value(b);
1065
1301
  const char *end = strptime(input, fmt, &tm);
1066
1302
 
1067
1303
  if (end == NULL || (*end != '\0' && !isspace(*end))) {
1068
- jv e = jv_invalid_with_msg(jv_string_fmt("date \"%s\" does not match format \"%s\"", input, fmt));
1069
- jv_free(a);
1070
- jv_free(b);
1071
- return e;
1304
+ return ret_error2(a, b, jv_string_fmt("date \"%s\" does not match format \"%s\"", input, fmt));
1072
1305
  }
1073
1306
  jv_free(b);
1074
- if (tm.tm_wday == 0 && tm.tm_yday == 0 && my_mktime(&tm) == (time_t)-2) {
1075
- jv_free(a);
1076
- return jv_invalid_with_msg(jv_string("strptime/1 not supported on this platform"));
1077
- }
1307
+ /*
1308
+ * This is OS X or some *BSD whose strptime() is just not that
1309
+ * helpful!
1310
+ *
1311
+ * We don't know that the format string did involve parsing a
1312
+ * year, or a month (if tm->tm_mon == 0). But with our invalid
1313
+ * day-of-week and day-of-year sentinel checks above, the worst
1314
+ * this can do is produce garbage.
1315
+ */
1316
+ #ifdef __APPLE__
1317
+ /*
1318
+ * Apple has made it worse, and different versions of the OS have different
1319
+ * behaviors. Some versions just don't touch the fields, but others do, and
1320
+ * sometimes provide wrong answers, at that! We can't tell at compile-time
1321
+ * which behavior the target system will have, so instead we always use our
1322
+ * functions to set these on OS X, and document that %u and %j are
1323
+ * unsupported on OS X.
1324
+ */
1325
+ set_tm_wday(&tm);
1326
+ set_tm_yday(&tm);
1327
+ #else
1328
+ if (tm.tm_wday == 8 && tm.tm_mday != 0 && tm.tm_mon >= 0 && tm.tm_mon <= 11)
1329
+ set_tm_wday(&tm);
1330
+ if (tm.tm_yday == 367 && tm.tm_mday != 0 && tm.tm_mon >= 0 && tm.tm_mon <= 11)
1331
+ set_tm_yday(&tm);
1332
+ #endif
1078
1333
  jv r = tm2jv(&tm);
1079
1334
  if (*end != '\0')
1080
1335
  r = jv_array_append(r, jv_string(end));
@@ -1092,8 +1347,10 @@ static jv f_strptime(jq_state *jq, jv a, jv b) {
1092
1347
  #define TO_TM_FIELD(t, j, i) \
1093
1348
  do { \
1094
1349
  jv n = jv_array_get(jv_copy(j), (i)); \
1095
- if (jv_get_kind(n) != (JV_KIND_NUMBER)) \
1350
+ if (jv_get_kind(n) != (JV_KIND_NUMBER)) { \
1351
+ jv_free(j); \
1096
1352
  return 0; \
1353
+ } \
1097
1354
  t = jv_number_value(n); \
1098
1355
  jv_free(n); \
1099
1356
  } while (0)
@@ -1126,9 +1383,9 @@ static int jv2tm(jv a, struct tm *tm) {
1126
1383
 
1127
1384
  static jv f_mktime(jq_state *jq, jv a) {
1128
1385
  if (jv_get_kind(a) != JV_KIND_ARRAY)
1129
- return jv_invalid_with_msg(jv_string("mktime requires array inputs"));
1386
+ return ret_error(a, jv_string("mktime requires array inputs"));
1130
1387
  if (jv_array_length(jv_copy(a)) < 6)
1131
- return jv_invalid_with_msg(jv_string("mktime requires parsed datetime inputs"));
1388
+ return ret_error(a, jv_string("mktime requires parsed datetime inputs"));
1132
1389
  struct tm tm;
1133
1390
  if (!jv2tm(a, &tm))
1134
1391
  return jv_invalid_with_msg(jv_string("mktime requires parsed datetime inputs"));
@@ -1143,7 +1400,7 @@ static jv f_mktime(jq_state *jq, jv a) {
1143
1400
  #ifdef HAVE_GMTIME_R
1144
1401
  static jv f_gmtime(jq_state *jq, jv a) {
1145
1402
  if (jv_get_kind(a) != JV_KIND_NUMBER)
1146
- return jv_invalid_with_msg(jv_string("gmtime() requires numeric inputs"));
1403
+ return ret_error(a, jv_string("gmtime() requires numeric inputs"));
1147
1404
  struct tm tm, *tmp;
1148
1405
  memset(&tm, 0, sizeof(tm));
1149
1406
  double fsecs = jv_number_value(a);
@@ -1158,7 +1415,7 @@ static jv f_gmtime(jq_state *jq, jv a) {
1158
1415
  #elif defined HAVE_GMTIME
1159
1416
  static jv f_gmtime(jq_state *jq, jv a) {
1160
1417
  if (jv_get_kind(a) != JV_KIND_NUMBER)
1161
- return jv_invalid_with_msg(jv_string("gmtime requires numeric inputs"));
1418
+ return ret_error(a, jv_string("gmtime requires numeric inputs"));
1162
1419
  struct tm tm, *tmp;
1163
1420
  memset(&tm, 0, sizeof(tm));
1164
1421
  double fsecs = jv_number_value(a);
@@ -1177,16 +1434,56 @@ static jv f_gmtime(jq_state *jq, jv a) {
1177
1434
  }
1178
1435
  #endif
1179
1436
 
1437
+ #ifdef HAVE_LOCALTIME_R
1438
+ static jv f_localtime(jq_state *jq, jv a) {
1439
+ if (jv_get_kind(a) != JV_KIND_NUMBER)
1440
+ return ret_error(a, jv_string("localtime() requires numeric inputs"));
1441
+ struct tm tm, *tmp;
1442
+ memset(&tm, 0, sizeof(tm));
1443
+ double fsecs = jv_number_value(a);
1444
+ time_t secs = fsecs;
1445
+ jv_free(a);
1446
+ tmp = localtime_r(&secs, &tm);
1447
+ if (tmp == NULL)
1448
+ return jv_invalid_with_msg(jv_string("error converting number of seconds since epoch to datetime"));
1449
+ a = tm2jv(tmp);
1450
+ return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1451
+ }
1452
+ #elif defined HAVE_GMTIME
1453
+ static jv f_localtime(jq_state *jq, jv a) {
1454
+ if (jv_get_kind(a) != JV_KIND_NUMBER)
1455
+ return ret_error(a, jv_string("localtime requires numeric inputs"));
1456
+ struct tm tm, *tmp;
1457
+ memset(&tm, 0, sizeof(tm));
1458
+ double fsecs = jv_number_value(a);
1459
+ time_t secs = fsecs;
1460
+ jv_free(a);
1461
+ tmp = localtime(&secs);
1462
+ if (tmp == NULL)
1463
+ return jv_invalid_with_msg(jv_string("error converting number of seconds since epoch to datetime"));
1464
+ a = tm2jv(tmp);
1465
+ return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
1466
+ }
1467
+ #else
1468
+ static jv f_localtime(jq_state *jq, jv a) {
1469
+ jv_free(a);
1470
+ return jv_invalid_with_msg(jv_string("localtime not implemented on this platform"));
1471
+ }
1472
+ #endif
1473
+
1180
1474
  #ifdef HAVE_STRFTIME
1181
1475
  static jv f_strftime(jq_state *jq, jv a, jv b) {
1182
1476
  if (jv_get_kind(a) == JV_KIND_NUMBER) {
1183
1477
  a = f_gmtime(jq, a);
1184
1478
  } else if (jv_get_kind(a) != JV_KIND_ARRAY) {
1185
- return jv_invalid_with_msg(jv_string("strftime/1 requires parsed datetime inputs"));
1479
+ return ret_error2(a, b, jv_string("strftime/1 requires parsed datetime inputs"));
1480
+ } else if (jv_get_kind(b) != JV_KIND_STRING) {
1481
+ return ret_error2(a, b, jv_string("strftime/1 requires a string format"));
1186
1482
  }
1187
1483
  struct tm tm;
1188
1484
  if (!jv2tm(a, &tm))
1189
- return jv_invalid_with_msg(jv_string("strftime/1 requires parsed datetime inputs")); \
1485
+ return ret_error(b, jv_string("strftime/1 requires parsed datetime inputs"));
1486
+
1190
1487
  const char *fmt = jv_string_value(b);
1191
1488
  size_t alloced = strlen(fmt) + 100;
1192
1489
  char *buf = alloca(alloced);
@@ -1198,13 +1495,43 @@ static jv f_strftime(jq_state *jq, jv a, jv b) {
1198
1495
  return jv_string(buf);
1199
1496
  }
1200
1497
  #else
1201
- static jv f_strftime(jq_state *jq, jv a) {
1498
+ static jv f_strftime(jq_state *jq, jv a, jv b) {
1202
1499
  jv_free(a);
1203
1500
  jv_free(b);
1204
1501
  return jv_invalid_with_msg(jv_string("strftime/1 not implemented on this platform"));
1205
1502
  }
1206
1503
  #endif
1207
1504
 
1505
+ #ifdef HAVE_STRFTIME
1506
+ static jv f_strflocaltime(jq_state *jq, jv a, jv b) {
1507
+ if (jv_get_kind(a) == JV_KIND_NUMBER) {
1508
+ a = f_localtime(jq, a);
1509
+ } else if (jv_get_kind(a) != JV_KIND_ARRAY) {
1510
+ return ret_error2(a, b, jv_string("strflocaltime/1 requires parsed datetime inputs"));
1511
+ } else if (jv_get_kind(b) != JV_KIND_STRING) {
1512
+ return ret_error2(a, b, jv_string("strflocaltime/1 requires a string format"));
1513
+ }
1514
+ struct tm tm;
1515
+ if (!jv2tm(a, &tm))
1516
+ return jv_invalid_with_msg(jv_string("strflocaltime/1 requires parsed datetime inputs"));
1517
+ const char *fmt = jv_string_value(b);
1518
+ size_t alloced = strlen(fmt) + 100;
1519
+ char *buf = alloca(alloced);
1520
+ size_t n = strftime(buf, alloced, fmt, &tm);
1521
+ jv_free(b);
1522
+ /* POSIX doesn't provide errno values for strftime() failures; weird */
1523
+ if (n == 0 || n > alloced)
1524
+ return jv_invalid_with_msg(jv_string("strflocaltime/1: unknown system failure"));
1525
+ return jv_string(buf);
1526
+ }
1527
+ #else
1528
+ static jv f_strflocaltime(jq_state *jq, jv a, jv b) {
1529
+ jv_free(a);
1530
+ jv_free(b);
1531
+ return jv_invalid_with_msg(jv_string("strflocaltime/1 not implemented on this platform"));
1532
+ }
1533
+ #endif
1534
+
1208
1535
  #ifdef HAVE_GETTIMEOFDAY
1209
1536
  static jv f_now(jq_state *jq, jv a) {
1210
1537
  jv_free(a);
@@ -1220,27 +1547,43 @@ static jv f_now(jq_state *jq, jv a) {
1220
1547
  }
1221
1548
  #endif
1222
1549
 
1223
- static jv f_current_filename(jq_state *jq) {
1550
+ static jv f_current_filename(jq_state *jq, jv a) {
1551
+ jv_free(a);
1552
+
1224
1553
  jv r = jq_util_input_get_current_filename(jq);
1225
1554
  if (jv_is_valid(r))
1226
1555
  return r;
1227
1556
  jv_free(r);
1228
1557
  return jv_null();
1229
1558
  }
1230
- static jv f_current_line(jq_state *jq) {
1559
+ static jv f_current_line(jq_state *jq, jv a) {
1560
+ jv_free(a);
1231
1561
  return jq_util_input_get_current_line(jq);
1232
1562
  }
1233
1563
 
1234
1564
  #define LIBM_DD(name) \
1235
- {(cfunction_ptr)f_ ## name, "_" #name, 1},
1565
+ {(cfunction_ptr)f_ ## name, #name, 1},
1236
1566
  #define LIBM_DD_NO(name)
1237
1567
 
1238
1568
  #define LIBM_DDD(name) \
1239
- {(cfunction_ptr)f_ ## name, "_" #name, 3},
1569
+ {(cfunction_ptr)f_ ## name, #name, 3},
1240
1570
  #define LIBM_DDD_NO(name)
1241
1571
 
1572
+ #define LIBM_DDDD(name) \
1573
+ {(cfunction_ptr)f_ ## name, #name, 4},
1574
+ #define LIBM_DDDD_NO(name)
1575
+
1242
1576
  static const struct cfunction function_list[] = {
1243
1577
  #include "libm.h"
1578
+ #ifdef HAVE_FREXP
1579
+ {(cfunction_ptr)f_frexp,"frexp", 1},
1580
+ #endif
1581
+ #ifdef HAVE_MODF
1582
+ {(cfunction_ptr)f_modf,"modf", 1},
1583
+ #endif
1584
+ #ifdef HAVE_LGAMMA_R
1585
+ {(cfunction_ptr)f_lgamma_r,"lgamma_r", 1},
1586
+ #endif
1244
1587
  {(cfunction_ptr)f_plus, "_plus", 3},
1245
1588
  {(cfunction_ptr)f_negate, "_negate", 1},
1246
1589
  {(cfunction_ptr)f_minus, "_minus", 3},
@@ -1273,6 +1616,7 @@ static const struct cfunction function_list[] = {
1273
1616
  {(cfunction_ptr)f_greatereq, "_greatereq", 3},
1274
1617
  {(cfunction_ptr)f_contains, "contains", 2},
1275
1618
  {(cfunction_ptr)f_length, "length", 1},
1619
+ {(cfunction_ptr)f_utf8bytelength, "utf8bytelength", 1},
1276
1620
  {(cfunction_ptr)f_type, "type", 1},
1277
1621
  {(cfunction_ptr)f_isinfinite, "isinfinite", 1},
1278
1622
  {(cfunction_ptr)f_isnan, "isnan", 1},
@@ -1289,6 +1633,8 @@ static const struct cfunction function_list[] = {
1289
1633
  {(cfunction_ptr)f_error, "error", 2},
1290
1634
  {(cfunction_ptr)f_format, "format", 2},
1291
1635
  {(cfunction_ptr)f_env, "env", 1},
1636
+ {(cfunction_ptr)f_halt, "halt", 1},
1637
+ {(cfunction_ptr)f_halt_error, "halt_error", 2},
1292
1638
  {(cfunction_ptr)f_get_search_list, "get_search_list", 1},
1293
1639
  {(cfunction_ptr)f_get_prog_origin, "get_prog_origin", 1},
1294
1640
  {(cfunction_ptr)f_get_jq_origin, "get_jq_origin", 1},
@@ -1299,14 +1645,18 @@ static const struct cfunction function_list[] = {
1299
1645
  {(cfunction_ptr)f_stderr, "stderr", 1},
1300
1646
  {(cfunction_ptr)f_strptime, "strptime", 2},
1301
1647
  {(cfunction_ptr)f_strftime, "strftime", 2},
1648
+ {(cfunction_ptr)f_strflocaltime, "strflocaltime", 2},
1302
1649
  {(cfunction_ptr)f_mktime, "mktime", 1},
1303
1650
  {(cfunction_ptr)f_gmtime, "gmtime", 1},
1651
+ {(cfunction_ptr)f_localtime, "localtime", 1},
1304
1652
  {(cfunction_ptr)f_now, "now", 1},
1305
1653
  {(cfunction_ptr)f_current_filename, "input_filename", 1},
1306
1654
  {(cfunction_ptr)f_current_line, "input_line_number", 1},
1307
1655
  };
1656
+ #undef LIBM_DDDD_NO
1308
1657
  #undef LIBM_DDD_NO
1309
1658
  #undef LIBM_DD_NO
1659
+ #undef LIBM_DDDD
1310
1660
  #undef LIBM_DDD
1311
1661
  #undef LIBM_DD
1312
1662
 
@@ -1339,315 +1689,68 @@ static block bind_bytecoded_builtins(block b) {
1339
1689
  {
1340
1690
  // Note that we can now define `range` as a jq-coded function
1341
1691
  block rangevar = gen_op_var_fresh(STOREV, "rangevar");
1342
- block init = BLOCK(gen_op_simple(DUP), gen_call("start", gen_noop()), rangevar);
1343
- block range = BLOCK(init,
1692
+ block rangestart = gen_op_var_fresh(STOREV, "rangestart");
1693
+ block range = BLOCK(gen_op_simple(DUP),
1694
+ gen_call("start", gen_noop()),
1695
+ rangestart,
1344
1696
  gen_call("end", gen_noop()),
1697
+ gen_op_simple(DUP),
1698
+ gen_op_bound(LOADV, rangestart),
1699
+ // Reset rangevar for every value generated by "end"
1700
+ rangevar,
1345
1701
  gen_op_bound(RANGE, rangevar));
1346
1702
  builtins = BLOCK(builtins, gen_function("range",
1347
1703
  BLOCK(gen_param("start"), gen_param("end")),
1348
1704
  range));
1349
1705
  }
1350
-
1351
- return block_bind_referenced(builtins, b, OP_IS_CALL_PSEUDO);
1706
+ return block_bind(builtins, b, OP_IS_CALL_PSEUDO);
1352
1707
  }
1353
1708
 
1354
- #define LIBM_DD(name) "def " #name ": _" #name ";",
1355
- #define LIBM_DDD(name) "def " #name "(a;b): _" #name "(a;b);",
1356
- #define LIBM_DD_NO(name) "def " #name ": \"Error: " #name "() not found at build time\"|error;",
1357
- #define LIBM_DDD_NO(name) "def " #name "(a;b): \"Error: " #name "() not found at build time\"|error;",
1358
1709
 
1359
- static const char* const jq_builtins[] = {
1360
- "def error: error(.);",
1361
- "def map(f): [.[] | f];",
1362
- "def select(f): if f then . else empty end;",
1363
- "def sort_by(f): _sort_by_impl(map([f]));",
1364
- "def group_by(f): _group_by_impl(map([f]));",
1365
- "def unique: group_by(.) | map(.[0]);",
1366
- "def unique_by(f): group_by(f) | map(.[0]);",
1367
- "def max_by(f): _max_by_impl(map([f]));",
1368
- "def min_by(f): _min_by_impl(map([f]));",
1710
+
1711
+ static const char* const jq_builtins =
1712
+ /* Include jq-coded builtins */
1713
+ #include "src/builtin.inc"
1714
+
1715
+ /* Include unsupported math functions next */
1716
+ #define LIBM_DD(name)
1717
+ #define LIBM_DDD(name)
1718
+ #define LIBM_DDDD(name)
1719
+ #define LIBM_DD_NO(name) "def " #name ": \"Error: " #name "/0 not found at build time\"|error;"
1720
+ #define LIBM_DDD_NO(name) "def " #name "(a;b): \"Error: " #name "/2 not found at build time\"|error;"
1721
+ #define LIBM_DDDD_NO(name) "def " #name "(a;b;c): \"Error: " #name "/3 not found at build time\"|error;"
1369
1722
  #include "libm.h"
1370
- "def add: reduce .[] as $x (null; . + $x);",
1371
- "def del(f): delpaths([path(f)]);",
1372
- "def _assign(paths; value): value as $v | reduce path(paths) as $p (.; setpath($p; $v));",
1373
- "def _modify(paths; update): reduce path(paths) as $p (.; setpath($p; getpath($p) | update));",
1374
- "def map_values(f): .[] |= f;",
1375
-
1376
- // recurse
1377
- "def recurse(f): def r: ., (f | select(. != null) | r); r;",
1378
- "def recurse(f; cond): def r: ., (f | select(cond) | r); r;",
1379
- "def recurse: recurse(.[]?);",
1380
- "def recurse_down: recurse;",
1381
-
1382
- "def to_entries: [keys_unsorted[] as $k | {key: $k, value: .[$k]}];",
1383
- "def from_entries: map({(.key // .Key // .Name): (if has(\"value\") then .value else .Value end)}) | add | .//={};",
1384
- "def with_entries(f): to_entries | map(f) | from_entries;",
1385
- "def reverse: [.[length - 1 - range(0;length)]];",
1386
- "def indices($i): if type == \"array\" and ($i|type) == \"array\" then .[$i]"
1387
- " elif type == \"array\" then .[[$i]]"
1388
- " elif type == \"string\" and ($i|type) == \"string\" then _strindices($i)"
1389
- " else .[$i] end;",
1390
- "def index($i): indices($i) | .[0];", // TODO: optimize
1391
- "def rindex($i): indices($i) | .[-1:][0];", // TODO: optimize
1392
- "def paths: path(recurse(if (type|. == \"array\" or . == \"object\") then .[] else empty end))|select(length > 0);",
1393
- "def paths(node_filter): . as $dot|paths|select(. as $p|$dot|getpath($p)|node_filter);",
1394
- "def any(generator; condition):"
1395
- " [label $out | foreach generator as $i"
1396
- " (false;"
1397
- " if . then break $out elif $i | condition then true else . end;"
1398
- " if . then . else empty end)] | length == 1;",
1399
- "def any(condition): any(.[]; condition);",
1400
- "def any: any(.);",
1401
- "def all(generator; condition): "
1402
- " [label $out | foreach generator as $i"
1403
- " (true;"
1404
- " if .|not then break $out elif $i | condition then . else false end;"
1405
- " if .|not then . else empty end)] | length == 0;",
1406
- "def all(condition): all(.[]; condition);",
1407
- "def all: all(.);",
1408
- "def isfinite: type == \"number\" and (isinfinite | not);",
1409
- "def arrays: select(type == \"array\");",
1410
- "def objects: select(type == \"object\");",
1411
- "def iterables: arrays, objects;",
1412
- "def booleans: select(type == \"boolean\");",
1413
- "def numbers: select(type == \"number\");",
1414
- "def normals: select(isnormal);",
1415
- "def finites: select(isfinite);",
1416
- "def strings: select(type == \"string\");",
1417
- "def nulls: select(type == \"null\");",
1418
- "def values: select(. != null);",
1419
- "def scalars: select(. == null or . == true or . == false or type == \"number\" or type == \"string\");",
1420
- "def scalars_or_empty: select(. == null or . == true or . == false or type == \"number\" or type == \"string\" or ((type==\"array\" or type==\"object\") and length==0));",
1421
- "def leaf_paths: paths(scalars);",
1422
- "def join($x): reduce .[] as $i (null; (.//\"\") + (if . == null then $i else $x + $i end))//\"\";",
1423
- "def _flatten($x): reduce .[] as $i ([]; if $i | type == \"array\" and $x != 0 then . + ($i | _flatten($x-1)) else . + [$i] end);",
1424
- "def flatten($x): if $x < 0 then error(\"flatten depth must not be negative\") else _flatten($x) end;",
1425
- "def flatten: _flatten(-1);",
1426
- "def range($x): range(0;$x);",
1427
- "def fromdateiso8601: strptime(\"%Y-%m-%dT%H:%M:%SZ\")|mktime;",
1428
- "def todateiso8601: strftime(\"%Y-%m-%dT%H:%M:%SZ\");",
1429
- "def fromdate: fromdateiso8601;",
1430
- "def todate: todateiso8601;",
1431
- "def match(re; mode): _match_impl(re; mode; false)|.[];",
1432
- "def match($val): ($val|type) as $vt | if $vt == \"string\" then match($val; null)"
1433
- " elif $vt == \"array\" and ($val | length) > 1 then match($val[0]; $val[1])"
1434
- " elif $vt == \"array\" and ($val | length) > 0 then match($val[0]; null)"
1435
- " else error( $vt + \" not a string or array\") end;",
1436
- "def test(re; mode): _match_impl(re; mode; true);",
1437
- "def test($val): ($val|type) as $vt | if $vt == \"string\" then test($val; null)"
1438
- " elif $vt == \"array\" and ($val | length) > 1 then test($val[0]; $val[1])"
1439
- " elif $vt == \"array\" and ($val | length) > 0 then test($val[0]; null)"
1440
- " else error( $vt + \" not a string or array\") end;",
1441
- "def capture(re; mods): match(re; mods) | reduce ( .captures | .[] | select(.name != null) | { (.name) : .string } ) as $pair ({}; . + $pair);",
1442
- "def capture($val): ($val|type) as $vt | if $vt == \"string\" then capture($val; null)"
1443
- " elif $vt == \"array\" and ($val | length) > 1 then capture($val[0]; $val[1])"
1444
- " elif $vt == \"array\" and ($val | length) > 0 then capture($val[0]; null)"
1445
- " else error( $vt + \" not a string or array\") end;",
1446
- "def scan(re):"
1447
- " match(re; \"g\")"
1448
- " | if (.captures|length > 0)"
1449
- " then [ .captures | .[] | .string ]"
1450
- " else .string"
1451
- " end ;",
1452
- //
1453
- // If input is an array, then emit a stream of successive subarrays of length n (or less),
1454
- // and similarly for strings.
1455
- "def _nwise(a; $n): if a|length <= $n then a else a[0:$n] , _nwise(a[$n:]; $n) end;",
1456
- "def _nwise($n): _nwise(.; $n);",
1457
- //
1458
- // splits/1 produces a stream; split/1 is retained for backward compatibility.
1459
- "def splits($re; flags): . as $s"
1460
- // # multiple occurrences of "g" are acceptable
1461
- " | [ match($re; \"g\" + flags) | (.offset, .offset + .length) ]"
1462
- " | [0] + . +[$s|length]"
1463
- " | _nwise(2)"
1464
- " | $s[.[0]:.[1] ] ;",
1465
- "def splits($re): splits($re; null);",
1466
- //
1467
- // split emits an array for backward compatibility
1468
- "def split($re; flags): [ splits($re; flags) ];",
1469
- //
1470
- // If s contains capture variables, then create a capture object and pipe it to s
1471
- "def sub($re; s):"
1472
- " . as $in"
1473
- " | [match($re)]"
1474
- " | if length == 0 then $in"
1475
- " else .[0]"
1476
- " | . as $r"
1477
- // # create the \"capture\" object:
1478
- " | reduce ( $r | .captures | .[] | select(.name != null) | { (.name) : .string } ) as $pair"
1479
- " ({}; . + $pair)"
1480
- " | $in[0:$r.offset] + s + $in[$r.offset+$r.length:]"
1481
- " end ;",
1482
- //
1483
- // If s contains capture variables, then create a capture object and pipe it to s
1484
- "def sub($re; s; flags):"
1485
- " def subg: explode | select(. != 103) | implode;"
1486
- // # "fla" should be flags with all occurrences of g removed; gs should be non-nil if flags has a g
1487
- " def sub1(fla; gs):"
1488
- " def mysub:"
1489
- " . as $in"
1490
- " | [match($re; fla)]"
1491
- " | if length == 0 then $in"
1492
- " else .[0] as $edit"
1493
- " | ($edit | .offset + .length) as $len"
1494
- // # create the "capture" object:
1495
- " | reduce ( $edit | .captures | .[] | select(.name != null) | { (.name) : .string } ) as $pair"
1496
- " ({}; . + $pair)"
1497
- " | $in[0:$edit.offset]"
1498
- " + s"
1499
- " + ($in[$len:] | if gs then mysub else . end)"
1500
- " end ;"
1501
- " mysub ;"
1502
- " (flags | index(\"g\")) as $gs"
1503
- " | (flags | if $gs then subg else . end) as $fla"
1504
- " | sub1($fla; $gs);",
1505
- //
1506
- "def sub($re; s): sub($re; s; \"\");",
1507
- // repeated substitution of re (which may contain named captures)
1508
- "def gsub($re; s; flags): sub($re; s; flags + \"g\");",
1509
- "def gsub($re; s): sub($re; s; \"g\");",
1510
-
1511
- //#######################################################################
1512
- // range/3, with a `by` expression argument
1513
- "def range($init; $upto; $by): "
1514
- " def _range: "
1515
- " if ($by > 0 and . < $upto) or ($by < 0 and . > $upto) then ., ((.+$by)|_range) else . end; "
1516
- " if $by == 0 then $init else $init|_range end | select(($by > 0 and . < $upto) or ($by < 0 and . > $upto));",
1517
- // generic iterator/generator
1518
- "def while(cond; update): "
1519
- " def _while: "
1520
- " if cond then ., (update | _while) else empty end; "
1521
- " _while;",
1522
- "def until(cond; next): "
1523
- " def _until: "
1524
- " if cond then . else (next|_until) end;"
1525
- " _until;",
1526
- "def limit($n; exp): if $n < 0 then exp else label $out | foreach exp as $item ([$n, null]; if .[0] < 1 then break $out else [.[0] -1, $item] end; .[1]) end;",
1527
- "def first(g): label $out | foreach g as $item ([false, null]; if .[0]==true then break $out else [true, $item] end; .[1]);",
1528
- "def last(g): reduce g as $item (null; $item);",
1529
- "def nth($n; g): if $n < 0 then error(\"nth doesn't support negative indices\") else last(limit($n + 1; g)) end;",
1530
- "def first: .[0];",
1531
- "def last: .[-1];",
1532
- "def nth($n): .[$n];",
1533
- "def combinations:"
1534
- " if length == 0 then [] else"
1535
- " .[0][] as $x"
1536
- " | (.[1:] | combinations) as $y"
1537
- " | [$x] + $y"
1538
- " end;",
1539
- "def combinations(n):"
1540
- " . as $dot"
1541
- " | [range(n) | $dot]"
1542
- " | combinations;",
1543
- // # transpose a possibly jagged matrix, quickly;
1544
- // # rows are padded with nulls so the result is always rectangular.
1545
- "def transpose:"
1546
- " if . == [] then []"
1547
- " else . as $in"
1548
- " | (map(length) | max) as $max"
1549
- " | length as $length"
1550
- " | reduce range(0; $max) as $j"
1551
- " ([]; . + [reduce range(0;$length) as $i ([]; . + [ $in[$i][$j] ] )] )"
1552
- " end;",
1553
- "def in(xs): . as $x | xs | has($x);",
1554
- "def inside(xs): . as $x | xs | contains($x);",
1555
- "def input: _input;",
1556
- "def repeat(exp): "
1557
- " def _repeat: "
1558
- " exp, _repeat;"
1559
- " _repeat;",
1560
- "def inputs: try repeat(_input) catch if .==\"break\" then empty else .|error end;",
1561
- // # like ruby's downcase - only characters A to Z are affected
1562
- "def ascii_downcase:"
1563
- " explode | map( if 65 <= . and . <= 90 then . + 32 else . end) | implode;",
1564
- // # like ruby's upcase - only characters a to z are affected
1565
- "def ascii_upcase:"
1566
- " explode | map( if 97 <= . and . <= 122 then . - 32 else . end) | implode;",
1567
-
1568
- // Streaming utilities
1569
- "def truncate_stream(stream):"
1570
- " . as $n | null | stream | . as $input | if (.[0]|length) > $n then setpath([0];$input[0][1:]) else empty end;",
1571
- "def fromstream(i):"
1572
- " foreach i as $item ("
1573
- " [null,false,null,false];"
1574
- " if ($item[0]|length) == 0 then [null,false,.[2],.[3]]"
1575
- " elif ($item|length) == 1 and ($item[0]|length) < 2 then [null,false,.[0],.[1]]"
1576
- " else . end |"
1577
- " . as $state |"
1578
- " if ($item|length) > 1 and ($item[0]|length) > 0 then"
1579
- " [.[0]|setpath(($item|.[0]); ($item|.[1])), "
1580
- " true, "
1581
- " $state[2], "
1582
- " $state[3]] "
1583
- " else ."
1584
- " end;"
1585
- " if ($item[0]|length) == 1 and ($item|length == 1) and .[3] then .[2] else empty end,"
1586
- " if ($item[0]|length) == 0 then $item[1] else empty end"
1587
- " );",
1588
- "def tostream:\n"
1589
- " {string:true,number:true,boolean:true,null:true} as $leaf_types |\n"
1590
- " . as $dot |\n"
1591
- " if $leaf_types[$dot|type] or length==0 then [[],$dot]\n"
1592
- " else\n"
1593
- " # We really need a _streaming_ form of `keys`.\n"
1594
- " # We can use `range` for arrays, but not for objects.\n"
1595
- " keys as $keys |\n"
1596
- " $keys[-1] as $last|\n"
1597
- " ((# for each key\n"
1598
- " $keys[] | . as $key |\n"
1599
- " $dot[$key] | . as $dot |\n"
1600
- " # recurse on each key/value\n"
1601
- " tostream|.[0]|=[$key]+.),\n"
1602
- " # then add the closing marker\n"
1603
- " [[$last]])\n"
1604
- " end;",
1605
-
1606
-
1607
- // # Assuming the input array is sorted, bsearch/1 returns
1608
- // # the index of the target if the target is in the input array; and otherwise
1609
- // # (-1 - ix), where ix is the insertion point that would leave the array sorted.
1610
- // # If the input is not sorted, bsearch will terminate but with irrelevant results.
1611
- "def bsearch(target):"
1612
- " if length == 0 then -1"
1613
- " elif length == 1 then"
1614
- " if target == .[0] then 0 elif target < .[0] then -1 else -2 end"
1615
- " else . as $in"
1616
- "" // # state variable: [start, end, answer]
1617
- "" // # where start and end are the upper and lower offsets to use.
1618
- " | [0, length-1, null]"
1619
- " | until( .[0] > .[1] ;"
1620
- " if .[2] != null then (.[1] = -1)" // # i.e. break
1621
- " else"
1622
- " ( ( (.[1] + .[0]) / 2 ) | floor ) as $mid"
1623
- " | $in[$mid] as $monkey"
1624
- " | if $monkey == target then (.[2] = $mid)" // # success
1625
- " elif .[0] == .[1] then (.[1] = -1)" // # failure
1626
- " elif $monkey < target then (.[0] = ($mid + 1))"
1627
- " else (.[1] = ($mid - 1))"
1628
- " end"
1629
- " end )"
1630
- " | if .[2] == null then" // # compute the insertion point
1631
- " if $in[ .[0] ] < target then (-2 -.[0])"
1632
- " else (-1 -.[0])"
1633
- " end"
1634
- " else .[2]"
1635
- " end"
1636
- " end;",
1637
- };
1723
+ #ifndef HAVE_FREXP
1724
+ "def frexp: \"Error: frexp/0 not found found at build time\"|error;"
1725
+ #endif
1726
+ #ifndef HAVE_MODF
1727
+ "def modf: \"Error: modf/0 not found found at build time\"|error;"
1728
+ #endif
1729
+ #ifndef HAVE_LGAMMA_R
1730
+ "def lgamma_r: \"Error: lgamma_r/0 not found found at build time\"|error;"
1731
+ #endif
1732
+ ;
1733
+
1734
+ #undef LIBM_DDDD_NO
1638
1735
  #undef LIBM_DDD_NO
1639
1736
  #undef LIBM_DD_NO
1737
+ #undef LIBM_DDDD
1640
1738
  #undef LIBM_DDD
1641
1739
  #undef LIBM_DD
1642
1740
 
1643
1741
 
1742
+ static block gen_builtin_list(block builtins) {
1743
+ jv list = jv_array_append(block_list_funcs(builtins, 1), jv_string("builtins/0"));
1744
+ return BLOCK(builtins, gen_function("builtins", gen_noop(), gen_const(list)));
1745
+ }
1746
+
1644
1747
  static int builtins_bind_one(jq_state *jq, block* bb, const char* code) {
1645
1748
  struct locfile* src;
1646
1749
  src = locfile_init(jq, "<builtin>", code, strlen(code));
1647
1750
  block funcs;
1648
1751
  int nerrors = jq_parse_library(src, &funcs);
1649
1752
  if (nerrors == 0) {
1650
- *bb = block_bind_referenced(funcs, *bb, OP_IS_CALL_PSEUDO);
1753
+ *bb = block_bind(funcs, *bb, OP_IS_CALL_PSEUDO);
1651
1754
  }
1652
1755
  locfile_free(src);
1653
1756
  return nerrors;
@@ -1669,16 +1772,18 @@ static int slurp_lib(jq_state *jq, block* bb) {
1669
1772
  }
1670
1773
 
1671
1774
  int builtins_bind(jq_state *jq, block* bb) {
1775
+ block builtins = gen_noop();
1672
1776
  int nerrors = slurp_lib(jq, bb);
1673
1777
  if (nerrors) {
1674
1778
  block_free(*bb);
1675
1779
  return nerrors;
1676
1780
  }
1677
- for (int i=(int)(sizeof(jq_builtins)/sizeof(jq_builtins[0]))-1; i>=0; i--) {
1678
- nerrors = builtins_bind_one(jq, bb, jq_builtins[i]);
1679
- assert(!nerrors);
1680
- }
1681
- *bb = bind_bytecoded_builtins(*bb);
1682
- *bb = gen_cbinding(function_list, sizeof(function_list)/sizeof(function_list[0]), *bb);
1781
+ nerrors = builtins_bind_one(jq, &builtins, jq_builtins);
1782
+ assert(!nerrors);
1783
+ builtins = bind_bytecoded_builtins(builtins);
1784
+ builtins = gen_cbinding(function_list, sizeof(function_list)/sizeof(function_list[0]), builtins);
1785
+ builtins = gen_builtin_list(builtins);
1786
+ *bb = block_bind(builtins, *bb, OP_IS_CALL_PSEUDO);
1787
+ *bb = block_drop_unreferenced(*bb);
1683
1788
  return nerrors;
1684
1789
  }