Files
scc/libs/argparse/include/argparse.h
zzy 630e22b73b feat(argparse): 添加命令行参数约束和错误处理功能
- 添加了命令行参数约束相关数据结构定义
- 新增错误上下文字段用于更好的错误提示
- 实现了参数验证功能,包括必需参数检查和值选择验证
- 改进错误处理流程,支持添加帮助信息和使用说明
- 优化调试输出格式,增加更多错误场景的处理

fix(parser): 修复语义分析器资源释放问题

- 在scc_sema_drop函数中添加空指针检查,避免空指针释放导致崩溃

refactor(dump): 重构AST节点转储实现

- 将树形转储上下文重构为更简洁的数据结构
- 修改转储回调函数签名以支持更好的缓冲区管理
- 优化内存拷贝操作,提高转储性能

style(amd64): 移除未使用的变量声明

- 删除scc_mcode_amd64_mov_r64_m64_sib函数中未使用的disp8变量
2026-04-11 11:42:31 +08:00

248 lines
8.7 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.
#ifndef __SCC_ARGPARSE_H__
#define __SCC_ARGPARSE_H__
#include "optparse.h"
#include <scc_core.h>
// TODO: 实现更多高级功能
// 1. 支持子命令嵌套层级限制
// 2. 支持选项分组显示Grouping
// 3. 支持自动补全脚本生成Bash/Zsh/Fish
// 4. 支持配置文件解析
// 5. 支持国际化i18n
/// @brief 命令行参数约束
typedef struct scc_argparse_spec scc_argparse_spec_t;
/// @brief 命令行参数 eg. someting
typedef struct scc_argparse_arg scc_argparse_arg_t;
/// @brief 命令行参数选项 eg. -a --long
typedef struct scc_argparse_opt scc_argparse_opt_t;
/// @brief 命令集合
typedef struct scc_argparse_cmd scc_argparse_cmd_t;
typedef SCC_VEC(scc_argparse_arg_t) scc_argparse_arg_vec_t;
typedef SCC_VEC(scc_argparse_opt_t) scc_argparse_opt_vec_t;
typedef SCC_VEC(scc_argparse_cmd_t) scc_argparse_cmd_vec_t;
typedef enum scc_argparse_val_type {
SCC_ARGPARSE_VAL_TYPE_UNKNOWN,
SCC_ARGPARSE_VAL_TYPE_STRING,
SCC_ARGPARSE_VAL_TYPE_BOOL,
SCC_ARGPARSE_VAL_TYPE_INT,
SCC_ARGPARSE_VAL_TYPE_FLOAT,
SCC_ARGPARSE_VAL_TYPE_ENUM,
SCC_ARGPARSE_VAL_TYPE_LIST,
SCC_ARGPARSE_VAL_TYPE_COUNT,
} scc_argparse_val_type_t;
typedef enum scc_argparse_err {
SCC_ARGPARSE_ERR_NONE,
SCC_ARGPARSE_ERR_PNT_DEFAULT,
SCC_ARGPARSE_ERR_UNKNOWN_ERR,
SCC_ARGPARSE_ERR_INVALID_ARG,
SCC_ARGPARSE_ERR_INVALID_VALUE,
SCC_ARGPARSE_ERR_MISSING_ARG,
SCC_ARGPARSE_ERR_MISSING_VALUE,
SCC_ARGPARSE_ERR_UNKNOWN_ARG,
SCC_ARGPARSE_ERR_UNKNOWN_VALUE,
} scc_argparse_err_t;
typedef SCC_VEC(const char *) scc_argparse_list_t;
// 约束规范结构体
struct scc_argparse_spec {
scc_argparse_val_type_t value_type; // 值类型
const char *raw_value;
// 存储位置
union {
cbool *bool_store; // 布尔值存储
int *int_store; // 整数存储
float *float_store; // 浮点数存储
const char **str_store; // 字符串存储
char **str_alloc_store; // 字符串存储使用alloc需要free
void **ptr_store; // 通用指针存储
scc_argparse_list_t *vec_store; // 新增:指向字符串向量的指针
} store;
// 枚举值约束
struct {
const char **values; // 枚举值数组
int count; // 枚举值数量
} choices;
// 其他约束标志
cbool flag_required; // 是否必须
cbool flag_store_as_count; // 是否存储为计数(如 -vvv 返回3
cbool flag_allow_empty; // 是否允许空字符串
cbool flag_hidden; // 是否隐藏(不显示在帮助)
cbool flag_takes_multiple; // 是否接受多个值(如 -I dir1 -I dir2
cbool flag_parse_complex; // 是否进行复杂解析(如 1K, 2M, 3G
};
struct scc_argparse_arg {
scc_argparse_spec_t spec;
const char *name;
const char *description;
};
struct scc_argparse_opt {
scc_argparse_spec_t spec;
char short_name;
const char *long_name;
const char *description;
};
struct scc_argparse_cmd {
const char *name;
const char *description;
scc_argparse_arg_vec_t args;
scc_argparse_opt_vec_t opts;
scc_argparse_cmd_vec_t subcmds;
};
typedef enum {
SCC_ARGPARSE_LANG_EN,
SCC_ARGPARSE_LANG_ZH,
} scc_argparse_lang_t;
typedef struct {
const char *prog_name;
const char *version;
const char *description;
const char *epilog;
scc_argparse_cmd_t root_cmd;
scc_argparse_lang_t lang;
cbool need_help;
cbool need_version;
cbool need_debug;
cbool need_error_add_help;
cbool need_error_add_usage;
} scc_argparse_t;
typedef SCC_VEC(scc_optparse_opt_t) scc_optparse_opt_vec_t;
typedef struct {
scc_argparse_cmd_t *current_cmd; // 当前正在解析的命令
scc_optparse_t optparse; // 底层解析器
scc_optparse_opt_vec_t opts; // 当前命令的选项列表
scc_optparse_result_t result; // 底层解析结果
const void *err_ctx; // 错误上下文(期待的参数或者当前解析的参数)
int positional_index; // 当前处理的位置参数索引
cbool parsing_done; // 是否已完成解析
} scc_argparse_context_t;
void scc_argparse_init(scc_argparse_t *parser, const char *program_name,
const char *description);
scc_argparse_cmd_t *scc_argparse_get_root(scc_argparse_t *parser);
void scc_argparse_drop(scc_argparse_t *parser);
int scc_argparse_parse(scc_argparse_t *parser, int argc, const char **argv);
void scc_argparse_cmd_init(scc_argparse_cmd_t *cmd, const char *name,
const char *description);
void scc_argparse_cmd_drop(scc_argparse_cmd_t *cmd);
void scc_argparse_cmd_add_arg(scc_argparse_cmd_t *cmd,
const scc_argparse_arg_t *arg);
void scc_argparse_cmd_add_opt(scc_argparse_cmd_t *cmd,
const scc_argparse_opt_t *opt);
void scc_argparse_cmd_add_subcmd(scc_argparse_cmd_t *cmd,
const scc_argparse_cmd_t *subcmd);
void scc_argparse_print_help(scc_argparse_t *parser, scc_argparse_cmd_t *cmd);
void scc_argparse_print_error(scc_argparse_context_t *ctx,
scc_argparse_t *parser, scc_argparse_err_t err);
static inline void scc_argparse_spec_init(scc_argparse_spec_t *spec) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_STRING;
spec->raw_value = nullptr;
spec->store.ptr_store = nullptr;
spec->choices.count = 0;
spec->choices.values = nullptr;
spec->flag_required = false;
spec->flag_store_as_count = false;
spec->flag_allow_empty = false;
spec->flag_hidden = false;
spec->flag_takes_multiple = false;
spec->flag_parse_complex = false;
}
static inline void scc_argparse_opt_init(scc_argparse_opt_t *opt,
char short_name, const char *long_name,
const char *desc) {
opt->short_name = short_name;
opt->long_name = long_name;
opt->description = desc;
scc_argparse_spec_init(&opt->spec);
}
static inline void scc_argparse_arg_init(scc_argparse_arg_t *arg,
const char *name, const char *desc) {
arg->name = name;
arg->description = desc;
scc_argparse_spec_init(&arg->spec);
}
static inline void scc_argparse_spec_setup_bool(scc_argparse_spec_t *spec,
cbool *store) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_BOOL;
spec->store.bool_store = store;
}
static inline void scc_argparse_spec_setup_count(scc_argparse_spec_t *spec,
int *store) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_COUNT;
spec->flag_store_as_count = true; // 自动设为计数模式
spec->store.int_store = store;
}
static inline void scc_argparse_spec_setup_string(scc_argparse_spec_t *spec,
const char **store) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_STRING;
spec->store.str_store = store;
}
static inline void scc_argparse_spec_setup_int(scc_argparse_spec_t *spec,
int *store) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_INT;
spec->store.int_store = store;
}
static inline void scc_argparse_spec_setup_float(scc_argparse_spec_t *spec,
float *store) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_FLOAT;
spec->store.float_store = store;
}
static inline void scc_argparse_spec_setup_choices(scc_argparse_spec_t *spec,
const char **values,
int count) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_ENUM;
spec->choices.values = values;
spec->choices.count = count;
}
// 添加设置列表的辅助函数(内联)
static inline void scc_argparse_spec_setup_list(scc_argparse_spec_t *spec,
scc_argparse_list_t *vec) {
spec->value_type = SCC_ARGPARSE_VAL_TYPE_LIST;
spec->store.vec_store = vec;
// 自动设置 flag_takes_multiple 为 true因为列表需要多个值
spec->flag_takes_multiple = true;
}
#define SCC_ARGPARSE_MACRO_SETTER(attr) \
static inline void scc_argparse_spec_set_##attr(scc_argparse_spec_t *spec, \
cbool flag) { \
spec->flag_##attr = flag; \
}
SCC_ARGPARSE_MACRO_SETTER(required)
SCC_ARGPARSE_MACRO_SETTER(allow_empty)
SCC_ARGPARSE_MACRO_SETTER(hidden)
SCC_ARGPARSE_MACRO_SETTER(takes_multiple)
SCC_ARGPARSE_MACRO_SETTER(parse_complex)
#endif /* __SCC_ARGPARSE_H__ */