zsv 1.3.1 → 1.4.3

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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +41 -3
  4. data/ext/zsv/extconf.rb +1 -1
  5. data/lib/zsv/version.rb +1 -1
  6. metadata +6 -226
  7. data/ext/zsv/vendor/zsv-1.3.0/app/2db.c +0 -756
  8. data/ext/zsv/vendor/zsv-1.3.0/app/2json.c +0 -381
  9. data/ext/zsv/vendor/zsv-1.3.0/app/2tsv.c +0 -228
  10. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/help.c +0 -123
  11. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/license.c +0 -39
  12. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/register.c +0 -104
  13. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/thirdparty.c +0 -41
  14. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/unregister.c +0 -1
  15. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/version.c +0 -14
  16. data/ext/zsv/vendor/zsv-1.3.0/app/check/simdutf_wrapper.h +0 -19
  17. data/ext/zsv/vendor/zsv-1.3.0/app/check/utf8.c +0 -116
  18. data/ext/zsv/vendor/zsv-1.3.0/app/check.c +0 -194
  19. data/ext/zsv/vendor/zsv-1.3.0/app/cli.c +0 -796
  20. data/ext/zsv/vendor/zsv-1.3.0/app/cli_const.h +0 -41
  21. data/ext/zsv/vendor/zsv-1.3.0/app/cli_export.h +0 -16
  22. data/ext/zsv/vendor/zsv-1.3.0/app/cli_ini.c +0 -280
  23. data/ext/zsv/vendor/zsv-1.3.0/app/cli_internal.h +0 -36
  24. data/ext/zsv/vendor/zsv-1.3.0/app/compare.c +0 -913
  25. data/ext/zsv/vendor/zsv-1.3.0/app/compare.h +0 -23
  26. data/ext/zsv/vendor/zsv-1.3.0/app/compare_added_column.c +0 -20
  27. data/ext/zsv/vendor/zsv-1.3.0/app/compare_internal.h +0 -140
  28. data/ext/zsv/vendor/zsv-1.3.0/app/compare_sort.c +0 -91
  29. data/ext/zsv/vendor/zsv-1.3.0/app/compare_unique_colname.c +0 -81
  30. data/ext/zsv/vendor/zsv-1.3.0/app/count-pull.c +0 -82
  31. data/ext/zsv/vendor/zsv-1.3.0/app/count.c +0 -404
  32. data/ext/zsv/vendor/zsv-1.3.0/app/desc.c +0 -569
  33. data/ext/zsv/vendor/zsv-1.3.0/app/echo.c +0 -365
  34. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/my_extension.c +0 -366
  35. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/mysheet_extension.c +0 -341
  36. data/ext/zsv/vendor/zsv-1.3.0/app/ext_template/YOUR_EXTENSION_zsvext.c +0 -263
  37. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.c +0 -298
  38. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.h +0 -157
  39. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/json_numeric.c +0 -177
  40. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.c +0 -444
  41. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.h +0 -145
  42. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/utils.c +0 -110
  43. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/include/memfile.h +0 -15
  44. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/src/memfile.c +0 -64
  45. data/ext/zsv/vendor/zsv-1.3.0/app/external/sglib/sglib.h +0 -1955
  46. data/ext/zsv/vendor/zsv-1.3.0/app/external/simdutf/simdutf.h +0 -6802
  47. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.c +0 -230517
  48. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.h +0 -12174
  49. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_and_csv_vtab.c +0 -2
  50. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.c +0 -142
  51. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.h +0 -49
  52. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-zsv.c +0 -485
  53. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab.c +0 -1015
  54. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3ext.h +0 -663
  55. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/vtab_helper.c +0 -85
  56. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_common.h +0 -75
  57. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_gen.h +0 -167
  58. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_parse.h +0 -228
  59. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_tree.h +0 -186
  60. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_version.h +0 -23
  61. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_common.h +0 -76
  62. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_gen.h +0 -167
  63. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_parse.h +0 -238
  64. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_tree.h +0 -186
  65. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl.c +0 -184
  66. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.c +0 -52
  67. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.h +0 -34
  68. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.c +0 -103
  69. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.h +0 -57
  70. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_bytestack.h +0 -69
  71. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.c +0 -220
  72. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.h +0 -34
  73. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_gen.c +0 -362
  74. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.c +0 -764
  75. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.h +0 -117
  76. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.c +0 -508
  77. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.h +0 -78
  78. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_tree.c +0 -505
  79. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_version.c +0 -7
  80. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/json_value.h +0 -59
  81. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/yajl_helper.h +0 -208
  82. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper.c +0 -795
  83. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper_internal.h +0 -28
  84. data/ext/zsv/vendor/zsv-1.3.0/app/flatten.c +0 -851
  85. data/ext/zsv/vendor/zsv-1.3.0/app/jq.c +0 -106
  86. data/ext/zsv/vendor/zsv-1.3.0/app/jq.h +0 -6
  87. data/ext/zsv/vendor/zsv-1.3.0/app/mv.c +0 -113
  88. data/ext/zsv/vendor/zsv-1.3.0/app/noop.c +0 -90
  89. data/ext/zsv/vendor/zsv-1.3.0/app/overwrite.c +0 -295
  90. data/ext/zsv/vendor/zsv-1.3.0/app/paste.c +0 -175
  91. data/ext/zsv/vendor/zsv-1.3.0/app/pretty.c +0 -693
  92. data/ext/zsv/vendor/zsv-1.3.0/app/prop.c +0 -980
  93. data/ext/zsv/vendor/zsv-1.3.0/app/rm.c +0 -131
  94. data/ext/zsv/vendor/zsv-1.3.0/app/select/fixed.c +0 -130
  95. data/ext/zsv/vendor/zsv-1.3.0/app/select/internal.h +0 -118
  96. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.c +0 -45
  97. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.h +0 -41
  98. data/ext/zsv/vendor/zsv-1.3.0/app/select/processing.c +0 -107
  99. data/ext/zsv/vendor/zsv-1.3.0/app/select/rand.c +0 -20
  100. data/ext/zsv/vendor/zsv-1.3.0/app/select/regex.c +0 -61
  101. data/ext/zsv/vendor/zsv-1.3.0/app/select/search.c +0 -14
  102. data/ext/zsv/vendor/zsv-1.3.0/app/select/selection.c +0 -192
  103. data/ext/zsv/vendor/zsv-1.3.0/app/select/usage.c +0 -72
  104. data/ext/zsv/vendor/zsv-1.3.0/app/select-pull.c +0 -812
  105. data/ext/zsv/vendor/zsv-1.3.0/app/select.c +0 -753
  106. data/ext/zsv/vendor/zsv-1.3.0/app/serialize.c +0 -372
  107. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/curses.h +0 -15
  108. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/cursor.c +0 -119
  109. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/errors.c +0 -45
  110. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.c +0 -63
  111. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.h +0 -12
  112. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/filter.c +0 -166
  113. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers.c +0 -214
  114. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers_internal.h +0 -128
  115. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/help.c +0 -43
  116. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.c +0 -81
  117. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.h +0 -25
  118. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.c +0 -325
  119. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.h +0 -73
  120. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/lexer.c +0 -203
  121. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/newline_handler.c +0 -7
  122. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/pivot.c +0 -318
  123. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.c +0 -134
  124. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.h +0 -119
  125. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/read-data.c +0 -322
  126. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.c +0 -203
  127. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.h +0 -36
  128. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet-sql.c +0 -167
  129. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet_internal.h +0 -36
  130. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sqlfilter.c +0 -153
  131. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/terminfo.c +0 -32
  132. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.c +0 -312
  133. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.h +0 -29
  134. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/ui_buffer.c +0 -266
  135. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/usage.c +0 -9
  136. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/utf8-width.c +0 -60
  137. data/ext/zsv/vendor/zsv-1.3.0/app/sheet.c +0 -1007
  138. data/ext/zsv/vendor/zsv-1.3.0/app/sql.c +0 -453
  139. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.c +0 -101
  140. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.h +0 -49
  141. data/ext/zsv/vendor/zsv-1.3.0/app/stack.c +0 -393
  142. data/ext/zsv/vendor/zsv-1.3.0/app/utils/arg.c +0 -322
  143. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cache.c +0 -228
  144. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cat.c +0 -91
  145. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.c +0 -240
  146. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.h +0 -63
  147. data/ext/zsv/vendor/zsv-1.3.0/app/utils/clock.c +0 -57
  148. data/ext/zsv/vendor/zsv-1.3.0/app/utils/db.c +0 -148
  149. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs-no-jq.c +0 -2
  150. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs.c +0 -427
  151. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_from_json.c +0 -253
  152. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_to_json.c +0 -121
  153. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dl.c +0 -20
  154. data/ext/zsv/vendor/zsv-1.3.0/app/utils/emcc/fs_api.c +0 -159
  155. data/ext/zsv/vendor/zsv-1.3.0/app/utils/err.c +0 -24
  156. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file-mem.c +0 -180
  157. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file.c +0 -256
  158. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.c +0 -197
  159. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.h +0 -49
  160. data/ext/zsv/vendor/zsv-1.3.0/app/utils/jq.c +0 -400
  161. data/ext/zsv/vendor/zsv-1.3.0/app/utils/json.c +0 -120
  162. data/ext/zsv/vendor/zsv-1.3.0/app/utils/mem.c +0 -18
  163. data/ext/zsv/vendor/zsv-1.3.0/app/utils/memmem.c +0 -132
  164. data/ext/zsv/vendor/zsv-1.3.0/app/utils/os.c +0 -178
  165. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite.c +0 -258
  166. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite_writer.c +0 -246
  167. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8-test.c +0 -123
  168. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.c +0 -153
  169. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.h +0 -54
  170. data/ext/zsv/vendor/zsv-1.3.0/app/utils/prop.c +0 -267
  171. data/ext/zsv/vendor/zsv-1.3.0/app/utils/signal.c +0 -53
  172. data/ext/zsv/vendor/zsv-1.3.0/app/utils/string.c +0 -357
  173. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dir_exists_longpath.c +0 -83
  174. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dl.c +0 -33
  175. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/fopen_longpath.c +0 -184
  176. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/foreach_dirent_longpath.c +0 -292
  177. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.c +0 -259
  178. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.h +0 -13
  179. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/mkdir_longpath.c +0 -255
  180. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/remove_longpath.c +0 -96
  181. data/ext/zsv/vendor/zsv-1.3.0/app/utils/writer.c +0 -361
  182. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command.h +0 -40
  183. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command_standalone.c +0 -16
  184. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_main.h +0 -44
  185. data/ext/zsv/vendor/zsv-1.3.0/examples/js/zsv_parser_api_dummy.c +0 -3
  186. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/parse_by_chunk.c +0 -100
  187. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/print_my_column.c +0 -143
  188. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/pull.c +0 -89
  189. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/simple.c +0 -123
  190. data/ext/zsv/vendor/zsv-1.3.0/fuzz/fuzz.c +0 -16
  191. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/api.h +0 -336
  192. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/common.h +0 -361
  193. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation.h +0 -62
  194. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation_private.h +0 -113
  195. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/sheet.h +0 -73
  196. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext.h +0 -329
  197. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/arg.h +0 -90
  198. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/cache.h +0 -49
  199. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/clock.h +0 -36
  200. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/compiler.h +0 -58
  201. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/db.h +0 -19
  202. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dirs.h +0 -147
  203. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dl.h +0 -22
  204. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/emcc/fs_api.h +0 -28
  205. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/err.h +0 -22
  206. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file-mem.h +0 -17
  207. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file.h +0 -99
  208. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/jq.h +0 -65
  209. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/json.h +0 -19
  210. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/mem.h +0 -19
  211. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/memmem.h +0 -13
  212. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/os.h +0 -54
  213. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite.h +0 -71
  214. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite_writer.h +0 -53
  215. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/prop.h +0 -107
  216. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/signal.h +0 -18
  217. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/sql.h +0 -11
  218. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/string.h +0 -148
  219. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/utf8.h +0 -41
  220. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/win/dl.h +0 -25
  221. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/writer.h +0 -101
  222. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/zsv_export.h +0 -33
  223. data/ext/zsv/vendor/zsv-1.3.0/include/zsv.h +0 -20
  224. data/ext/zsv/vendor/zsv-1.3.0/src/vector_delim.c +0 -60
  225. data/ext/zsv/vendor/zsv-1.3.0/src/zsv.c +0 -484
  226. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_internal.c +0 -731
  227. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_delim.c +0 -285
  228. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_fixed.c +0 -88
  229. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_strencode.c +0 -51
@@ -1,381 +0,0 @@
1
- /*
2
- * Copyright (C) 2021-2022 Liquidaty and zsv contributors. All rights reserved.
3
- * This file is part of zsv/lib, distributed under the license defined at
4
- * https://opensource.org/licenses/MIT
5
- */
6
-
7
- #include <stdio.h>
8
- #include <string.h>
9
- #include <stdlib.h>
10
- #include <jsonwriter.h>
11
- #include <sqlite3.h>
12
-
13
- #define ZSV_COMMAND 2json
14
- #include "zsv_command.h"
15
-
16
- #include <zsv/utils/writer.h>
17
- #include <zsv/utils/mem.h>
18
- #include <zsv/utils/db.h>
19
-
20
- struct zsv_2json_header {
21
- struct zsv_2json_header *next;
22
- char *name;
23
- };
24
-
25
- #define LQ_2JSON_MAX_INDEXES 32
26
-
27
- struct zsv_2json_data {
28
- zsv_parser parser;
29
- jsonwriter_handle jsw;
30
-
31
- size_t rows_processed; // includes header row
32
-
33
- struct {
34
- const char *clauses[LQ_2JSON_MAX_INDEXES];
35
- char unique[LQ_2JSON_MAX_INDEXES];
36
- unsigned count;
37
- } indexes;
38
-
39
- struct zsv_2json_header *headers, *current_header;
40
- struct zsv_2json_header **headers_next;
41
-
42
- char *db_tablename;
43
-
44
- #define ZSV_JSON_SCHEMA_OBJECT 1
45
- #define ZSV_JSON_SCHEMA_DATABASE 2
46
- unsigned char schema : 2;
47
- unsigned char no_header : 1;
48
- unsigned char no_empty : 1;
49
- unsigned char err : 1;
50
- unsigned char from_db : 1;
51
- unsigned char compact : 1;
52
- unsigned char _ : 1;
53
- };
54
-
55
- static void zsv_2json_cleanup(struct zsv_2json_data *data) {
56
- for (struct zsv_2json_header *next, *h = data->headers; h; h = next) {
57
- next = h->next;
58
- if (h->name)
59
- free(h->name);
60
- free(h);
61
- }
62
- free(data->db_tablename);
63
- }
64
-
65
- static void write_header_cell(struct zsv_2json_data *data, const unsigned char *utf8_value, size_t len) {
66
- if (data->schema == ZSV_JSON_SCHEMA_OBJECT) {
67
- struct zsv_2json_header *h;
68
- if (!(h = calloc(1, sizeof(*h)))) {
69
- fprintf(stderr, "Out of memory!\n");
70
- data->err = 1;
71
- } else {
72
- *data->headers_next = h;
73
- data->headers_next = &h->next;
74
- if ((h->name = malloc(len + 1))) {
75
- memcpy(h->name, utf8_value, len);
76
- h->name[len] = '\0';
77
- }
78
- }
79
- } else {
80
- // to do: add options to set data type, etc
81
- jsonwriter_start_object(data->jsw);
82
- jsonwriter_object_key(data->jsw, "name");
83
- jsonwriter_strn(data->jsw, utf8_value, len);
84
- jsonwriter_end(data->jsw);
85
- }
86
- }
87
-
88
- static void write_data_cell(struct zsv_2json_data *data, const unsigned char *utf8_value, size_t len) {
89
- if (data->schema == ZSV_JSON_SCHEMA_OBJECT) {
90
- if (!data->current_header)
91
- return;
92
- char *current_header_name = data->current_header->name;
93
- data->current_header = data->current_header->next;
94
-
95
- if (len || !data->no_empty)
96
- jsonwriter_object_key(data->jsw, current_header_name);
97
- else
98
- return;
99
- }
100
- jsonwriter_strn(data->jsw, utf8_value, len);
101
- }
102
-
103
- static char *zsv_2json_db_first_tname(sqlite3 *db) {
104
- char *tname = NULL;
105
- sqlite3_stmt *stmt = NULL;
106
- const char *sql = "select name from sqlite_master where type = 'table'";
107
- if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK)
108
- fprintf(stderr, "Unable to prepare %s: %s\n", sql, sqlite3_errmsg(db));
109
- else if (sqlite3_step(stmt) == SQLITE_ROW) {
110
- const unsigned char *text = sqlite3_column_text(stmt, 0);
111
- if (text) {
112
- int len = sqlite3_column_bytes(stmt, 0);
113
- tname = zsv_memdup(text, len);
114
- }
115
- }
116
- if (stmt)
117
- sqlite3_finalize(stmt);
118
- return tname;
119
- }
120
-
121
- static void zsv_2json_row(void *ctx) {
122
- struct zsv_2json_data *data = ctx;
123
- unsigned int cols = zsv_cell_count(data->parser);
124
- if (cols) {
125
- char obj = 0;
126
- char arr = 0;
127
- if (!data->rows_processed) { // header row
128
- jsonwriter_start_array(data->jsw); // start array of rows
129
- if (data->schema == ZSV_JSON_SCHEMA_DATABASE) {
130
- jsonwriter_start_object(data->jsw); // start this row
131
- obj = 1;
132
-
133
- if (data->db_tablename)
134
- jsonwriter_object_cstr(data->jsw, "name", data->db_tablename);
135
-
136
- // to do: check index syntax (as of now, we just take argument value
137
- // as-is and assume it will translate into a valid SQLITE3 command)
138
- char have_index = 0;
139
- for (unsigned i = 0; i < data->indexes.count; i++) {
140
- const char *name_start = data->indexes.clauses[i];
141
- const char *on = strstr(name_start, " on ");
142
- if (on) {
143
- on += 4;
144
- while (*on == ' ')
145
- on++;
146
- }
147
- if (!on || !*on)
148
- continue;
149
-
150
- const char *name_end = name_start;
151
- while (name_end && *name_end && *name_end != ' ')
152
- name_end++;
153
-
154
- if (name_end > name_start) {
155
- if (!have_index) {
156
- have_index = 1;
157
- jsonwriter_object_object(data->jsw, "indexes");
158
- }
159
- char *tmp = zsv_memdup(name_start, name_end - name_start);
160
- jsonwriter_object_object(data->jsw, tmp); // this index
161
- free(tmp);
162
- jsonwriter_object_cstr(data->jsw, "on", on);
163
- if (data->indexes.unique[i])
164
- jsonwriter_object_bool(data->jsw, "unique", 1);
165
- jsonwriter_end_object(data->jsw); // end this index
166
- }
167
- }
168
- if (have_index)
169
- jsonwriter_end_object(data->jsw); // indexes
170
-
171
- jsonwriter_object_array(data->jsw, "columns");
172
- arr = 1;
173
- } else if (data->schema != ZSV_JSON_SCHEMA_OBJECT) {
174
- jsonwriter_start_array(data->jsw); // start this row
175
- arr = 1;
176
- }
177
- } else { // processing a data row, not header row
178
- if (data->schema == ZSV_JSON_SCHEMA_OBJECT) {
179
- jsonwriter_start_object(data->jsw); // start this row
180
- obj = 1;
181
- } else {
182
- if (data->rows_processed == 1 && data->schema == ZSV_JSON_SCHEMA_DATABASE)
183
- jsonwriter_start_array(data->jsw); // start the table-data element
184
- jsonwriter_start_array(data->jsw); // start this row
185
- arr = 1;
186
- }
187
- }
188
-
189
- for (unsigned int i = 0; i < cols; i++) {
190
- struct zsv_cell cell = zsv_get_cell(data->parser, i);
191
- // output this cell
192
- if (!data->rows_processed && !data->no_header) // this is header row
193
- write_header_cell(data, cell.str, cell.len);
194
- else
195
- write_data_cell(data, cell.str, cell.len);
196
- }
197
-
198
- // end this row
199
- if (arr)
200
- jsonwriter_end_array(data->jsw);
201
- if (obj)
202
- jsonwriter_end_object(data->jsw);
203
- data->rows_processed++;
204
- }
205
- data->current_header = data->headers;
206
- }
207
-
208
- static int zsv_db2json(const char *input_filename, char **tname, jsonwriter_handle jsw) {
209
- sqlite3 *db;
210
- int rc =
211
- sqlite3_open_v2(input_filename, &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
212
- int err = 0;
213
- if (!db)
214
- fprintf(stderr, "Unable to open db at %s\n", input_filename), err = 1;
215
- else if (rc != SQLITE_OK)
216
- fprintf(stderr, "Unable to open db at %s: %s\n", input_filename, sqlite3_errmsg(db)), err = 1;
217
- else if (!*tname)
218
- *tname = zsv_2json_db_first_tname(db);
219
-
220
- if (!*tname)
221
- fprintf(stderr, "No table name provided, and none found in %s\n", input_filename), err = 1;
222
- else
223
- err = zsv_dbtable2json(db, *tname, jsw, 0);
224
- return err;
225
- }
226
-
227
- int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *optsp,
228
- struct zsv_prop_handler *custom_prop_handler) {
229
- struct zsv_opts opts = *optsp;
230
- struct zsv_2json_data data = {0};
231
- data.headers_next = &data.headers;
232
-
233
- const char *usage[] = {
234
- APPNAME ": streaming CSV to JSON converter, or SQLite3 DB to JSON converter",
235
- "",
236
- "Usage: " APPNAME " [options] [file.csv]",
237
- "",
238
- "Options:",
239
- " -h,--help : show usage",
240
- " -o,--output <filename> : filename to write output to",
241
- " --compact : output compact JSON",
242
- " --from-db : input is sqlite3 database",
243
- " --db-table <table_name> : name of table in input database to convert",
244
- " --object : output as array of objects",
245
- " --no-empty : omit empty properties (only with --object)",
246
- " --database : output in database schema",
247
- " --no-header : treat the header row as a data row",
248
- " --index <name_on_expr> : add index to database schema",
249
- " --unique-index <name_on_expr> : add unique index to database schema",
250
- NULL,
251
- };
252
-
253
- FILE *out = NULL;
254
- const char *input_path = NULL;
255
- enum zsv_status err = zsv_status_ok;
256
- int done = 0;
257
-
258
- for (int i = 1; !err && !done && i < argc; i++) {
259
- if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
260
- for (int j = 0; usage[j]; j++)
261
- fprintf(stdout, "%s\n", usage[j]);
262
- done = 1;
263
- } else if (!strcmp(argv[i], "-o") || !strcmp(argv[i], "--output")) {
264
- if (++i >= argc)
265
- fprintf(stderr, "%s option requires a filename value\n", argv[i - 1]), err = zsv_status_error;
266
- else if (out && out != stdout)
267
- fprintf(stderr, "Output file specified more than once\n"), err = zsv_status_error;
268
- else if (!(out = fopen(argv[i], "wb")))
269
- fprintf(stderr, "Unable to open for writing: %s\n", argv[i]), err = zsv_status_error;
270
- } else if (!strcmp(argv[i], "--index") || !strcmp(argv[i], "--unique-index")) {
271
- if (++i >= argc)
272
- fprintf(stderr, "%s option requires a filename value\n", argv[i - 1]), err = zsv_status_error;
273
- else if (data.indexes.count > LQ_2JSON_MAX_INDEXES)
274
- fprintf(stderr, "Max index count exceeded; ignoring %s\n", argv[i]), err = zsv_status_error;
275
- else if (!strstr(argv[i], " on "))
276
- fprintf(stderr, "Index value should be in the form of 'index_name on expr'; got %s\n", argv[i]),
277
- err = zsv_status_error;
278
- else {
279
- if (!strcmp(argv[i - 1], "--unique-index"))
280
- data.indexes.unique[data.indexes.count] = 1;
281
- data.indexes.clauses[data.indexes.count++] = argv[i];
282
- }
283
- } else if (!strcmp(argv[i], "--no-empty")) {
284
- data.no_empty = 1;
285
- } else if (!strcmp(argv[i], "--db-table")) {
286
- if (++i >= argc)
287
- fprintf(stderr, "%s option requires a table name value\n", argv[i - 1]), err = zsv_status_error;
288
- else if (data.db_tablename)
289
- fprintf(stderr, "%s option specified more than once\n", argv[i - 1]), err = zsv_status_error;
290
- else
291
- data.db_tablename = strdup(argv[i]);
292
- } else if (!strcmp(argv[i], "--from-db")) {
293
- if (++i >= argc)
294
- fprintf(stderr, "%s option requires a filename value\n", argv[i - 1]), err = zsv_status_error;
295
- else if (opts.stream)
296
- fprintf(stderr, "Input file specified more than once\n"), err = zsv_status_error;
297
- else if (!(opts.stream = fopen(argv[i], "rb")))
298
- fprintf(stderr, "Unable to open for reading: %s\n", argv[i]), err = zsv_status_error;
299
- else {
300
- input_path = argv[i];
301
- data.from_db = 1;
302
- }
303
- } else if (!strcmp(argv[i], "--database") || !strcmp(argv[i], "--object")) {
304
- if (data.schema)
305
- fprintf(stderr, "Output schema specified more than once\n"), err = zsv_status_error;
306
- else if (!strcmp(argv[i], "--database"))
307
- data.schema = ZSV_JSON_SCHEMA_DATABASE;
308
- else
309
- data.schema = ZSV_JSON_SCHEMA_OBJECT;
310
- } else if (!strcmp(argv[i], "--no-header"))
311
- data.no_header = 1;
312
- else if (!strcmp(argv[i], "--compact"))
313
- data.compact = 1;
314
- else {
315
- if (opts.stream)
316
- fprintf(stderr, "Input file specified more than once\n"), err = zsv_status_error;
317
- else if (!(opts.stream = fopen(argv[i], "rb")))
318
- fprintf(stderr, "Unable to open for reading: %s\n", argv[i]), err = zsv_status_error;
319
- else
320
- input_path = argv[i];
321
- }
322
- }
323
-
324
- if (!(err || done)) {
325
- if (data.indexes.count && data.schema != ZSV_JSON_SCHEMA_DATABASE)
326
- fprintf(stderr, "--index/--unique-index can only be used with --database\n"), err = zsv_status_error;
327
- else if (data.no_header && data.schema)
328
- fprintf(stderr, "--no-header cannot be used together with --object or --database\n"), err = zsv_status_error;
329
- else if (data.no_empty && data.schema != ZSV_JSON_SCHEMA_OBJECT)
330
- fprintf(stderr, "--no-empty can only be used with --object\n"), err = zsv_status_error;
331
- else if (!opts.stream) {
332
- if (data.from_db)
333
- fprintf(stderr, "Database input specified, but no input file provided\n"), err = zsv_status_error;
334
- else {
335
- #ifdef NO_STDIN
336
- fprintf(stderr, "Please specify an input file\n"), err = zsv_status_error;
337
- #else
338
- opts.stream = stdin;
339
- #endif
340
- }
341
- }
342
- }
343
-
344
- if (!(err || done)) {
345
- if (!out)
346
- out = stdout;
347
- if (!(data.jsw = jsonwriter_new(out)))
348
- err = zsv_status_error;
349
- else {
350
- if (data.compact)
351
- jsonwriter_set_option(data.jsw, jsonwriter_option_compact);
352
- if (data.from_db) {
353
- if (opts.stream != stdin) {
354
- fclose(opts.stream);
355
- opts.stream = NULL;
356
- }
357
- err = zsv_db2json(input_path, &data.db_tablename, data.jsw);
358
- } else {
359
- opts.row_handler = zsv_2json_row;
360
- opts.ctx = &data;
361
- if (zsv_new_with_properties(&opts, custom_prop_handler, input_path, &data.parser) == zsv_status_ok) {
362
- zsv_handle_ctrl_c_signal();
363
- while (!data.err && !zsv_signal_interrupted && zsv_parse_more(data.parser) == zsv_status_ok)
364
- ;
365
- zsv_finish(data.parser);
366
- zsv_delete(data.parser);
367
- jsonwriter_end_all(data.jsw);
368
- }
369
- err = data.err;
370
- }
371
- }
372
- jsonwriter_delete(data.jsw);
373
- }
374
-
375
- zsv_2json_cleanup(&data);
376
- if (opts.stream && opts.stream != stdin)
377
- fclose(opts.stream);
378
- if (out && out != stdout)
379
- fclose(out);
380
- return err;
381
- }
@@ -1,228 +0,0 @@
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 <stdio.h>
10
- #include <string.h>
11
- #include <stdlib.h>
12
- #define ZSV_COMMAND 2tsv
13
- #include "zsv_command.h"
14
-
15
- #include <zsv/utils/utf8.h>
16
-
17
- enum zsv_2tsv_status {
18
- zsv_2tsv_status_ok = 0,
19
- zsv_2tsv_status_out_of_memory
20
- };
21
-
22
- #define ZSV_2TSV_BUFF_SIZE 65536
23
-
24
- struct static_buff {
25
- char *buff; // will be ZSV_2TSV_BUFF_SIZE
26
- size_t used;
27
- FILE *stream;
28
- };
29
-
30
- struct zsv_2tsv_data {
31
- zsv_parser parser;
32
- struct static_buff out;
33
- unsigned char convert_to_space : 1;
34
- unsigned char _ : 7;
35
- };
36
-
37
- __attribute__((always_inline)) static inline void zsv_2tsv_flush(struct static_buff *b) {
38
- fwrite(b->buff, b->used, 1, b->stream);
39
- b->used = 0;
40
- }
41
-
42
- static inline void zsv_2tsv_write(struct static_buff *b, const unsigned char *s, size_t n) {
43
- if (n) {
44
- if (VERY_UNLIKELY(n + b->used > ZSV_2TSV_BUFF_SIZE)) {
45
- zsv_2tsv_flush(b);
46
- if (VERY_UNLIKELY(n > ZSV_2TSV_BUFF_SIZE)) { // n too big, so write directly
47
- fwrite(s, n, 1, b->stream);
48
- return;
49
- }
50
- }
51
- // n + used < buff size
52
- memcpy(b->buff + b->used, s, n);
53
- b->used += n;
54
- }
55
- }
56
-
57
- // zsv_to_tsv(): convert, if necessary, to text suitable for tab-delimited output.
58
- // - return NULL if nothing to convert
59
- // - else, return allocated char * of converted tsv (caller must free), and update *lenp
60
- // - on error, set *err
61
- __attribute__((always_inline)) static inline unsigned char *zsv_to_tsv(const unsigned char *utf8, size_t *len,
62
- enum zsv_2tsv_status *err,
63
- char convert_to_space) {
64
- // replace tab, newline and lf with \t, \n or \r or backslash
65
- size_t do_convert = 0;
66
- for (size_t i = 0; i < *len; i++) {
67
- if (UNLIKELY(utf8[i] == '\t' || utf8[i] == '\n' || utf8[i] == '\r' || utf8[i] == '\\'))
68
- do_convert++;
69
- }
70
- if (LIKELY(do_convert == 0))
71
- return NULL;
72
-
73
- unsigned char *converted = malloc(*len + do_convert + 1);
74
- if (!converted)
75
- *err = zsv_2tsv_status_out_of_memory;
76
- else {
77
- size_t j = 0;
78
- for (size_t i = 0; i < *len; i++) {
79
- if (UNLIKELY(utf8[i] == '\t' || utf8[i] == '\n' || utf8[i] == '\r' || utf8[i] == '\\')) {
80
- if (convert_to_space)
81
- converted[j++] = utf8[i] == '\\' ? '\\' : ' ';
82
- else {
83
- converted[j++] = '\\';
84
- converted[j++] = utf8[i] == '\t' ? 't' : utf8[i] == '\n' ? 'n' : utf8[i] == '\r' ? 'r' : '\\';
85
- }
86
- } else
87
- converted[j++] = utf8[i];
88
- }
89
- converted[j] = '\0';
90
- *len = j;
91
- }
92
- return converted;
93
- }
94
-
95
- __attribute__((always_inline)) static inline void zsv_2tsv_cell(struct zsv_2tsv_data *data, unsigned char *utf8_value,
96
- size_t len, char no_newline_or_slash,
97
- char convert_to_space) {
98
- // output cell contents (converted if necessary)
99
- if (len) {
100
- enum zsv_2tsv_status err = zsv_2tsv_status_ok;
101
- if (VERY_LIKELY(no_newline_or_slash && !memchr(utf8_value, '\t', len))) {
102
- zsv_2tsv_write(&data->out, utf8_value, len);
103
- return;
104
- }
105
-
106
- // if we're here, there either definitely an embedded tab, or maybe an embedded \n or \r
107
- unsigned char *converted = zsv_to_tsv(utf8_value, &len, &err, convert_to_space);
108
- if (converted != NULL) {
109
- zsv_2tsv_write(&data->out, converted, len);
110
- free(converted);
111
- } else if (UNLIKELY(err))
112
- fprintf(stderr, "Out of memory!\n");
113
- else
114
- zsv_2tsv_write(&data->out, utf8_value, len);
115
- }
116
- }
117
-
118
- static void zsv_2tsv_row(void *ctx) {
119
- struct zsv_2tsv_data *data = ctx;
120
- unsigned int cols = zsv_cell_count(data->parser);
121
- if (cols) {
122
- struct zsv_cell cell = zsv_get_cell(data->parser, 0);
123
- struct zsv_cell end = zsv_get_cell(data->parser, cols - 1);
124
- unsigned char *start = cell.str;
125
- size_t row_len = end.str + end.len - start;
126
- char no_newline_or_slash = 0;
127
- if (LIKELY(!(memchr(start, '\n', row_len) || memchr(start, '\r', row_len) || memchr(start, '\\', row_len))))
128
- no_newline_or_slash = 1;
129
-
130
- const char convert_to_space = data->convert_to_space;
131
- zsv_2tsv_cell(ctx, cell.str, cell.len, no_newline_or_slash, convert_to_space);
132
- for (unsigned int i = 1; i < cols; i++) {
133
- zsv_2tsv_write(&data->out, (const unsigned char *)"\t", 1);
134
- cell = zsv_get_cell(data->parser, i);
135
- zsv_2tsv_cell(ctx, cell.str, cell.len, no_newline_or_slash, convert_to_space);
136
- }
137
- }
138
- zsv_2tsv_write(&data->out, (const unsigned char *)"\n", 1);
139
- }
140
-
141
- int zsv_2tsv_usage(int rc) {
142
- static const char *zsv_2tsv_usage_msg[] = {
143
- APPNAME ": convert CSV to TSV (tab-delimited text) suitable for simple-delimiter",
144
- " text processing. By default, embedded tabs or multilines will be escaped",
145
- " to \\t, \\n or \\r, respectively",
146
- "",
147
- "Usage: " APPNAME " [filename] [options]",
148
- " e.g. " APPNAME " < file.csv > file.tsv",
149
- "",
150
- "Options:",
151
- " -o <file> : save output to <file>",
152
- " --convert-to-space: convert embedded \\t, \\n or \\r to space",
153
- NULL,
154
- };
155
-
156
- for (size_t i = 0; zsv_2tsv_usage_msg[i]; i++)
157
- fprintf(stdout, "%s\n", zsv_2tsv_usage_msg[i]);
158
-
159
- return rc;
160
- }
161
-
162
- int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *optsp,
163
- struct zsv_prop_handler *custom_prop_handler) {
164
- struct zsv_opts opts = *optsp;
165
- struct zsv_2tsv_data data = {0};
166
- const char *input_path = NULL;
167
- int err = 0;
168
- for (int i = 1; !err && i < argc; i++) {
169
- if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
170
- return zsv_2tsv_usage(0);
171
- if (!strcmp(argv[i], "--convert-to-space"))
172
- data.convert_to_space = 1;
173
- else if (!strcmp(argv[i], "-o") || !strcmp(argv[i], "--output")) {
174
- if (++i >= argc)
175
- fprintf(stderr, "%s option requires a filename value\n", argv[i - 1]), err = 1;
176
- else if (data.out.stream && data.out.stream != stdout)
177
- fprintf(stderr, "Output file specified more than once\n"), err = 1;
178
- else if (!(data.out.stream = fopen(argv[i], "wb")))
179
- fprintf(stderr, "Unable to open for writing: %s\n", argv[i]), err = 1;
180
- } else {
181
- if (opts.stream)
182
- fprintf(stderr, "Input file specified more than once\n"), err = 1;
183
- else if (!(opts.stream = fopen(argv[i], "rb")))
184
- fprintf(stderr, "Unable to open for reading: %s\n", argv[i]), err = 1;
185
- else
186
- input_path = argv[i];
187
- }
188
- }
189
-
190
- if (err) {
191
- goto exit_2tsv;
192
- }
193
-
194
- if (!opts.stream) {
195
- #ifdef NO_STDIN
196
- fprintf(stderr, "Please specify an input file\n");
197
- err = 1;
198
- goto exit_2tsv;
199
- #else
200
- opts.stream = stdin;
201
- #endif
202
- }
203
-
204
- if (!data.out.stream)
205
- data.out.stream = stdout;
206
-
207
- opts.row_handler = zsv_2tsv_row;
208
- opts.ctx = &data;
209
- if (zsv_new_with_properties(&opts, custom_prop_handler, input_path, &data.parser) == zsv_status_ok) {
210
- char output[ZSV_2TSV_BUFF_SIZE];
211
- data.out.buff = output;
212
-
213
- zsv_handle_ctrl_c_signal();
214
- enum zsv_status status;
215
- while (!zsv_signal_interrupted && (status = zsv_parse_more(data.parser)) == zsv_status_ok)
216
- ;
217
- zsv_finish(data.parser);
218
- zsv_delete(data.parser);
219
- zsv_2tsv_flush(&data.out);
220
- }
221
-
222
- exit_2tsv:
223
- if (opts.stream && opts.stream != stdin)
224
- fclose(opts.stream);
225
- if (data.out.stream && data.out.stream != stdout)
226
- fclose(data.out.stream);
227
- return err;
228
- }