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,131 @@
1
+ /* Copyright (C) 2022 Guarnerix Inc dba Liquidaty - All Rights Reserved
2
+ * Unauthorized copying of this file, via any medium is strictly prohibited
3
+ * Proprietary and confidential
4
+ * Written by Matt Wong <matt@guarnerix.com>
5
+ */
6
+
7
+ /*
8
+ * remove a given file and its cache
9
+ */
10
+
11
+ #include <stdlib.h>
12
+ #include <stdio.h>
13
+ #include <string.h>
14
+ #include <unistd.h> // unlink()
15
+ #include <errno.h>
16
+
17
+ #define ZSV_COMMAND_NO_OPTIONS
18
+ #define ZSV_COMMAND rm
19
+ #include "zsv_command.h"
20
+
21
+ #include <zsv/utils/dirs.h>
22
+ #include <zsv/utils/cache.h>
23
+
24
+ /**
25
+ * TO DO: add --orphaned option to remove all orphaned caches
26
+ */
27
+ const char *zsv_rm_usage_msg[] = {
28
+ APPNAME ": remove a file and its related cache",
29
+ "",
30
+ "Usage: " APPNAME " [options] <filepath>",
31
+ "",
32
+ "Options:",
33
+ " -v,--verbose : verbose output",
34
+ #ifndef NO_STDIN
35
+ " -f,--force : do not prompt for confirmation",
36
+ #endif
37
+ " -k,--keep : do not remove related cache",
38
+ " -C,--cache : only remove related cache (not the file)",
39
+ NULL,
40
+ };
41
+
42
+ static int zsv_rm_usage(FILE *target) {
43
+ for (size_t j = 0; zsv_rm_usage_msg[j]; j++)
44
+ fprintf(target, "%s\n", zsv_rm_usage_msg[j]);
45
+ return target == stdout ? 0 : 1;
46
+ }
47
+
48
+ int ZSV_MAIN_NO_OPTIONS_FUNC(ZSV_COMMAND)(int argc, const char *argv[]) {
49
+ int err = 0;
50
+ if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))
51
+ err = zsv_rm_usage(stdout);
52
+ else if (argc < 2)
53
+ err = zsv_rm_usage(stderr);
54
+ else {
55
+ const char *filepath = NULL;
56
+ char force = 0;
57
+ #ifdef NO_STDIN
58
+ force = 1;
59
+ #endif
60
+ char remove_cache = 1;
61
+ char remove_file = 1;
62
+ char verbose = 0;
63
+ for (int i = 1; !err && i < argc; i++) {
64
+ const char *arg = argv[i];
65
+ if (*arg == '-') {
66
+ if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose"))
67
+ verbose = 1;
68
+ else if (!strcmp(arg, "-f") || !strcmp(arg, "--force"))
69
+ force = 1;
70
+ else if (!strcmp(arg, "-k") || !strcmp(arg, "--keep"))
71
+ remove_cache = 0;
72
+ else if (!strcmp(arg, "-C") || !strcmp(arg, "--cache"))
73
+ remove_file = 0;
74
+ else
75
+ err = zsv_printerr(1, "Unrecognized option: %s", arg);
76
+ } else if (!filepath)
77
+ filepath = arg;
78
+ else
79
+ err = zsv_printerr(1, "Unrecognized option: %s", arg);
80
+ }
81
+
82
+ if (!err && !filepath)
83
+ err = zsv_rm_usage(stderr);
84
+ else if (remove_file == 0 && remove_cache == 0)
85
+ err = fprintf(stderr, "Nothing to remove\n");
86
+
87
+ if (!err) {
88
+ char ok = 1;
89
+ #ifndef NO_STDIN
90
+ if (!force) {
91
+ ok = 0;
92
+ if (!remove_file)
93
+ printf("Are you sure you want to remove the entire cache for the file %s?\n", filepath);
94
+ else
95
+ printf("Are you sure you want to remove the file %s%s?\n", filepath,
96
+ remove_cache ? " and all of its cache contents" : "");
97
+ char buff[64];
98
+ if (fscanf(stdin, "%60s", buff) == 1 && strchr("Yy", buff[0]))
99
+ ok = 1;
100
+ }
101
+ #endif
102
+ if (ok) {
103
+ if (remove_file) {
104
+ if (verbose)
105
+ fprintf(stderr, "Removing %s", filepath);
106
+ err = unlink(filepath);
107
+ if (err) {
108
+ if (err == ENOENT && force)
109
+ err = 0;
110
+ else
111
+ perror(filepath);
112
+ }
113
+ }
114
+ if (!err) {
115
+ unsigned char *cache_dir = zsv_cache_path((const unsigned char *)filepath, NULL, 0);
116
+ if (!cache_dir)
117
+ err = zsv_printerr(ENOMEM, "Out of memory!");
118
+ else if (zsv_dir_exists((const char *)cache_dir)) {
119
+ err = zsv_remove_dir_recursive(cache_dir);
120
+ if (verbose) {
121
+ if (!err)
122
+ fprintf(stderr, "Removed cache %s", cache_dir);
123
+ }
124
+ }
125
+ free(cache_dir);
126
+ }
127
+ }
128
+ }
129
+ }
130
+ return err;
131
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Get a list of ending positions for each column name based on the ending position of each column name
3
+ * where the first row is of the below form (dash = whitespace):
4
+ * ----COLUMN1----COLUMN2-----COLUMN3----
5
+ *
6
+ * Approach:
7
+ * - read the first [256k] of data [to do: alternatively, read only the first line]
8
+ * - merge all read lines into a single line where line[i] = 'x' for each position i at which
9
+ * a non-white char appeared in any scanned line
10
+ * - from the merged line, find each instance of white followed by not-white,
11
+ * but ignore the first instance of it
12
+ */
13
+ static enum zsv_status auto_detect_fixed_column_sizes(struct fixed *fixed, struct zsv_opts *opts, unsigned char *buff,
14
+ size_t buffsize, size_t *buff_used, char verbose) {
15
+ size_t max_lines = fixed->max_lines ? fixed->max_lines : 9999999999;
16
+ enum zsv_status stat = zsv_status_ok;
17
+
18
+ fixed->count = 0;
19
+ char *line = calloc(buffsize, sizeof(*buff));
20
+ if (!line) {
21
+ stat = zsv_status_memory;
22
+ goto auto_detect_fixed_column_sizes_exit;
23
+ }
24
+ memset(line, ' ', buffsize);
25
+
26
+ *buff_used = fread(buff, 1, buffsize, opts->stream);
27
+ if (!*buff_used) {
28
+ stat = zsv_status_no_more_input;
29
+ goto auto_detect_fixed_column_sizes_exit;
30
+ }
31
+
32
+ size_t lines_read = 0;
33
+ size_t line_end = 0;
34
+ size_t line_cursor = 0;
35
+ char first = 1;
36
+ char was_space = 1;
37
+ char was_line_end = 0;
38
+ for (size_t i = 0; i < *buff_used && (!line_end || max_lines == 0 || lines_read < max_lines);
39
+ i++, line_cursor = was_line_end ? 0 : line_cursor + 1) {
40
+ was_line_end = 0;
41
+ // TO DO: support multi-byte unicode chars?
42
+ switch (buff[i]) {
43
+ case '\n':
44
+ case '\r':
45
+ if (line_cursor > line_end)
46
+ line_end = line_cursor;
47
+ was_line_end = 1;
48
+ was_space = 1;
49
+ lines_read++;
50
+ break;
51
+ case '\t':
52
+ case '\v':
53
+ case '\f':
54
+ case ' ':
55
+ was_space = 1;
56
+ break;
57
+ default:
58
+ line[line_cursor] = 'x';
59
+ if (was_space) {
60
+ if (!line_end) { // only count columns for the first line
61
+ if (first)
62
+ first = 0;
63
+ else
64
+ fixed->count++;
65
+ }
66
+ }
67
+ was_space = 0;
68
+ }
69
+ }
70
+ if (!first)
71
+ fixed->count++;
72
+
73
+ if (!line_end) {
74
+ stat = zsv_status_error;
75
+ goto auto_detect_fixed_column_sizes_exit;
76
+ }
77
+
78
+ if (verbose)
79
+ fprintf(stderr, "Calculating %zu columns from line:\n%.*s\n", fixed->count, (int)line_end, line);
80
+
81
+ // allocate offsets
82
+ free(fixed->offsets);
83
+ fixed->offsets = NULL; // unnecessary line to silence codeQL false positive
84
+ fixed->offsets = calloc(fixed->count, sizeof(*fixed->offsets));
85
+ if (!fixed->offsets) {
86
+ stat = zsv_status_memory;
87
+ goto auto_detect_fixed_column_sizes_exit;
88
+ }
89
+
90
+ // now we have our merged line, so calculate the sizes
91
+ // do the loop again, but assign values this time
92
+ int count = 0;
93
+ was_space = 1;
94
+ first = 1;
95
+ if (verbose)
96
+ fprintf(stderr, "Running --fixed ");
97
+ size_t i;
98
+ for (i = 0; i < line_end; i++) {
99
+ if (line[i] == 'x') {
100
+ if (was_space) {
101
+ if (first)
102
+ first = 0;
103
+ else {
104
+ if (verbose)
105
+ fprintf(stderr, "%s%zu", count ? "," : "", i);
106
+ fixed->offsets[count++] = i;
107
+ }
108
+ }
109
+ was_space = 0;
110
+ } else
111
+ was_space = 1;
112
+ }
113
+ if (!first) {
114
+ if (verbose)
115
+ fprintf(stderr, "%s%zu", count ? "," : "", i);
116
+ if (i)
117
+ fixed->offsets[count++] = i;
118
+ fixed->count = count;
119
+ }
120
+ if (verbose)
121
+ fprintf(stderr, "\n");
122
+
123
+ // add a buffer to the last column in case subsequent lines are longer than what we scanned
124
+ if (fixed->count)
125
+ fixed->offsets[fixed->count - 1] += 50;
126
+
127
+ auto_detect_fixed_column_sizes_exit:
128
+ free(line);
129
+ return stat;
130
+ }
@@ -0,0 +1,118 @@
1
+ #include <sys/types.h> // Required for off_t
2
+
3
+ #ifndef ZSV_NO_PARALLEL
4
+ #include "parallel.h"
5
+ #endif
6
+
7
+ #define ZSV_SELECT_MAX_COLS_DEFAULT 1024
8
+ #define ZSV_SELECT_MAX_COLS_DEFAULT_S "1024"
9
+
10
+ struct zsv_select_search_str {
11
+ struct zsv_select_search_str *next;
12
+ const char *value;
13
+ size_t len;
14
+ };
15
+
16
+ struct zsv_select_uint_list {
17
+ struct zsv_select_uint_list *next;
18
+ unsigned int value;
19
+ };
20
+
21
+ struct fixed {
22
+ size_t *offsets;
23
+ size_t count;
24
+ size_t max_lines; // max lines to use to calculate offsets
25
+ char autodetect;
26
+ };
27
+
28
+ struct zsv_select_data {
29
+ const char *input_path;
30
+ unsigned int current_column_ix;
31
+ size_t data_row_count;
32
+
33
+ struct zsv_opts *opts;
34
+ zsv_parser parser;
35
+ unsigned int errcount;
36
+
37
+ unsigned int output_col_index; // num of cols printed in current row
38
+
39
+ // output columns:
40
+ const char **col_argv;
41
+ int col_argc;
42
+ char *cols_to_print; // better: bitfield
43
+
44
+ struct {
45
+ unsigned int ix; // index of the input column to be output
46
+ struct { // merge data: only used with --merge
47
+ struct zsv_select_uint_list *indexes, **last_index;
48
+ } merge;
49
+ } *out2in; // array of .output_cols_count length; out2in[x] = y where x = output ix, y = input info
50
+
51
+ unsigned int output_cols_count; // total count of output columns
52
+
53
+ #define MAX_EXCLUSIONS 1024
54
+ const unsigned char *exclusions[MAX_EXCLUSIONS];
55
+ unsigned int exclusion_count;
56
+
57
+ unsigned int header_name_count;
58
+ unsigned char **header_names;
59
+
60
+ const char *prepend_header; // --prepend-header
61
+
62
+ char header_finished;
63
+
64
+ char embedded_lineend;
65
+
66
+ double sample_pct;
67
+
68
+ unsigned sample_every_n;
69
+
70
+ size_t data_rows_limit;
71
+ size_t skip_data_rows;
72
+
73
+ struct zsv_select_search_str *search_strings;
74
+ #ifdef HAVE_PCRE2_8
75
+ struct zsv_select_regex *search_regexs;
76
+ #endif
77
+
78
+ zsv_csv_writer csv_writer;
79
+
80
+ size_t overflow_size;
81
+
82
+ struct fixed fixed;
83
+
84
+ #ifndef ZSV_NO_PARALLEL
85
+ unsigned num_chunks;
86
+ off_t end_offset_limit; // Byte offset where the current parser instance should stop
87
+ off_t next_row_start; // Actual byte offset of the last row that was processed
88
+ struct zsv_parallel_data *parallel_data; // Pointer to the thread management structure
89
+ #endif
90
+
91
+ // FLAGS
92
+ unsigned char whitespace_clean_flags;
93
+
94
+ unsigned char print_all_cols : 1;
95
+ unsigned char use_header_indexes : 1;
96
+ unsigned char no_trim_whitespace : 1;
97
+ unsigned char cancelled : 1;
98
+ unsigned char skip_this_row : 1;
99
+ unsigned char verbose : 1;
100
+ unsigned char clean_white : 1;
101
+ unsigned char prepend_line_number : 1;
102
+
103
+ unsigned char any_clean : 1;
104
+ #define ZSV_SELECT_DISTINCT_MERGE 2
105
+ unsigned char distinct : 2; // 1 = ignore subsequent cols, ZSV_SELECT_DISTINCT_MERGE = merge subsequent cols (first
106
+ // non-null value)
107
+ unsigned char unescape : 1;
108
+ unsigned char no_header : 1; // --no-header
109
+ unsigned char run_in_parallel : 1; // Flag if parallel mode is active
110
+ unsigned char _ : 2; // Reduced padding by 1 bit due to addition of run_in_parallel
111
+ };
112
+
113
+ enum zsv_select_column_index_selection_type {
114
+ zsv_select_column_index_selection_type_none = 0,
115
+ zsv_select_column_index_selection_type_single,
116
+ zsv_select_column_index_selection_type_range,
117
+ zsv_select_column_index_selection_type_lower_bounded
118
+ };
@@ -0,0 +1,45 @@
1
+ #include <errno.h>
2
+
3
+ static struct zsv_parallel_data *zsv_parallel_data_new(unsigned num_chunks) {
4
+ struct zsv_parallel_data *pdata = calloc(1, sizeof(*pdata));
5
+ if (pdata) {
6
+ pdata->threads = calloc(num_chunks, sizeof(*pdata->threads));
7
+ pdata->chunk_data = calloc(num_chunks, sizeof(*pdata->chunk_data));
8
+ pdata->num_chunks = num_chunks;
9
+ if (pdata->threads && pdata->chunk_data)
10
+ return pdata;
11
+ zsv_parallel_data_delete(pdata);
12
+ }
13
+ // if we got here, we had a memory allocation failure
14
+ errno = ENOMEM;
15
+ return NULL;
16
+ }
17
+
18
+ static void zsv_chunk_data_clear_output(struct zsv_chunk_data *c) {
19
+ if (c) {
20
+ #ifdef __linux__
21
+ if (c->tmp_output_filename) {
22
+ unlink(c->tmp_output_filename);
23
+ free(c->tmp_output_filename);
24
+ c->tmp_output_filename = NULL;
25
+ }
26
+ #else
27
+ if (c->tmp_f) {
28
+ zsv_memfile_close(c->tmp_f);
29
+ c->tmp_f = NULL;
30
+ }
31
+ #endif
32
+ }
33
+ }
34
+
35
+ static void zsv_parallel_data_delete(struct zsv_parallel_data *pdata) {
36
+ if (pdata) {
37
+ for (unsigned int i = 0; i < pdata->num_chunks; i++) {
38
+ if (pdata->chunk_data)
39
+ zsv_chunk_data_clear_output(&pdata->chunk_data[i]);
40
+ }
41
+ free(pdata->threads);
42
+ free(pdata->chunk_data);
43
+ free(pdata);
44
+ }
45
+ }
@@ -0,0 +1,41 @@
1
+ #ifndef ZSV_SELECT_PARALLEL_H
2
+ #define ZSV_SELECT_PARALLEL_H
3
+
4
+ #include <sys/types.h> // Required for off_t
5
+ #include <pthread.h> // Required for pthread_t
6
+
7
+ /**
8
+ * @brief Data structure passed to each worker thread (Chunk 2, 3, 4)
9
+ * Uses in-memory output buffer to avoid I/O lock contention.
10
+ */
11
+ struct zsv_chunk_data {
12
+ #ifdef __linux__
13
+ char *tmp_output_filename; // use temp file because we can use zero-copy file concatenation
14
+ #else
15
+ void *tmp_f; // use zsv_memfile * because we cannot do zero-copy file concatenation
16
+ #endif
17
+ off_t start_offset;
18
+ off_t end_offset; // Stop processing when current offset exceeds this
19
+ off_t actual_next_row_start;
20
+ struct zsv_opts *opts; // Configuration options (read-only)
21
+ enum zsv_status status;
22
+ int id;
23
+ unsigned char skip : 1;
24
+ unsigned char _ : 7;
25
+ };
26
+
27
+ /**
28
+ * @brief Structure to manage thread handles and chunk data for parallel processing.
29
+ */
30
+ struct zsv_parallel_data {
31
+ struct zsv_select_data *main_data;
32
+ unsigned num_chunks;
33
+ pthread_t *threads; // array of N (num_chunks) pointers
34
+ struct zsv_chunk_data *chunk_data; // array of N chunk datas
35
+ };
36
+
37
+ static struct zsv_parallel_data *zsv_parallel_data_new(unsigned num_chunks);
38
+ static void zsv_chunk_data_clear_output(struct zsv_chunk_data *c);
39
+ static void zsv_parallel_data_delete(struct zsv_parallel_data *pdata);
40
+
41
+ #endif
@@ -0,0 +1,107 @@
1
+ #ifndef NDEBUG
2
+ __attribute__((always_inline)) static inline
3
+ #endif
4
+ unsigned char *
5
+ zsv_select_cell_clean(struct zsv_select_data *data, unsigned char *utf8_value, char *quoted, size_t *lenp) {
6
+
7
+ size_t len = *lenp;
8
+ // to do: option to replace or warn non-printable chars 0 - 31:
9
+ // vectorized scan
10
+ // replace or warn if found
11
+ if (UNLIKELY(data->unescape)) {
12
+ size_t new_len = zsv_strunescape_backslash(utf8_value, len);
13
+ if (new_len != len) {
14
+ *quoted = 1;
15
+ len = new_len;
16
+ }
17
+ }
18
+
19
+ if (UNLIKELY(!data->no_trim_whitespace))
20
+ utf8_value = (unsigned char *)zsv_strtrim(utf8_value, &len);
21
+
22
+ if (UNLIKELY(data->clean_white))
23
+ len = zsv_strwhite(utf8_value, len, data->whitespace_clean_flags); // to do: zsv_clean
24
+
25
+ if (UNLIKELY(data->embedded_lineend && *quoted)) {
26
+ unsigned char *tmp;
27
+ const char *to_replace[] = {"\r\n", "\r", "\n"};
28
+ for (int i = 0; i < 3; i++) {
29
+ while ((tmp = memmem(utf8_value, len, to_replace[i], strlen(to_replace[i])))) {
30
+ if (strlen(to_replace[i]) == 1)
31
+ *tmp = data->embedded_lineend;
32
+ else {
33
+ size_t right_len = utf8_value + len - tmp;
34
+ memmove(tmp + 1, tmp + 2, right_len - 2);
35
+ *tmp = data->embedded_lineend;
36
+ len--;
37
+ }
38
+ }
39
+ }
40
+ if (data->no_trim_whitespace)
41
+ utf8_value = (unsigned char *)zsv_strtrim(utf8_value, &len);
42
+ }
43
+ *lenp = len;
44
+ return utf8_value;
45
+ }
46
+
47
+ static inline char zsv_select_row_search_hit(struct zsv_select_data *data) {
48
+ if (!data->search_strings
49
+ #ifdef HAVE_PCRE2_8
50
+ && !data->search_regexs
51
+ #endif
52
+ )
53
+ return 1;
54
+
55
+ char have_overwrite = 0;
56
+ unsigned int j = zsv_cell_count(data->parser);
57
+ // Convert all bytes between cells to NUL so we can accurately search the entire row in one goe
58
+ unsigned char *start = NULL;
59
+ unsigned char *end = NULL;
60
+ for (unsigned int i = 0; i < j; i++) {
61
+ struct zsv_cell cell = zsv_get_cell(data->parser, i);
62
+ if (cell.overwritten)
63
+ have_overwrite = 1;
64
+ if (i == 0)
65
+ start = cell.str;
66
+ if (UNLIKELY(data->any_clean != 0))
67
+ cell.str = zsv_select_cell_clean(data, cell.str, &cell.quoted, &cell.len);
68
+ if (end) {
69
+ while (end < cell.str) {
70
+ *end = '\0';
71
+ end++;
72
+ }
73
+ }
74
+ end = cell.str + cell.len;
75
+ }
76
+
77
+ if (have_overwrite) {
78
+ for (unsigned int i = 0; i < j; i++) {
79
+ struct zsv_cell cell = zsv_get_cell(data->parser, i);
80
+ if (cell.len) {
81
+ start = cell.str;
82
+ end = cell.str + cell.len;
83
+ for (struct zsv_select_search_str *ss = data->search_strings; ss; ss = ss->next)
84
+ if (ss->value && *ss->value && end > start && memmem(start, end - start, ss->value, ss->len))
85
+ return 1;
86
+ #ifdef HAVE_PCRE2_8
87
+ for (struct zsv_select_regex *rs = data->search_regexs; rs; rs = rs->next)
88
+ if (rs->regex && zsv_pcre2_8_match(rs->regex, start, end - start))
89
+ return 1;
90
+ #endif
91
+ }
92
+ }
93
+ } else {
94
+ if (end > start) {
95
+ for (struct zsv_select_search_str *ss = data->search_strings; ss; ss = ss->next)
96
+ if (ss->value && *ss->value && end > start && memmem(start, end - start, ss->value, ss->len))
97
+ return 1;
98
+
99
+ #ifdef HAVE_PCRE2_8
100
+ for (struct zsv_select_regex *rs = data->search_regexs; rs; rs = rs->next)
101
+ if (rs->regex && zsv_pcre2_8_match(rs->regex, start, end - start))
102
+ return 1;
103
+ #endif
104
+ }
105
+ }
106
+ return 0;
107
+ }
@@ -0,0 +1,20 @@
1
+ // demo_random_bw_1_and_100(): this is a poor random number generator. you probably
2
+ // will want to use a better one
3
+ static double demo_random_bw_1_and_100(void) {
4
+ #ifdef HAVE_ARC4RANDOM_UNIFORM
5
+ return (long double)(arc4random_uniform(1000000)) / 10000;
6
+ #else
7
+ double max = 100.0;
8
+ unsigned int n;
9
+ #ifdef HAVE_RAND_S
10
+ unsigned int tries = 0;
11
+ while (rand_s(&n) && tries++ < 10)
12
+ ;
13
+ return (double)n / ((double)UINT_MAX + 1) * max;
14
+ #else
15
+ unsigned int umax = ~0;
16
+ n = rand();
17
+ return (double)n / ((double)(umax) + 1) * max;
18
+ #endif
19
+ #endif
20
+ }
@@ -0,0 +1,61 @@
1
+ #ifdef HAVE_PCRE2_8
2
+
3
+ #include "../utils/pcre2-8/pcre2-8.h"
4
+
5
+ struct zsv_select_regex {
6
+ struct zsv_select_regex *next;
7
+ const char *pattern;
8
+ regex_handle_t *regex;
9
+ // unsigned char has_anchors:1;
10
+ unsigned char _ : 7;
11
+ };
12
+
13
+ static void zsv_select_regexs_delete(struct zsv_select_regex *rs) {
14
+ for (struct zsv_select_regex *next; rs; rs = next) {
15
+ next = rs->next;
16
+ zsv_pcre2_8_delete(rs->regex);
17
+ free(rs);
18
+ }
19
+ }
20
+
21
+ static void zsv_select_add_regex(struct zsv_select_data *data, const char *pattern) {
22
+ if (pattern && *pattern) {
23
+ struct zsv_select_regex *sr = calloc(1, sizeof(*sr));
24
+ sr->pattern = pattern;
25
+ sr->regex = zsv_pcre2_8_new(pattern, 0);
26
+ if (sr->regex) {
27
+ sr->next = data->search_regexs;
28
+ data->search_regexs = sr;
29
+ } else
30
+ free(sr->regex);
31
+ }
32
+ }
33
+
34
+ /**
35
+ * @brief create a full, independent duplicate of the regex list
36
+ */
37
+ static struct zsv_select_regex *zsv_select_regexs_dup(struct zsv_select_regex *src) {
38
+ struct zsv_select_regex *head = NULL;
39
+ struct zsv_select_regex **tail = &head;
40
+
41
+ while (src) {
42
+ struct zsv_select_regex *new_node = calloc(1, sizeof(*new_node));
43
+ if (!new_node) {
44
+ zsv_select_regexs_delete(head);
45
+ return NULL;
46
+ }
47
+
48
+ // Copy the pattern pointer (safe, strings are static/const)
49
+ new_node->pattern = src->pattern;
50
+
51
+ // FULL RECOMPILE: Call the standard new() function.
52
+ // This creates a fresh pcre2_code AND a fresh match_data buffer.
53
+ new_node->regex = zsv_pcre2_8_new(src->pattern, 0);
54
+
55
+ *tail = new_node;
56
+ tail = &new_node->next;
57
+ src = src->next;
58
+ }
59
+ return head;
60
+ }
61
+ #endif
@@ -0,0 +1,14 @@
1
+ static void zsv_select_search_str_delete(struct zsv_select_search_str *ss) {
2
+ for (struct zsv_select_search_str *next; ss; ss = next) {
3
+ next = ss->next;
4
+ free(ss);
5
+ }
6
+ }
7
+
8
+ static void zsv_select_add_search(struct zsv_select_data *data, const char *value) {
9
+ struct zsv_select_search_str *ss = calloc(1, sizeof(*ss));
10
+ ss->value = value;
11
+ ss->len = value ? strlen(value) : 0;
12
+ ss->next = data->search_strings;
13
+ data->search_strings = ss;
14
+ }