From 1bc2a436583b0e898decf13e695a1908a894a38c Mon Sep 17 00:00:00 2001 From: untir_l <87096069+untir-l@users.noreply.github.com> Date: Fri, 18 Feb 2022 18:31:12 +0530 Subject: 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). --- .gitmodules | 6 +++--- Makefile | 4 ++-- getopt | 1 - hitomezashi_cli.c | 44 ++++++++++++++++++++++++-------------------- optparse | 1 + 5 files changed, 30 insertions(+), 26 deletions(-) delete mode 160000 getopt create mode 160000 optparse 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 diff --git a/Makefile b/Makefile index e632760..41323c3 100644 --- a/Makefile +++ b/Makefile @@ -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 index 55d8fef..0000000 --- a/getopt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 55d8fefe680d9b7e68ab80eb46e1bd4ad324fc29 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 #include #include @@ -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 index 0000000..f0c65c9 --- /dev/null +++ b/optparse @@ -0,0 +1 @@ +Subproject commit f0c65c9ea9afca3d19d11faa16db2f73f6b468a8 -- cgit v1.2.3-57-g22cb