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,372 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2021 Liquidaty and zsv contributors. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* This file is part of zsv/lib, distributed under the MIT license as defined at
|
|
5
|
+
* https://opensource.org/licenses/MIT
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include <stdio.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
|
|
11
|
+
#define _GNU_SOURCE 1
|
|
12
|
+
#include <string.h>
|
|
13
|
+
#include <ctype.h>
|
|
14
|
+
|
|
15
|
+
#define ZSV_COMMAND serialize
|
|
16
|
+
#include "zsv_command.h"
|
|
17
|
+
|
|
18
|
+
#include <zsv/utils/writer.h>
|
|
19
|
+
#include <zsv/utils/string.h>
|
|
20
|
+
|
|
21
|
+
struct output_header_name {
|
|
22
|
+
unsigned char *str;
|
|
23
|
+
size_t len;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
struct serialize_additional_column {
|
|
27
|
+
struct serialize_additional_column *next;
|
|
28
|
+
unsigned char *name;
|
|
29
|
+
size_t len;
|
|
30
|
+
size_t position_plus_1; // 0 = unassigned / not found
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
struct serialize_data {
|
|
34
|
+
FILE *in;
|
|
35
|
+
const char *input_path;
|
|
36
|
+
zsv_csv_writer csv_writer;
|
|
37
|
+
zsv_parser parser;
|
|
38
|
+
|
|
39
|
+
struct output_header_name *header_names;
|
|
40
|
+
unsigned int col_count;
|
|
41
|
+
unsigned int id_column_position;
|
|
42
|
+
|
|
43
|
+
char *err_msg;
|
|
44
|
+
|
|
45
|
+
struct serialize_additional_column *additional_columns;
|
|
46
|
+
struct serialize_additional_column **additional_columns_next;
|
|
47
|
+
struct {
|
|
48
|
+
const char *value;
|
|
49
|
+
unsigned char *value_lc; // only used if case_insensitive is set
|
|
50
|
+
size_t len;
|
|
51
|
+
unsigned char case_insensitive : 1;
|
|
52
|
+
unsigned char entire : 1;
|
|
53
|
+
unsigned _ : 6;
|
|
54
|
+
} filter;
|
|
55
|
+
unsigned char use_column_position : 1;
|
|
56
|
+
unsigned char _ : 7;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
static void serialize_write_tuple(struct serialize_data *data, const unsigned char *id, size_t id_len, char id_quoted,
|
|
60
|
+
const unsigned char *colname, size_t colname_len, const unsigned char *s, size_t len,
|
|
61
|
+
char quoted) {
|
|
62
|
+
// write row ID, column name, cell value
|
|
63
|
+
zsv_writer_cell(data->csv_writer, 1, id, id_len, id_quoted);
|
|
64
|
+
zsv_writer_cell(data->csv_writer, 0, colname, colname_len, 0);
|
|
65
|
+
zsv_writer_cell(data->csv_writer, 0, s, len, quoted);
|
|
66
|
+
|
|
67
|
+
// to do: write additional column headers
|
|
68
|
+
for (struct serialize_additional_column *col = data->additional_columns; col; col = col->next) {
|
|
69
|
+
if (col->position_plus_1) {
|
|
70
|
+
struct zsv_cell c = zsv_get_cell(data->parser, col->position_plus_1 - 1);
|
|
71
|
+
zsv_writer_cell(data->csv_writer, 0, c.str, c.len, c.quoted);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static inline void serialize_cell(struct serialize_data *data, struct zsv_cell id, unsigned i) {
|
|
77
|
+
struct zsv_cell cell = zsv_get_cell(data->parser, i);
|
|
78
|
+
char skip = 0;
|
|
79
|
+
if (data->filter.value) {
|
|
80
|
+
if (data->filter.case_insensitive) {
|
|
81
|
+
if (data->filter.entire) {
|
|
82
|
+
int err = 0;
|
|
83
|
+
skip = zsv_strincmp(cell.str, cell.len, (const unsigned char *)data->filter.value, data->filter.len);
|
|
84
|
+
if (err) {
|
|
85
|
+
skip = 1;
|
|
86
|
+
fprintf(stderr, "Ignoring invalid utf8: %.*s\n", (int)cell.len, cell.str);
|
|
87
|
+
}
|
|
88
|
+
} else { // case-insensitive, not-entire-cell. skip if not contains
|
|
89
|
+
if (data->filter.value_lc) {
|
|
90
|
+
size_t len = cell.len;
|
|
91
|
+
unsigned char *tmp = zsv_strtolowercase(cell.str, &len);
|
|
92
|
+
if (tmp) {
|
|
93
|
+
skip = !zsv_strstr(tmp, data->filter.value_lc);
|
|
94
|
+
free(tmp);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
if (data->filter.entire) // case-sensitive, exact / entire-cell. skip if not equal
|
|
100
|
+
skip = !(cell.len == data->filter.len && !memcmp(cell.str, data->filter.value, cell.len));
|
|
101
|
+
else // case-sensitive, not-entire-cell. skip if not contains
|
|
102
|
+
skip = !memmem(cell.str, cell.len, data->filter.value, data->filter.len);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!skip)
|
|
107
|
+
// write tuple
|
|
108
|
+
serialize_write_tuple(data, id.str, id.len, id.quoted, data->header_names[i].str, data->header_names[i].len,
|
|
109
|
+
cell.str, cell.len, cell.quoted);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static void serialize_row(void *hook);
|
|
113
|
+
|
|
114
|
+
static void serialize_header(void *hook) {
|
|
115
|
+
struct serialize_data *data = hook;
|
|
116
|
+
zsv_set_row_handler(data->parser, serialize_row);
|
|
117
|
+
if (data->err_msg)
|
|
118
|
+
return;
|
|
119
|
+
|
|
120
|
+
data->col_count = zsv_cell_count(data->parser);
|
|
121
|
+
if (!data->col_count)
|
|
122
|
+
asprintf(&data->err_msg, "No columns read in first row; aborting\n");
|
|
123
|
+
else {
|
|
124
|
+
// write header
|
|
125
|
+
struct zsv_cell idCell = zsv_get_cell(data->parser, data->id_column_position);
|
|
126
|
+
if (idCell.len == 0) {
|
|
127
|
+
idCell.str = (unsigned char *)"(Blank)";
|
|
128
|
+
idCell.len = strlen((const char *)idCell.str);
|
|
129
|
+
}
|
|
130
|
+
// if we have additional columns, find them and output their header names
|
|
131
|
+
if (data->additional_columns) {
|
|
132
|
+
for (struct serialize_additional_column *c = data->additional_columns; c && !data->err_msg; c = c->next) {
|
|
133
|
+
for (unsigned i = 0; i < data->col_count && !data->err_msg; i++) {
|
|
134
|
+
struct zsv_cell tmp = zsv_get_cell(data->parser, i);
|
|
135
|
+
|
|
136
|
+
if (!zsv_strincmp(tmp.str, tmp.len, c->name, c->len)) {
|
|
137
|
+
// found
|
|
138
|
+
c->position_plus_1 = i + 1;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (!c->position_plus_1)
|
|
143
|
+
asprintf(&data->err_msg, "Column '%s' not found\n", (char *)c->name);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (!data->err_msg) {
|
|
147
|
+
data->header_names = calloc(data->col_count, sizeof(*data->header_names));
|
|
148
|
+
if (!data->header_names)
|
|
149
|
+
asprintf(&data->err_msg, "Out of memory!");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
for (unsigned i = 1; i < data->col_count && !data->err_msg; i++) {
|
|
153
|
+
struct zsv_cell cell = zsv_get_cell(data->parser, i);
|
|
154
|
+
// save the column header name
|
|
155
|
+
if (data->use_column_position)
|
|
156
|
+
asprintf((char **)&data->header_names[i].str, "%u", i);
|
|
157
|
+
else {
|
|
158
|
+
struct zsv_cell c = zsv_get_cell(data->parser, i);
|
|
159
|
+
if (i == 0 && c.len == 0)
|
|
160
|
+
data->header_names[i].str = (unsigned char *)strdup("(Blank)");
|
|
161
|
+
else
|
|
162
|
+
data->header_names[i].str = zsv_writer_str_to_csv(cell.str, cell.len);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (data->header_names[i].str)
|
|
166
|
+
data->header_names[i].len = strlen((const char *)data->header_names[i].str);
|
|
167
|
+
else if (cell.len)
|
|
168
|
+
asprintf(&data->err_msg, "Out of memory!");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!data->err_msg) {
|
|
172
|
+
// print the output table header
|
|
173
|
+
serialize_write_tuple(data, idCell.str, idCell.len, idCell.quoted, (const unsigned char *)"Column",
|
|
174
|
+
strlen("Column"), (const unsigned char *)"Value", strlen("Value"), 0);
|
|
175
|
+
|
|
176
|
+
if (data->use_column_position) {
|
|
177
|
+
// process the header row as if it was a data row
|
|
178
|
+
// output ID cell
|
|
179
|
+
struct zsv_cell cell = zsv_get_cell(data->parser, data->id_column_position);
|
|
180
|
+
serialize_write_tuple(data, (const unsigned char *)"Header", strlen("Header"), 0, (const unsigned char *)"0", 1,
|
|
181
|
+
cell.str, cell.len, cell.quoted);
|
|
182
|
+
|
|
183
|
+
// output other cells
|
|
184
|
+
for (unsigned i = 0; i < data->col_count; i++) {
|
|
185
|
+
if (i != data->id_column_position) {
|
|
186
|
+
cell = zsv_get_cell(data->parser, i);
|
|
187
|
+
serialize_write_tuple(data, (const unsigned char *)"Header", strlen("Header"), 0, data->header_names[i].str,
|
|
188
|
+
data->header_names[i].len, cell.str, cell.len, cell.quoted);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
static void serialize_row(void *hook) {
|
|
197
|
+
struct serialize_data *data = hook;
|
|
198
|
+
if (data->err_msg)
|
|
199
|
+
return;
|
|
200
|
+
|
|
201
|
+
// get the row id
|
|
202
|
+
struct zsv_cell id = zsv_get_cell(data->parser, data->id_column_position);
|
|
203
|
+
|
|
204
|
+
unsigned j = zsv_cell_count(data->parser);
|
|
205
|
+
for (unsigned i = 0; i < j && i < data->col_count; i++)
|
|
206
|
+
if (i != data->id_column_position)
|
|
207
|
+
serialize_cell(data, id, i);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const char *serialize_usage_msg[] = {
|
|
211
|
+
APPNAME ": serialize a CSV file into row/column/value triplets",
|
|
212
|
+
"",
|
|
213
|
+
"Usage: " APPNAME " [<filename>]",
|
|
214
|
+
"",
|
|
215
|
+
"Options:",
|
|
216
|
+
" -b : output with BOM",
|
|
217
|
+
" -f,--filter <value> : only output cells with text that contains the given value",
|
|
218
|
+
" -e,--entire : match the entire cell's content (only applicable with -f)",
|
|
219
|
+
" -i,--case-insensitive : use case-insensitive match for the filter value",
|
|
220
|
+
" --id-column <n> : the 1-based position of the column to use as the identifier (default=1, max=2000)",
|
|
221
|
+
" -p,--position : output column position instead of name; the second column",
|
|
222
|
+
" will be position 1, and the first row will be treated as a",
|
|
223
|
+
" normal data row",
|
|
224
|
+
" -a,--add <column name> : add additional columns to output. may be specified",
|
|
225
|
+
" multiple times for multiple additional columns",
|
|
226
|
+
NULL,
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
static int serialize_usage(void) {
|
|
230
|
+
for (size_t i = 0; serialize_usage_msg[i]; i++)
|
|
231
|
+
fprintf(stdout, "%s\n", serialize_usage_msg[i]);
|
|
232
|
+
return 1;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
static void serialize_cleanup(struct serialize_data *data) {
|
|
236
|
+
zsv_writer_delete(data->csv_writer);
|
|
237
|
+
|
|
238
|
+
free(data->filter.value_lc);
|
|
239
|
+
free(data->err_msg);
|
|
240
|
+
|
|
241
|
+
if (data->header_names) {
|
|
242
|
+
for (unsigned int i = 0; i < data->col_count; i++)
|
|
243
|
+
free(data->header_names[i].str);
|
|
244
|
+
free(data->header_names);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (data->in && data->in != stdin)
|
|
248
|
+
fclose(data->in);
|
|
249
|
+
|
|
250
|
+
for (struct serialize_additional_column *next, *c = data->additional_columns; c; c = next) {
|
|
251
|
+
next = c->next;
|
|
252
|
+
free(c->name);
|
|
253
|
+
free(c);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
static int serialize_append_additional_column(struct serialize_data *data, const char *name) {
|
|
258
|
+
struct serialize_additional_column *c = calloc(1, sizeof(*c));
|
|
259
|
+
if (c) {
|
|
260
|
+
if ((c->name = (unsigned char *)strdup(name))) {
|
|
261
|
+
c->len = strlen((char *)c->name);
|
|
262
|
+
if (!data->additional_columns)
|
|
263
|
+
data->additional_columns = c;
|
|
264
|
+
else
|
|
265
|
+
*data->additional_columns_next = c;
|
|
266
|
+
data->additional_columns_next = &c->next;
|
|
267
|
+
return 0;
|
|
268
|
+
}
|
|
269
|
+
free(c);
|
|
270
|
+
}
|
|
271
|
+
return 1;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *opts,
|
|
275
|
+
struct zsv_prop_handler *custom_prop_handler) {
|
|
276
|
+
if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) {
|
|
277
|
+
serialize_usage();
|
|
278
|
+
return 0;
|
|
279
|
+
} else {
|
|
280
|
+
struct zsv_csv_writer_options writer_opts = zsv_writer_get_default_opts();
|
|
281
|
+
struct serialize_data data = {0};
|
|
282
|
+
int err = 0;
|
|
283
|
+
for (int arg_i = 1; !err && arg_i < argc; arg_i++) {
|
|
284
|
+
const char *arg = argv[arg_i];
|
|
285
|
+
if (!strcmp(arg, "-f") || !strcmp(arg, "--filter")) {
|
|
286
|
+
if (arg_i + 1 < argc)
|
|
287
|
+
data.filter.value = argv[++arg_i];
|
|
288
|
+
else {
|
|
289
|
+
fprintf(stderr, "filter option requires a value\n");
|
|
290
|
+
err = 1;
|
|
291
|
+
}
|
|
292
|
+
} else if (!strcmp(arg, "-a") || !strcmp(arg, "--add")) {
|
|
293
|
+
if (arg_i + 1 < argc)
|
|
294
|
+
err = serialize_append_additional_column(&data, argv[++arg_i]);
|
|
295
|
+
else {
|
|
296
|
+
fprintf(stderr, "%s option requires a value\n", argv[arg_i]);
|
|
297
|
+
err = 1;
|
|
298
|
+
}
|
|
299
|
+
} else if (!strcmp(arg, "-i") || !strcmp(arg, "--case-insensitive"))
|
|
300
|
+
data.filter.case_insensitive = 1;
|
|
301
|
+
else if (!strcmp(arg, "--id-column")) {
|
|
302
|
+
if (arg_i + 1 < argc && atoi(argv[arg_i + 1]) > 0 && atoi(argv[arg_i + 1]) <= 2000)
|
|
303
|
+
data.id_column_position = atoi(argv[++arg_i]) - 1;
|
|
304
|
+
else {
|
|
305
|
+
fprintf(stderr, "%s option requires a value between 1 and 2000\n", argv[arg_i]);
|
|
306
|
+
err = 1;
|
|
307
|
+
}
|
|
308
|
+
} else if (!strcmp(arg, "-p") || !strcmp(arg, "--position"))
|
|
309
|
+
data.use_column_position = 1;
|
|
310
|
+
else if (!strcmp(arg, "-e") || !strcmp(arg, "--entire"))
|
|
311
|
+
data.filter.entire = 1;
|
|
312
|
+
else if (!strcmp(argv[arg_i], "-b"))
|
|
313
|
+
writer_opts.with_bom = 1;
|
|
314
|
+
else if (data.in) {
|
|
315
|
+
err = 1;
|
|
316
|
+
fprintf(stderr, "Input file specified twice, or unrecognized argument: %s\n", argv[arg_i]);
|
|
317
|
+
} else if (!(data.in = fopen(argv[arg_i], "rb"))) {
|
|
318
|
+
err = 1;
|
|
319
|
+
fprintf(stderr, "Could not open for reading: %s\n", argv[arg_i]);
|
|
320
|
+
} else
|
|
321
|
+
data.input_path = argv[arg_i];
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (data.filter.value) {
|
|
325
|
+
data.filter.len = strlen(data.filter.value);
|
|
326
|
+
if (data.filter.case_insensitive)
|
|
327
|
+
data.filter.value_lc = zsv_strtolowercase((const unsigned char *)data.filter.value, &data.filter.len);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (!data.in) {
|
|
331
|
+
#ifdef NO_STDIN
|
|
332
|
+
fprintf(stderr, "Please specify an input file\n");
|
|
333
|
+
err = 1;
|
|
334
|
+
#else
|
|
335
|
+
data.in = stdin;
|
|
336
|
+
#endif
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (err) {
|
|
340
|
+
serialize_cleanup(&data);
|
|
341
|
+
return 1;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
opts->row_handler = serialize_header;
|
|
345
|
+
opts->stream = data.in;
|
|
346
|
+
const char *input_path = data.input_path;
|
|
347
|
+
|
|
348
|
+
opts->ctx = &data;
|
|
349
|
+
data.csv_writer = zsv_writer_new(&writer_opts);
|
|
350
|
+
if (zsv_new_with_properties(opts, custom_prop_handler, input_path, &data.parser) != zsv_status_ok ||
|
|
351
|
+
!data.csv_writer) {
|
|
352
|
+
serialize_cleanup(&data);
|
|
353
|
+
return 1;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// create a local csv writer buff for faster performance
|
|
357
|
+
unsigned char writer_buff[64];
|
|
358
|
+
zsv_writer_set_temp_buff(data.csv_writer, writer_buff, sizeof(writer_buff));
|
|
359
|
+
|
|
360
|
+
// process the input data
|
|
361
|
+
zsv_handle_ctrl_c_signal();
|
|
362
|
+
while (!zsv_signal_interrupted && zsv_parse_more(data.parser) == zsv_status_ok)
|
|
363
|
+
;
|
|
364
|
+
|
|
365
|
+
if (data.err_msg)
|
|
366
|
+
fprintf(stderr, "Error: %s\n", data.err_msg);
|
|
367
|
+
zsv_finish(data.parser);
|
|
368
|
+
zsv_delete(data.parser);
|
|
369
|
+
serialize_cleanup(&data);
|
|
370
|
+
}
|
|
371
|
+
return 0;
|
|
372
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#if defined(WIN32) || defined(_WIN32)
|
|
2
|
+
#ifdef HAVE_NCURSESW
|
|
3
|
+
#include <ncursesw/ncurses.h>
|
|
4
|
+
#else
|
|
5
|
+
#include <ncurses/ncurses.h>
|
|
6
|
+
#endif // HAVE_NCURSESW
|
|
7
|
+
#else
|
|
8
|
+
#if __has_include(<ncursesw/curses.h>)
|
|
9
|
+
#include <ncursesw/curses.h>
|
|
10
|
+
#elif __has_include(<curses.h>)
|
|
11
|
+
#include <curses.h>
|
|
12
|
+
#else
|
|
13
|
+
#error Cannot find ncurses include file!
|
|
14
|
+
#endif
|
|
15
|
+
#endif
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
static size_t input_offset_top(void) {
|
|
2
|
+
return 0;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
static size_t input_offset_bottom(struct zsvsheet_input_dimensions *input_dims,
|
|
6
|
+
size_t buffer_row_count // number of rows in the buffer, w/o regard to header
|
|
7
|
+
) {
|
|
8
|
+
return input_dims->row_count - buffer_row_count;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static size_t input_offset_centered(struct zsvsheet_input_dimensions *input_dims,
|
|
12
|
+
size_t buffer_row_count, // number of rows in the buffer, w/o regard to header
|
|
13
|
+
size_t target_raw_ix // raw row index starting at zero, w/o regard to header
|
|
14
|
+
) {
|
|
15
|
+
if (input_dims->row_count <= buffer_row_count) // entire input fits in buffer
|
|
16
|
+
return input_offset_top();
|
|
17
|
+
size_t buffer_half_row_count = buffer_row_count / 2;
|
|
18
|
+
if (target_raw_ix <= buffer_half_row_count) // target is at the top of the file
|
|
19
|
+
return input_offset_top();
|
|
20
|
+
if (target_raw_ix + buffer_half_row_count > input_dims->row_count) // target is at the end of the file
|
|
21
|
+
return input_offset_bottom(input_dims, buffer_row_count);
|
|
22
|
+
return target_raw_ix - buffer_half_row_count;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// zsvsheet_goto_input_raw_row
|
|
26
|
+
// return non-zero if buffer must be reloaded
|
|
27
|
+
/*
|
|
28
|
+
------- INPUT
|
|
29
|
+
0 | header | => BUFFER[BHEADSPAN]
|
|
30
|
+
1 | ... | => BUFFER[BHEADSPAN]
|
|
31
|
+
2 | data
|
|
32
|
+
------- BUFFER[BHEADSPAN:]
|
|
33
|
+
ioff->3 |
|
|
34
|
+
4 |
|
|
35
|
+
------- DISPLAY DATA
|
|
36
|
+
5 | boff-> | displayed data 1
|
|
37
|
+
6 | | displayed data 2
|
|
38
|
+
...
|
|
39
|
+
N+4| | displayed data M = max_y - BHEADSPAN - 1
|
|
40
|
+
-------
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
static void set_window_to_cursor(struct zsvsheet_rowcol *buff_offset, size_t target_raw_row,
|
|
44
|
+
struct zsvsheet_rowcol *input_offset, size_t input_header_span,
|
|
45
|
+
struct zsvsheet_display_dimensions *ddims, size_t cursor_row) {
|
|
46
|
+
// assume that input_offset->row is fixed; set buff_offset->row
|
|
47
|
+
if (target_raw_row + ddims->header_span >= input_offset->row + cursor_row + input_header_span)
|
|
48
|
+
buff_offset->row = target_raw_row - input_offset->row - cursor_row + ddims->header_span - input_header_span;
|
|
49
|
+
else
|
|
50
|
+
buff_offset->row = 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static int zsvsheet_goto_input_raw_row(struct zsvsheet_ui_buffer *uib, size_t input_raw_num, size_t input_header_span,
|
|
54
|
+
struct zsvsheet_display_dimensions *ddims, size_t final_cursor_position) {
|
|
55
|
+
zsvsheet_screen_buffer_t buffer = uib->buffer;
|
|
56
|
+
struct zsvsheet_rowcol *input_offset = &uib->input_offset;
|
|
57
|
+
struct zsvsheet_rowcol *buff_offset = &uib->buff_offset;
|
|
58
|
+
struct zsvsheet_input_dimensions *input_dims = &uib->dimensions;
|
|
59
|
+
size_t *cursor_rowp = &uib->cursor_row;
|
|
60
|
+
|
|
61
|
+
size_t buffer_rows = zsvsheet_screen_buffer_rows(buffer);
|
|
62
|
+
int update_buffer = 0;
|
|
63
|
+
if (input_raw_num < input_offset->row + input_header_span // move the buffer up
|
|
64
|
+
|| input_raw_num + input_header_span + 1 > input_offset->row + buffer_rows // move the buffer down
|
|
65
|
+
) {
|
|
66
|
+
input_offset->row = input_offset_centered(input_dims, buffer_rows, input_raw_num);
|
|
67
|
+
update_buffer = 1;
|
|
68
|
+
} else if (!(input_raw_num >= input_offset->row + buff_offset->row &&
|
|
69
|
+
input_raw_num <=
|
|
70
|
+
input_offset->row + buff_offset->row + (ddims->rows + ddims->header_span + ddims->footer_span))) {
|
|
71
|
+
// buffer already has the data but display window needs to move
|
|
72
|
+
} else {
|
|
73
|
+
if (final_cursor_position == (size_t)-1) {
|
|
74
|
+
// just move the cursor however much we needed to shift
|
|
75
|
+
size_t current = zsvsheet_get_input_raw_row(input_offset, buff_offset, *cursor_rowp);
|
|
76
|
+
final_cursor_position = *cursor_rowp + input_raw_num - current;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (final_cursor_position == (size_t)-1)
|
|
80
|
+
final_cursor_position = ddims->header_span;
|
|
81
|
+
if (final_cursor_position < ddims->header_span)
|
|
82
|
+
final_cursor_position = ddims->header_span;
|
|
83
|
+
if (final_cursor_position > ddims->rows - ddims->footer_span - 1)
|
|
84
|
+
final_cursor_position = ddims->rows - ddims->footer_span - 1;
|
|
85
|
+
*cursor_rowp = final_cursor_position;
|
|
86
|
+
|
|
87
|
+
// we may still need to update the buffer if the row we are jumping to will be
|
|
88
|
+
// in the middle of the screen and therefore we still want to display additional
|
|
89
|
+
// rows, and those additional rows are not loaded into the buffer
|
|
90
|
+
if (!update_buffer && final_cursor_position < ddims->rows - 1) {
|
|
91
|
+
size_t last_raw_row_to_display = input_raw_num + (ddims->rows - 1 - final_cursor_position);
|
|
92
|
+
if (last_raw_row_to_display > input_dims->row_count)
|
|
93
|
+
last_raw_row_to_display = input_dims->row_count;
|
|
94
|
+
if (last_raw_row_to_display < input_offset->row + input_header_span // move the buffer up
|
|
95
|
+
|| last_raw_row_to_display + input_header_span + 1 > input_offset->row + buffer_rows // move the buffer down
|
|
96
|
+
) {
|
|
97
|
+
input_offset->row = input_offset_centered(input_dims, buffer_rows, input_raw_num);
|
|
98
|
+
update_buffer = 1;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
set_window_to_cursor(buff_offset, input_raw_num, input_offset, input_header_span, ddims, *cursor_rowp);
|
|
102
|
+
return update_buffer;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static int cursor_right(int max_x, unsigned display_width, size_t max_col_count, size_t *cursor_colp,
|
|
106
|
+
size_t *start_colp) {
|
|
107
|
+
size_t cursor_col = *cursor_colp;
|
|
108
|
+
size_t start_col = *start_colp;
|
|
109
|
+
int rc = 1;
|
|
110
|
+
if (cursor_col + 1 < max_x / display_width && start_col + cursor_col + 1 < max_col_count) {
|
|
111
|
+
cursor_col++;
|
|
112
|
+
} else if ((start_col + max_x / display_width) < max_col_count) {
|
|
113
|
+
start_col++;
|
|
114
|
+
} else
|
|
115
|
+
rc = 0;
|
|
116
|
+
*cursor_colp = cursor_col;
|
|
117
|
+
*start_colp = start_col;
|
|
118
|
+
return rc;
|
|
119
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
struct zsvsheet_errors_data {
|
|
2
|
+
struct zsvsheet_ui_buffer *uib;
|
|
3
|
+
size_t rows_fetched;
|
|
4
|
+
const char *row_data[1];
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const unsigned char **zsvsheet_errors_header(void *d) {
|
|
8
|
+
struct zsvsheet_errors_data *data = d;
|
|
9
|
+
data->row_data[0] = "Error";
|
|
10
|
+
return (const unsigned char **)data->row_data;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const unsigned char *zsvsheet_errors_status(void *_) {
|
|
14
|
+
(void)(_);
|
|
15
|
+
return (const unsigned char *)"<esc> to exit, then :errors-clear to clear";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const unsigned char **zsvsheet_errors_row(void *d) {
|
|
19
|
+
struct zsvsheet_errors_data *data = d;
|
|
20
|
+
while (data->rows_fetched < data->uib->parse_errs.count) {
|
|
21
|
+
data->row_data[0] = data->uib->parse_errs.errors[data->rows_fetched];
|
|
22
|
+
data->rows_fetched++;
|
|
23
|
+
if (data->row_data[0] && *data->row_data[0])
|
|
24
|
+
return (const unsigned char **)data->row_data;
|
|
25
|
+
}
|
|
26
|
+
return NULL;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static zsvsheet_status zsvsheet_errors_handler(struct zsvsheet_proc_context *ctx) {
|
|
30
|
+
struct zsvsheet_errors_data d = {0};
|
|
31
|
+
d.uib = zsvsheet_buffer_current(ctx);
|
|
32
|
+
if (!d.uib)
|
|
33
|
+
return zsvsheet_status_error;
|
|
34
|
+
if (ctx->proc_id == zsvsheet_builtin_proc_errors_clear) {
|
|
35
|
+
uib_parse_errs_clear(&d.uib->parse_errs);
|
|
36
|
+
return zsvsheet_status_ok;
|
|
37
|
+
}
|
|
38
|
+
if (d.uib->parse_errs.count == 0) {
|
|
39
|
+
zsvsheet_ui_buffer_set_status(d.uib, "No errors");
|
|
40
|
+
return zsvsheet_status_ok;
|
|
41
|
+
}
|
|
42
|
+
const size_t cols = 1;
|
|
43
|
+
return zsvsheet_buffer_new_static(ctx, cols, zsvsheet_errors_header, zsvsheet_errors_row, zsvsheet_errors_status, &d,
|
|
44
|
+
NULL);
|
|
45
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
int zsvsheet_ui_buffer_open_file_opts(struct zsvsheet_ui_buffer_opts *uibopts,
|
|
2
|
+
struct zsv_prop_handler *custom_prop_handler,
|
|
3
|
+
struct zsvsheet_ui_buffer **ui_buffer_stack_bottom,
|
|
4
|
+
struct zsvsheet_ui_buffer **ui_buffer_stack_top) {
|
|
5
|
+
struct zsvsheet_opts zsvsheet_opts = {0};
|
|
6
|
+
struct zsvsheet_screen_buffer_opts bopts = {0};
|
|
7
|
+
struct zsvsheet_ui_buffer *tmp_ui_buffer = NULL;
|
|
8
|
+
|
|
9
|
+
if (!uibopts->buff_opts)
|
|
10
|
+
uibopts->buff_opts = &bopts;
|
|
11
|
+
|
|
12
|
+
int err = 0;
|
|
13
|
+
if ((err = read_data(&tmp_ui_buffer, uibopts, 0, 0, 0, &zsvsheet_opts, custom_prop_handler)) != 0 || !tmp_ui_buffer ||
|
|
14
|
+
!tmp_ui_buffer->buff_used_rows) {
|
|
15
|
+
zsvsheet_ui_buffer_delete(tmp_ui_buffer);
|
|
16
|
+
if (err)
|
|
17
|
+
return err;
|
|
18
|
+
return -1;
|
|
19
|
+
}
|
|
20
|
+
tmp_ui_buffer->cursor_row = 1; // first row is header
|
|
21
|
+
zsvsheet_ui_buffer_push(ui_buffer_stack_bottom, ui_buffer_stack_top, tmp_ui_buffer);
|
|
22
|
+
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
int zsvsheet_ui_buffer_open_file(const char *filename, const struct zsv_opts *zsv_optsp,
|
|
27
|
+
struct zsv_prop_handler *custom_prop_handler,
|
|
28
|
+
struct zsvsheet_ui_buffer **ui_buffer_stack_bottom,
|
|
29
|
+
struct zsvsheet_ui_buffer **ui_buffer_stack_top) {
|
|
30
|
+
struct zsvsheet_ui_buffer_opts uibopts = {0};
|
|
31
|
+
uibopts.filename = filename;
|
|
32
|
+
if (zsv_optsp)
|
|
33
|
+
uibopts.zsv_opts = *zsv_optsp;
|
|
34
|
+
|
|
35
|
+
return zsvsheet_ui_buffer_open_file_opts(&uibopts, custom_prop_handler, ui_buffer_stack_bottom, ui_buffer_stack_top);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/****** API ******/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Open a tabular file as a new buffer
|
|
42
|
+
*/
|
|
43
|
+
zsvsheet_status zsvsheet_open_file(struct zsvsheet_proc_context *ctx, const char *filepath, struct zsv_opts *zopts) {
|
|
44
|
+
struct zsvsheet_sheet_context *state = (struct zsvsheet_sheet_context *)ctx->subcommand_context;
|
|
45
|
+
struct zsvsheet_display_info *di = &state->display_info;
|
|
46
|
+
if (!di || !di->ui_buffers.base || !di->ui_buffers.current)
|
|
47
|
+
return zsvsheet_status_error;
|
|
48
|
+
int err = zsvsheet_ui_buffer_open_file(filepath, zopts, NULL, di->ui_buffers.base, di->ui_buffers.current);
|
|
49
|
+
if (err)
|
|
50
|
+
return zsvsheet_status_error;
|
|
51
|
+
return zsvsheet_status_ok;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
zsvsheet_status zsvsheet_open_file_opts(struct zsvsheet_proc_context *ctx, struct zsvsheet_ui_buffer_opts *opts) {
|
|
55
|
+
struct zsvsheet_sheet_context *state = (struct zsvsheet_sheet_context *)ctx->subcommand_context;
|
|
56
|
+
struct zsvsheet_display_info *di = &state->display_info;
|
|
57
|
+
if (!di || !di->ui_buffers.base || !di->ui_buffers.current)
|
|
58
|
+
return zsvsheet_status_error;
|
|
59
|
+
int err = zsvsheet_ui_buffer_open_file_opts(opts, NULL, di->ui_buffers.base, di->ui_buffers.current);
|
|
60
|
+
if (err)
|
|
61
|
+
return zsvsheet_status_error;
|
|
62
|
+
return zsvsheet_status_ok;
|
|
63
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#ifndef ZSVSHEET_FILE_H
|
|
2
|
+
#define ZSVSHEET_FILE_H
|
|
3
|
+
|
|
4
|
+
int zsvsheet_ui_buffer_open_file(const char *filename, const struct zsv_opts *zsv_optsp,
|
|
5
|
+
struct zsv_prop_handler *custom_prop_handler,
|
|
6
|
+
struct zsvsheet_ui_buffer **ui_buffer_stack_bottom,
|
|
7
|
+
struct zsvsheet_ui_buffer **ui_buffer_stack_top);
|
|
8
|
+
|
|
9
|
+
zsvsheet_status zsvsheet_open_file_opts(struct zsvsheet_proc_context *ctx, struct zsvsheet_ui_buffer_opts *opts);
|
|
10
|
+
zsvsheet_status zsvsheet_open_file(struct zsvsheet_proc_context *ctx, const char *filepath, struct zsv_opts *zopts);
|
|
11
|
+
|
|
12
|
+
#endif
|