From 9eff8474265d38f2fa9d974cdf2dde46e42535f5 Mon Sep 17 00:00:00 2001 From: liquidaty Date: Tue, 5 Nov 2024 11:57:56 -0800 Subject: [PATCH] updated README, paste usage. add placeholder for paste tests (#262) * updated README, paste usage. add placeholder for paste tests --- README.md | 11 +++++++---- TO-DO.md | 1 + app/paste.c | 40 +++++++++++++++++++++++++--------------- app/test/Makefile | 5 ++++- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index a8c7a690..a2e59ae8 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ generic-delimited and fixed-width formats, as well as multi-row-span headers The ZSV CLI can be compiled to virtually any target, including [WebAssembly](examples/js), and offers features including `select`, `count`, direct CSV `sql`, `flatten`, `serialize`, `2json` conversion, `2db` sqlite3 -conversion, `stack`, `pretty`, `2tsv`, `compare`, `paste` and more. +conversion, `stack`, `pretty`, `2tsv`, `compare`, `paste`, `overwrite` and more. The ZSV CLI also includes `sheet`, an in-console interactive grid viewer (TO DO: that can be extended with your custom code for manipulating and) for viewing @@ -102,7 +102,8 @@ that implements the expected - Includes the `zsv` CLI with the following built-in commands: - `sheet`, an in-console interactive and extendable grid viewer - `select`, `count`, `sql` query, `desc`ribe, `flatten`, `serialize`, `2json`, - `2db`, `stack`, `pretty`, `2tsv`, `paste`, `compare`, `jq`, `prop`, `rm` + `2db`, `stack`, `pretty`, `2tsv`, `paste`, `compare`, `overwrite`, + `jq`, `prop`, `rm` - easily [convert between CSV/JSON/sqlite3](docs/csv_json_sqlite.md) - [compare multiple files](docs/compare.md) - CLI is easy to extend/customize with a few lines of code via modular plug-in @@ -308,8 +309,8 @@ needs. - `2tsv`: convert to TSV (tab-delimited) format - `compare`: compare two or more tables of data and output the differences - `paste` (alpha): horizontally paste two tables together (given inputs X and Y, - output 1...N rows where each row all columns of X in row N, followed by all - columns of Y in row N) + output 1...N rows where each row contains the entire corresponding + row in X followed by the entire corresponding row in Y) - `serialize` (inverse of flatten): convert an NxM table to a single 3x (Nx(M-1)) table with columns: Row, Column Name, Column Value - `flatten` (inverse of serialize): flatten a table by combining rows that share @@ -317,6 +318,8 @@ needs. - `stack`: merge CSV files vertically - `jq`: run a `jq` filter - `2db`: [convert from JSON to sqlite3 db](docs/csv_json_sqlite.md) +- `overwrite`: overwrite a cell value; changes will be reflected in any zsv + command when the --apply-overwrites option is specified - `prop`: view or save parsing options associated with a file, such as initial rows to ignore, or header row span. Saved options are be applied by default when processing that file. diff --git a/TO-DO.md b/TO-DO.md index 3cdabb9d..ab2fc7bc 100644 --- a/TO-DO.md +++ b/TO-DO.md @@ -7,6 +7,7 @@ # CLI - add index-related parser options to general command-line options +- change --overwrite-auto to --apply-overwrites --- ## Performance diff --git a/app/paste.c b/app/paste.c index 6c8ac338..d42ae2a5 100644 --- a/app/paste.c +++ b/app/paste.c @@ -15,12 +15,24 @@ #include "zsv_command.h" static int zsv_paste_usage() { - static const char *usage = "Usage: paste [ ...]\n" - "\n" - "Options:\n" - " -h,--help : show usage\n"; - printf("%s\n", usage); - return 1; + /* clang-format off */ + static const char *usage[] = { + "Usage: paste [ ...]", + "", + "Horizontally paste two tables together: given inputs X, Y, ... of N rows", + "outputs 1...N rows, where each row i contains:", + " row i of input X,", + " followed by row i of input Y,", + " [followed by ...]", + "", + "Options:", + " -h,--help : show usage", + NULL + }; + /* clang-format on */ + for (int i = 0; usage[i]; i++) + printf("%s\n", usage[i]); + return 0; } struct zsv_paste_input_file { @@ -114,10 +126,15 @@ static enum zsv_paste_status zsv_paste_add_input(const char *fname, struct zsv_p int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *opts, struct zsv_prop_handler *custom_prop_handler, const char *opts_used) { + for (int i = 1; i < argc; i++) { + const char *arg = argv[i]; + if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) + return zsv_paste_usage(); + } + struct zsv_paste_input_file *inputs = NULL; struct zsv_paste_input_file **next_input = &inputs; enum zsv_paste_status status = zsv_paste_status_ok; - struct zsv_csv_writer_options writer_opts = zsv_writer_get_default_opts(); zsv_csv_writer writer = zsv_writer_new(&writer_opts); if (!writer) { @@ -127,15 +144,8 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op for (int i = 1; status == zsv_paste_status_ok && i < argc; i++) { const char *arg = argv[i]; - if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) { - zsv_paste_usage(); - goto zsv_paste_done; - } - - if (0) { // !strcmp(arg, "-x") || !strcmp(arg, "--my-arg")) { ... - } else { + if (!(!strcmp(arg, "-h") || !strcmp(arg, "--help"))) status = zsv_paste_add_input(arg, next_input, &next_input, opts, custom_prop_handler, opts_used); - } } if (status == zsv_paste_status_ok) { diff --git a/app/test/Makefile b/app/test/Makefile index 91d66c2f..9ef15b5c 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -48,7 +48,7 @@ TEST_DATA_DIR=${THIS_LIB_BASE}/data SOURCES=echo count count-pull select select-pull sql 2json serialize flatten pretty desc stack 2db 2tsv jq compare overwrite TARGETS=$(addprefix ${BUILD_DIR}/bin/zsv_,$(addsuffix ${EXE},${SOURCES})) -TESTS=test-blank-leading-rows $(addprefix test-,${SOURCES}) test-rm test-mv test-2json-help test-sheet +TESTS=test-blank-leading-rows $(addprefix test-,${SOURCES}) test-rm test-mv test-2json-help test-sheet test-paste ifeq ($(ZSV_BUILD_SHEET),1) SOURCES+=sheet @@ -100,6 +100,9 @@ CLI: test: ${TESTS} +test-paste: + @echo "TO DO: test paste" + .SECONDARY: worldcitiespop_mil.csv .PHONY: help test test-% test-stack clean