From a744225b69776f5e6077cd6413785740cd7e4fff Mon Sep 17 00:00:00 2001 From: liquidaty Date: Thu, 30 May 2024 21:45:00 -0700 Subject: [PATCH] misc updates for building extensions (#170) * updates to extension API and example --- app/cli.c | 14 +++++++--- app/compare.c | 20 +++++++++++-- app/compare.h | 2 +- app/compare_internal.h | 4 ++- app/ext_example/my_extension.c | 2 +- .../test/expected/zsvext-test-3.out | 8 +++--- .../test/expected/zsvext-test-4.err | 2 +- app/ext_template/YOUR_EXTENSION_zsvext.c | 28 ++++++++----------- configure | 9 +++++- include/zsv/ext.h | 7 ++++- include/zsv/ext/implementation_private.h | 8 +++--- 11 files changed, 67 insertions(+), 37 deletions(-) diff --git a/app/cli.c b/app/cli.c index ae7b723..282ec80 100644 --- a/app/cli.c +++ b/app/cli.c @@ -116,10 +116,15 @@ struct zsv_execution_data { int argc; const char **argv; - + char opts_used[ZSV_OPTS_SIZE_MAX]; void *custom_context; // user-defined }; +static const char *ext_opts_used(zsv_execution_context ctx) { + struct zsv_execution_data *d = ctx; + return d->opts_used; +} + static struct zsv_opts ext_parser_opts(zsv_execution_context ctx) { (void)(ctx); return zsv_get_default_opts(); @@ -344,6 +349,7 @@ static struct zsv_ext_callbacks *zsv_ext_callbacks_init(struct zsv_ext_callbacks e->ext_parse_all = ext_parse_all; e->ext_parser_opts = ext_parser_opts; + e->ext_opts_used = ext_opts_used; } return e; } @@ -401,14 +407,14 @@ static enum zsv_ext_status run_extension(int argc, const char *argv[], struct zs return zsv_ext_status_unrecognized_cmd; } - struct zsv_execution_data ctx; + struct zsv_execution_data ctx = { 0 }; if((stat = execution_context_init(&ctx, argc, argv)) == zsv_ext_status_ok) { struct zsv_opts opts; - zsv_args_to_opts(argc, argv, &argc, argv, &opts, NULL); + zsv_args_to_opts(argc, argv, &argc, argv, &opts, ctx.opts_used); zsv_set_default_opts(opts); // need a corresponding zsv_set_default_custom_prop_handler? - stat = cmd->main(&ctx, ctx.argc - 1, &ctx.argv[1]); + stat = cmd->main(&ctx, ctx.argc - 1, &ctx.argv[1], &opts, ctx.opts_used); } if(stat != zsv_ext_status_ok) diff --git a/app/compare.c b/app/compare.c index de8330f..b86a2f7 100644 --- a/app/compare.c +++ b/app/compare.c @@ -10,6 +10,8 @@ #include #include #include +#include + #include #include @@ -291,8 +293,11 @@ static void zsv_compare_print_row(struct zsv_compare_data *data, } } - if(different) + if(different) { zsv_compare_output_tuple(data, key_input, output_col->name, values, 0); + if(data->diff_count < INT_MAX) + data->diff_count++; + } } free(values); } @@ -438,7 +443,7 @@ input_init_unsorted(struct zsv_compare_data *data, return zsv_compare_status_ok; } -zsv_compare_handle zsv_compare_new() { +zsv_compare_handle zsv_compare_new(void) { zsv_compare_handle z = calloc(1, sizeof(*z)); #if defined(ZSV_COMPARE_CMP_FUNC) && defined(ZSV_COMPARE_CMP_CTX) zsv_compare_set_comparison(z, ZSV_COMPARE_CMP_FUNC, ZSV_COMPARE_CMP_CTX); @@ -610,7 +615,7 @@ static enum zsv_compare_status zsv_compare_next(struct zsv_compare_data *data) { return zsv_compare_status_ok; } -static int compare_usage() { +static int compare_usage(void) { static const char *usage[] = { "Usage: compare [options] [file1.csv] [file2.csv] [...]", "Options:", @@ -631,6 +636,7 @@ static int compare_usage() { " --json-object : output as an array of objects", " --print-key-colname: when outputting key column diffs,", " print column name instead of ", + " -e,--exit-code : return < 0 on error, else the number of differences found", "", "NOTES", "", @@ -725,6 +731,8 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op } } else if(!strcmp(arg, "--sort")) { data->sort = 1; + } else if(!strcmp(arg, "--exit-code") || !strcmp(arg, "-e")) { + data->return_count = 1; } else if(!strcmp(arg, "--json")) { data->writer.type = ZSV_COMPARE_OUTPUT_TYPE_JSON; } else if(!strcmp(arg, "--json-object")) { @@ -931,6 +939,12 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op zsv_set_default_custom_prop_handler(original_default_custom_prop_handler); } + if(data->return_count) { + if(err) + err = -1; + else + err = data->diff_count; + } zsv_compare_delete(data); return err; } diff --git a/app/compare.h b/app/compare.h index 3ba41a3..bd5cce4 100644 --- a/app/compare.h +++ b/app/compare.h @@ -16,7 +16,7 @@ typedef int (*zsv_compare_cell_func)(void *ctx, struct zsv_cell, struct zsv_cell void *struct_zsv_compare_data, unsigned input_col_ix); -zsv_compare_handle zsv_compare_new(); +zsv_compare_handle zsv_compare_new(void); // enum zsv_compare_status zsv_compare_set_inputs(zsv_compare_handle, unsigned input_count, unsigned key_count); void zsv_compare_set_input_parser(zsv_compare_handle cmp, zsv_parser p, unsigned ix); void zsv_compare_delete(zsv_compare_handle); diff --git a/app/compare_internal.h b/app/compare_internal.h index 4c3acc7..a4cd213 100644 --- a/app/compare_internal.h +++ b/app/compare_internal.h @@ -90,6 +90,7 @@ struct zsv_compare_data { struct zsv_compare_added_column *added_columns; zsv_compare_unique_colname *added_colnames; unsigned added_colcount; + int diff_count; // total number of differences; will use this as return code if -e option is specified zsv_compare_cell_func cmp; void *cmp_ctx; @@ -134,7 +135,8 @@ struct zsv_compare_data { unsigned char sort:1; unsigned char sort_in_memory:1; unsigned char print_key_col_names:1; - unsigned char _:5; + unsigned char return_count:1; + unsigned char _:4; }; #endif diff --git a/app/ext_example/my_extension.c b/app/ext_example/my_extension.c index ba646e0..d822b16 100644 --- a/app/ext_example/my_extension.c +++ b/app/ext_example/my_extension.c @@ -100,7 +100,7 @@ enum zsv_ext_status zsv_ext_init(struct zsv_ext_callbacks *cb, zsv_execution_con * previously called */ enum zsv_ext_status zsv_ext_exit() { - fprintf(stderr, "Exiting dl example!\n"); + fprintf(stderr, "Exiting extension example!\n"); return zsv_ext_status_ok; } /** diff --git a/app/ext_example/test/expected/zsvext-test-3.out b/app/ext_example/test/expected/zsvext-test-3.out index a474057..0c0aa0c 100644 --- a/app/ext_example/test/expected/zsvext-test-3.out +++ b/app/ext_example/test/expected/zsvext-test-3.out @@ -1,6 +1,6 @@ Extension my registered -Exiting dl example! -Exiting dl example! +Exiting extension example! +Exiting extension example! Extension my unregistered Extension my was not already registered zsv: streaming csv processor @@ -59,8 +59,8 @@ Other commands: (No extended commands) Extension my registered -Exiting dl example! -Exiting dl example! +Exiting extension example! +Exiting extension example! zsv: streaming csv processor Usage: diff --git a/app/ext_example/test/expected/zsvext-test-4.err b/app/ext_example/test/expected/zsvext-test-4.err index 0e0bfdc..eb7e55b 100644 --- a/app/ext_example/test/expected/zsvext-test-4.err +++ b/app/ext_example/test/expected/zsvext-test-4.err @@ -1,2 +1,2 @@ Note: for third-party licenses & acknowledgements, run `zsv thirdparty` -Exiting dl example! +Exiting extension example! diff --git a/app/ext_template/YOUR_EXTENSION_zsvext.c b/app/ext_template/YOUR_EXTENSION_zsvext.c index 684ac89..ad488ff 100644 --- a/app/ext_template/YOUR_EXTENSION_zsvext.c +++ b/app/ext_template/YOUR_EXTENSION_zsvext.c @@ -234,22 +234,18 @@ static enum zsv_ext_status YOUR_COMMAND_main(zsv_execution_context ctx, int argc /** * Alternatively, for more granular control we could use the following: * ``` - * struct zsv_opts opts; - * memset(&opts, 0, sizeof(opts)); - * enum zsv_ext_status stat = zsv_cb.ext_parser_opts(ctx, &opts); - * if(stat == zsv_ext_status_ok) { - * zsv_parser parser = new_with_context(ctx, &opts); - * if(!parser) - * stat = zsv_ext_status_memory; - * else { - * opts.row = YOUR_COMMAND_rowhandler; - * // ... set other options here ... - * zsv_parser p = new_with_context(ctx, &opts); - * while((stat = zsv_parse_more(parser)) == zsv_status_ok) ; - * if(stat == zsv_status_ok) - * stat = zsv_finish(p); - * zsv_delete(p); - * } + * struct zsv_opts opts = zsv_cb.ext_parser_opts(ctx); + * zsv_parser parser = new_with_context(ctx, &opts); + * if(!parser) + * stat = zsv_ext_status_memory; + * else { + * opts.row = YOUR_COMMAND_rowhandler; + * // ... set other options here ... + * zsv_parser p = new_with_context(ctx, &opts); + * while((stat = zsv_parse_more(parser)) == zsv_status_ok) ; + * if(stat == zsv_status_ok) + * stat = zsv_finish(p); + * zsv_delete(p); * } * ``` */ diff --git a/configure b/configure index eb1f132..dab5701 100755 --- a/configure +++ b/configure @@ -553,12 +553,19 @@ if [ "$FORCE_SSE2" = "no" ]; then tryflag CFLAGS -mno-sse2 elif [ "$FORCE_SSE2" = "yes" ] ; then CFLAGS_SSE=-msse2 + if ! "$CC" --version | grep -i emcc >/dev/null; then + CFLAGS_SSE+= -msimd128 -experimental-wasm-simd + fi if [ "$CROSS_COMPILING" = "no" ] ; then trycpusupport sse2 || echo "warning: sse2 forced but not supported on native CPU" fi elif [ "$FORCE_SSE2" = "auto" ] && [ "$CROSS_COMPILING" = "no" ] ; then if [ "$CFLAGS_SSE" = "" ] && [ "$CROSS_COMPILING" = "no" ] ; then - trycpusupport sse2 && tryflag CFLAGS_SSE -msse2 + if trycpusupport sse2 && tryflag CFLAGS_SSE -msse2 ; then + if ! "$CC" --version | grep -i emcc >/dev/null; then + CFLAGS_SSE+= -msimd128 -experimental-wasm-simd + fi + fi fi fi diff --git a/include/zsv/ext.h b/include/zsv/ext.h index 59edf38..833a895 100644 --- a/include/zsv/ext.h +++ b/include/zsv/ext.h @@ -57,7 +57,7 @@ typedef void * zsv_execution_context; /** * Signature of the function called for each implemented sub-command */ -typedef enum zsv_ext_status (*zsv_ext_main)(zsv_execution_context ctx, int argc, const char *argv[]); +typedef enum zsv_ext_status (*zsv_ext_main)(zsv_execution_context ctx, int argc, const char *argv[], struct zsv_opts *opts, const char *opts_used); /** * ZSV callbacks structure @@ -117,6 +117,11 @@ struct zsv_ext_callbacks { */ struct zsv_opts (*ext_parser_opts)(zsv_execution_context ctx); + /** + * fetch options_used from execution context + */ + const char *(*ext_opts_used)(zsv_execution_context ctx); + /** * convenience function that calls ext_args_to_opts, allocates parser, * sets custom ctx, runs parser, and de-allocates parser diff --git a/include/zsv/ext/implementation_private.h b/include/zsv/ext/implementation_private.h index c4d04d7..8a8f9f7 100644 --- a/include/zsv/ext/implementation_private.h +++ b/include/zsv/ext/implementation_private.h @@ -27,7 +27,7 @@ * - your library would be named zsvextmy.dll (or .so or .dylib) */ ZSV_EXT_EXPORT -const char *zsv_ext_id(); +const char *zsv_ext_id(void); /** * Initialize your module @@ -84,7 +84,7 @@ void zsv_ext_errfree(char *errstr); * @return Zero on success, non-zero on fail */ ZSV_EXT_EXPORT -enum zsv_ext_status zsv_ext_exit(); +enum zsv_ext_status zsv_ext_exit(void); /** * Help message. Displayed when user enters any command beginning with @@ -102,7 +102,7 @@ const char * const *zsv_ext_help(int argc, const char *argv[]); * */ ZSV_EXT_EXPORT -const char * const *zsv_ext_license(); +const char * const *zsv_ext_license(void); /** * Version message. Displayed when user enters any command beginning with @@ -110,4 +110,4 @@ const char * const *zsv_ext_license(); * */ ZSV_EXT_EXPORT -const char * const *zsv_ext_version(); +const char * const *zsv_ext_version(void);