diff options
author | untir_l <87096069+untir-l@users.noreply.github.com> | 2022-02-18 13:01:12 +0000 |
---|---|---|
committer | untir-l <87096069+untir-l@users.noreply.github.com> | 2022-02-25 09:56:49 +0000 |
commit | 1bc2a436583b0e898decf13e695a1908a894a38c (patch) | |
tree | c2a984a4b7bfef841e44792cbabae360390485aa | |
parent | cde12d91839f2db46711edb5946b03ea2704bcb6 (diff) | |
download | hitomezashi-1bc2a436583b0e898decf13e695a1908a894a38c.tar hitomezashi-1bc2a436583b0e898decf13e695a1908a894a38c.tar.gz hitomezashi-1bc2a436583b0e898decf13e695a1908a894a38c.zip |
Change argument parsing to use optparse, fix bugs in it, misc. changes
- Change argument parsing library from xgetopt to optparse (pretty close to a
drop-in replacement).
- Fix bugs in the argument parsing. There were several.
- Remove an extraneous printf added for debugging purposes.
- Add more bounds checks for numeric arguments to avoid passing garbage to the
library code and hitting assertions when the input is bad.
- Change the clang-format invocation in the Makefile to have --verbose.
- Change -Wpedantic to --pedantic-errors in CFLAGS, add -Wno-unused-function
so it doesn't complain about the ones from optparse (such are the perils of
single-header libraries).
-rw-r--r-- | .gitmodules | 6 | ||||
-rw-r--r-- | Makefile | 4 | ||||
m--------- | getopt | 0 | ||||
-rw-r--r-- | hitomezashi_cli.c | 44 | ||||
m--------- | optparse | 0 |
5 files changed, 29 insertions, 25 deletions
diff --git a/.gitmodules b/.gitmodules index 0aa3466..4bb7845 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "getopt"] - path = getopt - url = https://github.com/skeeto/getopt.git +[submodule "optparse"] + path = optparse + url = https://github.com/skeeto/optparse @@ -1,7 +1,7 @@ .POSIX: CC = gcc -CFLAGS = -std=c11 -Wall -Wpedantic -O3 `sdl2-config --cflags` +CFLAGS = -std=c11 -Wall -Wno-unused-function --pedantic-errors -O3 `sdl2-config --cflags` LDLIBS = `sdl2-config --libs` AR = ar ARFLAGS = rcs @@ -18,7 +18,7 @@ hitomezashi_cli: hitomezashi_cli.o libhitomezashi.a hitomezashi_cli.o: hitomezashi_cli.c hitomezashi_cli.h format-code: - clang-format -i *.c *.h + clang-format -i --verbose *.c *.h clean: rm -f *.a *.o hitomezashi_cli diff --git a/getopt b/getopt deleted file mode 160000 -Subproject 55d8fefe680d9b7e68ab80eb46e1bd4ad324fc2 diff --git a/hitomezashi_cli.c b/hitomezashi_cli.c index 4a9f02d..c83affe 100644 --- a/hitomezashi_cli.c +++ b/hitomezashi_cli.c @@ -1,7 +1,9 @@ #include "hitomezashi_cli.h" #include "SDL.h" -#include "getopt/xgetopt.h" +#define OPTPARSE_IMPLEMENTATION +#define OPTPARSE_API static #include "hitomezashi.h" +#include "optparse/optparse.h" #include <limits.h> #include <stdbool.h> #include <stddef.h> @@ -74,7 +76,6 @@ char *hitomezashi_cli_ascii_binary_str_to_ints(char *ascii_str, size_t n) { break; default:; free(res); - printf("%d\n", ascii_str[i]); return NULL; } } @@ -93,24 +94,25 @@ void hitomezashi_cli_handle_args(char **out_file_path, int *x_pattern_len, bool gap_specified = false; bool thickness_specified = false; - struct xgetopt xgetopt_state = XGETOPT_INIT; + struct optparse options; + optparse_init(&options, argv); int option; - while ((option = xgetopt(&xgetopt_state, argc, argv, "o:x:y:g:t:h") != -1)) { - switch (xgetopt_state.optopt) { + while ((option = optparse(&options, ":o:x:y:g:t:h")) != -1) { + switch (option) { case 'o':; - *out_file_path = xgetopt_state.optarg; + *out_file_path = options.optarg; out_file_path_specified = true; break; case 'x':; - size_t x_pattern_len_l = strlen(xgetopt_state.optarg); + size_t x_pattern_len_l = strlen(options.optarg); if (x_pattern_len_l >= INT_MAX) { SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "X pattern length must be shorter than %d", INT_MAX); exit(Hitomezashi_Cli_Exit_Code_Err_Handle_Args); } *x_pattern_len = x_pattern_len_l; - *x_pattern = hitomezashi_cli_ascii_binary_str_to_ints( - xgetopt_state.optarg, *x_pattern_len); + *x_pattern = hitomezashi_cli_ascii_binary_str_to_ints(options.optarg, + *x_pattern_len); if (!*x_pattern) { SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Invalid x pattern; see -h"); exit(Hitomezashi_Cli_Exit_Code_Err_Handle_Args); @@ -118,15 +120,15 @@ void hitomezashi_cli_handle_args(char **out_file_path, int *x_pattern_len, x_pattern_specified = true; break; case 'y':; - size_t y_pattern_len_l = strlen(xgetopt_state.optarg); + size_t y_pattern_len_l = strlen(options.optarg); if (y_pattern_len_l >= INT_MAX) { SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Y pattern length must be shorter than %d", INT_MAX); exit(Hitomezashi_Cli_Exit_Code_Err_Handle_Args); } *y_pattern_len = y_pattern_len_l; - *y_pattern = hitomezashi_cli_ascii_binary_str_to_ints( - xgetopt_state.optarg, *y_pattern_len); + *y_pattern = hitomezashi_cli_ascii_binary_str_to_ints(options.optarg, + *y_pattern_len); if (!*y_pattern) { SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Invalid y pattern; see -h"); exit(Hitomezashi_Cli_Exit_Code_Err_Handle_Args); @@ -134,21 +136,23 @@ void hitomezashi_cli_handle_args(char **out_file_path, int *x_pattern_len, y_pattern_specified = true; break; case 'g':; - long gap_l = strtol(xgetopt_state.optarg, NULL, 0); - if (gap_l >= INT_MAX) { + long gap_l = strtol(options.optarg, NULL, 0); + if (gap_l <= 0 || gap_l >= INT_MAX) { SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, - "Value for gap must be less than %d", INT_MAX); + "Value for gap must be positive and less than %d", + INT_MAX); exit(Hitomezashi_Cli_Exit_Code_Err_Handle_Args); } *gap = gap_l; gap_specified = true; break; case 't':; - long thickness_l = strtol(xgetopt_state.optarg, NULL, 0); - if (thickness_l >= INT_MAX) { - SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, - "Value for line thickness must be less than %d", - INT_MAX); + long thickness_l = strtol(options.optarg, NULL, 0); + if (thickness_l <= 0 || thickness_l >= INT_MAX) { + SDL_LogCritical( + SDL_LOG_CATEGORY_ERROR, + "Value for line thickness must be positive and less than %d", + INT_MAX); exit(Hitomezashi_Cli_Exit_Code_Err_Handle_Args); } *thickness = thickness_l; diff --git a/optparse b/optparse new file mode 160000 +Subproject f0c65c9ea9afca3d19d11faa16db2f73f6b468a |