diff --git a/.gitignore b/.gitignore index a8a26a8..bf52bfb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ **/bin/ +_codeql_detected_source_root diff --git a/src/c-argparse.c b/src/c-argparse.c index bd0ee37..d3679b0 100644 --- a/src/c-argparse.c +++ b/src/c-argparse.c @@ -6,7 +6,7 @@ #include #include -#define BASE_10 (10) +static const int BASE_10 = 10; typedef enum { POSITIONAL, SHORT_FLAG, @@ -92,71 +92,43 @@ carg_error_t carg_parse_args(const int argc, char **argv, void carg_print_args(carg_pos_t *positionals, int num_positionals, carg_opt_t *options, int num_options) { for (int pos_idx = 0; pos_idx < num_positionals; pos_idx++) { - const int format_pattern_len = 10; - char format_pattern[] = "pos_%d : %0 \n"; + printf("pos_%d : ", pos_idx); switch (positionals[pos_idx].type) { case CARG_INT32: - format_pattern[format_pattern_len] = 'd'; - printf(format_pattern, pos_idx, - *((int32_t *)positionals[pos_idx].destination)); + printf("%d \n", *((int32_t *)positionals[pos_idx].destination)); break; case CARG_UINT64: - format_pattern[format_pattern_len] = 'l'; - format_pattern[format_pattern_len + 1] = 'u'; - printf(format_pattern, pos_idx, - *((uint64_t *)positionals[pos_idx].destination)); + printf("%lu \n", *((uint64_t *)positionals[pos_idx].destination)); break; case CARG_DOUBLE: - format_pattern[format_pattern_len] = 'e'; - printf(format_pattern, pos_idx, - *((double *)(positionals[pos_idx].destination))); + printf("%e \n", *((double *)(positionals[pos_idx].destination))); break; case CARG_BOOL: - format_pattern[format_pattern_len] = 'd'; - printf(format_pattern, pos_idx, - *((int *)positionals[pos_idx].destination)); + printf("%d \n", *((int *)positionals[pos_idx].destination)); break; case CARG_STRING: - format_pattern[format_pattern_len] = 's'; - printf(format_pattern, pos_idx, - *(const char **)positionals[pos_idx].destination); + printf("%s \n", *(const char **)positionals[pos_idx].destination); break; } } for (int opt_idx = 0; opt_idx < num_options; opt_idx++) { - const int format_pattern_len = 10; - char format_pattern[] = "%s (%c): %0 \n"; + printf("%s (%c): ", options[opt_idx].long_flag, + options[opt_idx].short_flag); switch (options[opt_idx].type) { case CARG_INT32: - format_pattern[format_pattern_len] = 'd'; - printf(format_pattern, options[opt_idx].long_flag, - options[opt_idx].short_flag, - *((int *)options[opt_idx].destination)); + printf("%d \n", *((int *)options[opt_idx].destination)); break; case CARG_UINT64: - format_pattern[format_pattern_len] = 'l'; - format_pattern[format_pattern_len + 1] = 'u'; - printf(format_pattern, options[opt_idx].long_flag, - options[opt_idx].short_flag, - *((unsigned long *)options[opt_idx].destination)); + printf("%lu \n", *((unsigned long *)options[opt_idx].destination)); break; case CARG_DOUBLE: - format_pattern[format_pattern_len] = 'e'; - printf(format_pattern, options[opt_idx].long_flag, - options[opt_idx].short_flag, - *((double *)options[opt_idx].destination)); + printf("%e \n", *((double *)options[opt_idx].destination)); break; case CARG_BOOL: - format_pattern[format_pattern_len] = 'd'; - printf(format_pattern, options[opt_idx].long_flag, - options[opt_idx].short_flag, - *((int *)options[opt_idx].destination)); + printf("%d \n", *((int *)options[opt_idx].destination)); break; case CARG_STRING: - format_pattern[format_pattern_len] = 's'; - printf(format_pattern, options[opt_idx].long_flag, - options[opt_idx].short_flag, - *(const char **)options[opt_idx].destination); + printf("%s \n", *(const char **)options[opt_idx].destination); break; } } @@ -170,6 +142,7 @@ static carg_error_t identify_arg_type(const char *const arg, size_t arg_len = strlen(arg); if (arg_len == 0) { + *detected_type = POSITIONAL; error_level = CARG_UNKNOWN_FAILURE; goto early_exit; } @@ -204,8 +177,10 @@ static carg_error_t handle_short_flag(char **argv, int *arg_idx_ptr, carg_opt_t *options, int num_options) { const int arg_idx = *arg_idx_ptr; carg_error_t error_level = CARG_SUCCESS; - char arg_flag = argv[arg_idx][1]; - size_t arg_len = strlen(&argv[arg_idx][1]); + char *arg_str = argv[arg_idx]; + /* arg_str is guaranteed to have at least 2 chars by identify_arg_type */ + const char arg_flag = arg_str[1]; + const int has_value = arg_str[2] != '\0'; char found = 0; int opt_idx = 0; char *arg_value = 0; @@ -219,17 +194,17 @@ static carg_error_t handle_short_flag(char **argv, int *arg_idx_ptr, error_level = CARG_UNKNOWN_FLAG; goto early_exit; } - if (options[opt_idx].type == CARG_BOOL && arg_len > 1) { + if (options[opt_idx].type == CARG_BOOL && has_value) { error_level = CARG_UNKNOWN_FLAG; goto early_exit; } - if (arg_len == 1 && options[opt_idx].type != CARG_BOOL && + if (!has_value && options[opt_idx].type != CARG_BOOL && argv[arg_idx + 1] == NULL) { error_level = CARG_MISSING_VALUE; goto early_exit; } - if (arg_len > 1) { - arg_value = &argv[arg_idx][2]; + if (has_value) { + arg_value = &arg_str[2]; } else if (options[opt_idx].type != CARG_BOOL) { arg_value = argv[arg_idx + 1]; (*arg_idx_ptr)++; @@ -245,23 +220,25 @@ static carg_error_t handle_long_flag(char **argv, int *arg_idx_ptr, const int arg_idx = *arg_idx_ptr; carg_error_t error_level = CARG_SUCCESS; char *arg_flag = &argv[arg_idx][2]; - size_t arg_len = strlen(&argv[arg_idx][2]); + const size_t arg_len = strlen(arg_flag); size_t def_len = 0; char found = 0; int opt_idx = 0; char *arg_value = 0; + char *equals_pos = strchr(arg_flag, '='); for (opt_idx = 0; opt_idx < num_options; opt_idx++) { def_len = strlen(options[opt_idx].long_flag); - if (arg_len == def_len && + if (equals_pos == NULL && arg_len == def_len && strncmp(options[opt_idx].long_flag, arg_flag, def_len) == 0) { found = 1; break; } - if (arg_len > def_len && - strncmp(options[opt_idx].long_flag, arg_flag, def_len) == 0 && - arg_flag[def_len] == '=') { + /* strchr guarantees equals_pos points within arg_flag string if not NULL */ + if (equals_pos != NULL && + (size_t)(equals_pos - arg_flag) == def_len && + strncmp(options[opt_idx].long_flag, arg_flag, def_len) == 0) { found = 1; break; } @@ -270,17 +247,17 @@ static carg_error_t handle_long_flag(char **argv, int *arg_idx_ptr, error_level = CARG_UNKNOWN_FLAG; goto early_exit; } - if (options[opt_idx].type == CARG_BOOL && arg_len > def_len) { + if (options[opt_idx].type == CARG_BOOL && equals_pos != NULL) { error_level = CARG_UNKNOWN_FLAG; goto early_exit; } - if (arg_len == def_len && options[opt_idx].type != CARG_BOOL && + if (equals_pos == NULL && options[opt_idx].type != CARG_BOOL && argv[arg_idx + 1] == NULL) { error_level = CARG_MISSING_VALUE; goto early_exit; } - if (arg_len > def_len) { - arg_value = &arg_flag[def_len + 1]; + if (equals_pos != NULL) { + arg_value = equals_pos + 1; } else if (options[opt_idx].type != CARG_BOOL) { arg_value = argv[arg_idx + 1]; (*arg_idx_ptr)++; diff --git a/src/c-argparse.h b/src/c-argparse.h index 555a151..7fd2721 100644 --- a/src/c-argparse.h +++ b/src/c-argparse.h @@ -1,5 +1,5 @@ -#ifndef __C_ARGPARSE_H__ -#define __C_ARGPARSE_H__ +#ifndef C_ARGPARSE_H_ +#define C_ARGPARSE_H_ typedef enum { CARG_INT32, @@ -41,4 +41,4 @@ void carg_print_args(carg_pos_t *positionals, int num_positionals, carg_opt_t *options, int num_options); void carg_print_help(char *exec_name, carg_pos_t *positionals, int num_positionals, carg_opt_t *options, int num_options); -#endif // !__C_ARGPARSE_H__ +#endif // !C_ARGPARSE_H_