From b72f0a2f2657356286f0eda7408b5816561bccb7 Mon Sep 17 00:00:00 2001 From: katherine Date: Sun, 25 Mar 2018 13:13:38 -0700 Subject: update documentation --- README.md | 53 +++++++++++++++++------------------------------------ doc/interface.md | 52 ++++++++++++++++++++++++++++++++++++++-------------- simple-opt.h | 11 +++++++---- 3 files changed, 62 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 9c51045..8fc29f9 100644 --- a/README.md +++ b/README.md @@ -55,38 +55,11 @@ 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 error message. you can do this bit + * yourself, if you'd like more control of the output */ + if (result.result_type != SIMPLE_OPT_RESULT_SUCCESS) { + simple_opt_print_error(stderr, argv[0], 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 */ @@ -176,17 +149,18 @@ occurs. ``` $ ./a.out -y -err: unrecognised option `-y` +./a.out: unrecognised option `-y` ``` ``` $ ./a.out --int -err: argument expected for option `--int` +./a.out: argument expected for option `--int` ``` ``` $ ./a.out --bool fake -err: bad argument `fake` passed to option `--bool` +./a.out: bad argument `fake` passed to option `--bool` +expected boolean, (yes|true|on) or (no|false|off) ``` if one of the options passed is the help flag (`-h` or `--help`), this example @@ -199,7 +173,7 @@ $ ./a.out --help Usage: ./a.out [OPTION]... [--] [NON-OPTION]... This is where you would put an overview description of the program and its - general functionality. + general functionality. -h --help print this help message and exit -b --bool[=BOOL] (optionally) takes a boolean arg! @@ -224,7 +198,7 @@ become: Usage: ./a.out [OPTION]... [--] [NON-OPTION]... This is where you would put an overview description of the program and its - general functionality. + general functionality. -h --help print this help message and exit -b --bool[=BOOL] (optionally) takes a boolean arg! @@ -300,3 +274,10 @@ $ ./a.out non-options --int=+1 can -d 3.9 be --uns 0 interleaved non-options: non-options can be interleaved ``` + +changelog +--------- + +v1.2: add optional error printing function + +v1.0: initial release diff --git a/doc/interface.md b/doc/interface.md index da07986..e757e80 100644 --- a/doc/interface.md +++ b/doc/interface.md @@ -166,10 +166,11 @@ contain the unrecognised option which was passed. if the type is `SIMPLE_OPT_BAD_ARG`, then `option_string` will be set, `option_type` will be set to the type of that option (`SIMPLE_OPT_BOOL` etc), +`option` will be made to point to the option within the provided option array, and the bad argument will be stored in `argument_string`. -if the type is `SIMPLE_OPT_MISSING_ARG`, `option_string` and `option_type` will -be set. +if the type is `SIMPLE_OPT_MISSING_ARG`, `option_string`, `option`, and +`option_type` will be set. the remaining result types are internal errors: @@ -230,22 +231,23 @@ about that parsing (also described above). usage message, similar to those typical of GNU cli commands: ``` -static void simple_opt_print_usage(FILE *f, unsigned width, char *usage_name, - char *usage_options, char *usage_summary, struct simple_opt *options); +static void simple_opt_print_usage(FILE *f, unsigned width, + char *command_name, char *command_options, char *command_summary, + struct simple_opt *options); ``` -`f` is a file pointer to which the message should be printed +`f` is a file pointer to which the message should be printed. `width` is the column width to which the output should be word-wrapped (passing 0 disables wrapping). a reasonable value here would be 80, but this could also be used to allow more dynamic behaviour (e.g. using something like `ncurses` or -`ioctl` to get the users's current terminal width) +`ioctl` to get the users's current terminal width). -`usage_name` is the name of the command as it will be printed in the usage +`command_name` is the name of the command as it will be printed in the usage statement. easiest is just to pass `argv[0]` here. -`usage_options` is a summary of what options the command takes (e.g. something -like `[OPTION]...`) +`command_options` is a summary of what options the command takes (e.g. +something like `[OPTION]...`) together, these two result in something that looks like: @@ -253,12 +255,12 @@ together, these two result in something that looks like: Usage: ./a.out [OPTION]... ``` -if both `usage_name` and `usage_options` are `NULL`, this initial line will not -be printed, allowing more flexibility to the programmer (if you wanted to, for -example, print multiple such lines on your own in order to represent different -use-cases) +if both `command_name` and `command_options` are `NULL`, this initial line will +not be printed, allowing more flexibility to the programmer (if you wanted to, +for example, print multiple such lines on your own in order to represent +different use-cases) -`usage_summary` is usually a one or two sentence overview summary of how the +`command_summary` is usually a one or two sentence overview summary of how the command behaves. if this is left as `NULL`, no summary will be printed. the final argument, `struct simple_opt *options`, is an array of options as @@ -271,3 +273,25 @@ occupies one column (that is, there are no wide characters, combining diacritics, etc), and that all characters are one byte (no multi-byte utf-8 characters). if these assumptions do not apply to your use case, you should use an alternative method for usage printing. + + +### simple_opt_print_error + +`simple_opt_print_error` takes three arguments and prints a default error +message, if there is one to be printed: + +``` +static void simple_opt_print_error(FILE *f, char *command_name, + struct simple_opt_result result); +``` + +`f` is a file pointer to which the message should be printed. + +`command_name` is the name of the command as it will be printed in the usage +statement. easiest is just to pass `argv[0]` here. if NULL is passed, "err:" +will be printed instead. + +`result` is a populated result from a call to `simple_opt_parse`. + +if the result's type field contains `SIMPLE_OPT_RESULT_SUCCESS`, nothing will +be printed. otherwise, the output is a summary of the error. diff --git a/simple-opt.h b/simple-opt.h index 9bc1141..0260467 100644 --- a/simple-opt.h +++ b/simple-opt.h @@ -96,8 +96,8 @@ struct simple_opt_result { static struct simple_opt_result simple_opt_parse(int argc, char **argv, struct simple_opt *options); -static void simple_opt_print_usage(FILE *f, unsigned width, char *command_name, - char *command_options, char *command_summary, +static void simple_opt_print_usage(FILE *f, unsigned width, + char *command_name, char *command_options, char *command_summary, struct simple_opt *options); static void simple_opt_print_error(FILE *f, char *command_name, @@ -525,8 +525,8 @@ static int sub_simple_opt_wrap_print(FILE *f, unsigned width, unsigned col, return col; } -static void simple_opt_print_usage(FILE *f, unsigned width, char *command_name, - char *command_options, char *command_summary, +static void simple_opt_print_usage(FILE *f, unsigned width, + char *command_name, char *command_options, char *command_summary, struct simple_opt *options) { char print_buffer[SIMPLE_OPT_USAGE_PRINT_BUFFER_WIDTH]; @@ -747,6 +747,9 @@ static void simple_opt_print_error(FILE *f, char *command_name, char *s; unsigned i; + if (result.result_type == SIMPLE_OPT_RESULT_SUCCESS) + return; + if (command_name != NULL) fprintf(f, "%s: ", command_name); else -- cgit v1.2.3