aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md53
-rw-r--r--doc/interface.md52
-rw-r--r--simple-opt.h11
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