#ifndef __SCC_ARGPARSE_H__ #define __SCC_ARGPARSE_H__ #include "optparse.h" #include // 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; // 约束规范结构体 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; // 通用指针存储 } 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; } #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__ */