zsv 1.3.0

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 (240) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +36 -0
  3. data/LICENSE +21 -0
  4. data/README.md +311 -0
  5. data/ext/zsv/common.h +34 -0
  6. data/ext/zsv/extconf.rb +137 -0
  7. data/ext/zsv/options.c +126 -0
  8. data/ext/zsv/options.h +31 -0
  9. data/ext/zsv/options_internal.h +8 -0
  10. data/ext/zsv/parser.c +300 -0
  11. data/ext/zsv/parser.h +62 -0
  12. data/ext/zsv/row.c +122 -0
  13. data/ext/zsv/row.h +39 -0
  14. data/ext/zsv/vendor/zsv-1.3.0/app/2db.c +756 -0
  15. data/ext/zsv/vendor/zsv-1.3.0/app/2json.c +381 -0
  16. data/ext/zsv/vendor/zsv-1.3.0/app/2tsv.c +228 -0
  17. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/help.c +123 -0
  18. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/license.c +39 -0
  19. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/register.c +104 -0
  20. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/thirdparty.c +41 -0
  21. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/unregister.c +1 -0
  22. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/version.c +14 -0
  23. data/ext/zsv/vendor/zsv-1.3.0/app/check/simdutf_wrapper.h +19 -0
  24. data/ext/zsv/vendor/zsv-1.3.0/app/check/utf8.c +116 -0
  25. data/ext/zsv/vendor/zsv-1.3.0/app/check.c +194 -0
  26. data/ext/zsv/vendor/zsv-1.3.0/app/cli.c +796 -0
  27. data/ext/zsv/vendor/zsv-1.3.0/app/cli_const.h +41 -0
  28. data/ext/zsv/vendor/zsv-1.3.0/app/cli_export.h +16 -0
  29. data/ext/zsv/vendor/zsv-1.3.0/app/cli_ini.c +280 -0
  30. data/ext/zsv/vendor/zsv-1.3.0/app/cli_internal.h +36 -0
  31. data/ext/zsv/vendor/zsv-1.3.0/app/compare.c +913 -0
  32. data/ext/zsv/vendor/zsv-1.3.0/app/compare.h +23 -0
  33. data/ext/zsv/vendor/zsv-1.3.0/app/compare_added_column.c +20 -0
  34. data/ext/zsv/vendor/zsv-1.3.0/app/compare_internal.h +140 -0
  35. data/ext/zsv/vendor/zsv-1.3.0/app/compare_sort.c +91 -0
  36. data/ext/zsv/vendor/zsv-1.3.0/app/compare_unique_colname.c +81 -0
  37. data/ext/zsv/vendor/zsv-1.3.0/app/count-pull.c +82 -0
  38. data/ext/zsv/vendor/zsv-1.3.0/app/count.c +404 -0
  39. data/ext/zsv/vendor/zsv-1.3.0/app/desc.c +569 -0
  40. data/ext/zsv/vendor/zsv-1.3.0/app/echo.c +365 -0
  41. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/my_extension.c +366 -0
  42. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/mysheet_extension.c +341 -0
  43. data/ext/zsv/vendor/zsv-1.3.0/app/ext_template/YOUR_EXTENSION_zsvext.c +263 -0
  44. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.c +298 -0
  45. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.h +157 -0
  46. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/json_numeric.c +177 -0
  47. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.c +444 -0
  48. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.h +145 -0
  49. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/utils.c +110 -0
  50. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/include/memfile.h +15 -0
  51. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/src/memfile.c +64 -0
  52. data/ext/zsv/vendor/zsv-1.3.0/app/external/sglib/sglib.h +1955 -0
  53. data/ext/zsv/vendor/zsv-1.3.0/app/external/simdutf/simdutf.h +6802 -0
  54. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.c +230517 -0
  55. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.h +12174 -0
  56. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_and_csv_vtab.c +2 -0
  57. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.c +142 -0
  58. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.h +49 -0
  59. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-zsv.c +485 -0
  60. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab.c +1015 -0
  61. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3ext.h +663 -0
  62. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/vtab_helper.c +85 -0
  63. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_common.h +75 -0
  64. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_gen.h +167 -0
  65. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_parse.h +228 -0
  66. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_tree.h +186 -0
  67. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_version.h +23 -0
  68. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_common.h +76 -0
  69. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_gen.h +167 -0
  70. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_parse.h +238 -0
  71. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_tree.h +186 -0
  72. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl.c +184 -0
  73. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.c +52 -0
  74. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.h +34 -0
  75. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.c +103 -0
  76. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.h +57 -0
  77. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_bytestack.h +69 -0
  78. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.c +220 -0
  79. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.h +34 -0
  80. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_gen.c +362 -0
  81. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.c +764 -0
  82. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.h +117 -0
  83. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.c +508 -0
  84. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.h +78 -0
  85. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_tree.c +505 -0
  86. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_version.c +7 -0
  87. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/json_value.h +59 -0
  88. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/yajl_helper.h +208 -0
  89. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper.c +795 -0
  90. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper_internal.h +28 -0
  91. data/ext/zsv/vendor/zsv-1.3.0/app/flatten.c +851 -0
  92. data/ext/zsv/vendor/zsv-1.3.0/app/jq.c +106 -0
  93. data/ext/zsv/vendor/zsv-1.3.0/app/jq.h +6 -0
  94. data/ext/zsv/vendor/zsv-1.3.0/app/mv.c +113 -0
  95. data/ext/zsv/vendor/zsv-1.3.0/app/noop.c +90 -0
  96. data/ext/zsv/vendor/zsv-1.3.0/app/overwrite.c +295 -0
  97. data/ext/zsv/vendor/zsv-1.3.0/app/paste.c +175 -0
  98. data/ext/zsv/vendor/zsv-1.3.0/app/pretty.c +693 -0
  99. data/ext/zsv/vendor/zsv-1.3.0/app/prop.c +980 -0
  100. data/ext/zsv/vendor/zsv-1.3.0/app/rm.c +131 -0
  101. data/ext/zsv/vendor/zsv-1.3.0/app/select/fixed.c +130 -0
  102. data/ext/zsv/vendor/zsv-1.3.0/app/select/internal.h +118 -0
  103. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.c +45 -0
  104. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.h +41 -0
  105. data/ext/zsv/vendor/zsv-1.3.0/app/select/processing.c +107 -0
  106. data/ext/zsv/vendor/zsv-1.3.0/app/select/rand.c +20 -0
  107. data/ext/zsv/vendor/zsv-1.3.0/app/select/regex.c +61 -0
  108. data/ext/zsv/vendor/zsv-1.3.0/app/select/search.c +14 -0
  109. data/ext/zsv/vendor/zsv-1.3.0/app/select/selection.c +192 -0
  110. data/ext/zsv/vendor/zsv-1.3.0/app/select/usage.c +72 -0
  111. data/ext/zsv/vendor/zsv-1.3.0/app/select-pull.c +812 -0
  112. data/ext/zsv/vendor/zsv-1.3.0/app/select.c +753 -0
  113. data/ext/zsv/vendor/zsv-1.3.0/app/serialize.c +372 -0
  114. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/curses.h +15 -0
  115. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/cursor.c +119 -0
  116. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/errors.c +45 -0
  117. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.c +63 -0
  118. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.h +12 -0
  119. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/filter.c +166 -0
  120. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers.c +214 -0
  121. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers_internal.h +128 -0
  122. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/help.c +43 -0
  123. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.c +81 -0
  124. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.h +25 -0
  125. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.c +325 -0
  126. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.h +73 -0
  127. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/lexer.c +203 -0
  128. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/newline_handler.c +7 -0
  129. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/pivot.c +318 -0
  130. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.c +134 -0
  131. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.h +119 -0
  132. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/read-data.c +322 -0
  133. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.c +203 -0
  134. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.h +36 -0
  135. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet-sql.c +167 -0
  136. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet_internal.h +36 -0
  137. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sqlfilter.c +153 -0
  138. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/terminfo.c +32 -0
  139. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.c +312 -0
  140. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.h +29 -0
  141. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/ui_buffer.c +266 -0
  142. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/usage.c +9 -0
  143. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/utf8-width.c +60 -0
  144. data/ext/zsv/vendor/zsv-1.3.0/app/sheet.c +1007 -0
  145. data/ext/zsv/vendor/zsv-1.3.0/app/sql.c +453 -0
  146. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.c +101 -0
  147. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.h +49 -0
  148. data/ext/zsv/vendor/zsv-1.3.0/app/stack.c +393 -0
  149. data/ext/zsv/vendor/zsv-1.3.0/app/utils/arg.c +322 -0
  150. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cache.c +228 -0
  151. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cat.c +91 -0
  152. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.c +240 -0
  153. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.h +63 -0
  154. data/ext/zsv/vendor/zsv-1.3.0/app/utils/clock.c +57 -0
  155. data/ext/zsv/vendor/zsv-1.3.0/app/utils/db.c +148 -0
  156. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs-no-jq.c +2 -0
  157. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs.c +427 -0
  158. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_from_json.c +253 -0
  159. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_to_json.c +121 -0
  160. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dl.c +20 -0
  161. data/ext/zsv/vendor/zsv-1.3.0/app/utils/emcc/fs_api.c +159 -0
  162. data/ext/zsv/vendor/zsv-1.3.0/app/utils/err.c +24 -0
  163. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file-mem.c +180 -0
  164. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file.c +256 -0
  165. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.c +197 -0
  166. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.h +49 -0
  167. data/ext/zsv/vendor/zsv-1.3.0/app/utils/jq.c +400 -0
  168. data/ext/zsv/vendor/zsv-1.3.0/app/utils/json.c +120 -0
  169. data/ext/zsv/vendor/zsv-1.3.0/app/utils/mem.c +18 -0
  170. data/ext/zsv/vendor/zsv-1.3.0/app/utils/memmem.c +132 -0
  171. data/ext/zsv/vendor/zsv-1.3.0/app/utils/os.c +178 -0
  172. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite.c +258 -0
  173. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite_writer.c +246 -0
  174. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8-test.c +123 -0
  175. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.c +153 -0
  176. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.h +54 -0
  177. data/ext/zsv/vendor/zsv-1.3.0/app/utils/prop.c +267 -0
  178. data/ext/zsv/vendor/zsv-1.3.0/app/utils/signal.c +53 -0
  179. data/ext/zsv/vendor/zsv-1.3.0/app/utils/string.c +357 -0
  180. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dir_exists_longpath.c +83 -0
  181. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dl.c +33 -0
  182. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/fopen_longpath.c +184 -0
  183. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/foreach_dirent_longpath.c +292 -0
  184. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.c +259 -0
  185. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.h +13 -0
  186. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/mkdir_longpath.c +255 -0
  187. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/remove_longpath.c +96 -0
  188. data/ext/zsv/vendor/zsv-1.3.0/app/utils/writer.c +361 -0
  189. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command.h +40 -0
  190. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command_standalone.c +16 -0
  191. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_main.h +44 -0
  192. data/ext/zsv/vendor/zsv-1.3.0/examples/js/zsv_parser_api_dummy.c +3 -0
  193. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/parse_by_chunk.c +100 -0
  194. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/print_my_column.c +143 -0
  195. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/pull.c +89 -0
  196. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/simple.c +123 -0
  197. data/ext/zsv/vendor/zsv-1.3.0/fuzz/fuzz.c +16 -0
  198. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/api.h +336 -0
  199. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/common.h +361 -0
  200. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation.h +62 -0
  201. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation_private.h +113 -0
  202. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/sheet.h +73 -0
  203. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext.h +329 -0
  204. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/arg.h +90 -0
  205. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/cache.h +49 -0
  206. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/clock.h +36 -0
  207. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/compiler.h +58 -0
  208. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/db.h +19 -0
  209. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dirs.h +147 -0
  210. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dl.h +22 -0
  211. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/emcc/fs_api.h +28 -0
  212. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/err.h +22 -0
  213. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file-mem.h +17 -0
  214. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file.h +99 -0
  215. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/jq.h +65 -0
  216. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/json.h +19 -0
  217. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/mem.h +19 -0
  218. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/memmem.h +13 -0
  219. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/os.h +54 -0
  220. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite.h +71 -0
  221. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite_writer.h +53 -0
  222. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/prop.h +107 -0
  223. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/signal.h +18 -0
  224. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/sql.h +11 -0
  225. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/string.h +148 -0
  226. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/utf8.h +41 -0
  227. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/win/dl.h +25 -0
  228. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/writer.h +101 -0
  229. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/zsv_export.h +33 -0
  230. data/ext/zsv/vendor/zsv-1.3.0/include/zsv.h +20 -0
  231. data/ext/zsv/vendor/zsv-1.3.0/src/vector_delim.c +60 -0
  232. data/ext/zsv/vendor/zsv-1.3.0/src/zsv.c +484 -0
  233. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_internal.c +731 -0
  234. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_delim.c +285 -0
  235. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_fixed.c +88 -0
  236. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_strencode.c +51 -0
  237. data/ext/zsv/zsv_ext.c +343 -0
  238. data/lib/zsv/version.rb +5 -0
  239. data/lib/zsv.rb +81 -0
  240. metadata +340 -0
@@ -0,0 +1,400 @@
1
+ #include <string.h>
2
+ #include <stdlib.h>
3
+ #include <zsv/utils/string.h>
4
+ #include <zsv/utils/writer.h>
5
+ #include <zsv/utils/jq.h>
6
+ #include <jq.h>
7
+ #include <jv.h>
8
+
9
+ // all jv_ functions defined here consume their jv value
10
+ // consumes:
11
+ // jv_string_length_bytes
12
+ // jv_dumpf
13
+ // jv_dump_string
14
+ //
15
+ // does not consume:
16
+ // jv_number_value
17
+ // jv_string_value
18
+ // jv_get_kind
19
+
20
+ static int jv_print_scalar_str(jv value, char inside_string, FILE *f, char as_csv) {
21
+ f = f ? f : stdout;
22
+ switch (jv_get_kind(value)) {
23
+ case JV_KIND_STRING: {
24
+ size_t len = jv_string_length_bytes(jv_copy(value));
25
+ const char *s = jv_string_value(value);
26
+ if (!as_csv)
27
+ fprintf(f, "%.*s", (int)len, s);
28
+ else {
29
+ unsigned char *csv = zsv_csv_quote((unsigned char *)s, len, NULL, 0);
30
+ if (!csv)
31
+ fprintf(f, "%.*s", (int)len, s);
32
+ else {
33
+ if (inside_string)
34
+ fprintf(f, "%s%.*s", inside_string > 1 ? ";" : "", (int)(strlen((char *)csv) - 2), csv + 1);
35
+ else
36
+ fprintf(f, "%s", csv);
37
+ free(csv);
38
+ }
39
+ }
40
+ jv_free(value);
41
+ return 1;
42
+ } break;
43
+ default:
44
+ break;
45
+ }
46
+ jv_free(value);
47
+ return 0;
48
+ }
49
+
50
+ static int jv_print_scalar(jv value, char inside_string, FILE *f, char as_csv) {
51
+ f = f ? f : stdout;
52
+ switch (jv_get_kind(value)) {
53
+ case JV_KIND_INVALID:
54
+ fprintf(f, "<invalid json>");
55
+ jv_free(value);
56
+ return 1;
57
+ case JV_KIND_NULL:
58
+ fprintf(f, "null");
59
+ jv_free(value);
60
+ return 1;
61
+ case JV_KIND_TRUE:
62
+ fprintf(f, "true");
63
+ jv_free(value);
64
+ return 1;
65
+ case JV_KIND_FALSE:
66
+ fprintf(f, "false");
67
+ jv_free(value);
68
+ return 1;
69
+ case JV_KIND_NUMBER: {
70
+ char s[64];
71
+ int n = snprintf(s, sizeof(s), "%lf", jv_number_value(value));
72
+ if (n > 0 && (size_t)n < sizeof(s))
73
+ fprintf(f, "%.*s", (int)zsv_strip_trailing_zeros(s, n), s);
74
+ }
75
+ jv_free(value);
76
+ return 1;
77
+ default:
78
+ return jv_print_scalar_str(value, inside_string, f, as_csv);
79
+ }
80
+ }
81
+
82
+ static void jv_to_csv_aux(jv value, FILE *f, int inside_string) {
83
+ f = f ? f : stdout;
84
+ if (!jv_print_scalar(jv_copy(value), inside_string, f, 1)) {
85
+ switch (jv_get_kind(value)) {
86
+ case JV_KIND_ARRAY:
87
+ // flatten
88
+ if (!inside_string)
89
+ fprintf(f, "\"");
90
+ jv_array_foreach(value, i, item) {
91
+ if (i)
92
+ fprintf(f, ";");
93
+ jv_to_csv_aux(item, f, 1);
94
+ }
95
+ if (!inside_string)
96
+ fprintf(f, "\"");
97
+ break;
98
+ case JV_KIND_OBJECT:
99
+ // flatten
100
+ if (!inside_string)
101
+ fprintf(f, "\"");
102
+ jv_object_foreach(value, key, item) {
103
+ jv_print_scalar(key, 1, f, 1);
104
+ fprintf(f, ":");
105
+ jv_to_csv_aux(item, f, 1);
106
+ fprintf(f, ";");
107
+ }
108
+ if (!inside_string)
109
+ fprintf(f, "\"");
110
+ break;
111
+ default:
112
+ break;
113
+ }
114
+ }
115
+ jv_free(value);
116
+ }
117
+
118
+ size_t zsv_jq_fwrite1(void *restrict FILE_ptr, const void *restrict buff, size_t len) {
119
+ return fwrite(buff, len, 1, FILE_ptr);
120
+ }
121
+
122
+ void jv_to_json_func(jv value, void *ctx) {
123
+ struct jv_to_json_ctx *data = ctx;
124
+ if (data->output_started)
125
+ data->write1(data->ctx, "\n", 1);
126
+ data->output_started = 1;
127
+ if (data->write1 == zsv_jq_fwrite1) {
128
+ if (data->raw_output && jv_get_kind(value) == JV_KIND_STRING)
129
+ fwrite(jv_string_value(value), 1, jv_string_length_bytes(jv_copy(value)), data->ctx);
130
+ else
131
+ jv_dumpf(value, data->ctx, data->flags);
132
+ } else {
133
+ // jv_dump_string is memory-inefficient
134
+ // would be better to create custom dump function that, instead of writing to string buffer,
135
+ // could directly invoke func()
136
+ jv jv_s = jv_dump_string(value, data->flags);
137
+ const char *p = jv_string_value(jv_s);
138
+ size_t len = jv_string_length_bytes(jv_copy(jv_s));
139
+ if (len)
140
+ data->write1(data->ctx, p, len);
141
+ jv_free(jv_s);
142
+ }
143
+ }
144
+
145
+ void jv_to_csv_multi(jv value, void *jv_to_csv_multi_ctx) {
146
+ struct jv_to_csv_multi_ctx *ctx = jv_to_csv_multi_ctx;
147
+ FILE *f = ctx->get_file(ctx->ctx);
148
+ jv_to_csv(value, f);
149
+ }
150
+
151
+ void jv_to_csv(jv value, void *file) {
152
+ FILE *f = file;
153
+ f = f ? f : stdout;
154
+ if (jv_print_scalar(jv_copy(value), 0, f, 1))
155
+ fprintf(f, "\n");
156
+ else {
157
+ switch (jv_get_kind(value)) {
158
+ case JV_KIND_ARRAY:
159
+ jv_array_foreach(value, i, item) {
160
+ if (i)
161
+ fprintf(f, ",");
162
+ jv_to_csv_aux(item, f, 0);
163
+ }
164
+ fprintf(f, "\n");
165
+ break;
166
+ case JV_KIND_OBJECT:
167
+ jv_object_foreach(value, key, item) {
168
+ jv_print_scalar(key, 0, f, 1);
169
+ fprintf(f, ",");
170
+ jv_to_csv_aux(item, f, 0);
171
+ fprintf(f, "\n");
172
+ }
173
+ fprintf(f, "\n");
174
+ break;
175
+ default:
176
+ break;
177
+ }
178
+ }
179
+ jv_free(value);
180
+ }
181
+
182
+ static void jv_to_txt_aux(jv value, FILE *f) {
183
+ f = f ? f : stdout;
184
+ if (!jv_print_scalar(jv_copy(value), 0, f, 0)) {
185
+ switch (jv_get_kind(value)) {
186
+ case JV_KIND_ARRAY:
187
+ // flatten
188
+ fprintf(f, "[");
189
+ jv_array_foreach(value, i, item) {
190
+ if (i)
191
+ fprintf(f, ";");
192
+ jv_to_txt_aux(item, f);
193
+ }
194
+ fprintf(f, "]");
195
+ break;
196
+ case JV_KIND_OBJECT:
197
+ // flatten
198
+ fprintf(f, "{");
199
+ jv_object_foreach(value, key, item) {
200
+ jv_print_scalar(key, 1, f, 0);
201
+ fprintf(f, ":");
202
+ jv_to_txt_aux(item, f);
203
+ fprintf(f, ";");
204
+ }
205
+ fprintf(f, "}");
206
+ break;
207
+ default:
208
+ break;
209
+ }
210
+ }
211
+ jv_free(value);
212
+ }
213
+
214
+ void jv_to_txt(jv value, void *file) {
215
+ FILE *f = file;
216
+ f = f ? f : stdout;
217
+ if (jv_print_scalar(jv_copy(value), 0, f, 0))
218
+ fprintf(f, "\n");
219
+ else {
220
+ switch (jv_get_kind(value)) {
221
+ case JV_KIND_ARRAY:
222
+ jv_array_foreach(value, i, item) {
223
+ if (i)
224
+ fprintf(f, ",");
225
+ jv_to_txt_aux(item, f);
226
+ }
227
+ fprintf(f, "\n");
228
+ break;
229
+ case JV_KIND_OBJECT:
230
+ jv_object_foreach(value, key, item) {
231
+ jv_print_scalar(key, 0, f, 0);
232
+ fprintf(f, ",");
233
+ jv_to_txt_aux(item, f);
234
+ fprintf(f, "\n");
235
+ }
236
+ fprintf(f, "\n");
237
+ break;
238
+ default:
239
+ break;
240
+ }
241
+ }
242
+ jv_free(value);
243
+ }
244
+
245
+ void jv_to_lqjq(jv value, void *h) {
246
+ zsv_jq_handle lqjq = h;
247
+
248
+ // jv_dump_string is memory-inefficient
249
+ // would be better to create custom dump function that, instead of writing to string buffer,
250
+ // could directly invoke func()
251
+ jv jv_s = jv_dump_string(value, 0);
252
+ size_t len = jv_string_length_bytes(jv_copy(jv_s));
253
+ const char *p = jv_string_value(jv_s);
254
+ if (len)
255
+ zsv_jq_parse(lqjq, p, len);
256
+ jv_free(jv_s);
257
+ }
258
+
259
+ struct zsv_jq_data {
260
+ void *jq;
261
+ struct jv_parser *parser;
262
+ void (*func)(jv, void *);
263
+ void *ctx;
264
+
265
+ FILE *trace;
266
+ enum zsv_jq_status status;
267
+ unsigned char non_null : 1;
268
+ unsigned char _ : 7;
269
+ };
270
+
271
+ static zsv_jq_handle zsv_jq_new_aux(const unsigned char *filter, void (*func)(jv, void *), void *ctx,
272
+ enum zsv_jq_status *statusp, int init_flags) {
273
+ enum zsv_jq_status status = zsv_jq_status_ok;
274
+ struct zsv_jq_data *d = calloc(1, sizeof(*d));
275
+ if (!d || !(d->jq = jq_init()) || !(d->parser = jv_parser_new(init_flags)))
276
+ status = zsv_jq_status_memory;
277
+ else if (!jq_compile(d->jq, (const char *)filter))
278
+ status = d->status = zsv_jq_status_compile;
279
+ if (status == zsv_jq_status_ok) {
280
+ d->func = func;
281
+ d->ctx = ctx;
282
+ } else {
283
+ zsv_jq_delete(d);
284
+ d = NULL;
285
+ }
286
+ if (statusp)
287
+ *statusp = status;
288
+ return d;
289
+ }
290
+
291
+ zsv_jq_handle zsv_jq_new(const unsigned char *filter, void (*func)(jv, void *), void *ctx,
292
+ enum zsv_jq_status *statusp) {
293
+ return zsv_jq_new_aux(filter, func, ctx, statusp, 0);
294
+ }
295
+
296
+ zsv_jq_handle zsv_jq_new_stream(const unsigned char *filter, void (*func)(jv, void *), void *ctx,
297
+ enum zsv_jq_status *statusp) {
298
+ return zsv_jq_new_aux(filter, func, ctx, statusp, JV_PARSE_STREAMING);
299
+ }
300
+
301
+ void zsv_jq_delete(zsv_jq_handle h) {
302
+ if (h) {
303
+ if (h->parser)
304
+ jv_parser_free(h->parser);
305
+ if (h->jq)
306
+ jq_teardown((jq_state **)&h->jq);
307
+ free(h);
308
+ }
309
+ }
310
+
311
+ static int zsv_jq_process(jq_state *jq, jv value, void (*func)(jv, void *), void *ctx);
312
+
313
+ size_t zsv_jq_write(const char *s, size_t n, size_t m, zsv_jq_handle h) {
314
+ zsv_jq_parse(h, s, n * m);
315
+ return n * m;
316
+ }
317
+
318
+ enum zsv_jq_status zsv_jq_parse_file(zsv_jq_handle h, FILE *f) {
319
+ char buff[4096];
320
+ for (size_t bytes_read = fread(buff, 1, sizeof(buff), f); bytes_read && h->status == zsv_jq_status_ok;
321
+ bytes_read = fread(buff, 1, sizeof(buff), f)) {
322
+ zsv_jq_parse(h, buff, bytes_read);
323
+ if (feof(f))
324
+ break;
325
+ }
326
+ return h->status;
327
+ }
328
+
329
+ enum zsv_jq_status zsv_jq_parse(zsv_jq_handle restrict h, const void *restrict s, size_t len) {
330
+ if (h->status != zsv_jq_status_ok)
331
+ return h->status;
332
+
333
+ jv_parser_set_buf(h->parser, (const char *)s, len, 1);
334
+ if (h->trace)
335
+ fwrite(s, len, 1, h->trace);
336
+
337
+ jv value;
338
+ while (jv_is_valid(value = jv_parser_next(h->parser))) {
339
+ if (!h->non_null && jv_get_kind(value) != JV_KIND_NULL)
340
+ h->non_null = 1;
341
+ zsv_jq_process(h->jq, value, h->func, h->ctx);
342
+ }
343
+
344
+ jv msg = jv_invalid_get_msg(value);
345
+ if (jv_get_kind(msg) == JV_KIND_STRING) {
346
+ fprintf(stderr, "jq: parse error: %s\n", jv_string_value(msg));
347
+ h->status = zsv_jq_status_error;
348
+ } else
349
+ jv_free(msg);
350
+ jv_free(value);
351
+
352
+ return h->status;
353
+ }
354
+
355
+ void zsv_jq_trace(zsv_jq_handle h, FILE *trace) {
356
+ if (h)
357
+ h->trace = trace;
358
+ }
359
+
360
+ enum zsv_jq_status zsv_jq_finish(zsv_jq_handle h) {
361
+ jv value;
362
+ jv_parser_set_buf(h->parser, "", 0, 0);
363
+ while (jv_is_valid(value = jv_parser_next(h->parser)))
364
+ zsv_jq_process(h->jq, value, h->func, h->ctx);
365
+ return zsv_jq_status_ok;
366
+ }
367
+
368
+ static int zsv_jq_process(jq_state *jq,
369
+ jv value, // will be consumed
370
+ void (*func)(jv, void *), void *ctx) {
371
+ int ret = 14; // No valid results && -e -> exit(4)
372
+ jq_start(jq, value, 0); // consumes value
373
+
374
+ jv result;
375
+ while (jv_is_valid(result = jq_next(jq))) {
376
+ ret = 0;
377
+ func(result, ctx);
378
+ }
379
+ jv_free(result);
380
+
381
+ return ret;
382
+ }
383
+
384
+ void jv_to_bool(jv value, void *char_result) {
385
+ char *c = char_result;
386
+ switch (jv_get_kind(value)) {
387
+ case JV_KIND_TRUE:
388
+ *c = 1;
389
+ break;
390
+ case JV_KIND_FALSE:
391
+ *c = 0;
392
+ break;
393
+ case JV_KIND_NUMBER:
394
+ *c = (jv_number_value(value) > 0);
395
+ break;
396
+ default:
397
+ break;
398
+ }
399
+ jv_free(value);
400
+ }
@@ -0,0 +1,120 @@
1
+ /*
2
+ * Copyright (C) 2021 Liquidaty and the zsv/lib contributors
3
+ * All rights reserved
4
+ *
5
+ * This file is part of zsv/lib, distributed under the license defined at
6
+ * https://opensource.org/licenses/MIT
7
+ */
8
+
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <stddef.h>
12
+
13
+ static inline char is_json_esc_char(unsigned char c) {
14
+ return (c == '"' || c == '\\' || c < 32);
15
+ }
16
+
17
+ static void str2hex(unsigned char *to, const unsigned char *p, size_t len) {
18
+ static const char *hex = "0123456789abcdef";
19
+
20
+ for (; len--; p++) {
21
+ *to++ = hex[p[0] >> 4];
22
+ *to++ = hex[p[0] & 0x0f];
23
+ }
24
+ }
25
+
26
+ static inline unsigned json_esc_char(unsigned char c, char replace[]) {
27
+ unsigned replacelen;
28
+ char hex = 0;
29
+ switch (c) {
30
+ case '"':
31
+ replace[1] = '"';
32
+ break;
33
+ case '\\':
34
+ replace[1] = '\\';
35
+ break;
36
+ case '\b':
37
+ replace[1] = 'b';
38
+ break;
39
+ case '\f':
40
+ replace[1] = 'f';
41
+ break;
42
+ case '\n':
43
+ replace[1] = 'n';
44
+ break;
45
+ case '\r':
46
+ replace[1] = 'r';
47
+ break;
48
+ case '\t':
49
+ replace[1] = 't';
50
+ break;
51
+ default:
52
+ hex = 1;
53
+ }
54
+
55
+ replace[0] = '\\';
56
+ if (hex) {
57
+ // unicode-hex: but 2/3 are not always zeroes...
58
+ replace[1] = 'u';
59
+ replace[2] = '0';
60
+ replace[3] = '0';
61
+ str2hex((unsigned char *)replace + 4, &c, 1);
62
+ replacelen = 6;
63
+ replace[6] = '\0';
64
+ } else {
65
+ replacelen = 2;
66
+ replace[2] = '\0';
67
+ }
68
+ return replacelen;
69
+ }
70
+
71
+ static unsigned json_escaped_str_len(const unsigned char *s, size_t len) {
72
+ unsigned count = 0;
73
+ for (size_t i = 0; i < len; i++, count++) {
74
+ switch (s[i]) {
75
+ case '"':
76
+ case '\\':
77
+ case '\b':
78
+ case '\f':
79
+ case '\n':
80
+ case '\r':
81
+ case '\t':
82
+ count++;
83
+ break;
84
+ default:
85
+ if (s[i] < 31)
86
+ count += 6;
87
+ break;
88
+ }
89
+ }
90
+ return count + 2; // + 2 for surrounding quotation marks
91
+ }
92
+
93
+ unsigned char *zsv_json_from_str_n(const unsigned char *s, size_t len) {
94
+ size_t new_len = json_escaped_str_len(s, len);
95
+ unsigned char *new_s = calloc(new_len + 2, sizeof(*new_s));
96
+ if (new_s) {
97
+ new_s[0] = new_s[new_len - 1] = (unsigned char)'"';
98
+ if (new_len == len + 2)
99
+ memcpy(new_s + 1, s, len);
100
+ else {
101
+ char replace[8];
102
+ for (size_t i = 0, j = 1; i < len && j < new_len - 1; i++) {
103
+ if (!is_json_esc_char(s[i]))
104
+ new_s[j++] = s[i];
105
+ else {
106
+ size_t rlen = json_esc_char(s[i], replace);
107
+ memcpy(new_s + j, replace, rlen);
108
+ j += rlen;
109
+ }
110
+ }
111
+ }
112
+ }
113
+ return new_s;
114
+ }
115
+
116
+ unsigned char *zsv_json_from_str(const unsigned char *s) {
117
+ if (!s)
118
+ return (unsigned char *)strdup("null");
119
+ return zsv_json_from_str_n(s, strlen((const char *)s));
120
+ }
@@ -0,0 +1,18 @@
1
+ /*
2
+ * Copyright (C) 2021 Liquidaty and the zsv/lib contributors
3
+ * All rights reserved
4
+ *
5
+ * This file is part of zsv/lib, distributed under the license defined at
6
+ * https://opensource.org/licenses/MIT
7
+ */
8
+
9
+ #include <stdlib.h> // calloc
10
+ #include <string.h> // memcpy
11
+
12
+ /* zsv_memdup(): return copy with double-NULL terminator. caller must free() */
13
+ void *zsv_memdup(const void *src, size_t n) {
14
+ void *m = calloc(1, n + 2);
15
+ if (n)
16
+ memcpy(m, src, n);
17
+ return m;
18
+ }
@@ -0,0 +1,132 @@
1
+ // from musl 1.37.5 system/lib/libc/musl/src/string/memmem.c
2
+ // clang-format off
3
+ #include <string.h>
4
+ #include <stdint.h>
5
+ static char *twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
6
+ {
7
+ uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
8
+ for (h++, k--; k; k--, hw = hw<<8 | *++h)
9
+ if (hw == nw) return (char *)h-1;
10
+ return 0;
11
+ }
12
+ static char *threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
13
+ {
14
+ uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
15
+ uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
16
+ for (h+=2, k-=2; k; k--, hw = (hw|*++h)<<8)
17
+ if (hw == nw) return (char *)h-2;
18
+ return 0;
19
+ }
20
+ static char *fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
21
+ {
22
+ uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
23
+ uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
24
+ for (h+=3, k-=3; k; k--, hw = hw<<8 | *++h)
25
+ if (hw == nw) return (char *)h-3;
26
+ return 0;
27
+ }
28
+ #define MAX(a,b) ((a)>(b)?(a):(b))
29
+ #define MIN(a,b) ((a)<(b)?(a):(b))
30
+ #define BITOP(a,b,op) \
31
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
32
+ static char *twoway_memmem(const unsigned char *h, const unsigned char *z, const unsigned char *n, size_t l)
33
+ {
34
+ size_t i, ip, jp, k, p, ms, p0, mem, mem0;
35
+ size_t byteset[32 / sizeof(size_t)] = { 0 };
36
+ size_t shift[256];
37
+ /* Computing length of needle and fill shift table */
38
+ for (i=0; i<l; i++)
39
+ BITOP(byteset, n[i], |=), shift[n[i]] = i+1;
40
+ /* Compute maximal suffix */
41
+ ip = -1; jp = 0; k = p = 1;
42
+ while (jp+k<l) {
43
+ if (n[ip+k] == n[jp+k]) {
44
+ if (k == p) {
45
+ jp += p;
46
+ k = 1;
47
+ } else k++;
48
+ } else if (n[ip+k] > n[jp+k]) {
49
+ jp += k;
50
+ k = 1;
51
+ p = jp - ip;
52
+ } else {
53
+ ip = jp++;
54
+ k = p = 1;
55
+ }
56
+ }
57
+ ms = ip;
58
+ p0 = p;
59
+ /* And with the opposite comparison */
60
+ ip = -1; jp = 0; k = p = 1;
61
+ while (jp+k<l) {
62
+ if (n[ip+k] == n[jp+k]) {
63
+ if (k == p) {
64
+ jp += p;
65
+ k = 1;
66
+ } else k++;
67
+ } else if (n[ip+k] < n[jp+k]) {
68
+ jp += k;
69
+ k = 1;
70
+ p = jp - ip;
71
+ } else {
72
+ ip = jp++;
73
+ k = p = 1;
74
+ }
75
+ }
76
+ if (ip+1 > ms+1) ms = ip;
77
+ else p = p0;
78
+ /* Periodic needle? */
79
+ if (memcmp(n, n+p, ms+1)) {
80
+ mem0 = 0;
81
+ p = MAX(ms, l-ms-1) + 1;
82
+ } else mem0 = l-p;
83
+ mem = 0;
84
+ /* Search loop */
85
+ for (;;) {
86
+ /* If remainder of haystack is shorter than needle, done */
87
+ if (z-h < l) return 0;
88
+ /* Check last byte first; advance by shift on mismatch */
89
+ if (BITOP(byteset, h[l-1], &)) {
90
+ k = l-shift[h[l-1]];
91
+ if (k) {
92
+ if (mem0 && mem && k < p) k = l-p;
93
+ h += k;
94
+ mem = 0;
95
+ continue;
96
+ }
97
+ } else {
98
+ h += l;
99
+ mem = 0;
100
+ continue;
101
+ }
102
+ /* Compare right half */
103
+ for (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++);
104
+ if (k < l) {
105
+ h += k-ms;
106
+ mem = 0;
107
+ continue;
108
+ }
109
+ /* Compare left half */
110
+ for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
111
+ if (k <= mem) return (char *)h;
112
+ h += p;
113
+ mem = mem0;
114
+ }
115
+ }
116
+ void *zsvmemmem(const void *h0, size_t k, const void *n0, size_t l)
117
+ {
118
+ const unsigned char *h = h0, *n = n0;
119
+ /* Return immediately on empty needle */
120
+ if (!l) return (void *)h;
121
+ /* Return immediately when needle is longer than haystack */
122
+ if (k<l) return 0;
123
+ /* Use faster algorithms for short needles */
124
+ h = memchr(h0, *n, k);
125
+ if (!h || l==1) return (void *)h;
126
+ k -= h - (const unsigned char *)h0;
127
+ if (k<l) return 0;
128
+ if (l==2) return twobyte_memmem(h, k, n);
129
+ if (l==3) return threebyte_memmem(h, k, n);
130
+ if (l==4) return fourbyte_memmem(h, k, n);
131
+ return twoway_memmem(h, h+k, n, l);
132
+ }