From 7b2acabfd690857e64f90b86998be3ee1430ce70 Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Tue, 30 Sep 2025 10:06:53 +0800 Subject: [PATCH 1/6] =?UTF-8?q?style:=20=E7=BB=9F=E4=B8=80=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F=E5=92=8C=E5=91=BD=E5=90=8D=E8=A7=84?= =?UTF-8?q?=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/ArgParse.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/include/ArgParse.h b/include/ArgParse.h index ed195d5..767aa26 100644 --- a/include/ArgParse.h +++ b/include/ArgParse.h @@ -7,14 +7,12 @@ extern "C" { #endif - #ifdef _MSC_VER - #define NORETURN __declspec(noreturn) +#define NORETURN __declspec(noreturn) #else - #define NORETURN _Noreturn +#define NORETURN _Noreturn #endif - #define ARG_DEFAULT_HELP_FLAG "--help" typedef struct ArgParse ArgParse; // 解析器 @@ -24,10 +22,10 @@ typedef int (*ArgParseCallback)(ArgParse *argParse, int val_len); // 回调函数 typedef enum { - NOVALUE = 0, // 无值 - SINGLEVALUE, // 单值 例如: -i https://www.baidu.com - MULTIVALUE, // 多值 例如: -s a b c 或 -s a -s b -s c等 -} ArgParseValueType; // 值类型 + ArgParseNOVALUE = 0, // 无值 + ArgParseSINGLEVALUE, // 单值 例如: -i https://www.baidu.com + ArgParseMULTIVALUE, // 多值 例如: -s a b c 或 -s a -s b -s c等 +} ArgParseValueType; // 值类型 typedef struct CommandArgs { /* 构造属性 */ @@ -77,7 +75,7 @@ typedef struct ArgParse { struct CommandArgs **global_args; // 全局参数 int global_args_len; // 全局参数个数 char *documentation; // 帮助文档 - ArgParseValueType value_type; // 值类型 程序默认需要的值例如 gcc main.c + ArgParseValueType value_type; // 值类型 程序默认需要的值例如 gcc main.c /* 解析所用到的属性*/ struct Command *current_command; // 当前解析到的命令 @@ -312,9 +310,9 @@ char * argParseGenerateArgErrorMsg(ArgParse *argParse, char *name, bool short_flag); NORETURN void argParseError(ArgParse *argParse, - Command *lastCommand, - const char *prefix, - const char *suffix); + Command *lastCommand, + const char *prefix, + const char *suffix); #ifdef __cplusplus } From 56a50201fe58535313612b6c4ca5d296b9dd78eb Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Tue, 30 Sep 2025 10:10:41 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E5=80=BC=E5=91=BD=E5=90=8D=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- examples/simple.c | 6 +++--- src/ArgParse.c | 22 +++++++++++----------- src/ArgParseTools.c | 18 +++++++++--------- tests/initArgParse.h | 26 +++++++++++++------------- tests/test_val.c | 26 +++++++++++++------------- 6 files changed, 52 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 9e4a2a9..cad0d32 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,11 @@ conan create . #include ArgParse *Init() { - ArgParse *ap = argParseInit("简单的命令行工具示例",NOVALUE); + ArgParse *ap = argParseInit("简单的命令行工具示例",ArgParseNOVALUE); // 添加第一个命令 Command *cmd = argParseAddCommand( - ap, "list", "列出文件列表", NULL, NULL, NULL, SINGLEVALUE); + ap, "list", "列出文件列表", NULL, NULL, NULL, ArgParseSINGLEVALUE); // 添加第一个命令的参数 argParseAddArg(cmd, @@ -56,7 +56,7 @@ ArgParse *Init() { NULL, NULL, false, - NOVALUE); + ArgParseNOVALUE); return ap; } diff --git a/examples/simple.c b/examples/simple.c index ad6d7f9..93a85ca 100644 --- a/examples/simple.c +++ b/examples/simple.c @@ -4,11 +4,11 @@ #include ArgParse *Init() { - ArgParse *ap = argParseInit("简单的命令行工具示例",NOVALUE); + ArgParse *ap = argParseInit("简单的命令行工具示例",ArgParseNOVALUE); // 添加第一个命令 Command *cmd = argParseAddCommand( - ap, "list", "列出文件列表", NULL, NULL, NULL, SINGLEVALUE); + ap, "list", "列出文件列表", NULL, NULL, NULL, ArgParseSINGLEVALUE); // 添加第一个命令的参数 argParseAddArg(cmd, @@ -18,7 +18,7 @@ ArgParse *Init() { NULL, NULL, false, - NOVALUE); + ArgParseNOVALUE); return ap; } diff --git a/src/ArgParse.c b/src/ArgParse.c index f7a71d5..8d5f60d 100644 --- a/src/ArgParse.c +++ b/src/ArgParse.c @@ -67,7 +67,7 @@ void argParseAutoHelp(ArgParse *argParse) { NULL, __helpCallback, false, - NOVALUE); + ArgParseNOVALUE); } int __commandHelpCallback(ArgParse *argParse, char **val, int val_len) { @@ -96,7 +96,7 @@ void argParseCommandAutoHelp(Command *command) { NULL, __commandHelpCallback, false, - NOVALUE); + ArgParseNOVALUE); } Command *argParseAddCommand(ArgParse *argParse, @@ -314,7 +314,7 @@ int __processArgs(ArgParse *argParse, CommandArgs *arg, int arg_index) { int current_index = arg_index; - if (arg->value_type == MULTIVALUE) { + if (arg->value_type == ArgParseMULTIVALUE) { for (int i = arg_index + 1; i < argParse->argc; i++) { if (checkArgType(argParse->argv[i]) == COMMAND) { // COMMAND是无--或-开头的字符串,也可认定为参数值 @@ -325,12 +325,12 @@ int __processArgs(ArgParse *argParse, CommandArgs *arg, int arg_index) { break; } } - } else if (arg->value_type == SINGLEVALUE) { + } else if (arg->value_type == ArgParseSINGLEVALUE) { if (arg_index + 1 < argParse->argc) { argParseSetArgVal(arg, argParse->argv[arg_index + 1]); current_index = arg_index + 1; } - } else if (arg->value_type == NOVALUE) { + } else if (arg->value_type == ArgParseNOVALUE) { current_index = arg_index; } @@ -437,7 +437,7 @@ int __processCommand(ArgParse *argParse, char *name, int command_index) { command = argParseFindCommand(argParse, name); // 查找命令 - if (command == NULL && argParse->value_type == NOVALUE) { + if (command == NULL && argParse->value_type == ArgParseNOVALUE) { char *msg = NULL; if (name != NULL) { msg = stringNewCopy("\033[1;31mERROR\033[0m:"); @@ -449,7 +449,7 @@ int __processCommand(ArgParse *argParse, char *name, int command_index) { return -1; } - if (command == NULL && argParse->value_type != NOVALUE) { + if (command == NULL && argParse->value_type != ArgParseNOVALUE) { return __processVal(argParse, command_index); } @@ -463,7 +463,7 @@ int __processCommand(ArgParse *argParse, char *name, int command_index) { switch (argType) { case COMMAND: { // 命令无值则处理子命令 - if (command->value_type == NOVALUE) { + if (command->value_type == ArgParseNOVALUE) { __processSubCommand(argParse, command, argParse->argv[i], i); return argParse->argc - 1; } else { @@ -751,12 +751,12 @@ char *argParseGenerateHelpForCommand(Command *command) { __catStr(&help_msg, 2, "\033[1;33mUsage\033[0m: ", command->name); switch (command->value_type) { - case NOVALUE: + case ArgParseNOVALUE: break; - case SINGLEVALUE: + case ArgParseSINGLEVALUE: __catStr(&help_msg, 1, " "); break; - case MULTIVALUE: + case ArgParseMULTIVALUE: __catStr(&help_msg, 1, " ..."); } diff --git a/src/ArgParseTools.c b/src/ArgParseTools.c index 159f0bb..e6fcb86 100644 --- a/src/ArgParseTools.c +++ b/src/ArgParseTools.c @@ -179,7 +179,7 @@ argParseFindGlobalArgs(ArgParse *argParse, char *name, bool short_flag) { * @return 成功返回true,失败返回false */ bool argParseSetArgVal(CommandArgs *args, char *val) { - if (args->value_type == MULTIVALUE) { // 多值 + if (args->value_type == ArgParseMULTIVALUE) { // 多值 args->val = realloc(args->val, (args->val_len + 1) * sizeof(char *)); if (args->val == NULL) { return false; @@ -190,7 +190,7 @@ bool argParseSetArgVal(CommandArgs *args, char *val) { } args->val_len++; return true; - } else if (args->value_type == SINGLEVALUE) { // 单值 + } else if (args->value_type == ArgParseSINGLEVALUE) { // 单值 if (args->val != NULL) { free(args->val); } @@ -205,7 +205,7 @@ bool argParseSetArgVal(CommandArgs *args, char *val) { } args->val_len = 1; return true; - } else if (args->value_type == NOVALUE) { // 无值 + } else if (args->value_type == ArgParseNOVALUE) { // 无值 return true; } @@ -213,7 +213,7 @@ bool argParseSetArgVal(CommandArgs *args, char *val) { } bool argParseSetCommandVal(Command *command, char *val) { - if (command->value_type == MULTIVALUE) { // 多值 + if (command->value_type == ArgParseMULTIVALUE) { // 多值 command->val = realloc(command->val, (command->val_len + 1) * sizeof(char *)); if (command->val == NULL) { @@ -225,7 +225,7 @@ bool argParseSetCommandVal(Command *command, char *val) { } command->val_len++; return true; - } else if (command->value_type == SINGLEVALUE) { // 单值 + } else if (command->value_type == ArgParseSINGLEVALUE) { // 单值 if (command->val != NULL) { free(command->val); } @@ -240,7 +240,7 @@ bool argParseSetCommandVal(Command *command, char *val) { } command->val_len = 1; return true; - } else if (command->value_type == NOVALUE) { // 无值 + } else if (command->value_type == ArgParseNOVALUE) { // 无值 return true; } return false; @@ -254,7 +254,7 @@ bool argParseSetCommandVal(Command *command, char *val) { */ bool argParseSetVal(ArgParse *argParse, char *val) { - if (argParse->value_type == MULTIVALUE) { // 多值 + if (argParse->value_type == ArgParseMULTIVALUE) { // 多值 argParse->val = realloc(argParse->val, (argParse->val_len + 1) * sizeof(char *)); if (argParse->val == NULL) { @@ -266,7 +266,7 @@ bool argParseSetVal(ArgParse *argParse, char *val) { } argParse->val_len++; return true; - } else if (argParse->value_type == SINGLEVALUE) { // 单值 + } else if (argParse->value_type == ArgParseSINGLEVALUE) { // 单值 if (argParse->val != NULL) { free(argParse->val); } @@ -281,7 +281,7 @@ bool argParseSetVal(ArgParse *argParse, char *val) { } argParse->val_len = 1; return true; - } else if (argParse->value_type == NOVALUE) { // 无值 + } else if (argParse->value_type == ArgParseNOVALUE) { // 无值 return true; } return false; diff --git a/tests/initArgParse.h b/tests/initArgParse.h index 0561878..d3379fb 100644 --- a/tests/initArgParse.h +++ b/tests/initArgParse.h @@ -4,7 +4,7 @@ #include ArgParse *initArgParse() { - ArgParse *argparse = argParseInit("测试程序",NOVALUE); + ArgParse *argparse = argParseInit("测试程序",ArgParseNOVALUE); Command *command = NULL; Command *sub_command = NULL; @@ -16,13 +16,13 @@ ArgParse *initArgParse() { NULL, NULL, false, - NOVALUE); + ArgParseNOVALUE); argParseAddGlobalArg( - argparse, "-q", "--quiet", "Quiet mode", NULL, NULL, false, NOVALUE); + argparse, "-q", "--quiet", "Quiet mode", NULL, NULL, false, ArgParseNOVALUE); // add arguments command = argParseAddCommand( - argparse, "install", "Install the package", NULL, NULL, NULL, NOVALUE); + argparse, "install", "Install the package", NULL, NULL, NULL, ArgParseNOVALUE); argParseAddArg(command, "-i", "--index", @@ -30,7 +30,7 @@ ArgParse *initArgParse() { "https://example.com", NULL, false, - SINGLEVALUE); + ArgParseSINGLEVALUE); argParseAddArg(command, "-f", "--file", @@ -38,7 +38,7 @@ ArgParse *initArgParse() { "package.json", NULL, false, - MULTIVALUE); + ArgParseMULTIVALUE); argParseAddArg(command, "-p", "--package", @@ -46,10 +46,10 @@ ArgParse *initArgParse() { "package.json", NULL, false, - MULTIVALUE); + ArgParseMULTIVALUE); sub_command = argParseAddSubCommand( - command, "tools", "Install tools", NULL, NULL, NULL, MULTIVALUE); + command, "tools", "Install tools", NULL, NULL, NULL, ArgParseMULTIVALUE); argParseAddArg(sub_command, "-t", @@ -58,9 +58,9 @@ ArgParse *initArgParse() { "Tool name", NULL, true, - MULTIVALUE); + ArgParseMULTIVALUE); sub_command = argParseAddSubCommand( - command, "tools_sub", "Install tools", NULL, NULL, NULL, MULTIVALUE); + command, "tools_sub", "Install tools", NULL, NULL, NULL, ArgParseMULTIVALUE); argParseAddArg(sub_command, "-s", @@ -69,7 +69,7 @@ ArgParse *initArgParse() { "tools subcommand test", NULL, true, - MULTIVALUE); + ArgParseMULTIVALUE); command = argParseAddCommand(argparse, "uninstall", @@ -77,7 +77,7 @@ ArgParse *initArgParse() { NULL, NULL, NULL, - SINGLEVALUE); + ArgParseSINGLEVALUE); argParseAddArg(command, "-p", "--package", @@ -85,7 +85,7 @@ ArgParse *initArgParse() { "Package name", NULL, true, - MULTIVALUE); + ArgParseMULTIVALUE); return argparse; } \ No newline at end of file diff --git a/tests/test_val.c b/tests/test_val.c index 17fbc05..eb4ca4b 100644 --- a/tests/test_val.c +++ b/tests/test_val.c @@ -5,7 +5,7 @@ #include ArgParse *initArgParse() { - ArgParse *argparse = argParseInit("测试程序", MULTIVALUE); + ArgParse *argparse = argParseInit("测试程序", ArgParseMULTIVALUE); Command *command = NULL; Command *sub_command = NULL; @@ -17,13 +17,13 @@ ArgParse *initArgParse() { NULL, NULL, false, - NOVALUE); + ArgParseNOVALUE); argParseAddGlobalArg( - argparse, "-q", "--quiet", "Quiet mode", NULL, NULL, false, NOVALUE); + argparse, "-q", "--quiet", "Quiet mode", NULL, NULL, false, ArgParseNOVALUE); // add arguments command = argParseAddCommand( - argparse, "install", "Install the package", NULL, NULL, NULL, NOVALUE); + argparse, "install", "Install the package", NULL, NULL, NULL, ArgParseNOVALUE); argParseAddArg(command, "-i", "--index", @@ -31,7 +31,7 @@ ArgParse *initArgParse() { "https://example.com", NULL, false, - SINGLEVALUE); + ArgParseSINGLEVALUE); argParseAddArg(command, "-f", "--file", @@ -39,7 +39,7 @@ ArgParse *initArgParse() { "package.json", NULL, false, - MULTIVALUE); + ArgParseMULTIVALUE); argParseAddArg(command, "-p", "--package", @@ -47,10 +47,10 @@ ArgParse *initArgParse() { "package.json", NULL, false, - MULTIVALUE); + ArgParseMULTIVALUE); sub_command = argParseAddSubCommand( - command, "tools", "Install tools", NULL, NULL, NULL, MULTIVALUE); + command, "tools", "Install tools", NULL, NULL, NULL, ArgParseMULTIVALUE); argParseAddArg(sub_command, "-t", @@ -59,9 +59,9 @@ ArgParse *initArgParse() { "Tool name", NULL, true, - MULTIVALUE); + ArgParseMULTIVALUE); sub_command = argParseAddSubCommand( - command, "tools_sub", "Install tools", NULL, NULL, NULL, MULTIVALUE); + command, "tools_sub", "Install tools", NULL, NULL, NULL, ArgParseMULTIVALUE); argParseAddArg(sub_command, "-s", @@ -70,7 +70,7 @@ ArgParse *initArgParse() { "tools subcommand test", NULL, true, - MULTIVALUE); + ArgParseMULTIVALUE); command = argParseAddCommand(argparse, "uninstall", @@ -78,7 +78,7 @@ ArgParse *initArgParse() { NULL, NULL, NULL, - SINGLEVALUE); + ArgParseSINGLEVALUE); argParseAddArg(command, "-p", "--package", @@ -86,7 +86,7 @@ ArgParse *initArgParse() { "Package name", NULL, true, - MULTIVALUE); + ArgParseMULTIVALUE); return argparse; } From 0a7179380a341f849f51ccfde5019d22f9e2be1f Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Tue, 30 Sep 2025 10:16:42 +0800 Subject: [PATCH 3/6] =?UTF-8?q?style:=20=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AF=B9=E9=BD=90=E5=92=8C=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ArgParse.c | 6 +++--- tests/initArgParse.h | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/ArgParse.c b/src/ArgParse.c index 8d5f60d..0839806 100644 --- a/src/ArgParse.c +++ b/src/ArgParse.c @@ -819,9 +819,9 @@ bool argParseCheckCommandTriggered(ArgParse *argParse, char *command_name) { } NORETURN void argParseError(ArgParse *argParse, - Command *lastCommand, - const char *prefix, - const char *suffix) { + Command *lastCommand, + const char *prefix, + const char *suffix) { if (argParse == NULL) { printf("ERROR: Parse is NULL\n"); exit(1); diff --git a/tests/initArgParse.h b/tests/initArgParse.h index d3379fb..119f530 100644 --- a/tests/initArgParse.h +++ b/tests/initArgParse.h @@ -4,7 +4,7 @@ #include ArgParse *initArgParse() { - ArgParse *argparse = argParseInit("测试程序",ArgParseNOVALUE); + ArgParse *argparse = argParseInit("测试程序", ArgParseNOVALUE); Command *command = NULL; Command *sub_command = NULL; @@ -17,12 +17,23 @@ ArgParse *initArgParse() { NULL, false, ArgParseNOVALUE); - argParseAddGlobalArg( - argparse, "-q", "--quiet", "Quiet mode", NULL, NULL, false, ArgParseNOVALUE); + argParseAddGlobalArg(argparse, + "-q", + "--quiet", + "Quiet mode", + NULL, + NULL, + false, + ArgParseNOVALUE); // add arguments - command = argParseAddCommand( - argparse, "install", "Install the package", NULL, NULL, NULL, ArgParseNOVALUE); + command = argParseAddCommand(argparse, + "install", + "Install the package", + NULL, + NULL, + NULL, + ArgParseNOVALUE); argParseAddArg(command, "-i", "--index", @@ -48,8 +59,13 @@ ArgParse *initArgParse() { false, ArgParseMULTIVALUE); - sub_command = argParseAddSubCommand( - command, "tools", "Install tools", NULL, NULL, NULL, ArgParseMULTIVALUE); + sub_command = argParseAddSubCommand(command, + "tools", + "Install tools", + NULL, + NULL, + NULL, + ArgParseMULTIVALUE); argParseAddArg(sub_command, "-t", @@ -59,8 +75,13 @@ ArgParse *initArgParse() { NULL, true, ArgParseMULTIVALUE); - sub_command = argParseAddSubCommand( - command, "tools_sub", "Install tools", NULL, NULL, NULL, ArgParseMULTIVALUE); + sub_command = argParseAddSubCommand(command, + "tools_sub", + "Install tools", + NULL, + NULL, + NULL, + ArgParseMULTIVALUE); argParseAddArg(sub_command, "-s", From 1345a0514e927310f69a547977225eb1d75c1cfe Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Tue, 30 Sep 2025 11:20:33 +0800 Subject: [PATCH 4/6] =?UTF-8?q?style:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F=E5=92=8C=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ArgParseTools.h | 14 ++++++------- tests/CMakeLists.txt | 7 ++++++- tests/test_mult_arg.c | 14 +++++-------- tests/test_single_arg.c | 6 +++--- tests/test_subcommand.c | 3 +-- tests/test_unknow_command.c | 1 - tests/test_val.c | 41 ++++++++++++++++++++++++++++--------- 7 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/ArgParseTools.h b/src/ArgParseTools.h index df1bcde..82e0837 100644 --- a/src/ArgParseTools.h +++ b/src/ArgParseTools.h @@ -26,14 +26,14 @@ Command *createCommand(char *name, CommandGroup *createCommandGroup(char *name, char *help); // 创建命令组 CommandGroup *addCommandToGroup(CommandGroup *group, - Command *command); // 添加命令到命令组 + Command *command); // 添加命令到命令组 -CommandArgs *createCommandArgs(char *short_opt, - char *long_opt, - char *default_val, - char *help, - ArgParseCallback callback, - bool required, +CommandArgs *createCommandArgs(char *short_opt, + char *long_opt, + char *default_val, + char *help, + ArgParseCallback callback, + bool required, ArgParseValueType value_type); // 创建命令参数 /** diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5d87e04..db66b41 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -36,4 +36,9 @@ set_tests_properties(${PROJECT_NAME}unknow_command_arg PROPERTIES WILL_FAIL TRUE # 未知命令选项测试,预期打印该命令的帮助信息 add_executable(${PROJECT_NAME}val test_val.c) target_link_libraries(${PROJECT_NAME}val CArgParse) -add_test(${PROJECT_NAME}val ${PROJECT_NAME}val file1.txt file2.txt file3.txt -v -q) \ No newline at end of file +add_test(${PROJECT_NAME}val ${PROJECT_NAME}val file1.txt file2.txt file3.txt -v -q) + +# 未知命令选项测试,预期打印该命令的帮助信息 +add_executable(${PROJECT_NAME}required test_required.c) +target_link_libraries(${PROJECT_NAME}required CArgParse) +add_test(${PROJECT_NAME}required ${PROJECT_NAME}required file1.txt file2.txt file3.txt -v -f d) \ No newline at end of file diff --git a/tests/test_mult_arg.c b/tests/test_mult_arg.c index d521abb..6b1cfdf 100644 --- a/tests/test_mult_arg.c +++ b/tests/test_mult_arg.c @@ -10,12 +10,11 @@ int main(int argc, char *argv[]) { const char *testv[3] = {"testpackge1", "testpackge2", "testpackge3"}; - // Test -p - char *val = argParseGetCurArg(argparse, "-p"); + char *val = argParseGetCurArg(argparse, "-p"); - int len = 0; - char **vals = argParseGetCurArgList(argparse, "-p", &len); + int len = 0; + char **vals = argParseGetCurArgList(argparse, "-p", &len); for (int i = 0; i < len; i++) { printf("-p Value: %s\n", vals[i]); @@ -27,18 +26,15 @@ int main(int argc, char *argv[]) { printf("-i Value: %s\n", val_i); assert(strcmp(val_i, "www.test.com") == 0); - - // Test -f - len = 0; + len = 0; const char *testf[2] = {"file1.txt", "file2.txt"}; - char **val_f = argParseGetCurArgList(argparse, "-f", &len); + char **val_f = argParseGetCurArgList(argparse, "-f", &len); for (int i = 0; i < len; i++) { printf("-f Value: %s\n", val_f[i]); assert(strcmp(val_f[i], testf[i]) == 0); } - argParseFree(argparse); return 0; diff --git a/tests/test_single_arg.c b/tests/test_single_arg.c index b99f859..144b414 100644 --- a/tests/test_single_arg.c +++ b/tests/test_single_arg.c @@ -10,10 +10,10 @@ int main(int argc, char *argv[]) { const char *testv[3] = {"testpackge1", "testpackge2", "testpackge3"}; - char *val = argParseGetCurArg(argparse, "-p"); + char *val = argParseGetCurArg(argparse, "-p"); - int len = 0; - char **vals = argParseGetCurArgList(argparse, "-p", &len); + int len = 0; + char **vals = argParseGetCurArgList(argparse, "-p", &len); for (int i = 0; i < len; i++) { printf("-p Value: %s\n", vals[i]); diff --git a/tests/test_subcommand.c b/tests/test_subcommand.c index 7b877cd..6893111 100644 --- a/tests/test_subcommand.c +++ b/tests/test_subcommand.c @@ -8,12 +8,11 @@ int main(int argc, char *argv[]) { argParseParse(argparse, argc, argv); - char *command_name = argParseGetCurCommandName(argparse); printf("command name: %s\n", command_name); assert(strcmp(command_name, "tools") == 0); - char * val = argParseGetCurArg(argparse, "-t"); + char *val = argParseGetCurArg(argparse, "-t"); printf("tools -t: %s\n", val); argParseFree(argparse); diff --git a/tests/test_unknow_command.c b/tests/test_unknow_command.c index 98da073..4a30c85 100644 --- a/tests/test_unknow_command.c +++ b/tests/test_unknow_command.c @@ -7,7 +7,6 @@ int main(int argc, char *argv[]) { argParseParse(argparse, argc, argv); - argParseFree(argparse); return 0; diff --git a/tests/test_val.c b/tests/test_val.c index eb4ca4b..9a2a78f 100644 --- a/tests/test_val.c +++ b/tests/test_val.c @@ -18,12 +18,23 @@ ArgParse *initArgParse() { NULL, false, ArgParseNOVALUE); - argParseAddGlobalArg( - argparse, "-q", "--quiet", "Quiet mode", NULL, NULL, false, ArgParseNOVALUE); + argParseAddGlobalArg(argparse, + "-q", + "--quiet", + "Quiet mode", + NULL, + NULL, + false, + ArgParseNOVALUE); // add arguments - command = argParseAddCommand( - argparse, "install", "Install the package", NULL, NULL, NULL, ArgParseNOVALUE); + command = argParseAddCommand(argparse, + "install", + "Install the package", + NULL, + NULL, + NULL, + ArgParseNOVALUE); argParseAddArg(command, "-i", "--index", @@ -49,8 +60,13 @@ ArgParse *initArgParse() { false, ArgParseMULTIVALUE); - sub_command = argParseAddSubCommand( - command, "tools", "Install tools", NULL, NULL, NULL, ArgParseMULTIVALUE); + sub_command = argParseAddSubCommand(command, + "tools", + "Install tools", + NULL, + NULL, + NULL, + ArgParseMULTIVALUE); argParseAddArg(sub_command, "-t", @@ -60,8 +76,13 @@ ArgParse *initArgParse() { NULL, true, ArgParseMULTIVALUE); - sub_command = argParseAddSubCommand( - command, "tools_sub", "Install tools", NULL, NULL, NULL, ArgParseMULTIVALUE); + sub_command = argParseAddSubCommand(command, + "tools_sub", + "Install tools", + NULL, + NULL, + NULL, + ArgParseMULTIVALUE); argParseAddArg(sub_command, "-s", @@ -101,8 +122,8 @@ int main(int argc, char *argv[]) { printf("val: %s\n", val); } - int len = 0; - char **vals = argParseGetValList(argparse, &len); + int len = 0; + char **vals = argParseGetValList(argparse, &len); char *test_val[3] = {"file1.txt", "file2.txt", "file3.txt"}; From 85a219126d0e6c5449a5d1a79d7e3a2b6180fd73 Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Tue, 30 Sep 2025 13:35:19 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BF=85=E5=A1=AB?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E6=9C=AA=E5=81=9A=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ArgParse.c | 58 +++++++++++++++-- tests/CMakeLists.txt | 8 ++- tests/test_required.c | 144 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+), 6 deletions(-) create mode 100644 tests/test_required.c diff --git a/src/ArgParse.c b/src/ArgParse.c index 0839806..7367d98 100644 --- a/src/ArgParse.c +++ b/src/ArgParse.c @@ -7,6 +7,10 @@ #include #include +#define RED "\033[0;31m" +#define BLUE "\033[0;34m" +#define RESET "\033[0m" + static bool _AutoHelp = true; // 是否自动添加帮助信息 static bool _COLOR = true; // 是否启用颜色 @@ -37,15 +41,20 @@ ArgParse *argParseInit(char *documentation, ArgParseValueType value_type) { /** * @brief 自动帮助信息回调函数 + * @param argParse ArgParse结构体指针 + * @param val 参数值 + * @param val_len 参数值长度 + * @return 无返回值,将直接结束程序 */ -int __helpCallback(ArgParse *argParse, char **val, int val_len) { +NORETURN int __helpCallback(ArgParse *argParse, char **val, int val_len) { if (argParse == NULL) { - return -1; + exit(1); } char *help_doc = argParseGenerateHelp(argParse); printf("%s\n", help_doc); free(help_doc); - return 0; + argParseFree(argParse); + exit(0); } /** @@ -523,6 +532,7 @@ int __processCommand(ArgParse *argParse, char *name, int command_index) { /** * @brief 解析命令行参数 + * @errors: 错误信息字符串统一又调用方申请,处理函数释放 * @param argParse 解析器指针 * @param argc 参数个数 * @param argv 参数列表 @@ -574,6 +584,47 @@ void argParseParse(ArgParse *argParse, int argc, char *argv[]) { argParse->current_command->val, argParse->current_command->val_len); } + + // 检查全局参数必填参数是否已设置 + for (int i = 0; i < argParse->global_args_len; i++) { + if (argParse->global_args[i]->required && + argParse->global_args[i]->is_trigged == false) { + // 错误处理,必填全局参数未设置 + char *msg = + stringNewCopy(RED "ERROR" RESET ": Global Option " BLUE); + if (argParse->global_args[i]->short_opt != NULL) { + __catStr(&msg, 1, argParse->global_args[i]->short_opt); + } else { + __catStr(&msg, 1, argParse->global_args[i]->long_opt); + } + __catStr(&msg, 1, RESET " is required"); + argParseError(argParse, NULL, msg, + NULL); // 错误处理 + } + } + + // 检查当前命令的必填参数是否已设置 + if (argParse->current_command != NULL) { + for (int i = 0; i < argParse->current_command->args_len; i++) { + if (argParse->current_command->args[i]->required && + argParse->current_command->args[i]->is_trigged == false) { + // 错误处理,必填参数未设置 + char *msg = stringNewCopy(RED "ERROR" RESET ": Command " BLUE); + __catStr(&msg, 1, argParse->current_command->name); + __catStr(&msg, 1, RESET " Option " BLUE); + if (argParse->current_command->args[i]->short_opt != NULL) { + __catStr( + &msg, 1, argParse->current_command->args[i]->short_opt); + } else { + __catStr( + &msg, 1, argParse->current_command->args[i]->long_opt); + } + __catStr(&msg, 1, RESET " is required"); + argParseError( + argParse, argParse->current_command, msg, NULL); // 错误处理 + } + } + } } /** @@ -841,7 +892,6 @@ NORETURN void argParseError(ArgParse *argParse, __catStr(&mgs, 2, "\n", suffix); } - // printf("\033[1;31mERROR\033[0m: Last command is unknown\n"); printf("%s\n", mgs); free(mgs); free(help); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index db66b41..6075c1e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -38,7 +38,11 @@ add_executable(${PROJECT_NAME}val test_val.c) target_link_libraries(${PROJECT_NAME}val CArgParse) add_test(${PROJECT_NAME}val ${PROJECT_NAME}val file1.txt file2.txt file3.txt -v -q) -# 未知命令选项测试,预期打印该命令的帮助信息 +# 必填参数测试 add_executable(${PROJECT_NAME}required test_required.c) target_link_libraries(${PROJECT_NAME}required CArgParse) -add_test(${PROJECT_NAME}required ${PROJECT_NAME}required file1.txt file2.txt file3.txt -v -f d) \ No newline at end of file +add_test(${PROJECT_NAME}required_1 ${PROJECT_NAME}required -f) +add_test(${PROJECT_NAME}required_2 ${PROJECT_NAME}required) +set_tests_properties(${PROJECT_NAME}required_2 PROPERTIES WILL_FAIL TRUE) +add_test(${PROJECT_NAME}required_3 ${PROJECT_NAME}required -h) +add_test(${PROJECT_NAME}required_4 ${PROJECT_NAME}required -f install -h) \ No newline at end of file diff --git a/tests/test_required.c b/tests/test_required.c new file mode 100644 index 0000000..9249791 --- /dev/null +++ b/tests/test_required.c @@ -0,0 +1,144 @@ +#include "ArgParse.h" +#include +#include +#include +#include +#include + +ArgParse *initArgParse() { + ArgParse *argparse = argParseInit("测试程序", ArgParseNOVALUE); + Command *command = NULL; + Command *sub_command = NULL; + + // add global arguments + argParseAddGlobalArg(argparse, + "-v", + "--version", + "Show version", + NULL, + NULL, + false, + ArgParseNOVALUE); + argParseAddGlobalArg(argparse, + "-f", + "--file", + "File name", + NULL, + NULL, + true, + ArgParseNOVALUE); + + // add arguments + command = argParseAddCommand(argparse, + "install", + "Install the package", + NULL, + NULL, + NULL, + ArgParseNOVALUE); + argParseAddArg(command, + "-i", + "--index", + "Index URL", + "https://example.com", + NULL, + false, + ArgParseSINGLEVALUE); + argParseAddArg(command, + "-f", + "--file", + "Package file", + "package.json", + NULL, + true, + ArgParseMULTIVALUE); + argParseAddArg(command, + "-p", + "--package", + "Package file", + "package.json", + NULL, + false, + ArgParseMULTIVALUE); + + sub_command = argParseAddSubCommand(command, + "tools", + "Install tools", + NULL, + NULL, + NULL, + ArgParseMULTIVALUE); + + argParseAddArg(sub_command, + "-t", + "--tool", + "Tool name", + "Tool name", + NULL, + true, + ArgParseMULTIVALUE); + sub_command = argParseAddSubCommand(command, + "tools_sub", + "Install tools", + NULL, + NULL, + NULL, + ArgParseMULTIVALUE); + + argParseAddArg(sub_command, + "-s", + "--source", + "test_source", + "tools subcommand test", + NULL, + true, + ArgParseMULTIVALUE); + + command = argParseAddCommand(argparse, + "uninstall", + "Uninstall the package", + NULL, + NULL, + NULL, + ArgParseSINGLEVALUE); + argParseAddArg(command, + "-p", + "--package", + "Package name", + "Package name", + NULL, + true, + ArgParseMULTIVALUE); + + return argparse; +} + +int main(int argc, char *argv[]) { + ArgParse *argparse = initArgParse(); + + argParseParse(argparse, argc, argv); + + char *val = argParseGetVal(argparse); + if (val) { + printf("val: %s\n", val); + } + + // int len = 0; + // char **vals = argParseGetValList(argparse, &len); + + // char *test_val[3] = {"file1.txt", "file2.txt", "file3.txt"}; + + // if (vals) { + // for (int i = 0; i < len; i++) { + // printf("vals: %s\n", vals[i]); + // assert(strcmp(vals[i], test_val[i]) == 0); + // } + // } + + // assert(argParseCheckGlobalTriggered(argparse, "-v")); + // assert(argParseCheckGlobalTriggered(argparse, "-f")); + + argParseFree(argparse); + + return 0; +} \ No newline at end of file From f58d83b4eea7646b1577290225ad71dc9bb16b2a Mon Sep 17 00:00:00 2001 From: youmetme <321640253@qq.com> Date: Tue, 30 Sep 2025 13:50:10 +0800 Subject: [PATCH 6/6] docs: update version to 0.3.2 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index d952c58..9301d0c 100644 --- a/conanfile.py +++ b/conanfile.py @@ -6,7 +6,7 @@ import os class loggingRecipe(ConanFile): name = "cargparse" - version = "0.3.1" + version = "0.3.2" license = "MIT" author = "321640253@qq.com" url = "https://gitea.youmetme.wang/youmetme/logging"