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,40 @@
|
|
|
1
|
+
#ifndef ZSV_COMMAND_H
|
|
2
|
+
#define ZSV_COMMAND_H
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Include zsv headers and entry point declaration
|
|
6
|
+
* If the command will *not* use common zsv parsing options, then prior to
|
|
7
|
+
* including this file, define
|
|
8
|
+
* ZSV_COMMAND_NO_OPTIONS
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#include <zsv.h>
|
|
12
|
+
#include <zsv/utils/arg.h>
|
|
13
|
+
#include <zsv/utils/prop.h>
|
|
14
|
+
#include <zsv/utils/compiler.h>
|
|
15
|
+
#include <zsv/utils/signal.h>
|
|
16
|
+
#include <zsv/utils/memmem.h>
|
|
17
|
+
|
|
18
|
+
#include "zsv_main.h"
|
|
19
|
+
|
|
20
|
+
#define APPNAME1(x) #x
|
|
21
|
+
#define APPNAME2(x) APPNAME1(x)
|
|
22
|
+
#define APPNAME APPNAME2(ZSV_COMMAND)
|
|
23
|
+
|
|
24
|
+
#include <zsv/utils/err.h>
|
|
25
|
+
|
|
26
|
+
#ifdef ZSV_COMMAND_NO_OPTIONS
|
|
27
|
+
ZSV_MAIN_NO_OPTIONS_DECL(ZSV_COMMAND);
|
|
28
|
+
#else
|
|
29
|
+
ZSV_MAIN_DECL(ZSV_COMMAND);
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* If we are currently compiling a standalone executable (e.g. zsv_select),
|
|
34
|
+
* then include the main() code
|
|
35
|
+
*/
|
|
36
|
+
#ifndef ZSV_CLI
|
|
37
|
+
#include "zsv_command_standalone.c"
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
#endif
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stub for standalone zsv command compilation e.g. for building zsv_select, zsv_count etc each as separate executables
|
|
3
|
+
*/
|
|
4
|
+
int main(int argc, const char *argv[]) {
|
|
5
|
+
#ifdef ZSV_COMMAND_NO_OPTIONS
|
|
6
|
+
// if ZSV_MAIN_NO_OPTIONS is defined, we just call the command entry point
|
|
7
|
+
// with the original argc and argv arguments
|
|
8
|
+
return ZSV_MAIN_NO_OPTIONS_FUNC(ZSV_COMMAND)(argc, argv);
|
|
9
|
+
#else
|
|
10
|
+
struct zsv_opts opts;
|
|
11
|
+
enum zsv_status stat = zsv_args_to_opts(argc, argv, &argc, argv, &opts);
|
|
12
|
+
if (stat != zsv_status_ok)
|
|
13
|
+
return stat;
|
|
14
|
+
return ZSV_MAIN_FUNC(ZSV_COMMAND)(argc, argv, &opts, NULL);
|
|
15
|
+
#endif
|
|
16
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#ifndef ZSV_MAIN_H
|
|
2
|
+
#define ZSV_MAIN_H
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ZSV commands can each be compiled as either a standalone executable or a
|
|
6
|
+
* command bundled into the `zsv` CLI. To support these different options
|
|
7
|
+
* without repeating common invocation code, we define two sets of macros: one
|
|
8
|
+
* set each for commands that do, and that do not, use common zsv parsing
|
|
9
|
+
* options. Each set has a macro each for the entry point name and declaration
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
#define ZSV_MAIN_FUNC1(x) zsv_##x##_main
|
|
13
|
+
#define ZSV_MAINEXT_FUNC1(x) zsv_##x##_mainext
|
|
14
|
+
#define ZSV_MAIN_NO_OPTIONS_FUNC1(x) zsv_##x##_main_no_options
|
|
15
|
+
|
|
16
|
+
struct zsv_opts;
|
|
17
|
+
struct zsv_prop_handler;
|
|
18
|
+
|
|
19
|
+
/* macros for commands that use common zsv parsing */
|
|
20
|
+
#define ZSV_MAIN_FUNC(x) ZSV_MAIN_FUNC1(x)
|
|
21
|
+
#define ZSV_MAINEXT_FUNC(x) ZSV_MAINEXT_FUNC1(x)
|
|
22
|
+
#define ZSV_MAIN_DECL(x) \
|
|
23
|
+
int ZSV_MAIN_FUNC(x)(int argc, const char *argv[], struct zsv_opts *opts, \
|
|
24
|
+
struct zsv_prop_handler *custom_prop_handler)
|
|
25
|
+
|
|
26
|
+
/* macros for commands that do not use common zsv parsing */
|
|
27
|
+
#define ZSV_MAIN_NO_OPTIONS_FUNC(x) ZSV_MAIN_NO_OPTIONS_FUNC1(x)
|
|
28
|
+
#define ZSV_MAIN_NO_OPTIONS_DECL(x) int ZSV_MAIN_NO_OPTIONS_FUNC(x)(int argc, const char *argv[])
|
|
29
|
+
|
|
30
|
+
/* macros for commands that require loading extensions before running */
|
|
31
|
+
#define ZSV_MAINEXT_FUNC_DEFINE(x) \
|
|
32
|
+
int ZSV_MAINEXT_FUNC(x)(int argc, const char *argv[], struct zsv_opts *optsp, \
|
|
33
|
+
struct zsv_prop_handler *custom_prop_handler) { \
|
|
34
|
+
int ZSV_MAIN_FUNC(x)(int argc, const char *argv[], struct zsv_opts *optsp, \
|
|
35
|
+
struct zsv_prop_handler *custom_prop_handler); \
|
|
36
|
+
/* initialize extensions */ \
|
|
37
|
+
struct cli_config config; \
|
|
38
|
+
config_init(&config, 1, 1, 0); \
|
|
39
|
+
return ZSV_MAIN_FUNC(sheet)(argc, argv, optsp, custom_prop_handler); \
|
|
40
|
+
} \
|
|
41
|
+
/* extra declaration to allow trailing semicolon */ int ZSV_MAIN_FUNC(x)( \
|
|
42
|
+
int argc, const char *argv[], struct zsv_opts *optsp, struct zsv_prop_handler *custom_prop_handler)
|
|
43
|
+
|
|
44
|
+
#endif
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#include <string.h>
|
|
2
|
+
#include <stdio.h>
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <zsv.h>
|
|
5
|
+
|
|
6
|
+
/** zsv example parsing in chunks
|
|
7
|
+
*
|
|
8
|
+
* This sample code shows how to use `zsv_parse_bytes()`
|
|
9
|
+
* to parse a chunk of bytes, instead of using `zsv_parse_more()`
|
|
10
|
+
* to pull data from a stream
|
|
11
|
+
*
|
|
12
|
+
* Note that, when given a choice, using `zsv_parse_more()`
|
|
13
|
+
* may be slightly more efficient / performant as is requires
|
|
14
|
+
* less memory copying
|
|
15
|
+
*
|
|
16
|
+
* In this example, we just count rows, but you could substitute in any
|
|
17
|
+
* row handler you want
|
|
18
|
+
**/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create a structure to hold our data while we parse
|
|
22
|
+
* In this case, we are just going to keep track of row count
|
|
23
|
+
*/
|
|
24
|
+
struct chunk_parse_data {
|
|
25
|
+
unsigned count;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Our row handler function will take a pointer to our data
|
|
30
|
+
* and increment its count by 1
|
|
31
|
+
*/
|
|
32
|
+
static void chunk_parse_row(void *dat) {
|
|
33
|
+
struct chunk_parse_data *data = dat;
|
|
34
|
+
data->count++;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Main routine will output a help message if called with -h or --help,
|
|
39
|
+
* otherwise will read from stdin and run through the CSV parser
|
|
40
|
+
*/
|
|
41
|
+
int main(int argc, const char *argv[]) {
|
|
42
|
+
if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) {
|
|
43
|
+
printf("Usage: parse_by_chunk < file.csv\n\n");
|
|
44
|
+
printf("Reads stdin in chunks, parses each chunk using `zsv_parse_bytes()`,\n");
|
|
45
|
+
printf("and outputs the number of rows parsed.\n");
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
FILE *f = stdin; /* read from stdin */
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* create a vanilla parser
|
|
53
|
+
*/
|
|
54
|
+
zsv_parser p = zsv_new(NULL);
|
|
55
|
+
if (!p)
|
|
56
|
+
fprintf(stderr, "Out of memory!");
|
|
57
|
+
else {
|
|
58
|
+
/**
|
|
59
|
+
* Configure the parser to use our row handler, and to pass
|
|
60
|
+
* it our data when it's called
|
|
61
|
+
*/
|
|
62
|
+
struct chunk_parse_data d = {0};
|
|
63
|
+
zsv_set_row_handler(p, chunk_parse_row);
|
|
64
|
+
zsv_set_context(p, &d);
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Allocate a buffer that we will fetch data from and pass to the parser.
|
|
68
|
+
* In this example we use a heap buffer, but we could just as well
|
|
69
|
+
* have allocated it on the stack
|
|
70
|
+
*/
|
|
71
|
+
int chunk_size = 4096;
|
|
72
|
+
unsigned char *buff = malloc(chunk_size);
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Read and parse each chunk until the end of the stream is reached
|
|
76
|
+
*/
|
|
77
|
+
while (1) {
|
|
78
|
+
size_t bytes_read = fread(buff, 1, chunk_size, f);
|
|
79
|
+
if (!bytes_read)
|
|
80
|
+
break;
|
|
81
|
+
zsv_parse_bytes(p, buff, bytes_read);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Finish any remaining parsing
|
|
86
|
+
*/
|
|
87
|
+
zsv_finish(p);
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Clean up
|
|
91
|
+
*/
|
|
92
|
+
zsv_delete(p);
|
|
93
|
+
free(buff);
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Print result
|
|
97
|
+
*/
|
|
98
|
+
printf("Count: %u\n", d.count);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple example using libzsv to call a row handler after each row is parsed
|
|
3
|
+
*
|
|
4
|
+
* In this example, we will use libzsv to parse a CSV file, look for a specified
|
|
5
|
+
* column of data, and for each row of data, output only that column
|
|
6
|
+
*
|
|
7
|
+
* Example:
|
|
8
|
+
* `echo "hi,there,you\na,b,c\nd,e,f" | ./print_my_column there
|
|
9
|
+
* Outputs:
|
|
10
|
+
* there
|
|
11
|
+
*
|
|
12
|
+
* In our implementation, we will define two row handlers. The first handler
|
|
13
|
+
* will be used to handle the first row, which we assume to be the header,
|
|
14
|
+
* and will search for the target column to identify what position it is in
|
|
15
|
+
* (or whether we can't find it). The second handler will be used to process
|
|
16
|
+
* each data row, and will output the target column
|
|
17
|
+
*/
|
|
18
|
+
static void print_my_column(void *ctx);
|
|
19
|
+
static void find_my_column(void *ctx);
|
|
20
|
+
|
|
21
|
+
#include <stdio.h>
|
|
22
|
+
#include <zsv.h>
|
|
23
|
+
#include <string.h>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* First, we define a structure that will contain all the information that
|
|
27
|
+
* our row handler will need
|
|
28
|
+
*/
|
|
29
|
+
struct my_data {
|
|
30
|
+
zsv_parser parser;
|
|
31
|
+
const char *target_column_name; /* name of column to find and output */
|
|
32
|
+
size_t target_column_position; /* will be set to the position of the column to output */
|
|
33
|
+
char not_found; /* if we can't find the column, we'll set this flag */
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Our first callback will search each cell in the (header) row. If it finds a match
|
|
38
|
+
* it sets the `target_column_position`, otherwise it halts further processing and
|
|
39
|
+
* sets the `not_found` flag
|
|
40
|
+
*/
|
|
41
|
+
static void find_my_column(void *ctx) {
|
|
42
|
+
struct my_data *data = ctx;
|
|
43
|
+
size_t target_column_name_len = strlen(data->target_column_name);
|
|
44
|
+
|
|
45
|
+
/* iterate through each cell */
|
|
46
|
+
size_t cell_count = zsv_cell_count(data->parser);
|
|
47
|
+
char found = 0;
|
|
48
|
+
for (size_t i = 0; i < cell_count; i++) {
|
|
49
|
+
struct zsv_cell c = zsv_get_cell(data->parser, i);
|
|
50
|
+
if (c.len == target_column_name_len && !memcmp(data->target_column_name, c.str, c.len)) {
|
|
51
|
+
data->target_column_position = i;
|
|
52
|
+
found = 1;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!found) {
|
|
58
|
+
/**
|
|
59
|
+
* We couldn't find the target column name in our header row. Output a message and abort
|
|
60
|
+
*/
|
|
61
|
+
fprintf(stderr, "Could not find column %.*s\n", (int)target_column_name_len, data->target_column_name);
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Once `zsv_abort()` is called, the parser will no longer invoke any callbacks
|
|
65
|
+
* and `zsv_parse_more()` will return `zsv_status_cancelled`
|
|
66
|
+
*/
|
|
67
|
+
zsv_abort(data->parser);
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* set a flag that we will later use to determine our program's exit code
|
|
71
|
+
*/
|
|
72
|
+
data->not_found = 1;
|
|
73
|
+
} else {
|
|
74
|
+
/**
|
|
75
|
+
* we found the column we are looking for. print its name, and change our row handler
|
|
76
|
+
* by calling `zsv_set_row_handler()`
|
|
77
|
+
*/
|
|
78
|
+
printf("%s\n", data->target_column_name);
|
|
79
|
+
zsv_set_row_handler(data->parser, print_my_column);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Output data from the selected column
|
|
85
|
+
*/
|
|
86
|
+
static void print_my_column(void *ctx) {
|
|
87
|
+
struct my_data *data = ctx;
|
|
88
|
+
|
|
89
|
+
/* use zsv_get_cell() to get our cell data */
|
|
90
|
+
struct zsv_cell c = zsv_get_cell(data->parser, data->target_column_position);
|
|
91
|
+
|
|
92
|
+
/* print the data, followed by a newline */
|
|
93
|
+
printf("%.*s\n", (int)c.len, c.str);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Main routine. Our example will take a single argument specifying a column
|
|
98
|
+
* name, read from stdin, and output, for each row, the specified column
|
|
99
|
+
*/
|
|
100
|
+
int main(int argc, const char *argv[]) {
|
|
101
|
+
if (argc < 2) {
|
|
102
|
+
fprintf(stderr, "Usage: print_my_column column_name < input.csv\n");
|
|
103
|
+
fprintf(stderr,
|
|
104
|
+
"Example:\n"
|
|
105
|
+
" echo \"A,B,C\\nA1,B1,C1\\nA2,B2,\\nA3,,C3\\n,,C3\" | %s B\n\n",
|
|
106
|
+
argv[0]);
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Initialize context data
|
|
112
|
+
*/
|
|
113
|
+
struct my_data data = {0};
|
|
114
|
+
data.target_column_name = argv[1];
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Initialize parser options
|
|
118
|
+
*/
|
|
119
|
+
struct zsv_opts opts = {0};
|
|
120
|
+
opts.row_handler = find_my_column;
|
|
121
|
+
opts.ctx = &data;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Create a parser
|
|
125
|
+
*/
|
|
126
|
+
data.parser = zsv_new(&opts);
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Continuously parse our input until we have no more input
|
|
130
|
+
* or an error has occurred (such as not finding the specified
|
|
131
|
+
* column name in the first row)
|
|
132
|
+
*/
|
|
133
|
+
while (zsv_parse_more(data.parser) == zsv_status_ok)
|
|
134
|
+
;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Clean up
|
|
138
|
+
*/
|
|
139
|
+
zsv_finish(data.parser);
|
|
140
|
+
zsv_delete(data.parser);
|
|
141
|
+
|
|
142
|
+
return data.not_found;
|
|
143
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#include <stdio.h>
|
|
2
|
+
#include <string.h>
|
|
3
|
+
#include <zsv.h>
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Simple example using libzsv as a pull parser for CSV input
|
|
7
|
+
*
|
|
8
|
+
* This is the same as simple.c, but uses pull parsing instead of push parsing
|
|
9
|
+
*
|
|
10
|
+
* We will check each cell in the row to determine if it is blank, and output
|
|
11
|
+
* the row number, the total number of cells and the number of blank cells
|
|
12
|
+
*
|
|
13
|
+
* Example:
|
|
14
|
+
* `echo 'abc,def\nghi,,,' | build/simple -`
|
|
15
|
+
* Outputs:
|
|
16
|
+
* Row 1 has 2 columns of which 0 are non-blank
|
|
17
|
+
* Row 2 has 4 columns of which 3 are non-blank
|
|
18
|
+
*
|
|
19
|
+
* With pull parsing, the parser just repeatedly calls zsv_next_row() so long
|
|
20
|
+
* as it returns `zsv_status_row`
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Main routine. Our program will take a single argument (a file name, or -)
|
|
25
|
+
* and output, for each row, the numbers of total and blank cells
|
|
26
|
+
*/
|
|
27
|
+
int main(int argc, const char *argv[]) {
|
|
28
|
+
if (argc != 2) {
|
|
29
|
+
fprintf(stderr, "Reads a CSV file or stdin, and for each row,\n"
|
|
30
|
+
" output counts of total and blank cells\n");
|
|
31
|
+
fprintf(stderr, "Usage: simple <filename or dash(-) for stdin>\n");
|
|
32
|
+
fprintf(stderr,
|
|
33
|
+
"Example:\n"
|
|
34
|
+
" echo \"A1,B1,C1\\nA2,B2,\\nA3,,C3\\n,,C3\" | %s -\n\n",
|
|
35
|
+
argv[0]);
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
FILE *f = strcmp(argv[1], "-") ? fopen(argv[1], "rb") : stdin;
|
|
40
|
+
if (!f) {
|
|
41
|
+
perror(argv[1]);
|
|
42
|
+
return 1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a parser
|
|
47
|
+
*/
|
|
48
|
+
struct zsv_opts opts = {0};
|
|
49
|
+
opts.stream = f;
|
|
50
|
+
zsv_parser parser = zsv_new(&opts);
|
|
51
|
+
if (!parser) {
|
|
52
|
+
fprintf(stderr, "Could not allocate parser!\n");
|
|
53
|
+
return -1;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* iterate through all rows
|
|
58
|
+
*/
|
|
59
|
+
size_t row_num = 0;
|
|
60
|
+
while (zsv_next_row(parser) == zsv_status_row) {
|
|
61
|
+
row_num++;
|
|
62
|
+
|
|
63
|
+
/* get a cell count */
|
|
64
|
+
size_t cell_count = zsv_cell_count(parser);
|
|
65
|
+
|
|
66
|
+
/* iterate through each cell in this row, to count blanks */
|
|
67
|
+
size_t nonblank = 0;
|
|
68
|
+
for (size_t i = 0; i < cell_count; i++) {
|
|
69
|
+
struct zsv_cell c = zsv_get_cell(parser, i);
|
|
70
|
+
/* use r.values[] and r.lengths[] to get cell data */
|
|
71
|
+
/* Here, we only care about lengths */
|
|
72
|
+
if (c.len > 0)
|
|
73
|
+
nonblank++;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* print our results for this row */
|
|
77
|
+
printf("Row %zu has %zu columns of which %zu %s non-blank\n", row_num, cell_count, nonblank,
|
|
78
|
+
nonblank == 1 ? "is" : "are");
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Clean up
|
|
82
|
+
*/
|
|
83
|
+
zsv_delete(parser);
|
|
84
|
+
|
|
85
|
+
if (f != stdin)
|
|
86
|
+
fclose(f);
|
|
87
|
+
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#include <stdio.h>
|
|
2
|
+
#include <string.h>
|
|
3
|
+
#include <zsv.h>
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Simple example using libzsv to call a row handler after each row is parsed
|
|
7
|
+
*
|
|
8
|
+
* In this super simple example, we will use libzsv to parse a CSV file
|
|
9
|
+
* and call our custom row handler after each row is parsed. Our row handler
|
|
10
|
+
* will check each cell in the row to determine if it is blank, and output
|
|
11
|
+
* the row number, the total number of cells and the number of blank cells
|
|
12
|
+
*
|
|
13
|
+
* Example:
|
|
14
|
+
* `echo 'abc,def\nghi,,,' | build/simple -`
|
|
15
|
+
* Outputs:
|
|
16
|
+
* Row 1 has 2 columns of which 0 are non-blank
|
|
17
|
+
* Row 2 has 4 columns of which 3 are non-blank
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* First, we define a structure that will contain all the information that
|
|
22
|
+
* our row handler will need
|
|
23
|
+
*/
|
|
24
|
+
struct my_data {
|
|
25
|
+
zsv_parser parser; /* used to access the parsed data */
|
|
26
|
+
size_t row_num; /* used to track the current row number */
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Our row handler is passed a pointer to our structure
|
|
31
|
+
*/
|
|
32
|
+
void my_row_handler(void *ctx) {
|
|
33
|
+
struct my_data *data = ctx;
|
|
34
|
+
|
|
35
|
+
/* get a cell count */
|
|
36
|
+
size_t cell_count = zsv_cell_count(data->parser);
|
|
37
|
+
|
|
38
|
+
/* iterate through each cell in this row, to count blanks */
|
|
39
|
+
size_t nonblank = 0;
|
|
40
|
+
for (size_t i = 0; i < cell_count; i++) {
|
|
41
|
+
/* use zsv_get_cell() to get our cell data */
|
|
42
|
+
struct zsv_cell c = zsv_get_cell(data->parser, i);
|
|
43
|
+
|
|
44
|
+
/* check if the cell data length is zero */
|
|
45
|
+
if (c.len > 0)
|
|
46
|
+
nonblank++;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* print our results for this row */
|
|
50
|
+
printf("Row %zu has %zu columns of which %zu %s non-blank\n", ++data->row_num, cell_count, nonblank,
|
|
51
|
+
nonblank == 1 ? "is" : "are");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Main routine. Our program will take a single argument (a file name, or -)
|
|
56
|
+
* and output, for each row, the numbers of total and blank cells
|
|
57
|
+
*/
|
|
58
|
+
int main(int argc, const char *argv[]) {
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Process our arguments; output usage and/or errors if appropriate
|
|
62
|
+
*/
|
|
63
|
+
if (argc != 2) {
|
|
64
|
+
fprintf(stderr, "Reads a CSV file or stdin, and for each row,\n"
|
|
65
|
+
" output counts of total and blank cells\n");
|
|
66
|
+
fprintf(stderr, "Usage: simple <filename or dash(-) for stdin>\n");
|
|
67
|
+
fprintf(stderr,
|
|
68
|
+
"Example:\n"
|
|
69
|
+
" echo \"A1,B1,C1\\nA2,B2,\\nA3,,C3\\n,,C3\" | %s -\n\n",
|
|
70
|
+
argv[0]);
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
FILE *f = strcmp(argv[1], "-") ? fopen(argv[1], "rb") : stdin;
|
|
75
|
+
if (!f) {
|
|
76
|
+
perror(argv[1]);
|
|
77
|
+
return 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Configure our parser options. Here, all we do is specify our row handler
|
|
82
|
+
* and the pointer that will be passed to our row handler. There are many
|
|
83
|
+
* other options to control the parser behavior (CSV vs TSV vs other
|
|
84
|
+
* delimited; header row span etc)-- for details, see
|
|
85
|
+
* ../../include/zsv/api.h
|
|
86
|
+
*/
|
|
87
|
+
struct zsv_opts opts = {0};
|
|
88
|
+
opts.row_handler = my_row_handler;
|
|
89
|
+
struct my_data data = {0};
|
|
90
|
+
opts.ctx = &data;
|
|
91
|
+
opts.stream = f;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Create a parser
|
|
95
|
+
*/
|
|
96
|
+
data.parser = zsv_new(&opts);
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Continuously parse our input until we have no more input
|
|
100
|
+
*/
|
|
101
|
+
enum zsv_status stat;
|
|
102
|
+
while ((stat = zsv_parse_more(data.parser)) == zsv_status_ok)
|
|
103
|
+
;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Clean up
|
|
107
|
+
*/
|
|
108
|
+
zsv_finish(data.parser);
|
|
109
|
+
zsv_delete(data.parser);
|
|
110
|
+
|
|
111
|
+
if (f != stdin)
|
|
112
|
+
fclose(f);
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* If there was a parse error, print it
|
|
116
|
+
*/
|
|
117
|
+
if (stat != zsv_status_no_more_input) {
|
|
118
|
+
fprintf(stderr, "Parse error: %s\n", zsv_parse_status_desc(stat));
|
|
119
|
+
return 1;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#include <unistd.h>
|
|
2
|
+
#include "../src/zsv.c"
|
|
3
|
+
|
|
4
|
+
__AFL_FUZZ_INIT();
|
|
5
|
+
|
|
6
|
+
int main() {
|
|
7
|
+
__AFL_INIT();
|
|
8
|
+
unsigned char *src = 0;
|
|
9
|
+
unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;
|
|
10
|
+
while (__AFL_LOOP(10000)) {
|
|
11
|
+
int len = __AFL_FUZZ_TESTCASE_LEN;
|
|
12
|
+
src = realloc(src, len);
|
|
13
|
+
memcpy(src, buf, len);
|
|
14
|
+
zsv_parse_bytes(zsv_new(0), src, len);
|
|
15
|
+
}
|
|
16
|
+
}
|