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,393 @@
1
+ /*
2
+ * Copyright (C) 2021 Liquidaty and zsv contributors. All rights reserved.
3
+ *
4
+ * This file is part of zsv/lib, distributed under the MIT license as defined at
5
+ * https://opensource.org/licenses/MIT
6
+ */
7
+
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <sglib.h>
12
+
13
+ #define ZSV_COMMAND stack
14
+ #include "zsv_command.h"
15
+
16
+ #include <zsv/utils/writer.h>
17
+ #include <zsv/utils/mem.h>
18
+ #include <zsv/utils/string.h>
19
+
20
+ const char *zsv_stack_usage_msg[] = {
21
+ APPNAME ": stack one or more csv files vertically, aligning columns with the same name",
22
+ "",
23
+ "Usage: " APPNAME " [options] filename [filename...]",
24
+ "",
25
+ "Options:",
26
+ " -o <filename> : output file",
27
+ " -b : output with BOM",
28
+ " -q : always add double-quotes",
29
+ // " --prepend-filename : output source filename as the first column of each output row",
30
+ " --unique : only output unique column names;",
31
+ " in case of duplicates, only the last (right-most) column will be kept",
32
+ NULL,
33
+ };
34
+
35
+ static int zsv_stack_usage(void) {
36
+ for (size_t i = 0; zsv_stack_usage_msg[i]; i++)
37
+ fprintf(stdout, "%s\n", zsv_stack_usage_msg[i]);
38
+ return 0;
39
+ }
40
+
41
+ typedef struct zsv_stack_colname {
42
+ struct zsv_stack_colname *next;
43
+ char unsigned *orig_name;
44
+ char unsigned *name;
45
+ unsigned occurrence;
46
+ unsigned dupes;
47
+ size_t global_position;
48
+ unsigned char color;
49
+ struct zsv_stack_colname *left;
50
+ struct zsv_stack_colname *right;
51
+ unsigned int raw_col_ix_plus_1;
52
+ } zsv_stack_colname;
53
+
54
+ static struct zsv_stack_colname *zsv_stack_colname_init(struct zsv_stack_colname *e, const unsigned char *name,
55
+ size_t len, unsigned occurrence) {
56
+ memset(e, 0, sizeof(*e));
57
+ if (len)
58
+ e->name = zsv_strtolowercase(name, &len);
59
+ else
60
+ e->name = calloc(1, 2);
61
+ e->occurrence = occurrence;
62
+ return e;
63
+ }
64
+
65
+ static void zsv_stack_colname_free(struct zsv_stack_colname *e) {
66
+ if (e->name)
67
+ free(e->name);
68
+ if (e->orig_name)
69
+ free(e->orig_name);
70
+ }
71
+
72
+ static void zsv_stack_colname_delete(struct zsv_stack_colname *e) {
73
+ zsv_stack_colname_free(e);
74
+ free(e);
75
+ }
76
+
77
+ static int zsv_stack_colname_cmp(zsv_stack_colname *x, zsv_stack_colname *y) {
78
+ int i = strcmp((const char *)x->name, (const char *)y->name);
79
+ if (i == 0)
80
+ return x->occurrence == y->occurrence ? 0 : x->occurrence > y->occurrence ? 1 : -1;
81
+ return i;
82
+ }
83
+
84
+ SGLIB_DEFINE_RBTREE_PROTOTYPES(zsv_stack_colname, left, right, color, zsv_stack_colname_cmp);
85
+ SGLIB_DEFINE_RBTREE_FUNCTIONS(zsv_stack_colname, left, right, color, zsv_stack_colname_cmp);
86
+
87
+ static void zsv_stack_colname_tree_delete(zsv_stack_colname **tree) {
88
+ if (tree && *tree) {
89
+ struct sglib_zsv_stack_colname_iterator it;
90
+ struct zsv_stack_colname *e;
91
+ for (e = sglib_zsv_stack_colname_it_init(&it, *tree); e; e = sglib_zsv_stack_colname_it_next(&it))
92
+ zsv_stack_colname_delete(e);
93
+ *tree = NULL;
94
+ }
95
+ }
96
+
97
+ struct zsv_stack_data;
98
+ struct zsv_stack_input_file {
99
+ struct zsv_stack_input_file *next;
100
+ FILE *f;
101
+ const char *fname;
102
+ zsv_parser parser;
103
+
104
+ // output_column_map[x] = n where x = output col ix, n = 0 if no map, else raw_column_ix
105
+ zsv_stack_colname *colnames;
106
+ size_t *output_column_map;
107
+ size_t output_column_map_size;
108
+ size_t header_row_end_offset; // location in buff at which the data row begins
109
+ struct zsv_stack_data *ctx;
110
+ unsigned char headers_done : 1;
111
+ unsigned char _ : 7;
112
+ };
113
+
114
+ struct zsv_stack_data {
115
+ struct zsv_stack_input_file *inputs;
116
+ struct zsv_stack_input_file *current_input;
117
+
118
+ unsigned inputs_count;
119
+ unsigned current_input_ix;
120
+ zsv_stack_colname *colnames;
121
+ zsv_stack_colname *first_colname;
122
+ zsv_stack_colname *last_colname;
123
+ unsigned colnames_count;
124
+ int err;
125
+
126
+ zsv_csv_writer csv_writer;
127
+
128
+ unsigned char unique_column_names : 1;
129
+ unsigned char _ : 7;
130
+ };
131
+
132
+ static struct zsv_stack_input_file **zsv_stack_input_file_add(const char *filename,
133
+ struct zsv_stack_input_file **target, unsigned *count,
134
+ FILE *f, struct zsv_stack_data *ctx) {
135
+ struct zsv_stack_input_file *e = calloc(1, sizeof(*e));
136
+ if (e) {
137
+ e->f = f;
138
+ e->fname = filename;
139
+ e->ctx = ctx;
140
+ *target = e;
141
+ (*count)++;
142
+ return &e->next;
143
+ }
144
+ return target;
145
+ }
146
+
147
+ static void zsv_stack_input_files_delete(struct zsv_stack_input_file *list) {
148
+ for (struct zsv_stack_input_file *next, *e = list; e; e = next) {
149
+ next = e->next;
150
+ if (e->f)
151
+ fclose(e->f);
152
+ if (e->output_column_map)
153
+ free(e->output_column_map);
154
+ zsv_stack_colname_tree_delete(&e->colnames);
155
+ zsv_delete(e->parser);
156
+ free(e);
157
+ }
158
+ }
159
+
160
+ static void zsv_stack_cleanup(struct zsv_stack_data *data) {
161
+ zsv_stack_input_files_delete(data->inputs);
162
+ zsv_stack_colname_tree_delete(&data->colnames);
163
+ zsv_writer_delete(data->csv_writer);
164
+ }
165
+
166
+ static struct zsv_stack_colname *zsv_stack_colname_get_or_add(struct zsv_cell c, unsigned occurrence,
167
+ struct zsv_stack_colname **tree, int *added) {
168
+ const unsigned char *name = c.str;
169
+ size_t name_len = c.len;
170
+ struct zsv_stack_colname e;
171
+ zsv_stack_colname_init(&e, name, name_len, occurrence);
172
+ struct zsv_stack_colname *found = sglib_zsv_stack_colname_find_member(*tree, &e);
173
+ if (found) {
174
+ found->dupes++;
175
+ zsv_stack_colname_free(&e);
176
+ } else {
177
+ found = calloc(1, sizeof(*found));
178
+ if (found) {
179
+ *added = 1;
180
+ *found = e;
181
+ if (name)
182
+ found->orig_name = name ? zsv_memdup(name, name_len) : calloc(1, 2);
183
+ sglib_zsv_stack_colname_add(tree, found);
184
+ }
185
+ }
186
+ return found;
187
+ }
188
+
189
+ // zsv_stack_consolidate_header(): return global position
190
+ static unsigned zsv_stack_consolidate_header(struct zsv_stack_data *d, struct zsv_cell cell, unsigned occurrence) {
191
+ int added = 0;
192
+ zsv_stack_colname *c = zsv_stack_colname_get_or_add(cell, occurrence, &d->colnames, &added);
193
+ if (!c)
194
+ d->err = 1;
195
+ else {
196
+ if (added) {
197
+ c->global_position = ++d->colnames_count;
198
+ if (d->last_colname)
199
+ d->last_colname->next = c;
200
+ else
201
+ d->first_colname = c;
202
+ d->last_colname = c;
203
+ }
204
+ return c->global_position;
205
+ }
206
+ return 0;
207
+ }
208
+
209
+ static void zsv_stack_header_row(void *ctx) {
210
+ struct zsv_stack_input_file *input = ctx;
211
+ if (!input->headers_done && !zsv_row_is_blank(input->parser)) { // skip any blank leading rows
212
+ input->headers_done = 1;
213
+ zsv_abort(input->parser);
214
+ }
215
+ }
216
+
217
+ static void zsv_stack_data_row(void *ctx) {
218
+ struct zsv_stack_input_file *input = ctx;
219
+ if (!input->headers_done) {
220
+ input->headers_done = 1;
221
+ return;
222
+ }
223
+ if (!zsv_row_is_blank(input->parser)) {
224
+ size_t colnames_count = input->ctx->colnames_count;
225
+ for (unsigned i = 0; i < colnames_count; i++) {
226
+ size_t raw_ix_plus_1;
227
+ if (i < input->output_column_map_size && ((raw_ix_plus_1 = input->output_column_map[i]))) {
228
+ struct zsv_cell cell = zsv_get_cell(input->parser, raw_ix_plus_1 - 1);
229
+ zsv_writer_cell(input->ctx->csv_writer, !i, cell.str, cell.len, cell.quoted);
230
+ } else
231
+ zsv_writer_cell(input->ctx->csv_writer, !i, 0x0, 0, 0);
232
+ }
233
+ }
234
+ }
235
+
236
+ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *opts,
237
+ struct zsv_prop_handler *custom_prop_handler) {
238
+ int err = 0;
239
+ if (argc < 2) {
240
+ zsv_stack_usage();
241
+ return 1;
242
+ }
243
+
244
+ if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))
245
+ return zsv_stack_usage();
246
+
247
+ struct zsv_opts saved_opts = *opts;
248
+ struct zsv_stack_data data = {0};
249
+ struct zsv_csv_writer_options writer_opts = zsv_writer_get_default_opts();
250
+ writer_opts.stream = stdout;
251
+
252
+ struct zsv_stack_input_file **next_input = &data.inputs;
253
+ for (int arg_i = 1; !data.err && arg_i < argc; arg_i++) {
254
+ const char *arg = argv[arg_i];
255
+ if (!strcmp(arg, "-b"))
256
+ writer_opts.with_bom = 1;
257
+ // else if (!strcmp(arg, "--prepend-filename")_)
258
+ // data.prepend_filename
259
+ else if (!strcmp(arg, "--unique"))
260
+ data.unique_column_names = 1;
261
+ else if (!strcmp(arg, "-o")) {
262
+ arg_i++;
263
+ if (arg_i >= argc)
264
+ fprintf(stderr, "-o option: no filename specified\n");
265
+ else {
266
+ if (!(writer_opts.stream = fopen(argv[arg_i], "wb"))) {
267
+ data.err = 1;
268
+ fprintf(stderr, "Unable to open file for writing: %s\n", argv[arg_i]);
269
+ }
270
+ }
271
+ } else if (*arg == '-') {
272
+ fprintf(stderr, "Unrecognized option: %s\n", arg);
273
+ data.err = 1;
274
+ } else {
275
+ FILE *f = fopen(arg, "rb");
276
+ if (!f) {
277
+ fprintf(stderr, "Could not open file for reading: %s\n", arg);
278
+ data.err = 1;
279
+ } else
280
+ next_input = zsv_stack_input_file_add(arg, next_input, &data.inputs_count, f, &data);
281
+ }
282
+ }
283
+
284
+ if (!(data.csv_writer = zsv_writer_new(&writer_opts)))
285
+ data.err = 1;
286
+
287
+ // collect all header names so we can line them up
288
+ unsigned i = 0;
289
+ for (struct zsv_stack_input_file *input = data.inputs; !data.err && input; input = input->next, i++) {
290
+ *opts = saved_opts;
291
+ opts->row_handler = zsv_stack_header_row;
292
+ opts->ctx = input;
293
+
294
+ // to do: max_cell_size
295
+ opts->stream = input->f;
296
+ if (zsv_new_with_properties(opts, custom_prop_handler, input->fname, &input->parser) != zsv_status_ok)
297
+ data.err = 1;
298
+ else {
299
+ zsv_handle_ctrl_c_signal();
300
+ enum zsv_status status;
301
+ while (!data.err && !input->headers_done && (status = zsv_parse_more(input->parser)) == zsv_status_ok)
302
+ ;
303
+ }
304
+ }
305
+
306
+ // we have read the header row of each input, so:
307
+ // - consolidate a column header names into a single list
308
+ // - assign output->input column mappings for each input
309
+
310
+ // first, get maximum size of consolidated cols, which is just the sum of the column count
311
+ // of all inputs
312
+ size_t max_columns_count = 0;
313
+ for (struct zsv_stack_input_file *input = data.inputs; !data.err && input; input = input->next)
314
+ max_columns_count += zsv_cell_count(input->parser);
315
+
316
+ // next, for each input, align the input columns with the output columns
317
+ for (struct zsv_stack_input_file *input = data.inputs; input && !data.err; input = input->next) {
318
+ if (max_columns_count) {
319
+ if (!(input->output_column_map = calloc(max_columns_count, sizeof(*input->output_column_map))))
320
+ data.err = 1;
321
+ else {
322
+ input->output_column_map_size = max_columns_count;
323
+ // assign column indexes to global columns
324
+ size_t cols_used = zsv_cell_count(input->parser);
325
+ for (unsigned col_ix = 0; col_ix < cols_used; col_ix++) {
326
+ struct zsv_cell cell = zsv_get_cell(input->parser, col_ix);
327
+ unsigned occurrence = 0;
328
+ if (!data.unique_column_names) {
329
+ int added;
330
+ zsv_stack_colname *c = zsv_stack_colname_get_or_add(cell, 0, &input->colnames, &added);
331
+ if (c)
332
+ occurrence = c->dupes;
333
+ }
334
+ size_t output_ix = zsv_stack_consolidate_header(&data, cell, occurrence);
335
+ if (output_ix)
336
+ input->output_column_map[output_ix - 1] = col_ix + 1;
337
+ }
338
+ }
339
+ }
340
+ zsv_delete(input->parser);
341
+ input->parser = NULL;
342
+ }
343
+
344
+ // not necessary, but free up unused memory by resizing each input's output_column_map
345
+ for (struct zsv_stack_input_file *input = data.inputs; input && !data.err; input = input->next) {
346
+ if (!data.colnames_count) {
347
+ if (input->output_column_map) {
348
+ free(input->output_column_map);
349
+ input->output_column_map = NULL;
350
+ }
351
+ } else {
352
+ size_t *resized = realloc(input->output_column_map, data.colnames_count * sizeof(*resized));
353
+ if (resized)
354
+ input->output_column_map = resized;
355
+ }
356
+ }
357
+
358
+ // print headers
359
+ for (struct zsv_stack_colname *e = data.first_colname; !data.err && e; e = e->next) {
360
+ const unsigned char *name = e->orig_name ? e->orig_name : e->name ? e->name : (const unsigned char *)"";
361
+ zsv_writer_cell(data.csv_writer, e == data.first_colname, name, strlen((const char *)name), 1);
362
+ }
363
+
364
+ // process data
365
+ for (struct zsv_stack_input_file *input = data.inputs; input && !data.err; input = input->next, i++) {
366
+ if (input->headers_done) {
367
+ *opts = saved_opts;
368
+ opts->row_handler = zsv_stack_data_row;
369
+ opts->ctx = input;
370
+
371
+ rewind(input->f);
372
+ input->headers_done = 0;
373
+ opts->stream = input->f;
374
+ if (zsv_new_with_properties(opts, custom_prop_handler, input->fname, &input->parser) != zsv_status_ok)
375
+ data.err = 1;
376
+ else {
377
+ enum zsv_status status = zsv_status_ok;
378
+ while (status == zsv_status_ok && !data.err && (status = zsv_parse_more(input->parser)) == zsv_status_ok)
379
+ ;
380
+ zsv_finish(input->parser);
381
+ zsv_delete(input->parser);
382
+ input->parser = NULL;
383
+ }
384
+ }
385
+ }
386
+ err = data.err;
387
+ zsv_stack_cleanup(&data);
388
+
389
+ if (writer_opts.stream && writer_opts.stream != stdout)
390
+ fclose(writer_opts.stream);
391
+
392
+ return err;
393
+ }
@@ -0,0 +1,322 @@
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 <stdio.h>
11
+ #include <string.h>
12
+ #include <zsv.h>
13
+ #include <zsv/utils/string.h>
14
+ #include <zsv/utils/arg.h>
15
+ #include <assert.h>
16
+
17
+ /*
18
+ * for now we don't really need thread support because this is only being used
19
+ * by the CLI. However, it's here anyway in case future enhancements or
20
+ * user customizations need multithreading support
21
+ */
22
+ #ifndef ZSVTLS
23
+ #ifndef NO_THREADING
24
+ #define ZSVTLS _Thread_local
25
+ #else
26
+ #define ZSVTLS
27
+ #endif
28
+ #endif
29
+ /*
30
+ * global zsv_default_opts for convenience funcs zsv_get_default_opts() and zsv_set_default_opts()
31
+ * for the cli to pass global opts to the standalone modules
32
+ */
33
+
34
+ /*
35
+ * Use a single function for all default-option operations, so as to be able
36
+ * to use thread-local storage with static initializer
37
+ */
38
+ static struct zsv_opts *zsv_with_default_opts(char mode) {
39
+ ZSVTLS static char zsv_default_opts_initd = 0;
40
+ ZSVTLS static struct zsv_opts zsv_default_opts = {0};
41
+
42
+ switch (mode) {
43
+ case 'c': // clear
44
+ memset(&zsv_default_opts, 0, sizeof(zsv_default_opts));
45
+ zsv_default_opts_initd = 0;
46
+ break;
47
+ case 'g': // get
48
+ if (!zsv_default_opts_initd) {
49
+ zsv_default_opts_initd = 1;
50
+ zsv_default_opts.max_row_size = ZSV_ROW_MAX_SIZE_DEFAULT;
51
+ zsv_default_opts.max_columns = ZSV_MAX_COLS_DEFAULT;
52
+ } else {
53
+ zsv_default_opts.max_row_size =
54
+ zsv_default_opts.max_row_size ? zsv_default_opts.max_row_size : ZSV_ROW_MAX_SIZE_DEFAULT;
55
+ zsv_default_opts.max_columns = zsv_default_opts.max_columns ? zsv_default_opts.max_columns : ZSV_MAX_COLS_DEFAULT;
56
+ }
57
+ break;
58
+ }
59
+ return &zsv_default_opts;
60
+ }
61
+
62
+ ZSV_EXPORT
63
+ void zsv_clear_default_opts(void) {
64
+ zsv_with_default_opts('c');
65
+ }
66
+
67
+ ZSV_EXPORT
68
+ struct zsv_opts zsv_get_default_opts(void) {
69
+ return *zsv_with_default_opts('g');
70
+ }
71
+
72
+ ZSV_EXPORT
73
+ void zsv_set_default_opts(struct zsv_opts opts) {
74
+ *zsv_with_default_opts(0) = opts;
75
+ }
76
+
77
+ /**
78
+ * str_array_index_of: return index in list, or size of list if not found
79
+ */
80
+ static inline int str_array_index_of(const char *list[], const char *s) {
81
+ int i;
82
+ for (i = 0; list[i] && strcmp(list[i], s); i++)
83
+ ;
84
+ return i;
85
+ }
86
+
87
+ #ifdef ZSV_EXTRAS
88
+
89
+ ZSV_EXPORT
90
+ void zsv_set_default_progress_callback(zsv_progress_callback cb, void *ctx, size_t rows_interval,
91
+ unsigned int seconds_interval) {
92
+ struct zsv_opts opts = zsv_get_default_opts();
93
+ opts.progress.callback = cb;
94
+ opts.progress.ctx = ctx;
95
+ opts.progress.rows_interval = rows_interval;
96
+ opts.progress.seconds_interval = seconds_interval;
97
+ zsv_set_default_opts(opts);
98
+ }
99
+
100
+ ZSV_EXPORT
101
+ void zsv_set_default_completed_callback(zsv_completed_callback cb, void *ctx) {
102
+ struct zsv_opts opts = zsv_get_default_opts();
103
+ opts.completed.callback = cb;
104
+ opts.completed.ctx = ctx;
105
+ zsv_set_default_opts(opts);
106
+ }
107
+
108
+ #endif
109
+
110
+ /**
111
+ * Convert common command-line arguments to zsv_opts
112
+ * Return new argc/argv values with processed args stripped out
113
+ * Initializes opts_out with `zsv_get_default_opts()`, then with
114
+ * the below common options if present:
115
+ * -B,--buff-size <N>
116
+ * -c,--max-column-count <N>
117
+ * -r,--max-row-size <N>
118
+ * -t,--tab-delim
119
+ * -O,--other-delim <C>
120
+ * -q,--no-quote
121
+ * -R,--skip-head <n>: skip specified number of initial rows
122
+ * -d,--header-row-span <n> : apply header depth (rowspan) of n
123
+ * -u,--malformed-utf8-replacement <string>: replacement string (can be empty) in case of malformed UTF8
124
+ * input (default for "desc" command is '?') -S,--keep-blank-headers : disable default behavior of ignoring leading
125
+ * blank rows -0,--header-row <header> : insert the provided CSV as the first row (in position 0) e.g. --header-row
126
+ * 'col1,col2,\"my col 3\"'", -v,--verbose
127
+ * -1,--apply-overwrites: automatically apply cached overwrites
128
+ *
129
+ * @param argc count of args to process
130
+ * @param argv args to process
131
+ * @param argc_out count of unprocessed args
132
+ * @param argv_out array of unprocessed arg values. Must be allocated by caller
133
+ * with size of at least argc * sizeof(*argv)
134
+ * @param opts_out options, updated to reflect any processed args
135
+ * @return zero on success, non-zero on error
136
+ */
137
+ ZSV_EXPORT
138
+ enum zsv_status zsv_args_to_opts(int argc, const char *argv[], int *argc_out, const char **argv_out,
139
+ struct zsv_opts *opts_out) {
140
+ #ifdef ZSV_EXTRAS
141
+ static const char *short_args = "BcrtOqvRdSu01L";
142
+ #else
143
+ static const char *short_args = "BcrtOqvRdSu0";
144
+ #endif
145
+
146
+ static const char *long_args[] = {
147
+ "buff-size",
148
+ "max-column-count",
149
+ "max-row-size",
150
+ "tab-delim",
151
+ "other-delim",
152
+ "no-quote",
153
+ "verbose",
154
+ "skip-head",
155
+ "header-row-span",
156
+ "keep-blank-headers",
157
+ "malformed-utf8-replacement",
158
+ "header-row",
159
+ #ifdef ZSV_EXTRAS
160
+ "apply-overwrites",
161
+ "limit-rows",
162
+ #endif
163
+ NULL,
164
+ };
165
+
166
+ *opts_out = zsv_get_default_opts();
167
+ int options_start = 1; // skip this many args before we start looking for options
168
+ int err = 0;
169
+ int new_argc = 0;
170
+ for (; new_argc < options_start && new_argc < argc; new_argc++)
171
+ argv_out[new_argc] = argv[new_argc];
172
+
173
+ for (int i = options_start; !err && i < argc; i++) {
174
+ char arg = 0;
175
+ if (*argv[i] != '-') { /* pass this option through */
176
+ argv_out[new_argc++] = argv[i];
177
+ continue;
178
+ }
179
+ unsigned found_ix = 0;
180
+ if (argv[i][1] != '-') {
181
+ char *strchr_result;
182
+ if (!argv[i][2] && (strchr_result = strchr(short_args, argv[i][1]))) {
183
+ arg = argv[i][1];
184
+ found_ix = strchr_result - short_args;
185
+ }
186
+ #ifndef ZSV_NO_ONLY_CRLF
187
+ } else if (!strcmp(argv[i] + 2, "only-crlf")) {
188
+ opts_out->only_crlf_rowend = 1;
189
+ continue;
190
+ #endif
191
+ } else {
192
+ found_ix = str_array_index_of(long_args, argv[i] + 2);
193
+ arg = short_args[found_ix];
194
+ }
195
+
196
+ char processed = 1;
197
+ switch (arg) {
198
+ case 't':
199
+ opts_out->delimiter = '\t';
200
+ break;
201
+ case 'S':
202
+ opts_out->keep_empty_header_rows = 1;
203
+ break;
204
+ case 'q':
205
+ opts_out->no_quotes = 1;
206
+ break;
207
+ case 'v':
208
+ opts_out->verbose = 1;
209
+ break;
210
+ #ifdef ZSV_EXTRAS
211
+ case '1':
212
+ opts_out->overwrite_auto = 1;
213
+ break;
214
+ case 'L':
215
+ #endif
216
+ case 'B':
217
+ case 'c':
218
+ case 'r':
219
+ case 'O':
220
+ case 'R':
221
+ case 'd':
222
+ case 'u':
223
+ case '0':
224
+ if (++i >= argc)
225
+ err = fprintf(stderr, "Error: option %s requires a value\n", argv[i - 1]);
226
+ else {
227
+ const char *val = argv[i];
228
+ if (arg == 'O') {
229
+ if (strlen(val) != 1 || *val == 0)
230
+ err = fprintf(stderr, "Error: delimiter '%s' may only be a single ascii character", val);
231
+ else if (strchr("\n\r\"", *val))
232
+ err = fprintf(stderr, "Error: column delimiter may not be '\\n', '\\r' or '\"'\n");
233
+ else
234
+ opts_out->delimiter = *val;
235
+ } else if (arg == 'u') {
236
+ if (!strcmp(val, "none"))
237
+ opts_out->malformed_utf8_replace = ZSV_MALFORMED_UTF8_DO_NOT_REPLACE;
238
+ else if (!*val)
239
+ opts_out->malformed_utf8_replace = ZSV_MALFORMED_UTF8_REMOVE;
240
+ else if (strlen(val) > 2 || *val < 0)
241
+ err =
242
+ fprintf(stderr, "Error: %s value must be a single-byte UTF8 char, empty string or 'none'\n", argv[i - 1]);
243
+ else
244
+ opts_out->malformed_utf8_replace = *val;
245
+ } else if (arg == '0') {
246
+ if (*val == 0)
247
+ err = fprintf(stderr, "Invalid empty Inserted header row\n");
248
+ else
249
+ opts_out->insert_header_row = argv[i];
250
+ } else {
251
+ /* arg = 'B', 'c', 'r', 'R', 'd', or 'L' (ZSV_EXTRAS only) */
252
+ long n = atol(val);
253
+ if (n < 0)
254
+ err = fprintf(stderr, "Error: option %s value may not be less than zero (got %li\n", val, n);
255
+ #ifdef ZSV_EXTRAS
256
+ else if (arg == 'L') {
257
+ if (n < 1)
258
+ err = fprintf(stderr, "Error: max rows may not be less than 1 (got %s)\n", val);
259
+ else
260
+ opts_out->max_rows = n;
261
+ } else
262
+ #endif
263
+ if (arg == 'B') {
264
+ if (n < ZSV_MIN_SCANNER_BUFFSIZE)
265
+ err =
266
+ fprintf(stderr, "Error: buff size may not be less than %u (got %s)\n", ZSV_MIN_SCANNER_BUFFSIZE, val);
267
+ else
268
+ opts_out->buffsize = n;
269
+ } else if (arg == 'c') {
270
+ if (n < 8)
271
+ err = fprintf(stderr, "Error: max column count may not be less than 8 (got %s)\n", val);
272
+ else
273
+ opts_out->max_columns = n;
274
+ } else if (arg == 'r') {
275
+ if (n < ZSV_ROW_MAX_SIZE_MIN)
276
+ err = fprintf(stderr, "Error: max row size size may not be less than %u (got %s)\n", ZSV_ROW_MAX_SIZE_MIN,
277
+ val);
278
+ else
279
+ opts_out->max_row_size = n;
280
+ } else if (arg == 'd') {
281
+ if (n < 8 && n >= 0)
282
+ opts_out->header_span = n;
283
+ else
284
+ err = fprintf(stderr, "Error: header_span must be an integer between 0 and 8\n");
285
+ } else if (arg == 'R') {
286
+ if (n >= 0)
287
+ opts_out->rows_to_ignore = n;
288
+ else
289
+ err = fprintf(stderr, "Error: rows_to_skip must be >= 0\n");
290
+ }
291
+ }
292
+ }
293
+ break;
294
+ default: /* pass this option through */
295
+ processed = 0;
296
+ argv_out[new_argc++] = argv[i];
297
+ break;
298
+ }
299
+ if (processed && opts_out) {
300
+ if (arg == 'R')
301
+ opts_out->option_overrides.skip_head = 1;
302
+ else if (arg == 'd')
303
+ opts_out->option_overrides.header_row_span = 1;
304
+ else if (arg == 'c')
305
+ opts_out->option_overrides.max_column_count = 1;
306
+ else if (arg == 'u')
307
+ opts_out->option_overrides.malformed_utf8_replacement = 1;
308
+ }
309
+ }
310
+
311
+ *argc_out = new_argc;
312
+ return err ? zsv_status_error : zsv_status_ok;
313
+ }
314
+
315
+ const char *zsv_next_arg(int arg_i, int argc, const char *argv[], int *err) {
316
+ if (!(arg_i < argc && strlen(argv[arg_i]) > 0)) {
317
+ fprintf(stderr, "%s option value invalid: should be non-empty string\n", argv[arg_i - 1]);
318
+ *err = 1;
319
+ return NULL;
320
+ }
321
+ return argv[arg_i];
322
+ }