Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
**/bin/
_codeql_detected_source_root
91 changes: 34 additions & 57 deletions src/c-argparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <stdlib.h>
#include <string.h>

#define BASE_10 (10)
static const int BASE_10 = 10;
typedef enum {
POSITIONAL,
SHORT_FLAG,
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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)++;
Expand All @@ -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;
}
Expand All @@ -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)++;
Expand Down
6 changes: 3 additions & 3 deletions src/c-argparse.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __C_ARGPARSE_H__
#define __C_ARGPARSE_H__
#ifndef C_ARGPARSE_H_
#define C_ARGPARSE_H_

typedef enum {
CARG_INT32,
Expand Down Expand Up @@ -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_