diff options
Diffstat (limited to '')
-rw-r--r-- | src/libargparser/argparser.c | 169 |
1 files changed, 149 insertions, 20 deletions
diff --git a/src/libargparser/argparser.c b/src/libargparser/argparser.c index d0aa957..415ae88 100644 --- a/src/libargparser/argparser.c +++ b/src/libargparser/argparser.c @@ -19,6 +19,137 @@ #include "argparser.h" +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + + +#define xfree(s) (free(s), s = NULL) + + +/** + * Initialise an argument parser + * + * @param parser The memory address of the parser to initialise + * @return Zero on success, -1 on error, `errno` will be set accordingly + */ +int args_initialise(args_parser_t* parser) +{ + parser->state->arguments = NULL; + parser->state->files = NULL; + parser->state->message = NULL; + parser->state->options = NULL; + parser->state->all_options = NULL; + parser->state->freequeue = NULL; + + parser->state->arguments_count = 0; + parser->state->unrecognised_count = 0; + parser->state->files_count = 0; + parser->state->options_count = 0; + parser->state->all_options_count = 0; + parser->state->freeptr = 0; + + parser->settings->linuxvt = getenv("TERM") ? !strcmp(getenv("TERM"), "linux") : 0; + parser->settings->alternative = 0; + parser->settings->stop_at_first_file = 0; + parser->settings->use_colours = AUTO; + parser->settings->program = NULL; + parser->settings->description = NULL; + parser->settings->usage = NULL; + parser->settings->longdescription = NULL; + parser->settings->error_out = stderr; + parser->settings->warning_out = stderr; + parser->settings->help_out = stderr; + parser->settings->abbreviations = args_standard_abbreviations; + + if ((parser->state->arguments = malloc(1 * sizeof(char*))) == NULL) goto fail; + if ((parser->state->files = malloc(1 * sizeof(char*))) == NULL) goto fail; + if ((parser->state->options = malloc(1 * sizeof(args_option_t))) == NULL) goto fail; + if ((parser->state->all_options = malloc(1 * sizeof(char*))) == NULL) goto fail; + if ((parser->state->freequeue = malloc(1 * sizeof(void*))) == NULL) goto fail; + + return 0; + fail: + xfree(parser->state->arguments); + xfree(parser->state->files); + xfree(parser->state->options); + xfree(parser->state->all_options); + xfree(parser->state->freequeue); + return -1; +} + + +/** + * Disposes of all resources, run this when you are done + * + * @param parser The parser + */ +void args_dispose(parser_t* parser) +{ + size_t i; + + parser->state->arguments_count = 0; + parser->state->unrecognised_count = 0; + parser->state->files_count = 0; + parser->state->all_options_count = 0; + + xfree(parser->settings->program); + xfree(parser->state->arguments); + xfree(parser->state->message); + xfree(parser->state->files); + for (i = 0; i < parser->state->options_count; i++) + free(parser->state->options[i].alternatives); + parser->state->options_count = 0; + xfree(parser->state->options); + xfree(parser->state->all_options); + xfree(parser->state->all_options_standard); + for (i = 0; i < parser->state->freeptr; i++) + free(parser->state->freequeue[i]); + parser->state->freeptr = 0; + xfree(parser->state->freequeue); +} + + +/** + * Checks the correctness of the number of used non-option arguments + * + * @param parser The parser + * @param min The minimum number of files + * @return Whether the usage was correct + */ +int args_test_files_min(args_parser_t* restrictparser, size_t min) +{ + return min <= parser->state->files_count; +} + + +/** + * Checks the correctness of the number of used non-option arguments + * + * @param parser The parser + * @param max The maximum number of files + * @return Whether the usage was correct + */ +int args_test_files_max(args_parser_t* parser, size_t max) +{ + return parser->state->files_count <= max; +} + + +/** + * Checks the correctness of the number of used non-option arguments + * + * @param parser The parser + * @param min The minimum number of files + * @param max The maximum number of files + * @return Whether the usage was correct + */ +int args_test_files(args_parser_t* parser, size_t min, size_t max) +{ + return (min <= parser->state->files_count) && (parser->state->files_count <= max); +} + /** * Dummy trigger @@ -77,7 +208,7 @@ int args_no_stickless(void* user_data, const char* value) int args_default_stickless(void* user_data, const char* argument) { (void) user_data; - return (*argument != '-') && (*argument != '+'); + return (argument[0] != '-') && (argument[0] != '+'); } @@ -99,28 +230,26 @@ int args_no_variadic_end(void* user_data, char* value) /** * The standard abbrevation expander * - * @param argument The option that not recognised - * @param options All recognised options - * @param count The number of elements in `options` - * @return The only possible expansion, otherwise `null` + * @param argument The option that not recognised + * @param options All recognised options + * @param standards The corresponding standard option for options in `options` + * @param count The number of elements in `options` and `standards` + * @return The only possible expansion, otherwise `NULL` */ -const char* args_standard_abbreviations(const char* argument, const char** options, size_t count) +const char* args_standard_abbreviations(const char* argument, const char** options, const char** standards, size_t count) { - const char* rc = null; + const char* found = NULL; size_t i; + for (i = 0; i < count; i++) - { - size_t match = 0; - const char* opt = *(options + i); - while (*(argument + match) && (*(opt + match) == *(argument + match))) - match++; - if (*(argument + match) == 0) - { - if (rc) - return null; - rc = opt; - } - } - return rc; + if (strstr(options[i], argument) == options[i]) + { + if (found == NULL) + found = standards[i]; + else + return NULL; + } + + return found; } |