From 71e11002bf1e50ecadbfa398cc172cd791b9c20a Mon Sep 17 00:00:00 2001 From: liquidaty Date: Tue, 12 Mar 2024 22:56:35 -0700 Subject: [PATCH] fix 153: zsv help 2json returns exit code 5 (#155) --- app/2json.c | 75 ++++++++++++++++++++++++----------------------- app/flatten.c | 14 +++++++++ app/test/Makefile | 6 +++- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/app/2json.c b/app/2json.c index d68265ab..2be29d06 100644 --- a/app/2json.c +++ b/app/2json.c @@ -230,36 +230,37 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op const char *usage[] = { - APPNAME ": streaming CSV to json converter, or sqlite3 db to JSON converter", - "", - "Usage: ", - " " APPNAME " [input.csv] [options]", - " " APPNAME " --from-db [options]", - "", - "Options:", - " -h, --help", - " -o, --output : output to specified filename", - " --compact : output compact JSON", - " --from-db : input is sqlite3 database", - " --db-table : name of table in input database to convert", - " --object : output as array of objects", - " --no-empty : omit empty properties (only with --object)", - " --database : output in database schema", - " --no-header : treat the header row as a data row", - " --index : add index to database schema", - " --unique-index : add unique index to database schema", - NULL + APPNAME ": streaming CSV to json converter, or sqlite3 db to JSON converter", + "", + "Usage: ", + " " APPNAME " [input.csv] [options]", + " " APPNAME " --from-db [options]", + "", + "Options:", + " -h, --help", + " -o, --output : output to specified filename", + " --compact : output compact JSON", + " --from-db : input is sqlite3 database", + " --db-table : name of table in input database to convert", + " --object : output as array of objects", + " --no-empty : omit empty properties (only with --object)", + " --database : output in database schema", + " --no-header : treat the header row as a data row", + " --index : add index to database schema", + " --unique-index : add unique index to database schema", + NULL }; FILE *out = NULL; const char *input_path = NULL; enum zsv_status err = zsv_status_ok; - - for(int i = 1; !err && i < argc; i++) { + int done = 0; + + for(int i = 1; !err && !done && i < argc; i++) { if(!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) { for(int j = 0; usage[j]; j++) fprintf(stdout, "%s\n", usage[j]); - err = zsv_status_error; + done = 1; } else if(!strcmp(argv[i], "-o") || !strcmp(argv[i], "--output")) { if(++i >= argc) fprintf(stderr, "%s option requires a filename value\n", argv[i-1]), err = zsv_status_error; @@ -320,27 +321,27 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op } } - if(err) - ; - else if(data.indexes.count && data.schema != ZSV_JSON_SCHEMA_DATABASE) - fprintf(stderr, "--index/--unique-index can only be used with --database\n"), err = zsv_status_error; - else if(data.no_header && data.schema) - fprintf(stderr, "--no-header cannot be used together with --object or --database\n"), err = zsv_status_error; - else if(data.no_empty && data.schema != ZSV_JSON_SCHEMA_OBJECT) - fprintf(stderr, "--no-empty can only be used with --object\n"), err = zsv_status_error; - else if(!opts->stream) { - if(data.from_db) - fprintf(stderr, "Database input specified, but no input file provided\n"), err = zsv_status_error; - else { + if(!(err || done)) { + if(data.indexes.count && data.schema != ZSV_JSON_SCHEMA_DATABASE) + fprintf(stderr, "--index/--unique-index can only be used with --database\n"), err = zsv_status_error; + else if(data.no_header && data.schema) + fprintf(stderr, "--no-header cannot be used together with --object or --database\n"), err = zsv_status_error; + else if(data.no_empty && data.schema != ZSV_JSON_SCHEMA_OBJECT) + fprintf(stderr, "--no-empty can only be used with --object\n"), err = zsv_status_error; + else if(!opts->stream) { + if(data.from_db) + fprintf(stderr, "Database input specified, but no input file provided\n"), err = zsv_status_error; + else { #ifdef NO_STDIN - fprintf(stderr, "Please specify an input file\n"), err = zsv_status_error; + fprintf(stderr, "Please specify an input file\n"), err = zsv_status_error; #else - opts->stream = stdin; + opts->stream = stdin; #endif + } } } - if(!err) { + if(!(err || done)) { if(!out) out = stdout; if(!(data.jsw = jsonwriter_new(out))) diff --git a/app/flatten.c b/app/flatten.c index c01fceac..1223f63b 100644 --- a/app/flatten.c +++ b/app/flatten.c @@ -526,6 +526,20 @@ const char *flatten_usage_msg[] = " (future: -a : aggregation method to use for the select-all placeholder)", " -o : name of file to save output to", NULL + /* + EXAMPLE + echo 'row,col,val +> A,ltv,100 +> A,loanid,A +> A,hi,there +> B,loanid,B +> B,ltv,90 +> B,hi,you +> B,xxx,zzz' | zsv flatten --row-id row --col-name col -V val +row,ltv,loanid,hi,xxx +A,100,A,there, +B,90,B,you,zzz + */ }; static void flatten_usage() { diff --git a/app/test/Makefile b/app/test/Makefile index d5f52807..394cd833 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 TARGETS=$(addprefix ${BUILD_DIR}/bin/zsv_,$(addsuffix ${EXE},${SOURCES})) -TESTS=test-blank-leading-rows $(addprefix test-,${SOURCES}) test-rm test-mv +TESTS=test-blank-leading-rows $(addprefix test-,${SOURCES}) test-rm test-mv test-2json-help COLOR_NONE=\033[0m COLOR_GREEN=\033[1;32m @@ -463,6 +463,10 @@ test-2json: test-%: ${BUILD_DIR}/bin/zsv_%${EXE} ${BUILD_DIR}/bin/zsv_2db${EXE} # ajv validate --strict-tuples=false -s ${THIS_MAKEFILE_DIR}/../../docs/db.schema.json -d expected/$@.out7.json [suffix must be json] +test-2json-help: test-%-help: ${BUILD_DIR}/bin/zsv_%${EXE} + @${TEST_INIT} + @[ "`$< -h | wc -l`" -gt 17 ] && ${TEST_PASS} || ${TEST_FAIL} # check output nonempty + @$< -h >/dev/null && ${TEST_PASS} || ${TEST_FAIL} # check exit code test-desc: test-%: ${BUILD_DIR}/bin/zsv_%${EXE} @${TEST_INIT}