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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +36 -0
- data/LICENSE +21 -0
- data/README.md +311 -0
- data/ext/zsv/common.h +34 -0
- data/ext/zsv/extconf.rb +137 -0
- data/ext/zsv/options.c +126 -0
- data/ext/zsv/options.h +31 -0
- data/ext/zsv/options_internal.h +8 -0
- data/ext/zsv/parser.c +300 -0
- data/ext/zsv/parser.h +62 -0
- data/ext/zsv/row.c +122 -0
- data/ext/zsv/row.h +39 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/2db.c +756 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/2json.c +381 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/2tsv.c +228 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/help.c +123 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/license.c +39 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/register.c +104 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/thirdparty.c +41 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/unregister.c +1 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/version.c +14 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/check/simdutf_wrapper.h +19 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/check/utf8.c +116 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/check.c +194 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli.c +796 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli_const.h +41 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli_export.h +16 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli_ini.c +280 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli_internal.h +36 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare.c +913 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare.h +23 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare_added_column.c +20 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare_internal.h +140 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare_sort.c +91 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare_unique_colname.c +81 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/count-pull.c +82 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/count.c +404 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/desc.c +569 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/echo.c +365 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/my_extension.c +366 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/mysheet_extension.c +341 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/ext_template/YOUR_EXTENSION_zsvext.c +263 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.c +298 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.h +157 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/json_numeric.c +177 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.c +444 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.h +145 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/utils.c +110 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/include/memfile.h +15 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/src/memfile.c +64 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sglib/sglib.h +1955 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/simdutf/simdutf.h +6802 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.c +230517 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.h +12174 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_and_csv_vtab.c +2 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.c +142 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.h +49 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-zsv.c +485 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab.c +1015 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3ext.h +663 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/vtab_helper.c +85 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_common.h +75 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_gen.h +167 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_parse.h +228 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_tree.h +186 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_version.h +23 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_common.h +76 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_gen.h +167 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_parse.h +238 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_tree.h +186 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl.c +184 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.c +52 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.h +34 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.c +103 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.h +57 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_bytestack.h +69 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.c +220 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.h +34 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_gen.c +362 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.c +764 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.h +117 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.c +508 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.h +78 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_tree.c +505 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_version.c +7 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/json_value.h +59 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/yajl_helper.h +208 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper.c +795 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper_internal.h +28 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/flatten.c +851 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/jq.c +106 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/jq.h +6 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/mv.c +113 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/noop.c +90 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/overwrite.c +295 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/paste.c +175 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/pretty.c +693 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/prop.c +980 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/rm.c +131 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/fixed.c +130 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/internal.h +118 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.c +45 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.h +41 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/processing.c +107 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/rand.c +20 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/regex.c +61 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/search.c +14 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/selection.c +192 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/usage.c +72 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select-pull.c +812 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select.c +753 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/serialize.c +372 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/curses.h +15 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/cursor.c +119 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/errors.c +45 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.c +63 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.h +12 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/filter.c +166 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers.c +214 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers_internal.h +128 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/help.c +43 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.c +81 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.h +25 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.c +325 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.h +73 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/lexer.c +203 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/newline_handler.c +7 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/pivot.c +318 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.c +134 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.h +119 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/read-data.c +322 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.c +203 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.h +36 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet-sql.c +167 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet_internal.h +36 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sqlfilter.c +153 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/terminfo.c +32 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.c +312 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.h +29 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/ui_buffer.c +266 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/usage.c +9 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/utf8-width.c +60 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet.c +1007 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sql.c +453 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.c +101 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.h +49 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/stack.c +393 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/arg.c +322 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/cache.c +228 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/cat.c +91 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.c +240 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.h +63 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/clock.c +57 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/db.c +148 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs-no-jq.c +2 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs.c +427 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_from_json.c +253 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_to_json.c +121 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dl.c +20 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/emcc/fs_api.c +159 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/err.c +24 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/file-mem.c +180 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/file.c +256 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.c +197 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.h +49 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/jq.c +400 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/json.c +120 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/mem.c +18 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/memmem.c +132 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/os.c +178 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite.c +258 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite_writer.c +246 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8-test.c +123 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.c +153 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.h +54 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/prop.c +267 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/signal.c +53 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/string.c +357 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dir_exists_longpath.c +83 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dl.c +33 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/fopen_longpath.c +184 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/foreach_dirent_longpath.c +292 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.c +259 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.h +13 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/mkdir_longpath.c +255 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/remove_longpath.c +96 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/writer.c +361 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command.h +40 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command_standalone.c +16 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/zsv_main.h +44 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/js/zsv_parser_api_dummy.c +3 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/lib/parse_by_chunk.c +100 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/lib/print_my_column.c +143 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/lib/pull.c +89 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/lib/simple.c +123 -0
- data/ext/zsv/vendor/zsv-1.3.0/fuzz/fuzz.c +16 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/api.h +336 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/common.h +361 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation.h +62 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation_private.h +113 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/sheet.h +73 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext.h +329 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/arg.h +90 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/cache.h +49 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/clock.h +36 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/compiler.h +58 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/db.h +19 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dirs.h +147 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dl.h +22 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/emcc/fs_api.h +28 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/err.h +22 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file-mem.h +17 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file.h +99 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/jq.h +65 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/json.h +19 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/mem.h +19 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/memmem.h +13 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/os.h +54 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite.h +71 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite_writer.h +53 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/prop.h +107 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/signal.h +18 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/sql.h +11 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/string.h +148 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/utf8.h +41 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/win/dl.h +25 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/writer.h +101 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/zsv_export.h +33 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv.h +20 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/vector_delim.c +60 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv.c +484 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv_internal.c +731 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_delim.c +285 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_fixed.c +88 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv_strencode.c +51 -0
- data/ext/zsv/zsv_ext.c +343 -0
- data/lib/zsv/version.rb +5 -0
- data/lib/zsv.rb +81 -0
- metadata +340 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#ifndef ZSV_COMPARE_H
|
|
2
|
+
#define ZSV_COMPARE_H
|
|
3
|
+
|
|
4
|
+
// public
|
|
5
|
+
enum zsv_compare_status {
|
|
6
|
+
zsv_compare_status_ok = 0,
|
|
7
|
+
zsv_compare_status_memory,
|
|
8
|
+
zsv_compare_status_no_data,
|
|
9
|
+
zsv_compare_status_no_more_input = 100,
|
|
10
|
+
zsv_compare_status_error = 199
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
typedef struct zsv_compare_data *zsv_compare_handle;
|
|
14
|
+
|
|
15
|
+
typedef int (*zsv_compare_cell_func)(void *ctx, struct zsv_cell, struct zsv_cell, void *struct_zsv_compare_data,
|
|
16
|
+
unsigned input_col_ix);
|
|
17
|
+
|
|
18
|
+
zsv_compare_handle zsv_compare_new(void);
|
|
19
|
+
void zsv_compare_set_input_parser(zsv_compare_handle cmp, zsv_parser p, unsigned ix);
|
|
20
|
+
void zsv_compare_delete(zsv_compare_handle);
|
|
21
|
+
void zsv_compare_set_comparison(zsv_compare_handle, zsv_compare_cell_func, void *);
|
|
22
|
+
|
|
23
|
+
#endif
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
static struct zsv_compare_added_column **zsv_compare_added_column_add(struct zsv_compare_added_column **next,
|
|
2
|
+
struct zsv_compare_unique_colname *added_colname,
|
|
3
|
+
enum zsv_compare_status *stat) {
|
|
4
|
+
struct zsv_compare_added_column *e = calloc(1, sizeof(*e));
|
|
5
|
+
if (!e)
|
|
6
|
+
*stat = zsv_compare_status_memory;
|
|
7
|
+
else {
|
|
8
|
+
e->colname = added_colname;
|
|
9
|
+
*next = e;
|
|
10
|
+
return &e->next;
|
|
11
|
+
}
|
|
12
|
+
return next;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static void zsv_compare_added_column_delete(struct zsv_compare_added_column *e) {
|
|
16
|
+
for (struct zsv_compare_added_column *next; e; e = next) {
|
|
17
|
+
next = e->next;
|
|
18
|
+
free(e);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#ifndef ZSV_COMPARE_PRIVATE_H
|
|
2
|
+
#define ZSV_COMPARE_PRIVATE_H
|
|
3
|
+
|
|
4
|
+
#include <sglib.h>
|
|
5
|
+
#include <sqlite3.h>
|
|
6
|
+
|
|
7
|
+
typedef struct zsv_compare_unique_colname {
|
|
8
|
+
struct zsv_compare_unique_colname *next; // retain order via linked list
|
|
9
|
+
|
|
10
|
+
// name and instance_num must be unique
|
|
11
|
+
unsigned char *name;
|
|
12
|
+
size_t name_len;
|
|
13
|
+
unsigned instance_num;
|
|
14
|
+
|
|
15
|
+
// keep track of how many instances we've seen in total
|
|
16
|
+
unsigned total_instances; // only applies if instance_num == 0
|
|
17
|
+
|
|
18
|
+
unsigned output_ix; // only used for output columns
|
|
19
|
+
|
|
20
|
+
struct zsv_compare_unique_colname *left;
|
|
21
|
+
struct zsv_compare_unique_colname *right;
|
|
22
|
+
unsigned char color;
|
|
23
|
+
unsigned char is_key;
|
|
24
|
+
} zsv_compare_unique_colname;
|
|
25
|
+
|
|
26
|
+
SGLIB_DEFINE_RBTREE_PROTOTYPES(zsv_compare_unique_colname, left, right, color, zsv_compare_unique_colname_cmp);
|
|
27
|
+
static void zsv_compare_unique_colnames_delete(zsv_compare_unique_colname **tree);
|
|
28
|
+
|
|
29
|
+
struct zsv_compare_input_key {
|
|
30
|
+
struct zsv_compare_key *key;
|
|
31
|
+
struct zsv_cell value;
|
|
32
|
+
unsigned col_ix;
|
|
33
|
+
unsigned char found;
|
|
34
|
+
unsigned char is_key;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
struct zsv_compare_input {
|
|
38
|
+
const char *path;
|
|
39
|
+
FILE *stream;
|
|
40
|
+
zsv_parser parser;
|
|
41
|
+
zsv_compare_unique_colname *colnames;
|
|
42
|
+
unsigned index; // order in which this input was added
|
|
43
|
+
|
|
44
|
+
unsigned col_count;
|
|
45
|
+
unsigned *out2in; // out2in[output column ix] = input column ix + 1 (zero for no match)
|
|
46
|
+
zsv_compare_unique_colname **output_colnames;
|
|
47
|
+
|
|
48
|
+
unsigned key_count;
|
|
49
|
+
struct zsv_compare_input_key *keys;
|
|
50
|
+
|
|
51
|
+
sqlite3_stmt *sort_stmt;
|
|
52
|
+
|
|
53
|
+
unsigned char row_loaded : 1;
|
|
54
|
+
unsigned char missing : 1;
|
|
55
|
+
unsigned char done : 1;
|
|
56
|
+
unsigned char added : 1;
|
|
57
|
+
unsigned char _ : 4;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
struct zsv_compare_key {
|
|
61
|
+
struct zsv_compare_key *next;
|
|
62
|
+
const char *name;
|
|
63
|
+
unsigned position_plus_1; // position can be specified in lieu of name
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
struct zsv_compare_added_column {
|
|
67
|
+
struct zsv_compare_added_column *next;
|
|
68
|
+
struct zsv_compare_unique_colname *colname;
|
|
69
|
+
struct zsv_compare_unique_colname *output_colname;
|
|
70
|
+
struct zsv_compare_input *input;
|
|
71
|
+
unsigned col_ix; // index of column in input from which to extract this value
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
struct zsv_compare_data {
|
|
75
|
+
enum zsv_compare_status status;
|
|
76
|
+
unsigned input_count; // number of allocated compare_input structs
|
|
77
|
+
struct zsv_compare_input *inputs;
|
|
78
|
+
struct zsv_compare_input **inputs_to_sort;
|
|
79
|
+
|
|
80
|
+
unsigned key_count;
|
|
81
|
+
struct zsv_compare_key *keys;
|
|
82
|
+
unsigned char *combined_key_names;
|
|
83
|
+
|
|
84
|
+
size_t row_count; // only matters if no ID columns are specified
|
|
85
|
+
|
|
86
|
+
unsigned output_colcount;
|
|
87
|
+
zsv_compare_unique_colname *output_colnames; // tree
|
|
88
|
+
zsv_compare_unique_colname **output_colnames_next;
|
|
89
|
+
zsv_compare_unique_colname *output_colnames_first; // linked list
|
|
90
|
+
|
|
91
|
+
struct zsv_compare_added_column *added_columns;
|
|
92
|
+
zsv_compare_unique_colname *added_colnames;
|
|
93
|
+
unsigned added_colcount;
|
|
94
|
+
int diff_count; // total number of differences; will use this as return code if -e option is specified
|
|
95
|
+
|
|
96
|
+
zsv_compare_cell_func cmp;
|
|
97
|
+
void *cmp_ctx;
|
|
98
|
+
|
|
99
|
+
enum zsv_status (*next_row)(struct zsv_compare_input *input);
|
|
100
|
+
struct zsv_cell (*get_cell)(struct zsv_compare_input *input, unsigned ix);
|
|
101
|
+
struct zsv_cell (*get_column_name)(struct zsv_compare_input *input, unsigned ix);
|
|
102
|
+
unsigned (*get_column_count)(struct zsv_compare_input *input);
|
|
103
|
+
enum zsv_compare_status (*input_init)(struct zsv_compare_data *data, struct zsv_compare_input *input,
|
|
104
|
+
struct zsv_opts *opts, struct zsv_prop_handler *custom_prop_handler);
|
|
105
|
+
|
|
106
|
+
sqlite3 *sort_db; // used when --sort option was specified
|
|
107
|
+
|
|
108
|
+
struct {
|
|
109
|
+
double value;
|
|
110
|
+
#define ZSV_COMPARE_MAX_NUMBER_BUFF_LEN 128
|
|
111
|
+
char str1[ZSV_COMPARE_MAX_NUMBER_BUFF_LEN];
|
|
112
|
+
char str2[ZSV_COMPARE_MAX_NUMBER_BUFF_LEN];
|
|
113
|
+
} tolerance;
|
|
114
|
+
struct {
|
|
115
|
+
char type; // 'j' for json
|
|
116
|
+
union {
|
|
117
|
+
zsv_csv_writer csv;
|
|
118
|
+
jsonwriter_handle jsw;
|
|
119
|
+
} handle;
|
|
120
|
+
|
|
121
|
+
struct {
|
|
122
|
+
unsigned used;
|
|
123
|
+
unsigned allocated;
|
|
124
|
+
char **names;
|
|
125
|
+
} properties;
|
|
126
|
+
|
|
127
|
+
unsigned cell_ix; // only used for json + object output
|
|
128
|
+
unsigned char compact : 1; // whether to output compact JSON
|
|
129
|
+
unsigned char object : 1; // whether to output JSON as objects
|
|
130
|
+
unsigned char _ : 6;
|
|
131
|
+
} writer;
|
|
132
|
+
|
|
133
|
+
unsigned char sort : 1;
|
|
134
|
+
unsigned char sort_in_memory : 1;
|
|
135
|
+
unsigned char print_key_col_names : 1;
|
|
136
|
+
unsigned char return_count : 1;
|
|
137
|
+
unsigned char _ : 4;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
#endif
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* To implement sorting, we will use sqlite, create a table for each CSV file and run "select * order by ..."
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#include "external/sqlite3/sqlite3_csv_vtab-mem.h"
|
|
6
|
+
|
|
7
|
+
static int zsv_compare_sort_prep_table(struct zsv_compare_data *data, const char *fname, char **err_msg,
|
|
8
|
+
unsigned int table_ix) {
|
|
9
|
+
#define ZSV_COMPARE_MAX_TABLES 1000
|
|
10
|
+
char *sql = NULL;
|
|
11
|
+
if (table_ix > ZSV_COMPARE_MAX_TABLES)
|
|
12
|
+
return -1;
|
|
13
|
+
|
|
14
|
+
sql = sqlite3_mprintf("CREATE VIRTUAL TABLE data%i USING csv(filename=%Q)", table_ix, fname);
|
|
15
|
+
|
|
16
|
+
if (!sql)
|
|
17
|
+
return -1;
|
|
18
|
+
|
|
19
|
+
int rc = sqlite3_exec(data->sort_db, sql, NULL, NULL, err_msg);
|
|
20
|
+
sqlite3_free(sql);
|
|
21
|
+
return rc;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static int zsv_compare_sort_stmt_prep(sqlite3 *db, sqlite3_stmt **stmtp, struct zsv_compare_key *keys, unsigned ix) {
|
|
25
|
+
sqlite3_str *select_clause = sqlite3_str_new(db);
|
|
26
|
+
if (!select_clause) {
|
|
27
|
+
fprintf(stderr, "Out of memory!\n");
|
|
28
|
+
return -1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
sqlite3_str_appendf(select_clause, "select * from data%i order by ", ix);
|
|
32
|
+
for (struct zsv_compare_key *key = keys; key; key = key->next)
|
|
33
|
+
sqlite3_str_appendf(select_clause, "%s\"%w\"", key == keys ? "" : ", ", key->name);
|
|
34
|
+
|
|
35
|
+
int rc = sqlite3_prepare_v2(db, sqlite3_str_value(select_clause), -1, stmtp, NULL);
|
|
36
|
+
if (rc != SQLITE_OK)
|
|
37
|
+
fprintf(stderr, "%s: %s\n", sqlite3_errstr(rc), sqlite3_str_value(select_clause));
|
|
38
|
+
sqlite3_free(sqlite3_str_finish(select_clause));
|
|
39
|
+
return rc;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static enum zsv_compare_status input_init_sorted(struct zsv_compare_data *data, struct zsv_compare_input *input,
|
|
43
|
+
struct zsv_opts *opts, struct zsv_prop_handler *custom_prop_handler) {
|
|
44
|
+
char *err_msg = NULL;
|
|
45
|
+
if (!sqlite3_zsv_list_add(input->path, opts, custom_prop_handler))
|
|
46
|
+
input->added = 1;
|
|
47
|
+
int rc = zsv_compare_sort_prep_table(data, input->path, &err_msg, input->index);
|
|
48
|
+
|
|
49
|
+
if (err_msg) {
|
|
50
|
+
fprintf(stderr, "%s\n", err_msg);
|
|
51
|
+
sqlite3_free(err_msg);
|
|
52
|
+
}
|
|
53
|
+
if (rc == SQLITE_OK)
|
|
54
|
+
rc = zsv_compare_sort_stmt_prep(data->sort_db, &input->sort_stmt, data->keys, input->index);
|
|
55
|
+
return rc == SQLITE_OK ? zsv_compare_status_ok : zsv_compare_status_error;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static enum zsv_status zsv_compare_next_sorted_row(struct zsv_compare_input *input) {
|
|
59
|
+
if (sqlite3_step(input->sort_stmt) == SQLITE_ROW)
|
|
60
|
+
return zsv_status_row;
|
|
61
|
+
|
|
62
|
+
// to do: check if error; if so return zsv_status_error
|
|
63
|
+
return zsv_status_done;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static struct zsv_cell zsv_compare_get_sorted_colname(struct zsv_compare_input *input, unsigned ix) {
|
|
67
|
+
struct zsv_cell c = {
|
|
68
|
+
.str = (unsigned char *)sqlite3_column_name(input->sort_stmt, (int)ix),
|
|
69
|
+
.quoted = 1,
|
|
70
|
+
};
|
|
71
|
+
c.len = c.str ? strlen((const char *)c.str) : 0;
|
|
72
|
+
return c;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static unsigned zsv_compare_get_sorted_colcount(struct zsv_compare_input *input) {
|
|
76
|
+
int col_count = sqlite3_column_count(input->sort_stmt);
|
|
77
|
+
if (col_count >= 0)
|
|
78
|
+
return (unsigned)col_count;
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static struct zsv_cell zsv_compare_get_sorted_cell(struct zsv_compare_input *input, unsigned ix) {
|
|
83
|
+
struct zsv_cell c = {
|
|
84
|
+
.str = (unsigned char *)sqlite3_column_text(input->sort_stmt, (int)ix),
|
|
85
|
+
.quoted = 1,
|
|
86
|
+
};
|
|
87
|
+
c.len = c.str ? sqlite3_column_bytes(input->sort_stmt, (int)ix) : 0;
|
|
88
|
+
if (c.len)
|
|
89
|
+
c.str = (unsigned char *)zsv_strtrim(c.str, &c.len);
|
|
90
|
+
return c;
|
|
91
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
static int zsv_compare_unique_colname_cmp(zsv_compare_unique_colname *x, zsv_compare_unique_colname *y) {
|
|
2
|
+
return x->instance_num == y->instance_num ? zsv_stricmp(x->name, y->name)
|
|
3
|
+
: x->instance_num > y->instance_num ? 1
|
|
4
|
+
: x->instance_num < y->instance_num ? -1
|
|
5
|
+
: 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
SGLIB_DEFINE_RBTREE_FUNCTIONS(zsv_compare_unique_colname, left, right, color, zsv_compare_unique_colname_cmp);
|
|
9
|
+
|
|
10
|
+
static void zsv_compare_unique_colname_delete(zsv_compare_unique_colname *e) {
|
|
11
|
+
if (e)
|
|
12
|
+
free(e->name);
|
|
13
|
+
free(e);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static void zsv_compare_unique_colnames_delete(zsv_compare_unique_colname **tree) {
|
|
17
|
+
if (tree && *tree) {
|
|
18
|
+
struct sglib_zsv_compare_unique_colname_iterator it;
|
|
19
|
+
struct zsv_compare_unique_colname *e;
|
|
20
|
+
for (e = sglib_zsv_compare_unique_colname_it_init(&it, *tree); e; e = sglib_zsv_compare_unique_colname_it_next(&it))
|
|
21
|
+
zsv_compare_unique_colname_delete(e);
|
|
22
|
+
*tree = NULL;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static struct zsv_compare_unique_colname *zsv_compare_unique_colname_new(const unsigned char *name, size_t len,
|
|
27
|
+
unsigned instance_num) {
|
|
28
|
+
zsv_compare_unique_colname *col = calloc(1, sizeof(*col));
|
|
29
|
+
if (!col || !(col->name = malloc(len + 1)))
|
|
30
|
+
; // handle out-of-memory error!
|
|
31
|
+
else {
|
|
32
|
+
memcpy(col->name, name, len);
|
|
33
|
+
col->name[len] = '\0';
|
|
34
|
+
col->name_len = len;
|
|
35
|
+
col->instance_num = instance_num;
|
|
36
|
+
}
|
|
37
|
+
return col;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// zsv_desc_column_update_unique(): return 1 if unique, 0 if dupe
|
|
41
|
+
static zsv_compare_unique_colname *zsv_compare_unique_colname_add_if_not_found(struct zsv_compare_unique_colname **tree,
|
|
42
|
+
const unsigned char *utf8_value,
|
|
43
|
+
size_t len, unsigned instance_num,
|
|
44
|
+
int *added) {
|
|
45
|
+
*added = 0;
|
|
46
|
+
zsv_compare_unique_colname *col = zsv_compare_unique_colname_new(utf8_value, len, instance_num);
|
|
47
|
+
zsv_compare_unique_colname *found = sglib_zsv_compare_unique_colname_find_member(*tree, col);
|
|
48
|
+
if (found) // not unique
|
|
49
|
+
zsv_compare_unique_colname_delete(col);
|
|
50
|
+
else {
|
|
51
|
+
sglib_zsv_compare_unique_colname_add(tree, col);
|
|
52
|
+
*added = 1;
|
|
53
|
+
found = col;
|
|
54
|
+
}
|
|
55
|
+
return found;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// add a colname to a list. allow duplicate names, but track instances
|
|
59
|
+
// separately (i.e.
|
|
60
|
+
static enum zsv_compare_status zsv_compare_unique_colname_add(zsv_compare_unique_colname **tree, const unsigned char *s,
|
|
61
|
+
unsigned len, zsv_compare_unique_colname **new_col) {
|
|
62
|
+
int added = 0;
|
|
63
|
+
unsigned instance_num = 0;
|
|
64
|
+
zsv_compare_unique_colname *_new_col =
|
|
65
|
+
zsv_compare_unique_colname_add_if_not_found(tree, s, len, instance_num, &added);
|
|
66
|
+
if (!_new_col)
|
|
67
|
+
return zsv_compare_status_error;
|
|
68
|
+
|
|
69
|
+
if (!added) { // we've seen this column before in this input
|
|
70
|
+
instance_num = ++_new_col->total_instances;
|
|
71
|
+
_new_col = zsv_compare_unique_colname_add_if_not_found(tree, s, len, instance_num, &added);
|
|
72
|
+
if (!added) { // should not happen
|
|
73
|
+
#ifndef NDEBUG
|
|
74
|
+
fprintf(stderr, "Unexpected error! %s: %i\n", __FILE__, __LINE__);
|
|
75
|
+
#endif
|
|
76
|
+
return zsv_compare_status_error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
*new_col = _new_col;
|
|
80
|
+
return zsv_compare_status_ok;
|
|
81
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
|
|
13
|
+
#define ZSV_COMMAND count_pull
|
|
14
|
+
#include "zsv_command.h"
|
|
15
|
+
|
|
16
|
+
static int count_usage(void) {
|
|
17
|
+
static const char *usage = "Usage: count [options]\n"
|
|
18
|
+
"\n"
|
|
19
|
+
"Options:\n"
|
|
20
|
+
" -h,--help : show usage\n"
|
|
21
|
+
" -i,--input <filename> : use specified file input\n";
|
|
22
|
+
printf("%s\n", usage);
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *opts,
|
|
27
|
+
struct zsv_prop_handler *custom_prop_handler) {
|
|
28
|
+
const char *input_path = NULL;
|
|
29
|
+
int err = 0;
|
|
30
|
+
for (int i = 1; !err && i < argc; i++) {
|
|
31
|
+
const char *arg = argv[i];
|
|
32
|
+
if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) {
|
|
33
|
+
count_usage();
|
|
34
|
+
goto count_done;
|
|
35
|
+
}
|
|
36
|
+
if (!strcmp(arg, "-i") || !strcmp(arg, "--input") || *arg != '-') {
|
|
37
|
+
err = 1;
|
|
38
|
+
if ((!strcmp(arg, "-i") || !strcmp(arg, "--input")) && ++i >= argc)
|
|
39
|
+
fprintf(stderr, "%s option requires a filename\n", arg);
|
|
40
|
+
else {
|
|
41
|
+
if (opts->stream)
|
|
42
|
+
fprintf(stderr, "Input may not be specified more than once\n");
|
|
43
|
+
else if (!(opts->stream = fopen(argv[i], "rb")))
|
|
44
|
+
fprintf(stderr, "Unable to open for reading: %s\n", argv[i]);
|
|
45
|
+
else {
|
|
46
|
+
input_path = argv[i];
|
|
47
|
+
err = 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
fprintf(stderr, "Unrecognized option: %s\n", arg);
|
|
52
|
+
err = 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
#ifdef NO_STDIN
|
|
57
|
+
if (!opts->stream || opts->stream == stdin) {
|
|
58
|
+
fprintf(stderr, "Please specify an input file\n");
|
|
59
|
+
err = 1;
|
|
60
|
+
}
|
|
61
|
+
#endif
|
|
62
|
+
|
|
63
|
+
if (!err) {
|
|
64
|
+
zsv_parser parser;
|
|
65
|
+
if (zsv_new_with_properties(opts, custom_prop_handler, input_path, &parser) != zsv_status_ok) {
|
|
66
|
+
fprintf(stderr, "Unable to initialize parser\n");
|
|
67
|
+
err = 1;
|
|
68
|
+
} else {
|
|
69
|
+
size_t count = 0;
|
|
70
|
+
while (zsv_next_row(parser) == zsv_status_row)
|
|
71
|
+
count++;
|
|
72
|
+
zsv_delete(parser);
|
|
73
|
+
printf("%zu\n", count > 0 ? count - 1 : 0);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
count_done:
|
|
78
|
+
if (opts->stream && opts->stream != stdin)
|
|
79
|
+
fclose(opts->stream);
|
|
80
|
+
|
|
81
|
+
return err;
|
|
82
|
+
}
|