Files
scc/libs/argparse/include/argparse.h
zzy b705e5d0ad feat(argparse): 添加列表类型参数支持
新增 scc_argparse_list_t 类型用于处理多个字符串值的参数,
并添加相应的配置函数 scc_argparse_spec_setup_list。

fix(lexer): 调整关键字标记处理逻辑

将关键字子类型从 SCC_TOK_SUBTYPE_KEYWORD 改为
SCC_TOK_SUBTYPE_IDENTIFIER,并移除相关的枚举定义。

refactor(lexer): 优化跳过换行功能实现

修改 scc_lexer_skip_until_newline 函数实现,改进循环逻辑和错误处理。

feat(pproc): 完善预处理器条件编译支持

重构条件编译状态管理,添加对 #ifdef、#ifndef、#elifdef、
#else、#endif 等指令的支持,并实现嵌套条件处理。

refactor(pproc): 优化文件包含路径处理

添加最大包含深度限制,改进包含路径添加功能,
修复文件状态结构命名。

docs(log): 更新日志模块标准库依赖

调整 stdarg.h 包含逻辑,更新编译器内置宏定义名称。

feat(core): 扩展核心类型定义

添加基础数据类型别名定义,完善类型系统支持。

feat(main): 实现命令行包含路径参数

添加 -I/--include 参数支持,允许用户指定额外的头文件搜索路径。
2026-02-21 10:46:49 +08:00

241 lines
8.4 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
typedef struct scc_argparse_spec scc_argparse_spec_t;
typedef struct scc_argparse_arg scc_argparse_arg_t;
typedef struct scc_argparse_opt scc_argparse_opt_t;
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;
} 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;
int positional_index; // 当前处理的位置参数索引
cbool parsing_done; // 是否已完成解析
scc_argparse_lang_t lang;
} 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_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 = null;
spec->store.ptr_store = null;
spec->choices.count = 0;
spec->choices.values = null;
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__ */