From fd5b37444a16e85606d56ab27ef0f84ddc20df78 Mon Sep 17 00:00:00 2001 From: katherine Date: Sun, 25 Mar 2018 00:59:34 -0700 Subject: add error-printing function --- doc/example.c | 34 +++---------------------- simple-opt.h | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 33 deletions(-) diff --git a/doc/example.c b/doc/example.c index e62e73f..50d8173 100644 --- a/doc/example.c +++ b/doc/example.c @@ -35,38 +35,10 @@ int main(int argc, char **argv) result = simple_opt_parse(argc, argv, options); - /* handle errors */ - switch (result.result_type) { - case SIMPLE_OPT_RESULT_UNRECOGNISED_OPTION: - fprintf(stderr, "err: unrecognised option `%s`\n", - result.option_string); + /* catch any errors and print a default result */ + if (result.result_type != SIMPLE_OPT_RESULT_SUCCESS) { + simple_opt_print_error(stderr, argv[0], options, result); return 1; - - case SIMPLE_OPT_RESULT_BAD_ARG: - fprintf(stderr, "err: bad argument `%s` passed to option `%s`\n", - result.argument_string, result.option_string); - return 1; - - case SIMPLE_OPT_RESULT_MISSING_ARG: - fprintf(stderr, "err: argument expected for option `%s`\n", - result.option_string); - return 1; - - case SIMPLE_OPT_RESULT_OPT_ARG_TOO_LONG: - fprintf(stderr, "internal err: argument passed to option `%s` is too long\n", - result.option_string); - return 1; - - case SIMPLE_OPT_RESULT_TOO_MANY_ARGS: - fprintf(stderr, "internal err: too many cli arguments passed\n"); - return 1; - - case SIMPLE_OPT_RESULT_MALFORMED_OPTION_STRUCT: - fprintf(stderr, "internal err: malformed option struct\n"); - return 1; - - default: - break; } /* if the help flag was passed, print usage */ diff --git a/simple-opt.h b/simple-opt.h index 16c7f6c..e4e582a 100644 --- a/simple-opt.h +++ b/simple-opt.h @@ -100,7 +100,7 @@ static void simple_opt_print_usage(FILE *f, unsigned width, char *command_name, struct simple_opt *options); static void simple_opt_print_error(FILE *f, char *command_name, - struct simple_opt *options); + struct simple_opt *options, struct simple_opt_result result); /* @@ -377,6 +377,7 @@ static struct simple_opt_result simple_opt_parse(int argc, char **argv, if (options[opt_i].type == SIMPLE_OPT_STRING && strlen(s) + 1 >= SIMPLE_OPT_OPT_ARG_MAX_WIDTH) { r.result_type = SIMPLE_OPT_RESULT_OPT_ARG_TOO_LONG; + r.option_type = options[opt_i].type; goto opt_copy_and_return; } @@ -389,6 +390,7 @@ static struct simple_opt_result simple_opt_parse(int argc, char **argv, i++; } else { r.result_type = SIMPLE_OPT_RESULT_BAD_ARG; + r.option_type = options[opt_i].type; strncpy(r.argument_string, s, SIMPLE_OPT_OPT_ARG_MAX_WIDTH); goto opt_copy_and_return; } @@ -731,9 +733,85 @@ static void simple_opt_print_usage(FILE *f, unsigned width, char *command_name, } static void simple_opt_print_error(FILE *f, char *command_name, - struct simple_opt *options) + struct simple_opt *options, struct simple_opt_result result) { + char *s; + unsigned i; + + if (command_name != NULL) + fprintf(f, "%s: ", command_name); + else + fprintf(f, "err: "); + + switch (result.result_type) { + case SIMPLE_OPT_RESULT_UNRECOGNISED_OPTION: + fprintf(f, "unrecognised option `%s`\n", + result.option_string); + break; + + case SIMPLE_OPT_RESULT_BAD_ARG: + fprintf(f, "bad argument `%s` passed to option `%s`\n", + result.argument_string, result.option_string); + switch (result.option_type) { + case SIMPLE_OPT_BOOL: + fprintf(f, + "expected boolean, (yes|true|on) or (no|false|off)\n"); + break; + case SIMPLE_OPT_INT: + fprintf(f, "expected integer value\n"); + break; + case SIMPLE_OPT_UNSIGNED: + fprintf(f, "expected unsigned integer value\n"); + break; + case SIMPLE_OPT_DOUBLE: + fprintf(f, "expected floating-point value\n"); + break; + case SIMPLE_OPT_CHAR: + fprintf(f, "expected single character\n"); + break; + case SIMPLE_OPT_STRING: + fprintf(f, "expected a string\n"); + break; + case SIMPLE_OPT_STRING_SET: + for (i = 0; options->string_set[i] != NULL; i++); + if (i == 1) + fprintf(f, "expected \"%s\"\n", options->string_set[0]); + else if (i == 2) + fprintf(f, "expected \"%s\" or \"%s\"\n", + options->string_set[0], options->string_set[1]); + else if (i == 3) + fprintf(f, "expected \"%s\", \"%s\" or \"%s\"\n", + options->string_set[0], options->string_set[1], + options->string_set[2]); + else + fprintf(f, "expected a string\n"); + break; + default: + break; + } + break; + + case SIMPLE_OPT_RESULT_MISSING_ARG: + fprintf(f, "argument expected for option `%s`\n", + result.option_string); + break; + + case SIMPLE_OPT_RESULT_OPT_ARG_TOO_LONG: + fprintf(f, "argument passed to option `%s` is too long\n", + result.option_string); + break; + case SIMPLE_OPT_RESULT_TOO_MANY_ARGS: + fprintf(f, "too many cli arguments received\n"); + break; + + case SIMPLE_OPT_RESULT_MALFORMED_OPTION_STRUCT: + fprintf(f, "malformed option struct (internal err)\n"); + break; + + default: + break; + } } #endif -- cgit v1.2.3