Files
CArgParse/src/ArgParseTools.c
2025-07-16 13:59:23 +08:00

328 lines
8.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "ArgParseTools.h"
#include "ArgParse.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
/**
* @brief 分配新内存复制字符串
* @param str 字符串
* @return 复制后的字符串内存指针
*/
char *stringNewCopy(char *str) {
if (str == NULL) {
return NULL;
}
char *mem = malloc(strlen(str) + 1);
if (mem == NULL) {
return NULL;
}
strcpy(mem, str);
return mem;
}
// 构造命令
Command *createCommand(char *name,
char *help,
char *default_val,
ArgParseCallback callback,
CommandGroup *group,
ArgParseValueType value_typ) {
// 构造命令结构
Command *command = malloc(sizeof(Command));
if (command == NULL || name == NULL) {
return NULL;
}
command->name = stringNewCopy(name);
if (command->name == NULL) {
return NULL;
}
command->help = stringNewCopy(help);
command->default_val = stringNewCopy(default_val);
command->callback = callback;
command->sub_commands = NULL;
command->sub_commands_len = 0;
command->args = NULL;
command->args_len = 0;
command->value_type = value_typ;
if (group != NULL) {
command->group = group;
} else {
command->group = NULL;
}
command->val = NULL;
command->val_len = 0;
command->is_trigged = false; // 是否被触发
return command;
}
ArgType checkArgType(char *arg) {
size_t len = strlen(arg);
if (len == 0) {
return BAD;
}
if (arg[0] == '-') {
if (len >= 2) {
if (arg[1] == '-') {
return LONG_ARG;
} else {
return SHORT_ARG;
}
}
} else {
return COMMAND;
}
return BAD;
}
// 寻找命令
Command *argParseFindCommand(ArgParse *argParse, char *name) {
for (size_t i = 0; i < argParse->commands_len; i++) {
if (strcmp(argParse->commands[i]->name, name) == 0) {
return argParse->commands[i];
}
}
return NULL;
}
Command *argParseFindSubCommand(Command *command, char *name) {
for (size_t i = 0; i < command->sub_commands_len; i++) {
if (strcmp(command->sub_commands[i]->name, name) == 0) {
return command->sub_commands[i];
}
}
return NULL;
}
CommandArgs *createCommandArgs(char *short_opt,
char *long_opt,
char *default_val,
char *help,
ArgParseCallback callback,
bool required,
ArgParseValueType value_type) {
CommandArgs *args = malloc(sizeof(CommandArgs));
if (short_opt == NULL && long_opt == NULL) {
return NULL;
}
// 分配内存
args->short_opt = stringNewCopy(short_opt);
args->long_opt = stringNewCopy(long_opt);
args->default_val = stringNewCopy(default_val);
args->help = stringNewCopy(help);
args->callback = callback;
args->required = required;
args->value_type = value_type;
// 解析属性初始化
args->val = NULL;
args->val_len = 0;
args->is_trigged = false; // 是否被触发
return args;
}
CommandArgs *
argParseFindCommandArgs(Command *command, char *name, bool short_flag) {
if (command == NULL) {
return NULL;
}
for (size_t i = 0; i < command->args_len; i++) {
if (short_flag) {
if (command->args[i]->short_opt != NULL &&
strcmp(command->args[i]->short_opt, name) == 0) {
return command->args[i];
}
} else {
if (command->args[i]->long_opt != NULL &&
strcmp(command->args[i]->long_opt, name) == 0) {
return command->args[i];
}
}
}
return NULL;
}
CommandArgs *
argParseFindGlobalArgs(ArgParse *argParse, char *name, bool short_flag) {
for (size_t i = 0; i < argParse->global_args_len; i++) {
if (short_flag) {
if (argParse->global_args[i]->short_opt != NULL &&
strcmp(argParse->global_args[i]->short_opt, name) == 0) {
return argParse->global_args[i];
}
} else {
if (argParse->global_args[i]->long_opt != NULL &&
strcmp(argParse->global_args[i]->long_opt, name) == 0) {
return argParse->global_args[i];
}
}
}
return NULL;
}
/**
* @brief 设置命令参数值
* @param args 参数
* @param val 值
* @return 成功返回true失败返回false
*/
bool argParseSetArgVal(CommandArgs *args, char *val) {
if (args->value_type == MULTIVALUE) { // 多值
args->val = realloc(args->val, (args->val_len + 1) * sizeof(char *));
if (args->val == NULL) {
return false;
}
args->val[args->val_len] = stringNewCopy(val);
if (args->val[args->val_len] == NULL) {
return false;
}
args->val_len++;
return true;
} else if (args->value_type == SINGLEVALUE) { // 单值
if (args->val != NULL) {
free(args->val);
}
args->val = malloc(sizeof(char *));
if (args->val == NULL) {
return false;
}
args->val[0] = stringNewCopy(val); // 分配内存
if (args->val[0] == NULL) {
return false;
}
args->val_len = 1;
return true;
} else if (args->value_type == NOVALUE) { // 无值
return true;
}
return false;
}
bool argParseSetCommandVal(Command *command, char *val) {
if (command->value_type == MULTIVALUE) { // 多值
command->val =
realloc(command->val, (command->val_len + 1) * sizeof(char *));
if (command->val == NULL) {
return false;
}
command->val[command->val_len] = stringNewCopy(val);
if (command->val[command->val_len] == NULL) {
return false;
}
command->val_len++;
return true;
} else if (command->value_type == SINGLEVALUE) { // 单值
if (command->val != NULL) {
free(command->val);
}
command->val = malloc(sizeof(char *));
if (command->val == NULL) {
return false;
}
command->val[0] = stringNewCopy(val); // 分配内存
if (command->val[0] == NULL) {
return false;
}
command->val_len = 1;
return true;
} else if (command->value_type == NOVALUE) { // 无值
return true;
}
return false;
}
/**
* @brief 设置解析值,该值为程序所需的无命令值例如`gcc mian.c`的`main.c`
* @param argParse 解析器
* @param val 值
* @return 成功返回true失败返回false
*/
bool argParseSetVal(ArgParse *argParse, char *val) {
if (argParse->value_type == MULTIVALUE) { // 多值
argParse->val =
realloc(argParse->val, (argParse->val_len + 1) * sizeof(char *));
if (argParse->val == NULL) {
return false;
}
argParse->val[argParse->val_len] = stringNewCopy(val);
if (argParse->val[argParse->val_len] == NULL) {
return false;
}
argParse->val_len++;
return true;
} else if (argParse->value_type == SINGLEVALUE) { // 单值
if (argParse->val != NULL) {
free(argParse->val);
}
argParse->val = malloc(sizeof(char *));
if (argParse->val == NULL) {
return false;
}
argParse->val[0] = stringNewCopy(val); // 分配内存
if (argParse->val[0] == NULL) {
return false;
}
argParse->val_len = 1;
return true;
} else if (argParse->value_type == NOVALUE) { // 无值
return true;
}
return false;
}
size_t __getStrlen(char *str) {
if (str == NULL) {
return 0;
}
return strlen(str);
}
void __catStr(char **dst, int count, ...) {
va_list args;
va_start(args, count);
size_t total_len = 0;
total_len = __getStrlen(*dst);
// 计算总长度
char *temp = NULL;
for (int i = 0; i < count; i++) {
temp = va_arg(args, char *);
total_len += __getStrlen(temp);
}
va_end(args);
// 分配内存
*dst = realloc(*dst, total_len + 1); // +1 是为了存储字符串结束符 '\0'
if (*dst == NULL) {
va_end(args);
return; // 处理内存分配失败
}
// 拼接字符串
va_start(args, count);
temp = NULL;
for (int i = 0; i < count; i++) {
temp = va_arg(args, char *);
strcat(*dst, temp);
}
va_end(args);
}