/* * argsparse.h * * Copyright 2026 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * */ #if (!defined(__LIB_argsparse_H_)) #define __LIB_argsparse_H_ #define ArgsGetSimpleFlags() simple_flags #define ArgsGetNamesVals() names_vals #define ArgsGetNamesFlags() names_flags #define ArgsGetDefault() default_arg #define ArgsGetSimpleSize() simple_size #define ArgsGetNamesSize() names_size #define ArgsGetSimpleNumbers() options_numbers_simple #define ArgsGetNamesNumbers() options_numbers_names typedef struct { char** simple_flags; char** names_vals; char** names_flags; char* default_arg; size_t* options_numbers_simple; size_t* options_numbers_names; size_t simple_size; size_t names_size; } __args_parse_t; int _lib_argparse_emulated_main(__args_parse_t* arg_list_named); __args_parse_t __sfdgssg_parse_result; #define arg_property_t char* /* Simulate array type */ #define args_config_t #define args_config_size_t (size_t) /* Macro for parsing the arguments of the main function */ #define __arglist(arg_list_named, conf, size) { \ __sfdgssg_parse_result.ArgsGetDefault() = NULL; \ __sfdgssg_parse_result.ArgsGetSimpleNumbers() = NULL; \ __sfdgssg_parse_result.ArgsGetNamesNumbers() = NULL; \ _lib_argsparse_main(__argc__, __argv__, (conf), (size)); \ int stat = _lib_argparse_emulated_main( \ &__sfdgssg_parse_result); \ size_t __flags = __conf_flags_size((conf), (size)); \ __free_string_array( \ __sfdgssg_parse_result.ArgsGetSimpleFlags(), \ __flags); \ __free_string_array( \ __sfdgssg_parse_result.ArgsGetNamesFlags(), \ (size) - __flags); \ __free_string_array( \ __sfdgssg_parse_result.ArgsGetNamesVals(), \ (size) - __flags); \ free(__sfdgssg_parse_result.ArgsGetDefault()); \ free(__sfdgssg_parse_result.ArgsGetSimpleNumbers()); \ free(__sfdgssg_parse_result.ArgsGetNamesNumbers()); \ return stat; \ } \ int _lib_argparse_emulated_main(__args_parse_t* arg_list_named) /* Data type instead of argc and argv in the main function */ #define args_t int __argc__, char** __argv__) __arglist( #include #include #include size_t __conf_flags_size(char** conf, size_t size) { unsigned int d = 0; size_t s = 0; while (d < size) { if (strchr(conf[d], '=') == NULL) { s ++; } d ++; } return s; } void __free_string_array(char** arr, size_t size) { unsigned int d = 0; while (d < size) { free(arr[d]); d ++; } free(arr); } static void* __sized_malloc(size_t size) { void* ptr = malloc(size); memset(ptr, ((int)(unsigned long)NULL), size); return ptr; } static unsigned char __compile_and_equals_sflag(char* flags, char* str) { if (strlen(str) > strlen(flags)) return 0; size_t i = 0; size_t slashes = 0; while (i < strlen(flags)) { if (flags[i] == '/') { slashes ++; } i ++; } i = 0; size_t f = 0; while (f < (slashes + 1)) { char st[32]; size_t d = i; char* slt = &flags[i]; while (flags[d] != '/' && flags[d] != '=' && flags[d] != '\0') { d ++; } strncpy(st, slt, d - i); st[d - i] = '\0'; i = d + 1; f ++; if (strncmp(st, str, strlen(st)) == 0) { return 1; } } return 0; } static void* malloc_str(char* str) { char* ptr = malloc((strlen(str)) * sizeof(char) + sizeof(char)); strcpy(ptr, str); return ptr; } int _lib_argsparse_main(int argc, char** argv, char** config, size_t size) { int i = 1; size_t flags = __conf_flags_size(config, size); __sfdgssg_parse_result.ArgsGetSimpleFlags() = __sized_malloc((flags) * sizeof(char**)); __sfdgssg_parse_result.ArgsGetNamesFlags() = __sized_malloc((size - flags) * sizeof(char**)); __sfdgssg_parse_result.ArgsGetNamesVals() = __sized_malloc((size - flags) * sizeof(char**)); __sfdgssg_parse_result.ArgsGetNamesNumbers() = __sized_malloc((size - flags) * sizeof(size_t)); __sfdgssg_parse_result.ArgsGetSimpleNumbers() = __sized_malloc((flags) * sizeof(size_t)); __args_parse_t* out = &__sfdgssg_parse_result; size_t simple_flags_count = 0; size_t names_flags_count = 0; unsigned char named_flag = 0; while (i < argc) { char* str = argv[i]; if (named_flag == 1) { out->ArgsGetNamesVals()[names_flags_count] = malloc_str(str); named_flag = 0; names_flags_count ++; i ++; continue; } unsigned int d = 0; while (d < size) { if (__compile_and_equals_sflag(config[d], str)) { if (strchr(config[d], '=') == NULL) { out->ArgsGetSimpleFlags()[simple_flags_count] = malloc_str(str); out->ArgsGetSimpleNumbers()[simple_flags_count] = d; simple_flags_count ++; } else { out->ArgsGetNamesFlags()[names_flags_count] = malloc_str(str); out->ArgsGetNamesNumbers()[names_flags_count] = d; named_flag = 1; } } else { free(out->ArgsGetDefault()); out->ArgsGetDefault() = malloc_str(str); } d ++; } i ++; } out->simple_size = simple_flags_count; out->names_size = names_flags_count; return EXIT_SUCCESS; } #endif /* __LIB_argsparse_H_ */