From 45ad74d3e26879bcbe42c397c370845a01e5dd18 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 18 Mar 2024 10:26:53 -0400 Subject: [PATCH] Add clang-format config file and re-format with clang-format 15 Add a clang-format config file, copied from: http://git.efficios.com/?p=babeltrace.git;a=blob;f=.clang-format;h=cba562531157c82aefa5a16f861ef044fa5388e0;hb=a165a5742a2b173e59900e515caa3b37a0afb42f Adjust it slightly to remove the things that are only relevant in the context of babeltrace. Re-format all C files with clang-format 15. Change-Id: If80c93c139d08fafaf11a8fd8dbca23fb80d4aca Signed-off-by: Simon Marchi --- .clang-format | 116 +++++ argpar/argpar.c | 1050 ++++++++++++++++++++--------------------- argpar/argpar.h | 116 +++-- tests/test-argpar.c | 1088 +++++++++++++++++-------------------------- 4 files changed, 1103 insertions(+), 1267 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ae350ab --- /dev/null +++ b/.clang-format @@ -0,0 +1,116 @@ +# For clang-format 15 +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: None +AlignConsecutiveDeclarations: None +AlignConsecutiveMacros: Consecutive +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: None +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: ["ARGPAR_HIDDEN"] +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Never + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: AfterColon +BreakInheritanceList: AfterColon +BreakStringLiterals: false +ColumnLimit: 100 +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: false +DerivePointerAlignment: false +DisableFormat: false +EmptyLineBeforeAccessModifier: Always +FixNamespaceComments: true +IncludeBlocks: Regroup +IncludeCategories: + # System C headers + - Regex: '^<.+\.h>$' + Priority: 2 + # System C++ headers + - Regex: "^<.+>$" + Priority: 1 + # The rest (local headers) + - Regex: ".+" + Priority: 3 +IncludeIsMainRegex: "please_dont_do_that" +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: NoIndent +IndentGotoLabels: false +IndentPPDirectives: AfterHash +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +Language: Cpp +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +PPIndentWidth: 4 +PointerAlignment: Right +ReferenceAlignment: Left +ReflowComments: false +SortIncludes: CaseInsensitive +SortUsingDeclarations: false +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Both +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +UseCRLF: false +UseTab: Never diff --git a/argpar/argpar.c b/argpar/argpar.c index fab0556..67b7769 100644 --- a/argpar/argpar.c +++ b/argpar/argpar.c @@ -20,16 +20,14 @@ * . */ #if defined(_WIN32) || defined(__CYGWIN__) -# define ARGPAR_HIDDEN +# define ARGPAR_HIDDEN #else -# define ARGPAR_HIDDEN __attribute__((visibility("hidden"))) +# define ARGPAR_HIDDEN __attribute__((visibility("hidden"))) #endif -#define ARGPAR_REALLOC(_ptr, _type, _nmemb) \ - ((_type *) realloc(_ptr, (_nmemb) * sizeof(_type))) +#define ARGPAR_REALLOC(_ptr, _type, _nmemb) ((_type *) realloc(_ptr, (_nmemb) * sizeof(_type))) -#define ARGPAR_CALLOC(_type, _nmemb) \ - ((_type *) calloc((_nmemb), sizeof(_type))) +#define ARGPAR_CALLOC(_type, _nmemb) ((_type *) calloc((_nmemb), sizeof(_type))) #define ARGPAR_ZALLOC(_type) ARGPAR_CALLOC(_type, 1) @@ -38,10 +36,10 @@ * Force usage of the assertion condition to prevent unused variable * warnings when `assert()` are disabled by the `NDEBUG` definition. */ -# define ARGPAR_ASSERT(_cond) ((void) sizeof((void) (_cond), 0)) +# define ARGPAR_ASSERT(_cond) ((void) sizeof((void) (_cond), 0)) #else -# include -# define ARGPAR_ASSERT(_cond) assert(_cond) +# include +# define ARGPAR_ASSERT(_cond) assert(_cond) #endif /* @@ -50,162 +48,159 @@ * Such a structure contains the state of an iterator between calls to * argpar_iter_next(). */ -struct argpar_iter { - /* - * Data provided by the user to argpar_iter_create(); immutable - * afterwards. - */ - struct { - unsigned int argc; - const char * const *argv; - const argpar_opt_descr_t *descrs; - } user; - - /* - * Index of the argument to process in the next - * argpar_iter_next() call. - */ - unsigned int i; - - /* Counter of non-option arguments */ - int non_opt_index; - - /* - * Current character within the current short option group: if - * it's not `NULL`, the parser is within a short option group, - * therefore it must resume there in the next argpar_iter_next() - * call. - */ - const char *short_opt_group_ch; - - /* Temporary character buffer which only grows */ - struct { - size_t size; - char *data; - } tmp_buf; +struct argpar_iter +{ + /* + * Data provided by the user to argpar_iter_create(); immutable + * afterwards. + */ + struct + { + unsigned int argc; + const char * const *argv; + const argpar_opt_descr_t *descrs; + } user; + + /* + * Index of the argument to process in the next + * argpar_iter_next() call. + */ + unsigned int i; + + /* Counter of non-option arguments */ + int non_opt_index; + + /* + * Current character within the current short option group: if + * it's not `NULL`, the parser is within a short option group, + * therefore it must resume there in the next argpar_iter_next() + * call. + */ + const char *short_opt_group_ch; + + /* Temporary character buffer which only grows */ + struct + { + size_t size; + char *data; + } tmp_buf; }; /* Base parsing item */ -struct argpar_item { - argpar_item_type_t type; +struct argpar_item +{ + argpar_item_type_t type; }; /* Option parsing item */ -typedef struct argpar_item_opt { - argpar_item_t base; +typedef struct argpar_item_opt +{ + argpar_item_t base; - /* Corresponding descriptor */ - const argpar_opt_descr_t *descr; + /* Corresponding descriptor */ + const argpar_opt_descr_t *descr; - /* Argument, or `NULL` if none; owned by this */ - char *arg; + /* Argument, or `NULL` if none; owned by this */ + char *arg; } argpar_item_opt_t; /* Non-option parsing item */ -typedef struct argpar_item_non_opt { - argpar_item_t base; - - /* - * Complete argument, pointing to one of the entries of the - * original arguments (`argv`). - */ - const char *arg; - - /* - * Index of this argument amongst all original arguments - * (`argv`). - */ - unsigned int orig_index; - - /* Index of this argument amongst other non-option arguments */ - unsigned int non_opt_index; +typedef struct argpar_item_non_opt +{ + argpar_item_t base; + + /* + * Complete argument, pointing to one of the entries of the + * original arguments (`argv`). + */ + const char *arg; + + /* + * Index of this argument amongst all original arguments + * (`argv`). + */ + unsigned int orig_index; + + /* Index of this argument amongst other non-option arguments */ + unsigned int non_opt_index; } argpar_item_non_opt_t; /* Parsing error */ -struct argpar_error { - /* Error type */ - argpar_error_type_t type; +struct argpar_error +{ + /* Error type */ + argpar_error_type_t type; - /* Original argument index */ - unsigned int orig_index; + /* Original argument index */ + unsigned int orig_index; - /* Name of unknown option; owned by this */ - char *unknown_opt_name; + /* Name of unknown option; owned by this */ + char *unknown_opt_name; - /* Option descriptor */ - const argpar_opt_descr_t *opt_descr; + /* Option descriptor */ + const argpar_opt_descr_t *opt_descr; - /* `true` if a short option caused the error */ - bool is_short; + /* `true` if a short option caused the error */ + bool is_short; }; -ARGPAR_HIDDEN -argpar_item_type_t argpar_item_type(const argpar_item_t * const item) +ARGPAR_HIDDEN argpar_item_type_t argpar_item_type(const argpar_item_t * const item) { - ARGPAR_ASSERT(item); - return item->type; + ARGPAR_ASSERT(item); + return item->type; } -ARGPAR_HIDDEN -const argpar_opt_descr_t *argpar_item_opt_descr( - const argpar_item_t * const item) +ARGPAR_HIDDEN const argpar_opt_descr_t *argpar_item_opt_descr(const argpar_item_t * const item) { - ARGPAR_ASSERT(item); - ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT); - return ((const argpar_item_opt_t *) item)->descr; + ARGPAR_ASSERT(item); + ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT); + return ((const argpar_item_opt_t *) item)->descr; } -ARGPAR_HIDDEN -const char *argpar_item_opt_arg(const argpar_item_t * const item) +ARGPAR_HIDDEN const char *argpar_item_opt_arg(const argpar_item_t * const item) { - ARGPAR_ASSERT(item); - ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT); - return ((const argpar_item_opt_t *) item)->arg; + ARGPAR_ASSERT(item); + ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT); + return ((const argpar_item_opt_t *) item)->arg; } -ARGPAR_HIDDEN -const char *argpar_item_non_opt_arg(const argpar_item_t * const item) +ARGPAR_HIDDEN const char *argpar_item_non_opt_arg(const argpar_item_t * const item) { - ARGPAR_ASSERT(item); - ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT); - return ((const argpar_item_non_opt_t *) item)->arg; + ARGPAR_ASSERT(item); + ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT); + return ((const argpar_item_non_opt_t *) item)->arg; } -ARGPAR_HIDDEN -unsigned int argpar_item_non_opt_orig_index( - const argpar_item_t * const item) +ARGPAR_HIDDEN unsigned int argpar_item_non_opt_orig_index(const argpar_item_t * const item) { - ARGPAR_ASSERT(item); - ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT); - return ((const argpar_item_non_opt_t *) item)->orig_index; + ARGPAR_ASSERT(item); + ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT); + return ((const argpar_item_non_opt_t *) item)->orig_index; } -ARGPAR_HIDDEN -unsigned int argpar_item_non_opt_non_opt_index( - const argpar_item_t * const item) +ARGPAR_HIDDEN unsigned int argpar_item_non_opt_non_opt_index(const argpar_item_t * const item) { - ARGPAR_ASSERT(item); - ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT); - return ((const argpar_item_non_opt_t *) item)->non_opt_index; + ARGPAR_ASSERT(item); + ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT); + return ((const argpar_item_non_opt_t *) item)->non_opt_index; } -ARGPAR_HIDDEN -void argpar_item_destroy(const argpar_item_t * const item) +ARGPAR_HIDDEN void argpar_item_destroy(const argpar_item_t * const item) { - if (!item) { - goto end; - } + if (!item) { + goto end; + } - if (item->type == ARGPAR_ITEM_TYPE_OPT) { - argpar_item_opt_t * const opt_item = (argpar_item_opt_t *) item; + if (item->type == ARGPAR_ITEM_TYPE_OPT) { + argpar_item_opt_t * const opt_item = (argpar_item_opt_t *) item; - free(opt_item->arg); - } + free(opt_item->arg); + } - free((void *) item); + free((void *) item); end: - return; + return; } /* @@ -214,34 +209,33 @@ end: * * Returns `NULL` on memory error. */ -static -argpar_item_opt_t *create_opt_item(const argpar_opt_descr_t * const descr, - const char * const arg) +static argpar_item_opt_t *create_opt_item(const argpar_opt_descr_t * const descr, + const char * const arg) { - argpar_item_opt_t *opt_item = ARGPAR_ZALLOC(argpar_item_opt_t); + argpar_item_opt_t *opt_item = ARGPAR_ZALLOC(argpar_item_opt_t); - if (!opt_item) { - goto end; - } + if (!opt_item) { + goto end; + } - opt_item->base.type = ARGPAR_ITEM_TYPE_OPT; - opt_item->descr = descr; + opt_item->base.type = ARGPAR_ITEM_TYPE_OPT; + opt_item->descr = descr; - if (arg) { - opt_item->arg = strdup(arg); - if (!opt_item->arg) { - goto error; - } - } + if (arg) { + opt_item->arg = strdup(arg); + if (!opt_item->arg) { + goto error; + } + } - goto end; + goto end; error: - argpar_item_destroy(&opt_item->base); - opt_item = NULL; + argpar_item_destroy(&opt_item->base); + opt_item = NULL; end: - return opt_item; + return opt_item; } /* @@ -251,25 +245,23 @@ end: * * Returns `NULL` on memory error. */ -static -argpar_item_non_opt_t *create_non_opt_item(const char * const arg, - const unsigned int orig_index, - const unsigned int non_opt_index) +static argpar_item_non_opt_t *create_non_opt_item(const char * const arg, + const unsigned int orig_index, + const unsigned int non_opt_index) { - argpar_item_non_opt_t * const non_opt_item = - ARGPAR_ZALLOC(argpar_item_non_opt_t); + argpar_item_non_opt_t * const non_opt_item = ARGPAR_ZALLOC(argpar_item_non_opt_t); - if (!non_opt_item) { - goto end; - } + if (!non_opt_item) { + goto end; + } - non_opt_item->base.type = ARGPAR_ITEM_TYPE_NON_OPT; - non_opt_item->arg = arg; - non_opt_item->orig_index = orig_index; - non_opt_item->non_opt_index = non_opt_index; + non_opt_item->base.type = ARGPAR_ITEM_TYPE_NON_OPT; + non_opt_item->arg = arg; + non_opt_item->orig_index = orig_index; + non_opt_item->non_opt_index = non_opt_index; end: - return non_opt_item; + return non_opt_item; } /* @@ -283,100 +275,92 @@ end: * Returns 0 on success (including if `error` is `NULL`) or -1 on memory * error. */ -static -int set_error(argpar_error_t ** const error, argpar_error_type_t type, - const char * const unknown_opt_name, - const argpar_opt_descr_t * const opt_descr, const bool is_short) +static int set_error(argpar_error_t ** const error, argpar_error_type_t type, + const char * const unknown_opt_name, + const argpar_opt_descr_t * const opt_descr, const bool is_short) { - int ret = 0; + int ret = 0; - if (!error) { - goto end; - } + if (!error) { + goto end; + } - *error = ARGPAR_ZALLOC(argpar_error_t); - if (!*error) { - goto error; - } + *error = ARGPAR_ZALLOC(argpar_error_t); + if (!*error) { + goto error; + } - (*error)->type = type; + (*error)->type = type; - if (unknown_opt_name) { - (*error)->unknown_opt_name = ARGPAR_CALLOC(char, - strlen(unknown_opt_name) + 1 + (is_short ? 1 : 2)); - if (!(*error)->unknown_opt_name) { - goto error; - } + if (unknown_opt_name) { + (*error)->unknown_opt_name = + ARGPAR_CALLOC(char, strlen(unknown_opt_name) + 1 + (is_short ? 1 : 2)); + if (!(*error)->unknown_opt_name) { + goto error; + } - if (is_short) { - strcpy((*error)->unknown_opt_name, "-"); - } else { - strcpy((*error)->unknown_opt_name, "--"); - } + if (is_short) { + strcpy((*error)->unknown_opt_name, "-"); + } else { + strcpy((*error)->unknown_opt_name, "--"); + } - strcat((*error)->unknown_opt_name, unknown_opt_name); - } + strcat((*error)->unknown_opt_name, unknown_opt_name); + } - (*error)->opt_descr = opt_descr; - (*error)->is_short = is_short; - goto end; + (*error)->opt_descr = opt_descr; + (*error)->is_short = is_short; + goto end; error: - argpar_error_destroy(*error); - ret = -1; + argpar_error_destroy(*error); + ret = -1; end: - return ret; + return ret; } -ARGPAR_HIDDEN -argpar_error_type_t argpar_error_type( - const argpar_error_t * const error) +ARGPAR_HIDDEN argpar_error_type_t argpar_error_type(const argpar_error_t * const error) { - ARGPAR_ASSERT(error); - return error->type; + ARGPAR_ASSERT(error); + return error->type; } -ARGPAR_HIDDEN -unsigned int argpar_error_orig_index(const argpar_error_t * const error) +ARGPAR_HIDDEN unsigned int argpar_error_orig_index(const argpar_error_t * const error) { - ARGPAR_ASSERT(error); - return error->orig_index; + ARGPAR_ASSERT(error); + return error->orig_index; } -ARGPAR_HIDDEN -const char *argpar_error_unknown_opt_name( - const argpar_error_t * const error) +ARGPAR_HIDDEN const char *argpar_error_unknown_opt_name(const argpar_error_t * const error) { - ARGPAR_ASSERT(error); - ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_UNKNOWN_OPT); - ARGPAR_ASSERT(error->unknown_opt_name); - return error->unknown_opt_name; + ARGPAR_ASSERT(error); + ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_UNKNOWN_OPT); + ARGPAR_ASSERT(error->unknown_opt_name); + return error->unknown_opt_name; } -ARGPAR_HIDDEN -const argpar_opt_descr_t *argpar_error_opt_descr( - const argpar_error_t * const error, bool * const is_short) +ARGPAR_HIDDEN const argpar_opt_descr_t *argpar_error_opt_descr(const argpar_error_t * const error, + bool * const is_short) { - ARGPAR_ASSERT(error); - ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_MISSING_OPT_ARG || - error->type == ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG); - ARGPAR_ASSERT(error->opt_descr); + ARGPAR_ASSERT(error); + ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_MISSING_OPT_ARG || + error->type == ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG); + ARGPAR_ASSERT(error->opt_descr); - if (is_short) { - *is_short = error->is_short; - } + if (is_short) { + *is_short = error->is_short; + } - return error->opt_descr; + return error->opt_descr; } -ARGPAR_HIDDEN -void argpar_error_destroy(const argpar_error_t * const error) +ARGPAR_HIDDEN void argpar_error_destroy(const argpar_error_t * const error) { - if (error) { - free(error->unknown_opt_name); - free((void *) error); - } + if (error) { + free(error->unknown_opt_name); + free((void *) error); + } } /* @@ -390,33 +374,31 @@ void argpar_error_destroy(const argpar_error_t * const error) * * Returns `NULL` if no descriptor is found. */ -static -const argpar_opt_descr_t *find_descr(const argpar_opt_descr_t * const descrs, - const char short_name, const char * const long_name) +static const argpar_opt_descr_t *find_descr(const argpar_opt_descr_t * const descrs, + const char short_name, const char * const long_name) { - const argpar_opt_descr_t *descr; + const argpar_opt_descr_t *descr; - for (descr = descrs; descr->short_name || descr->long_name; descr++) { - if (short_name && descr->short_name && - short_name == descr->short_name) { - goto end; - } + for (descr = descrs; descr->short_name || descr->long_name; descr++) { + if (short_name && descr->short_name && short_name == descr->short_name) { + goto end; + } - if (long_name && descr->long_name && - strcmp(long_name, descr->long_name) == 0) { - goto end; - } - } + if (long_name && descr->long_name && strcmp(long_name, descr->long_name) == 0) { + goto end; + } + } end: - return !descr->short_name && !descr->long_name ? NULL : descr; + return !descr->short_name && !descr->long_name ? NULL : descr; } /* Return type of parse_short_opt_group() and parse_long_opt() */ -typedef enum parse_orig_arg_opt_ret { - PARSE_ORIG_ARG_OPT_RET_OK, - PARSE_ORIG_ARG_OPT_RET_ERROR = -1, - PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY = -2, +typedef enum parse_orig_arg_opt_ret +{ + PARSE_ORIG_ARG_OPT_RET_OK, + PARSE_ORIG_ARG_OPT_RET_ERROR = -1, + PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY = -2, } parse_orig_arg_opt_ret_t; /* @@ -428,97 +410,90 @@ typedef enum parse_orig_arg_opt_ret { * On error (except for `PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY`), sets * `*error`. */ -static -parse_orig_arg_opt_ret_t parse_short_opt_group( - const char * const short_opt_group, - const char * const next_orig_arg, - const argpar_opt_descr_t * const descrs, - argpar_iter_t * const iter, argpar_error_t ** const error, - argpar_item_t ** const item) +static parse_orig_arg_opt_ret_t +parse_short_opt_group(const char * const short_opt_group, const char * const next_orig_arg, + const argpar_opt_descr_t * const descrs, argpar_iter_t * const iter, + argpar_error_t ** const error, argpar_item_t ** const item) { - parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK; - bool used_next_orig_arg = false; - const char *opt_arg = NULL; - const argpar_opt_descr_t *descr; - argpar_item_opt_t *opt_item; - - ARGPAR_ASSERT(strlen(short_opt_group) != 0); - - if (!iter->short_opt_group_ch) { - iter->short_opt_group_ch = short_opt_group; - } - - /* Find corresponding option descriptor */ - descr = find_descr(descrs, *iter->short_opt_group_ch, NULL); - if (!descr) { - const char unknown_opt_name[] = - {*iter->short_opt_group_ch, '\0'}; - - ret = PARSE_ORIG_ARG_OPT_RET_ERROR; - - if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT, - unknown_opt_name, NULL, true)) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; - } - - goto error; - } - - if (descr->with_arg) { - if (iter->short_opt_group_ch[1]) { - /* `-oarg` form */ - opt_arg = &iter->short_opt_group_ch[1]; - } else { - /* `-o arg` form */ - opt_arg = next_orig_arg; - used_next_orig_arg = true; - } - - /* - * We accept `-o ''` (empty option argument), but not - * `-o` alone if an option argument is expected. - */ - if (!opt_arg || (iter->short_opt_group_ch[1] && - strlen(opt_arg) == 0)) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR; - - if (set_error(error, ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, - NULL, descr, true)) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; - } - - goto error; - } - } - - /* Create and append option argument */ - opt_item = create_opt_item(descr, opt_arg); - if (!opt_item) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; - goto error; - } - - *item = &opt_item->base; - iter->short_opt_group_ch++; - - if (descr->with_arg || !*iter->short_opt_group_ch) { - /* Option has an argument: no more options */ - iter->short_opt_group_ch = NULL; - - if (used_next_orig_arg) { - iter->i += 2; - } else { - iter->i++; - } - } - - goto end; + parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK; + bool used_next_orig_arg = false; + const char *opt_arg = NULL; + const argpar_opt_descr_t *descr; + argpar_item_opt_t *opt_item; + + ARGPAR_ASSERT(strlen(short_opt_group) != 0); + + if (!iter->short_opt_group_ch) { + iter->short_opt_group_ch = short_opt_group; + } + + /* Find corresponding option descriptor */ + descr = find_descr(descrs, *iter->short_opt_group_ch, NULL); + if (!descr) { + const char unknown_opt_name[] = {*iter->short_opt_group_ch, '\0'}; + + ret = PARSE_ORIG_ARG_OPT_RET_ERROR; + + if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT, unknown_opt_name, NULL, true)) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; + } + + goto error; + } + + if (descr->with_arg) { + if (iter->short_opt_group_ch[1]) { + /* `-oarg` form */ + opt_arg = &iter->short_opt_group_ch[1]; + } else { + /* `-o arg` form */ + opt_arg = next_orig_arg; + used_next_orig_arg = true; + } + + /* + * We accept `-o ''` (empty option argument), but not + * `-o` alone if an option argument is expected. + */ + if (!opt_arg || (iter->short_opt_group_ch[1] && strlen(opt_arg) == 0)) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR; + + if (set_error(error, ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, NULL, descr, true)) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; + } + + goto error; + } + } + + /* Create and append option argument */ + opt_item = create_opt_item(descr, opt_arg); + if (!opt_item) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; + goto error; + } + + *item = &opt_item->base; + iter->short_opt_group_ch++; + + if (descr->with_arg || !*iter->short_opt_group_ch) { + /* Option has an argument: no more options */ + iter->short_opt_group_ch = NULL; + + if (used_next_orig_arg) { + iter->i += 2; + } else { + iter->i++; + } + } + + goto end; error: - ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK); + ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK); end: - return ret; + return ret; } /* @@ -529,119 +504,113 @@ end: * On error (except for `PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY`), sets * `*error`. */ -static -parse_orig_arg_opt_ret_t parse_long_opt(const char * const long_opt_arg, - const char * const next_orig_arg, - const argpar_opt_descr_t * const descrs, - argpar_iter_t * const iter, argpar_error_t ** const error, - argpar_item_t ** const item) +static parse_orig_arg_opt_ret_t +parse_long_opt(const char * const long_opt_arg, const char * const next_orig_arg, + const argpar_opt_descr_t * const descrs, argpar_iter_t * const iter, + argpar_error_t ** const error, argpar_item_t ** const item) { - parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK; - const argpar_opt_descr_t *descr; - argpar_item_opt_t *opt_item; - bool used_next_orig_arg = false; - - /* Option's argument, if any */ - const char *opt_arg = NULL; - - /* Position of first `=`, if any */ - const char *eq_pos; - - /* Option name */ - const char *long_opt_name = long_opt_arg; - - ARGPAR_ASSERT(strlen(long_opt_arg) != 0); - - /* Find the first `=` in original argument */ - eq_pos = strchr(long_opt_arg, '='); - if (eq_pos) { - const size_t long_opt_name_size = eq_pos - long_opt_arg; - - /* Isolate the option name */ - while (long_opt_name_size > iter->tmp_buf.size - 1) { - iter->tmp_buf.size *= 2; - iter->tmp_buf.data = ARGPAR_REALLOC(iter->tmp_buf.data, - char, iter->tmp_buf.size); - if (!iter->tmp_buf.data) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; - goto error; - } - } - - memcpy(iter->tmp_buf.data, long_opt_arg, long_opt_name_size); - iter->tmp_buf.data[long_opt_name_size] = '\0'; - long_opt_name = iter->tmp_buf.data; - } - - /* Find corresponding option descriptor */ - descr = find_descr(descrs, '\0', long_opt_name); - if (!descr) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR; - - if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT, - long_opt_name, NULL, false)) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; - } - - goto error; - } - - /* Find option's argument if any */ - if (descr->with_arg) { - if (eq_pos) { - /* `--long-opt=arg` style */ - opt_arg = eq_pos + 1; - } else { - /* `--long-opt arg` style */ - if (!next_orig_arg) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR; - - if (set_error(error, ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, - NULL, descr, false)) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; - } - - goto error; - } - - opt_arg = next_orig_arg; - used_next_orig_arg = true; - } - } else if (eq_pos) { - /* - * Unexpected `--opt=arg` style for a long option which - * doesn't accept an argument. - */ - ret = PARSE_ORIG_ARG_OPT_RET_ERROR; - - if (set_error(error, ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG, - NULL, descr, false)) { - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; - } - - goto error; - } - - /* Create and append option argument */ - opt_item = create_opt_item(descr, opt_arg); - if (!opt_item) { - goto error; - } - - if (used_next_orig_arg) { - iter->i += 2; - } else { - iter->i++; - } - - *item = &opt_item->base; - goto end; + parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK; + const argpar_opt_descr_t *descr; + argpar_item_opt_t *opt_item; + bool used_next_orig_arg = false; + + /* Option's argument, if any */ + const char *opt_arg = NULL; + + /* Position of first `=`, if any */ + const char *eq_pos; + + /* Option name */ + const char *long_opt_name = long_opt_arg; + + ARGPAR_ASSERT(strlen(long_opt_arg) != 0); + + /* Find the first `=` in original argument */ + eq_pos = strchr(long_opt_arg, '='); + if (eq_pos) { + const size_t long_opt_name_size = eq_pos - long_opt_arg; + + /* Isolate the option name */ + while (long_opt_name_size > iter->tmp_buf.size - 1) { + iter->tmp_buf.size *= 2; + iter->tmp_buf.data = ARGPAR_REALLOC(iter->tmp_buf.data, char, iter->tmp_buf.size); + if (!iter->tmp_buf.data) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; + goto error; + } + } + + memcpy(iter->tmp_buf.data, long_opt_arg, long_opt_name_size); + iter->tmp_buf.data[long_opt_name_size] = '\0'; + long_opt_name = iter->tmp_buf.data; + } + + /* Find corresponding option descriptor */ + descr = find_descr(descrs, '\0', long_opt_name); + if (!descr) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR; + + if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT, long_opt_name, NULL, false)) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; + } + + goto error; + } + + /* Find option's argument if any */ + if (descr->with_arg) { + if (eq_pos) { + /* `--long-opt=arg` style */ + opt_arg = eq_pos + 1; + } else { + /* `--long-opt arg` style */ + if (!next_orig_arg) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR; + + if (set_error(error, ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, NULL, descr, false)) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; + } + + goto error; + } + + opt_arg = next_orig_arg; + used_next_orig_arg = true; + } + } else if (eq_pos) { + /* + * Unexpected `--opt=arg` style for a long option which + * doesn't accept an argument. + */ + ret = PARSE_ORIG_ARG_OPT_RET_ERROR; + + if (set_error(error, ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG, NULL, descr, false)) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; + } + + goto error; + } + + /* Create and append option argument */ + opt_item = create_opt_item(descr, opt_arg); + if (!opt_item) { + goto error; + } + + if (used_next_orig_arg) { + iter->i += 2; + } else { + iter->i++; + } + + *item = &opt_item->base; + goto end; error: - ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK); + ARGPAR_ASSERT(ret != PARSE_ORIG_ARG_OPT_RET_OK); end: - return ret; + return ret; } /* @@ -652,139 +621,126 @@ end: * On error (except for `PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY`), sets * `*error`. */ -static -parse_orig_arg_opt_ret_t parse_orig_arg_opt(const char * const orig_arg, - const char * const next_orig_arg, - const argpar_opt_descr_t * const descrs, - argpar_iter_t * const iter, argpar_error_t ** const error, - argpar_item_t ** const item) +static parse_orig_arg_opt_ret_t +parse_orig_arg_opt(const char * const orig_arg, const char * const next_orig_arg, + const argpar_opt_descr_t * const descrs, argpar_iter_t * const iter, + argpar_error_t ** const error, argpar_item_t ** const item) { - parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK; + parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK; - ARGPAR_ASSERT(orig_arg[0] == '-'); + ARGPAR_ASSERT(orig_arg[0] == '-'); - if (orig_arg[1] == '-') { - /* Long option */ - ret = parse_long_opt(&orig_arg[2], next_orig_arg, descrs, iter, - error, item); - } else { - /* Short option */ - ret = parse_short_opt_group(&orig_arg[1], next_orig_arg, descrs, - iter, error, item); - } + if (orig_arg[1] == '-') { + /* Long option */ + ret = parse_long_opt(&orig_arg[2], next_orig_arg, descrs, iter, error, item); + } else { + /* Short option */ + ret = parse_short_opt_group(&orig_arg[1], next_orig_arg, descrs, iter, error, item); + } - return ret; + return ret; } -ARGPAR_HIDDEN -argpar_iter_t *argpar_iter_create(const unsigned int argc, - const char * const * const argv, - const argpar_opt_descr_t * const descrs) +ARGPAR_HIDDEN argpar_iter_t *argpar_iter_create(const unsigned int argc, + const char * const * const argv, + const argpar_opt_descr_t * const descrs) { - argpar_iter_t *iter = ARGPAR_ZALLOC(argpar_iter_t); - - if (!iter) { - goto end; - } - - iter->user.argc = argc; - iter->user.argv = argv; - iter->user.descrs = descrs; - iter->tmp_buf.size = 128; - iter->tmp_buf.data = ARGPAR_CALLOC(char, iter->tmp_buf.size); - if (!iter->tmp_buf.data) { - argpar_iter_destroy(iter); - iter = NULL; - goto end; - } + argpar_iter_t *iter = ARGPAR_ZALLOC(argpar_iter_t); + + if (!iter) { + goto end; + } + + iter->user.argc = argc; + iter->user.argv = argv; + iter->user.descrs = descrs; + iter->tmp_buf.size = 128; + iter->tmp_buf.data = ARGPAR_CALLOC(char, iter->tmp_buf.size); + if (!iter->tmp_buf.data) { + argpar_iter_destroy(iter); + iter = NULL; + goto end; + } end: - return iter; + return iter; } -ARGPAR_HIDDEN -void argpar_iter_destroy(argpar_iter_t * const iter) +ARGPAR_HIDDEN void argpar_iter_destroy(argpar_iter_t * const iter) { - if (iter) { - free(iter->tmp_buf.data); - free(iter); - } + if (iter) { + free(iter->tmp_buf.data); + free(iter); + } } -ARGPAR_HIDDEN -argpar_iter_next_status_t argpar_iter_next(argpar_iter_t * const iter, - const argpar_item_t ** const item, - const argpar_error_t ** const error) +ARGPAR_HIDDEN argpar_iter_next_status_t argpar_iter_next(argpar_iter_t * const iter, + const argpar_item_t ** const item, + const argpar_error_t ** const error) { - argpar_iter_next_status_t status; - parse_orig_arg_opt_ret_t parse_orig_arg_opt_ret; - const char *orig_arg; - const char *next_orig_arg; - argpar_error_t ** const nc_error = (argpar_error_t **) error; - - ARGPAR_ASSERT(iter->i <= iter->user.argc); - - if (error) { - *nc_error = NULL; - } - - if (iter->i == iter->user.argc) { - status = ARGPAR_ITER_NEXT_STATUS_END; - goto end; - } - - orig_arg = iter->user.argv[iter->i]; - next_orig_arg = - iter->i < (iter->user.argc - 1) ? - iter->user.argv[iter->i + 1] : NULL; - - if (strcmp(orig_arg, "-") == 0 || strcmp(orig_arg, "--") == 0 || - orig_arg[0] != '-') { - /* Non-option argument */ - const argpar_item_non_opt_t * const non_opt_item = - create_non_opt_item(orig_arg, iter->i, - iter->non_opt_index); - - if (!non_opt_item) { - status = ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY; - goto end; - } - - iter->non_opt_index++; - iter->i++; - *item = &non_opt_item->base; - status = ARGPAR_ITER_NEXT_STATUS_OK; - goto end; - } - - /* Option argument */ - parse_orig_arg_opt_ret = parse_orig_arg_opt(orig_arg, - next_orig_arg, iter->user.descrs, iter, nc_error, - (argpar_item_t **) item); - switch (parse_orig_arg_opt_ret) { - case PARSE_ORIG_ARG_OPT_RET_OK: - status = ARGPAR_ITER_NEXT_STATUS_OK; - break; - case PARSE_ORIG_ARG_OPT_RET_ERROR: - if (error) { - ARGPAR_ASSERT(*error); - (*nc_error)->orig_index = iter->i; - } - status = ARGPAR_ITER_NEXT_STATUS_ERROR; - break; - case PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY: - status = ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY; - break; - default: - abort(); - } + argpar_iter_next_status_t status; + parse_orig_arg_opt_ret_t parse_orig_arg_opt_ret; + const char *orig_arg; + const char *next_orig_arg; + argpar_error_t ** const nc_error = (argpar_error_t **) error; + + ARGPAR_ASSERT(iter->i <= iter->user.argc); + + if (error) { + *nc_error = NULL; + } + + if (iter->i == iter->user.argc) { + status = ARGPAR_ITER_NEXT_STATUS_END; + goto end; + } + + orig_arg = iter->user.argv[iter->i]; + next_orig_arg = iter->i < (iter->user.argc - 1) ? iter->user.argv[iter->i + 1] : NULL; + + if (strcmp(orig_arg, "-") == 0 || strcmp(orig_arg, "--") == 0 || orig_arg[0] != '-') { + /* Non-option argument */ + const argpar_item_non_opt_t * const non_opt_item = + create_non_opt_item(orig_arg, iter->i, iter->non_opt_index); + + if (!non_opt_item) { + status = ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY; + goto end; + } + + iter->non_opt_index++; + iter->i++; + *item = &non_opt_item->base; + status = ARGPAR_ITER_NEXT_STATUS_OK; + goto end; + } + + /* Option argument */ + parse_orig_arg_opt_ret = parse_orig_arg_opt(orig_arg, next_orig_arg, iter->user.descrs, iter, + nc_error, (argpar_item_t **) item); + switch (parse_orig_arg_opt_ret) { + case PARSE_ORIG_ARG_OPT_RET_OK: + status = ARGPAR_ITER_NEXT_STATUS_OK; + break; + case PARSE_ORIG_ARG_OPT_RET_ERROR: + if (error) { + ARGPAR_ASSERT(*error); + (*nc_error)->orig_index = iter->i; + } + status = ARGPAR_ITER_NEXT_STATUS_ERROR; + break; + case PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY: + status = ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY; + break; + default: + abort(); + } end: - return status; + return status; } -ARGPAR_HIDDEN -unsigned int argpar_iter_ingested_orig_args(const argpar_iter_t * const iter) +ARGPAR_HIDDEN unsigned int argpar_iter_ingested_orig_args(const argpar_iter_t * const iter) { - return iter->i; + return iter->i; } diff --git a/argpar/argpar.h b/argpar/argpar.h index b1709b3..4f2083a 100644 --- a/argpar/argpar.h +++ b/argpar/argpar.h @@ -113,9 +113,9 @@ argpar_iter_next() produces the following items, in this order: /* Internal: `noexcept` specifier if C++ ≥ 11 */ #if defined(__cplusplus) && (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)) -# define ARGPAR_NOEXCEPT noexcept +# define ARGPAR_NOEXCEPT noexcept #else -# define ARGPAR_NOEXCEPT +# define ARGPAR_NOEXCEPT #endif typedef struct argpar_opt_descr argpar_opt_descr_t; @@ -130,12 +130,13 @@ typedef struct argpar_opt_descr argpar_opt_descr_t; Type of a parsing item, as returned by \link argpar_item_type(const argpar_item *) argpar_item_type()\endlink. */ -typedef enum argpar_item_type { - /// Option - ARGPAR_ITEM_TYPE_OPT, +typedef enum argpar_item_type +{ + /// Option + ARGPAR_ITEM_TYPE_OPT, - /// Non-option - ARGPAR_ITEM_TYPE_NON_OPT, + /// Non-option + ARGPAR_ITEM_TYPE_NON_OPT, } argpar_item_type_t; /*! @@ -178,8 +179,7 @@ argpar_item_type_t argpar_item_type(const argpar_item_t *item) ARGPAR_NOEXCEPT; @pre \p item has the type #ARGPAR_ITEM_TYPE_OPT. */ -const argpar_opt_descr_t *argpar_item_opt_descr( - const argpar_item_t *item) ARGPAR_NOEXCEPT; +const argpar_opt_descr_t *argpar_item_opt_descr(const argpar_item_t *item) ARGPAR_NOEXCEPT; /*! @brief @@ -217,8 +217,7 @@ const char *argpar_item_opt_arg(const argpar_item_t *item) ARGPAR_NOEXCEPT; @pre \p item has the type #ARGPAR_ITEM_TYPE_NON_OPT. */ -const char *argpar_item_non_opt_arg( - const argpar_item_t *item) ARGPAR_NOEXCEPT; +const char *argpar_item_non_opt_arg(const argpar_item_t *item) ARGPAR_NOEXCEPT; /*! @brief @@ -251,8 +250,7 @@ argument index of \c mix is 4. argpar_item_non_opt_non_opt_index() -- Returns the non-option index of a non-option parsing item. */ -unsigned int argpar_item_non_opt_orig_index( - const argpar_item_t *item) ARGPAR_NOEXCEPT; +unsigned int argpar_item_non_opt_orig_index(const argpar_item_t *item) ARGPAR_NOEXCEPT; /*! @brief @@ -284,8 +282,7 @@ argument index of \c mix is 1. argpar_item_non_opt_orig_index() -- Returns the original argument index of a non-option parsing item. */ -unsigned int argpar_item_non_opt_non_opt_index( - const argpar_item_t *item) ARGPAR_NOEXCEPT; +unsigned int argpar_item_non_opt_non_opt_index(const argpar_item_t *item) ARGPAR_NOEXCEPT; /*! @brief @@ -307,11 +304,11 @@ void argpar_item_destroy(const argpar_item_t *item) ARGPAR_NOEXCEPT; Item to destroy and variable to reset (const argpar_item_t * type). */ -#define ARGPAR_ITEM_DESTROY_AND_RESET(_item) \ - { \ - argpar_item_destroy(_item); \ - _item = NULL; \ - } +#define ARGPAR_ITEM_DESTROY_AND_RESET(_item) \ + { \ + argpar_item_destroy(_item); \ + _item = NULL; \ + } /// @} @@ -325,15 +322,16 @@ void argpar_item_destroy(const argpar_item_t *item) ARGPAR_NOEXCEPT; Parsing error type, as returned by \link argpar_error_type(const argpar_error_t *) argpar_error_type()\endlink. */ -typedef enum argpar_error_type { - /// Unknown option error - ARGPAR_ERROR_TYPE_UNKNOWN_OPT, +typedef enum argpar_error_type +{ + /// Unknown option error + ARGPAR_ERROR_TYPE_UNKNOWN_OPT, - /// Missing option argument error - ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, + /// Missing option argument error + ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, - /// Unexpected option argument error - ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG, + /// Unexpected option argument error + ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG, } argpar_error_type_t; /*! @@ -357,8 +355,7 @@ typedef struct argpar_error argpar_error_t; @pre \p error is not \c NULL. */ -argpar_error_type_t argpar_error_type( - const argpar_error_t *error) ARGPAR_NOEXCEPT; +argpar_error_type_t argpar_error_type(const argpar_error_t *error) ARGPAR_NOEXCEPT; /*! @brief @@ -375,8 +372,7 @@ argpar_error_type_t argpar_error_type( @pre \p error is not \c NULL. */ -unsigned int argpar_error_orig_index( - const argpar_error_t *error) ARGPAR_NOEXCEPT; +unsigned int argpar_error_orig_index(const argpar_error_t *error) ARGPAR_NOEXCEPT; /*! @brief @@ -403,8 +399,7 @@ part (\--mireille in the last example). \link argpar_error_type(const argpar_error_t *) argpar_error_type()\endlink, is #ARGPAR_ERROR_TYPE_UNKNOWN_OPT. */ -const char *argpar_error_unknown_opt_name( - const argpar_error_t *error) ARGPAR_NOEXCEPT; +const char *argpar_error_unknown_opt_name(const argpar_error_t *error) ARGPAR_NOEXCEPT; /*! @brief @@ -436,7 +431,7 @@ const char *argpar_error_unknown_opt_name( #ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG. */ const argpar_opt_descr_t *argpar_error_opt_descr(const argpar_error_t *error, - bool *is_short) ARGPAR_NOEXCEPT; + bool *is_short) ARGPAR_NOEXCEPT; /*! @brief @@ -472,18 +467,19 @@ const argpar_opt_descr_t descrs[] = { }; @endcode */ -typedef struct argpar_opt_descr { - /// Numeric ID, to uniquely identify this descriptor - const int id; +typedef struct argpar_opt_descr +{ + /// Numeric ID, to uniquely identify this descriptor + const int id; - /// Short option character, or '\0' - const char short_name; + /// Short option character, or '\0' + const char short_name; - /// Long option name (without the \-- prefix), or \c NULL - const char * const long_name; + /// Long option name (without the \-- prefix), or \c NULL + const char * const long_name; - /// \c true if this option has an argument - const bool with_arg; + /// \c true if this option has an argument + const bool with_arg; } argpar_opt_descr_t; /*! @@ -501,7 +497,10 @@ const argpar_opt_descr_t descrs[] = { }; @endcode */ -#define ARGPAR_OPT_DESCR_SENTINEL { -1, '\0', NULL, false } +#define ARGPAR_OPT_DESCR_SENTINEL \ + { \ + -1, '\0', NULL, false \ + } /*! @struct argpar_iter @@ -568,7 +567,7 @@ argpar_iter_next(). argpar_iter_destroy() -- Destroys an argument parsing iterator. */ argpar_iter_t *argpar_iter_create(unsigned int argc, const char * const *argv, - const argpar_opt_descr_t *descrs) ARGPAR_NOEXCEPT; + const argpar_opt_descr_t *descrs) ARGPAR_NOEXCEPT; /*! @brief @@ -588,18 +587,19 @@ void argpar_iter_destroy(argpar_iter_t *iter) ARGPAR_NOEXCEPT; Error status enumerators have a negative value. */ -typedef enum argpar_iter_next_status { - /// Success - ARGPAR_ITER_NEXT_STATUS_OK, +typedef enum argpar_iter_next_status +{ + /// Success + ARGPAR_ITER_NEXT_STATUS_OK, - /// End of iteration (no more original arguments to parse) - ARGPAR_ITER_NEXT_STATUS_END, + /// End of iteration (no more original arguments to parse) + ARGPAR_ITER_NEXT_STATUS_END, - /// Parsing error - ARGPAR_ITER_NEXT_STATUS_ERROR = -1, + /// Parsing error + ARGPAR_ITER_NEXT_STATUS_ERROR = -1, - /// Memory error - ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY = -12, + /// Memory error + ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY = -12, } argpar_iter_next_status_t; /*! @@ -635,9 +635,8 @@ If there are no more original arguments to parse, this function returns @pre \p item is not \c NULL. */ -argpar_iter_next_status_t argpar_iter_next(argpar_iter_t *iter, - const argpar_item_t **item, - const argpar_error_t **error) ARGPAR_NOEXCEPT; +argpar_iter_next_status_t argpar_iter_next(argpar_iter_t *iter, const argpar_item_t **item, + const argpar_error_t **error) ARGPAR_NOEXCEPT; /* * Returns the number of ingested elements from `argv`, as passed to @@ -661,8 +660,7 @@ argpar_iter_next_status_t argpar_iter_next(argpar_iter_t *iter, @pre \p iter is not \c NULL. */ -unsigned int argpar_iter_ingested_orig_args( - const argpar_iter_t *iter) ARGPAR_NOEXCEPT; +unsigned int argpar_iter_ingested_orig_args(const argpar_iter_t *iter) ARGPAR_NOEXCEPT; /// @} diff --git a/tests/test-argpar.c b/tests/test-argpar.c index b1b4539..9591e6e 100644 --- a/tests/test-argpar.c +++ b/tests/test-argpar.c @@ -17,14 +17,14 @@ */ #include -#include +#include +#include #include +#include #include -#include -#include -#include "tap/tap.h" #include "argpar/argpar.h" +#include "tap/tap.h" /* * Formats `item` and appends the resulting string to `res_str` to @@ -37,54 +37,46 @@ * ‣ Uses the `arg` form for non-option arguments, where `A` is the * original argument index and `B` is the non-option argument index. */ -static -void append_to_res_str(GString * const res_str, - const argpar_item_t * const item) +static void append_to_res_str(GString * const res_str, const argpar_item_t * const item) { - if (res_str->len > 0) { - g_string_append_c(res_str, ' '); - } - - switch (argpar_item_type(item)) { - case ARGPAR_ITEM_TYPE_OPT: - { - const argpar_opt_descr_t * const descr = - argpar_item_opt_descr(item); - const char * const arg = argpar_item_opt_arg(item); - - if (descr->long_name) { - g_string_append_printf(res_str, "--%s", - descr->long_name); - - if (arg) { - g_string_append_printf(res_str, "=%s", arg); - } - } else if (descr->short_name) { - g_string_append_printf(res_str, "-%c", - descr->short_name); - - if (arg) { - g_string_append_printf(res_str, " %s", arg); - } - } - - break; - } - case ARGPAR_ITEM_TYPE_NON_OPT: - { - const char * const arg = argpar_item_non_opt_arg(item); - const unsigned int orig_index = - argpar_item_non_opt_orig_index(item); - const unsigned int non_opt_index = - argpar_item_non_opt_non_opt_index(item); - - g_string_append_printf(res_str, "%s<%u,%u>", arg, orig_index, - non_opt_index); - break; - } - default: - abort(); - } + if (res_str->len > 0) { + g_string_append_c(res_str, ' '); + } + + switch (argpar_item_type(item)) { + case ARGPAR_ITEM_TYPE_OPT: + { + const argpar_opt_descr_t * const descr = argpar_item_opt_descr(item); + const char * const arg = argpar_item_opt_arg(item); + + if (descr->long_name) { + g_string_append_printf(res_str, "--%s", descr->long_name); + + if (arg) { + g_string_append_printf(res_str, "=%s", arg); + } + } else if (descr->short_name) { + g_string_append_printf(res_str, "-%c", descr->short_name); + + if (arg) { + g_string_append_printf(res_str, " %s", arg); + } + } + + break; + } + case ARGPAR_ITEM_TYPE_NON_OPT: + { + const char * const arg = argpar_item_non_opt_arg(item); + const unsigned int orig_index = argpar_item_non_opt_orig_index(item); + const unsigned int non_opt_index = argpar_item_non_opt_non_opt_index(item); + + g_string_append_printf(res_str, "%s<%u,%u>", arg, orig_index, non_opt_index); + break; + } + default: + abort(); + } } /* @@ -99,412 +91,269 @@ void append_to_res_str(GString * const res_str, * This function builds the resulting command line from parsing items * by space-separating each formatted item (see append_to_res_str()). */ -static -void test_succeed(const char * const cmdline, - const char * const expected_cmd_line, - const argpar_opt_descr_t * const descrs, - const unsigned int expected_ingested_orig_args) +static void test_succeed(const char * const cmdline, const char * const expected_cmd_line, + const argpar_opt_descr_t * const descrs, + const unsigned int expected_ingested_orig_args) { - argpar_iter_t *iter = NULL; - const argpar_item_t *item = NULL; - const argpar_error_t *error = NULL; - GString * const res_str = g_string_new(NULL); - gchar ** const argv = g_strsplit(cmdline, " ", 0); - unsigned int i, actual_ingested_orig_args; - - assert(argv); - assert(res_str); - iter = argpar_iter_create(g_strv_length(argv), - (const char * const *) argv, descrs); - assert(iter); - - for (i = 0; ; i++) { - argpar_iter_next_status_t status; - - ARGPAR_ITEM_DESTROY_AND_RESET(item); - status = argpar_iter_next(iter, &item, &error); - - ok(status == ARGPAR_ITER_NEXT_STATUS_OK || - status == ARGPAR_ITER_NEXT_STATUS_END, - "argpar_iter_next() returns the expected status " - "(%d) for command line `%s` (call %u)", - status, cmdline, i + 1); - ok(!error, - "argpar_iter_next() doesn't set an error for " - "command line `%s` (call %u)", - cmdline, i + 1); - - if (status == ARGPAR_ITER_NEXT_STATUS_END) { - ok(!item, - "argpar_iter_next() doesn't set an item " - "for status `ARGPAR_ITER_NEXT_STATUS_END` " - "and command line `%s` (call %u)", - cmdline, i + 1); - break; - } - - append_to_res_str(res_str, item); - } - - actual_ingested_orig_args = argpar_iter_ingested_orig_args(iter); - ok(actual_ingested_orig_args == expected_ingested_orig_args, - "argpar_iter_ingested_orig_args() returns the expected " - "number of ingested original arguments for command line `%s`", - cmdline); - - if (actual_ingested_orig_args != expected_ingested_orig_args) { - diag("Expected: %u Got: %u", expected_ingested_orig_args, - actual_ingested_orig_args); - } - - ok(strcmp(expected_cmd_line, res_str->str) == 0, - "argpar_iter_next() returns the expected parsing items " - "for command line `%s`", cmdline); - - if (strcmp(expected_cmd_line, res_str->str) != 0) { - diag("Expected: `%s`", expected_cmd_line); - diag("Got: `%s`", res_str->str); - } - - argpar_item_destroy(item); - argpar_iter_destroy(iter); - assert(!error); - g_string_free(res_str, TRUE); - g_strfreev(argv); + argpar_iter_t *iter = NULL; + const argpar_item_t *item = NULL; + const argpar_error_t *error = NULL; + GString * const res_str = g_string_new(NULL); + gchar ** const argv = g_strsplit(cmdline, " ", 0); + unsigned int i, actual_ingested_orig_args; + + assert(argv); + assert(res_str); + iter = argpar_iter_create(g_strv_length(argv), (const char * const *) argv, descrs); + assert(iter); + + for (i = 0;; i++) { + argpar_iter_next_status_t status; + + ARGPAR_ITEM_DESTROY_AND_RESET(item); + status = argpar_iter_next(iter, &item, &error); + + ok(status == ARGPAR_ITER_NEXT_STATUS_OK || status == ARGPAR_ITER_NEXT_STATUS_END, + "argpar_iter_next() returns the expected status (%d) for command line `%s` (call %u)", + status, cmdline, i + 1); + ok(!error, "argpar_iter_next() doesn't set an error for command line `%s` (call %u)", + cmdline, i + 1); + + if (status == ARGPAR_ITER_NEXT_STATUS_END) { + ok(!item, + "argpar_iter_next() doesn't set an item for status `ARGPAR_ITER_NEXT_STATUS_END` " + "and command line `%s` (call %u)", + cmdline, i + 1); + break; + } + + append_to_res_str(res_str, item); + } + + actual_ingested_orig_args = argpar_iter_ingested_orig_args(iter); + ok(actual_ingested_orig_args == expected_ingested_orig_args, + "argpar_iter_ingested_orig_args() returns the expected number of ingested original " + "arguments for command line `%s`", + cmdline); + + if (actual_ingested_orig_args != expected_ingested_orig_args) { + diag("Expected: %u Got: %u", expected_ingested_orig_args, actual_ingested_orig_args); + } + + ok(strcmp(expected_cmd_line, res_str->str) == 0, + "argpar_iter_next() returns the expected parsing items for command line `%s`", cmdline); + + if (strcmp(expected_cmd_line, res_str->str) != 0) { + diag("Expected: `%s`", expected_cmd_line); + diag("Got: `%s`", res_str->str); + } + + argpar_item_destroy(item); + argpar_iter_destroy(iter); + assert(!error); + g_string_free(res_str, TRUE); + g_strfreev(argv); } -static -void succeed_tests(void) +static void succeed_tests(void) { - /* No arguments */ - { - const argpar_opt_descr_t descrs[] = { - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "", - "", - descrs, 0); - } + /* No arguments */ + { + const argpar_opt_descr_t descrs[] = {ARGPAR_OPT_DESCR_SENTINEL}; - /* Single long option */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "salut", false }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "--salut", - "--salut", - descrs, 1); - } + test_succeed("", "", descrs, 0); + } - /* Single short option */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'f', NULL, false }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-f", - "-f", - descrs, 1); - } + /* Single long option */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "salut", false}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Short and long option (aliases) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'f', "flaw", false }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-f --flaw", - "--flaw --flaw", - descrs, 2); - } + test_succeed("--salut", "--salut", descrs, 1); + } - /* Long option with argument (space form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "tooth", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "--tooth 67", - "--tooth=67", - descrs, 2); - } + /* Single short option */ + { + const argpar_opt_descr_t descrs[] = {{0, 'f', NULL, false}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Long option with argument (equal form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "polish", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "--polish=brick", - "--polish=brick", - descrs, 1); - } - - /* Short option with argument (space form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'c', NULL, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-c chilly", - "-c chilly", - descrs, 2); - } - - /* Short option with argument (glued form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'c', NULL, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-cchilly", - "-c chilly", - descrs, 1); - } - - /* Short and long option (aliases) with argument (all forms) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'd', "dry", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "--dry=rate -dthing --dry street --dry=shape", - "--dry=rate --dry=thing --dry=street --dry=shape", - descrs, 5); - } + test_succeed("-f", "-f", descrs, 1); + } - /* Many short options, last one with argument (glued form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'd', NULL, false }, - { 0, 'e', NULL, false }, - { 0, 'f', NULL, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-defmeow", - "-d -e -f meow", - descrs, 1); - } + /* Short and long option (aliases) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'f', "flaw", false}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Many options */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'd', NULL, false }, - { 0, 'e', "east", true }, - { 0, '\0', "mind", false }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-d --mind -destart --mind --east cough -d --east=itch", - "-d --mind -d --east=start --mind --east=cough -d --east=itch", - descrs, 8); - } + test_succeed("-f --flaw", "--flaw --flaw", descrs, 2); + } - /* Single non-option argument */ - { - const argpar_opt_descr_t descrs[] = { - ARGPAR_OPT_DESCR_SENTINEL - }; + /* Long option with argument (space form) */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "tooth", true}, ARGPAR_OPT_DESCR_SENTINEL}; - test_succeed( - "kilojoule", - "kilojoule<0,0>", - descrs, 1); - } + test_succeed("--tooth 67", "--tooth=67", descrs, 2); + } - /* Two non-option arguments */ - { - const argpar_opt_descr_t descrs[] = { - ARGPAR_OPT_DESCR_SENTINEL - }; + /* Long option with argument (equal form) */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "polish", true}, ARGPAR_OPT_DESCR_SENTINEL}; - test_succeed( - "kilojoule mitaine", - "kilojoule<0,0> mitaine<1,1>", - descrs, 2); - } + test_succeed("--polish=brick", "--polish=brick", descrs, 1); + } - /* Single non-option argument mixed with options */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'd', NULL, false }, - { 0, '\0', "squeeze", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-d sprout yes --squeeze little bag -d", - "-d sprout<1,0> yes<2,1> --squeeze=little bag<5,2> -d", - descrs, 7); - } + /* Short option with argument (space form) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'c', NULL, true}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Valid `---opt` */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "-fuel", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "---fuel=three", - "---fuel=three", - descrs, 1); - } + test_succeed("-c chilly", "-c chilly", descrs, 2); + } - /* Long option containing `=` in argument (equal form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "zebra", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "--zebra=three=yes", - "--zebra=three=yes", - descrs, 1); - } + /* Short option with argument (glued form) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'c', NULL, true}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Short option's argument starting with `-` (glued form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'z', NULL, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-z-will", - "-z -will", - descrs, 1); - } + test_succeed("-cchilly", "-c chilly", descrs, 1); + } - /* Short option's argument starting with `-` (space form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'z', NULL, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-z -will", - "-z -will", - descrs, 2); - } + /* Short and long option (aliases) with argument (all forms) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'd', "dry", true}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Long option's argument starting with `-` (space form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "janine", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "--janine -sutto", - "--janine=-sutto", - descrs, 2); - } + test_succeed("--dry=rate -dthing --dry street --dry=shape", + "--dry=rate --dry=thing --dry=street --dry=shape", descrs, 5); + } - /* Long option's argument starting with `-` (equal form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "janine", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "--janine=-sutto", - "--janine=-sutto", - descrs, 1); - } + /* Many short options, last one with argument (glued form) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'd', NULL, false}, + {0, 'e', NULL, false}, + {0, 'f', NULL, true}, + ARGPAR_OPT_DESCR_SENTINEL}; - /* Long option's empty argument (equal form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'f', NULL, false }, - { 0, '\0', "yeah", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-f --yeah= -f", - "-f --yeah= -f", - descrs, 3); - } + test_succeed("-defmeow", "-d -e -f meow", descrs, 1); + } - /* `-` non-option argument */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'f', NULL, false }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-f - -f", - "-f -<1,0> -f", - descrs, 3); - } + /* Many options */ + { + const argpar_opt_descr_t descrs[] = {{0, 'd', NULL, false}, + {0, 'e', "east", true}, + {0, '\0', "mind", false}, + ARGPAR_OPT_DESCR_SENTINEL}; - /* `--` non-option argument */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'f', NULL, false }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_succeed( - "-f -- -f", - "-f --<1,0> -f", - descrs, 3); - } + test_succeed("-d --mind -destart --mind --east cough -d --east=itch", + "-d --mind -d --east=start --mind --east=cough -d --east=itch", descrs, 8); + } - /* Very long name of long option */ - { - const char opt_name[] = - "kale-chips-waistcoat-yr-bicycle-rights-gochujang-" - "woke-tumeric-flexitarian-biodiesel-chillwave-cliche-" - "ethical-cardigan-listicle-pok-pok-sustainable-live-" - "edge-jianbing-gochujang-butcher-disrupt-tattooed-" - "tumeric-prism-photo-booth-vape-kogi-jean-shorts-" - "blog-williamsburg-fingerstache-palo-santo-artisan-" - "affogato-occupy-skateboard-adaptogen-neutra-celiac-" - "put-a-bird-on-it-kombucha-everyday-carry-hot-chicken-" - "craft-beer-subway-tile-tote-bag-disrupt-selvage-" - "raclette-art-party-readymade-paleo-heirloom-trust-" - "fund-small-batch-kinfolk-woke-cardigan-prism-" - "chambray-la-croix-hashtag-unicorn-edison-bulb-tbh-" - "cornhole-cliche-tattooed-green-juice-adaptogen-" - "kitsch-lo-fi-vexillologist-migas-gentrify-" - "viral-raw-denim"; - const argpar_opt_descr_t descrs[] = { - { 0, '\0', opt_name, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - char cmdline[1024]; - - sprintf(cmdline, "--%s=23", opt_name); - test_succeed(cmdline, cmdline, descrs, 1); - } + /* Single non-option argument */ + { + const argpar_opt_descr_t descrs[] = {ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("kilojoule", "kilojoule<0,0>", descrs, 1); + } + + /* Two non-option arguments */ + { + const argpar_opt_descr_t descrs[] = {ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("kilojoule mitaine", "kilojoule<0,0> mitaine<1,1>", descrs, 2); + } + + /* Single non-option argument mixed with options */ + { + const argpar_opt_descr_t descrs[] = {{0, 'd', NULL, false}, + {0, '\0', "squeeze", true}, + ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("-d sprout yes --squeeze little bag -d", + "-d sprout<1,0> yes<2,1> --squeeze=little bag<5,2> -d", descrs, 7); + } + + /* Valid `---opt` */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "-fuel", true}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("---fuel=three", "---fuel=three", descrs, 1); + } + + /* Long option containing `=` in argument (equal form) */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "zebra", true}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("--zebra=three=yes", "--zebra=three=yes", descrs, 1); + } + + /* Short option's argument starting with `-` (glued form) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'z', NULL, true}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("-z-will", "-z -will", descrs, 1); + } + + /* Short option's argument starting with `-` (space form) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'z', NULL, true}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("-z -will", "-z -will", descrs, 2); + } + + /* Long option's argument starting with `-` (space form) */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "janine", true}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("--janine -sutto", "--janine=-sutto", descrs, 2); + } + + /* Long option's argument starting with `-` (equal form) */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "janine", true}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("--janine=-sutto", "--janine=-sutto", descrs, 1); + } + + /* Long option's empty argument (equal form) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'f', NULL, false}, + {0, '\0', "yeah", true}, + ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("-f --yeah= -f", "-f --yeah= -f", descrs, 3); + } + + /* `-` non-option argument */ + { + const argpar_opt_descr_t descrs[] = {{0, 'f', NULL, false}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("-f - -f", "-f -<1,0> -f", descrs, 3); + } + + /* `--` non-option argument */ + { + const argpar_opt_descr_t descrs[] = {{0, 'f', NULL, false}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_succeed("-f -- -f", "-f --<1,0> -f", descrs, 3); + } + + /* Very long name of long option */ + { + const char opt_name[] = "kale-chips-waistcoat-yr-bicycle-rights-gochujang-" + "woke-tumeric-flexitarian-biodiesel-chillwave-cliche-" + "ethical-cardigan-listicle-pok-pok-sustainable-live-" + "edge-jianbing-gochujang-butcher-disrupt-tattooed-" + "tumeric-prism-photo-booth-vape-kogi-jean-shorts-" + "blog-williamsburg-fingerstache-palo-santo-artisan-" + "affogato-occupy-skateboard-adaptogen-neutra-celiac-" + "put-a-bird-on-it-kombucha-everyday-carry-hot-chicken-" + "craft-beer-subway-tile-tote-bag-disrupt-selvage-" + "raclette-art-party-readymade-paleo-heirloom-trust-" + "fund-small-batch-kinfolk-woke-cardigan-prism-" + "chambray-la-croix-hashtag-unicorn-edison-bulb-tbh-" + "cornhole-cliche-tattooed-green-juice-adaptogen-" + "kitsch-lo-fi-vexillologist-migas-gentrify-" + "viral-raw-denim"; + const argpar_opt_descr_t descrs[] = {{0, '\0', opt_name, true}, ARGPAR_OPT_DESCR_SENTINEL}; + char cmdline[1024]; + + sprintf(cmdline, "--%s=23", opt_name); + test_succeed(cmdline, cmdline, descrs, 1); + } } /* @@ -526,95 +375,78 @@ void succeed_tests(void) * This function splits `cmdline` on spaces to create an original * argument array. */ -static -void test_fail(const char * const cmdline, - const argpar_error_type_t expected_error_type, - const unsigned int expected_orig_index, - const char * const expected_unknown_opt_name, - const unsigned int expected_opt_descr_index, - const bool expected_is_short, - const argpar_opt_descr_t * const descrs) +static void test_fail(const char * const cmdline, const argpar_error_type_t expected_error_type, + const unsigned int expected_orig_index, + const char * const expected_unknown_opt_name, + const unsigned int expected_opt_descr_index, const bool expected_is_short, + const argpar_opt_descr_t * const descrs) { - argpar_iter_t *iter = NULL; - const argpar_item_t *item = NULL; - gchar ** const argv = g_strsplit(cmdline, " ", 0); - unsigned int i; - const argpar_error_t *error = NULL; - - iter = argpar_iter_create(g_strv_length(argv), - (const char * const *) argv, descrs); - assert(iter); - - for (i = 0; ; i++) { - argpar_iter_next_status_t status; - - ARGPAR_ITEM_DESTROY_AND_RESET(item); - status = argpar_iter_next(iter, &item, &error); - ok(status == ARGPAR_ITER_NEXT_STATUS_OK || - (status == ARGPAR_ITER_NEXT_STATUS_ERROR && - argpar_error_type(error) == expected_error_type), - "argpar_iter_next() returns the expected status " - "and error type (%d) for command line `%s` (call %u)", - expected_error_type, cmdline, i + 1); - - if (status != ARGPAR_ITER_NEXT_STATUS_OK) { - ok(!item, - "argpar_iter_next() doesn't set an item " - "for other status than " - "`ARGPAR_ITER_NEXT_STATUS_OK` " - "and command line `%s` (call %u)", - cmdline, i + 1); - ok(error, - "argpar_iter_next() sets an error for " - "other status than " - " `ARGPAR_ITER_NEXT_STATUS_OK` " - "and command line `%s` (call %u)", - cmdline, i + 1); - ok(argpar_error_orig_index(error) == - expected_orig_index, - "argpar_iter_next() sets an error with " - "the expected original argument index " - "for command line `%s` (call %u)", - cmdline, i + 1); - - if (argpar_error_type(error) == ARGPAR_ERROR_TYPE_UNKNOWN_OPT) { - ok(strcmp(argpar_error_unknown_opt_name(error), - expected_unknown_opt_name) == 0, - "argpar_iter_next() sets an error with " - "the expected unknown option name " - "for command line `%s` (call %u)", - cmdline, i + 1); - } else { - bool is_short; - - ok(argpar_error_opt_descr(error, &is_short) == - &descrs[expected_opt_descr_index], - "argpar_iter_next() sets an error with " - "the expected option descriptor " - "for command line `%s` (call %u)", - cmdline, i + 1); - ok(is_short == expected_is_short, - "argpar_iter_next() sets an error with " - "the expected option type " - "for command line `%s` (call %u)", - cmdline, i + 1); - } - break; - } - - ok(item, - "argpar_iter_next() sets an item for status " - "`ARGPAR_ITER_NEXT_STATUS_OK` " - "and command line `%s` (call %u)", - cmdline, i + 1); - ok(!error, - "argpar_iter_next() doesn't set an error for status " - "`ARGPAR_ITER_NEXT_STATUS_OK` " - "and command line `%s` (call %u)", - cmdline, i + 1); - } - - /* + argpar_iter_t *iter = NULL; + const argpar_item_t *item = NULL; + gchar ** const argv = g_strsplit(cmdline, " ", 0); + unsigned int i; + const argpar_error_t *error = NULL; + + iter = argpar_iter_create(g_strv_length(argv), (const char * const *) argv, descrs); + assert(iter); + + for (i = 0;; i++) { + argpar_iter_next_status_t status; + + ARGPAR_ITEM_DESTROY_AND_RESET(item); + status = argpar_iter_next(iter, &item, &error); + ok(status == ARGPAR_ITER_NEXT_STATUS_OK || + (status == ARGPAR_ITER_NEXT_STATUS_ERROR && + argpar_error_type(error) == expected_error_type), + "argpar_iter_next() returns the expected status and error type (%d) " + "for command line `%s` (call %u)", + expected_error_type, cmdline, i + 1); + + if (status != ARGPAR_ITER_NEXT_STATUS_OK) { + ok(!item, + "argpar_iter_next() doesn't set an item for other status than " + "`ARGPAR_ITER_NEXT_STATUS_OK` and command line `%s` (call %u)", + cmdline, i + 1); + ok(error, + "argpar_iter_next() sets an error for other status than " + "`ARGPAR_ITER_NEXT_STATUS_OK` and command line `%s` (call %u)", + cmdline, i + 1); + ok(argpar_error_orig_index(error) == expected_orig_index, + "argpar_iter_next() sets an error with the expected original argument index " + "for command line `%s` (call %u)", + cmdline, i + 1); + + if (argpar_error_type(error) == ARGPAR_ERROR_TYPE_UNKNOWN_OPT) { + ok(strcmp(argpar_error_unknown_opt_name(error), expected_unknown_opt_name) == 0, + "argpar_iter_next() sets an error with the expected unknown option name " + "for command line `%s` (call %u)", + cmdline, i + 1); + } else { + bool is_short; + + ok(argpar_error_opt_descr(error, &is_short) == &descrs[expected_opt_descr_index], + "argpar_iter_next() sets an error with the expected option descriptor " + "for command line `%s` (call %u)", + cmdline, i + 1); + ok(is_short == expected_is_short, + "argpar_iter_next() sets an error with the expected option type " + "for command line `%s` (call %u)", + cmdline, i + 1); + } + break; + } + + ok(item, + "argpar_iter_next() sets an item for status `ARGPAR_ITER_NEXT_STATUS_OK` " + "and command line `%s` (call %u)", + cmdline, i + 1); + ok(!error, + "argpar_iter_next() doesn't set an error for status `ARGPAR_ITER_NEXT_STATUS_OK` " + "and command line `%s` (call %u)", + cmdline, i + 1); + } + + /* ok(strcmp(expected_error, error) == 0, "argpar_iter_next() sets the expected error string " "for command line `%s`", cmdline); @@ -625,163 +457,97 @@ void test_fail(const char * const cmdline, } */ - argpar_item_destroy(item); - argpar_iter_destroy(iter); - argpar_error_destroy(error); - g_strfreev(argv); + argpar_item_destroy(item); + argpar_iter_destroy(iter); + argpar_error_destroy(error); + g_strfreev(argv); } -static -void fail_tests(void) +static void fail_tests(void) { + /* Unknown short option (space form) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'd', NULL, true}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Unknown short option (space form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'd', NULL, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "-d salut -e -d meow", - ARGPAR_ERROR_TYPE_UNKNOWN_OPT, - 2, "-e", 0, false, - descrs); - } + test_fail("-d salut -e -d meow", ARGPAR_ERROR_TYPE_UNKNOWN_OPT, 2, "-e", 0, false, descrs); + } - /* Unknown short option (glued form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'd', 0, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "-dsalut -e -d meow", - ARGPAR_ERROR_TYPE_UNKNOWN_OPT, - 1, "-e", 0, false, - descrs); - } + /* Unknown short option (glued form) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'd', 0, true}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Unknown long option (space form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "sink", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "--sink party --food --sink impulse", - ARGPAR_ERROR_TYPE_UNKNOWN_OPT, - 2, "--food", 0, false, - descrs); - } + test_fail("-dsalut -e -d meow", ARGPAR_ERROR_TYPE_UNKNOWN_OPT, 1, "-e", 0, false, descrs); + } - /* Unknown long option (equal form) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "sink", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "--sink=party --food --sink=impulse", - ARGPAR_ERROR_TYPE_UNKNOWN_OPT, - 1, "--food", 0, false, - descrs); - } + /* Unknown long option (space form) */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "sink", true}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Unknown option before non-option argument */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "thumb", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "--thumb=party --food=18 bateau --thumb waves", - ARGPAR_ERROR_TYPE_UNKNOWN_OPT, - 1, "--food", 0, false, - descrs); - } + test_fail("--sink party --food --sink impulse", ARGPAR_ERROR_TYPE_UNKNOWN_OPT, 2, "--food", + 0, false, descrs); + } - /* Unknown option after non-option argument */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "thumb", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "--thumb=party wound --food --thumb waves", - ARGPAR_ERROR_TYPE_UNKNOWN_OPT, - 2, "--food", 0, false, - descrs); - } + /* Unknown long option (equal form) */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "sink", true}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Missing long option argument */ - { - const argpar_opt_descr_t descrs[] = { - { 0, '\0', "thumb", true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "allo --thumb", - ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, - 1, NULL, 0, false, - descrs); - } + test_fail("--sink=party --food --sink=impulse", ARGPAR_ERROR_TYPE_UNKNOWN_OPT, 1, "--food", + 0, false, descrs); + } - /* Missing short option argument */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'k', NULL, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "zoom heille -k", - ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, - 2, NULL, 0, true, - descrs); - } + /* Unknown option before non-option argument */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "thumb", true}, ARGPAR_OPT_DESCR_SENTINEL}; - /* Missing short option argument (multiple glued) */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'a', NULL, false }, - { 0, 'b', NULL, false }, - { 0, 'c', NULL, true }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "-abc", - ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, - 0, NULL, 2, true, - descrs); - } + test_fail("--thumb=party --food=18 bateau --thumb waves", ARGPAR_ERROR_TYPE_UNKNOWN_OPT, 1, + "--food", 0, false, descrs); + } - /* Unexpected long option argument */ - { - const argpar_opt_descr_t descrs[] = { - { 0, 'c', "chevre", false }, - ARGPAR_OPT_DESCR_SENTINEL - }; - - test_fail( - "ambulance --chevre=fromage tar -cjv", - ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG, - 1, NULL, 0, false, - descrs); - } + /* Unknown option after non-option argument */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "thumb", true}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_fail("--thumb=party wound --food --thumb waves", ARGPAR_ERROR_TYPE_UNKNOWN_OPT, 2, + "--food", 0, false, descrs); + } + + /* Missing long option argument */ + { + const argpar_opt_descr_t descrs[] = {{0, '\0', "thumb", true}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_fail("allo --thumb", ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, 1, NULL, 0, false, descrs); + } + + /* Missing short option argument */ + { + const argpar_opt_descr_t descrs[] = {{0, 'k', NULL, true}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_fail("zoom heille -k", ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, 2, NULL, 0, true, descrs); + } + + /* Missing short option argument (multiple glued) */ + { + const argpar_opt_descr_t descrs[] = {{0, 'a', NULL, false}, + {0, 'b', NULL, false}, + {0, 'c', NULL, true}, + ARGPAR_OPT_DESCR_SENTINEL}; + + test_fail("-abc", ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, 0, NULL, 2, true, descrs); + } + + /* Unexpected long option argument */ + { + const argpar_opt_descr_t descrs[] = {{0, 'c', "chevre", false}, ARGPAR_OPT_DESCR_SENTINEL}; + + test_fail("ambulance --chevre=fromage tar -cjv", ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG, 1, + NULL, 0, false, descrs); + } } int main(void) { - plan_tests(309); - succeed_tests(); - fail_tests(); - return exit_status(); + plan_tests(309); + succeed_tests(); + fail_tests(); + return exit_status(); } -- 2.34.1