feat(argparse): 添加选择类型支持和错误处理优化
添加了 SCC_ARGPARSE_ERR_PNT_DEFAULT 错误类型用于默认操作处理, 实现了 scc_argparse_spec_setup_choices 函数支持枚举选择, 重构了错误处理流程使返回值更加一致。 修复了长选项名称匹配的逻辑错误。 feat(lexer): 添加换行符和注释符号的词法标记 新增 SCC_TOK_ENDLINE 和 SCC_TOK_SHARP 标记类型, 改进词法分析器对换行符和井号的识别处理。 feat(scc_core): 添加常用宏定义 添加 scc_min 和 scc_max 宏定义提供基础数值比较功能。 feat(main): 实现编译器主程序和命令行接口 创建主程序入口实现完整的编译流程, 集成预处理器、词法分析、语法分析和IR生成模块, 添加AST和IR输出功能支持调试查看中间表示。 chore(build): 配置项目构建依赖关系 创建 cbuild.toml 配置文件定义项目包信息和依赖库, 建立编译器各组件库之间的依赖关系管理。
This commit is contained in:
@@ -132,29 +132,33 @@ static int handle_parse_error(scc_argparse_t *parser,
|
||||
return error;
|
||||
}
|
||||
|
||||
static void validate_and_cleanup(scc_argparse_context_t *ctx,
|
||||
scc_argparse_t *parser) {
|
||||
// 检查必需参数是否都已提供
|
||||
scc_vec_foreach(ctx->current_cmd->args, i) {
|
||||
scc_argparse_arg_t *arg = &scc_vec_at(ctx->current_cmd->args, i);
|
||||
if (arg->spec.flag_required && *arg->spec.store.str_store == NULL) {
|
||||
scc_argparse_print_error(ctx, SCC_ARGPARSE_ERR_MISSING_ARG);
|
||||
break;
|
||||
static int validate_and_cleanup(scc_argparse_context_t *ctx,
|
||||
scc_argparse_t *parser, int errcode) {
|
||||
if (errcode == SCC_ARGPARSE_ERR_NONE) {
|
||||
// 检查必需参数是否都已提供
|
||||
scc_vec_foreach(ctx->current_cmd->args, i) {
|
||||
scc_argparse_arg_t *arg = &scc_vec_at(ctx->current_cmd->args, i);
|
||||
if (arg->spec.flag_required && *arg->spec.store.str_store == NULL) {
|
||||
errcode = SCC_ARGPARSE_ERR_MISSING_ARG;
|
||||
scc_argparse_print_error(ctx, errcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清理资源
|
||||
scc_vec_free(ctx->opts);
|
||||
scc_optparse_drop(&ctx->optparse);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
static void handle_option(scc_argparse_context_t *ctx, scc_argparse_t *parser) {
|
||||
static int handle_option(scc_argparse_context_t *ctx, scc_argparse_t *parser) {
|
||||
scc_argparse_opt_t *opt = (scc_argparse_opt_t *)ctx->result.opt->user_data;
|
||||
|
||||
if (parser->need_help && scc_strcmp(opt->long_name, "help") == 0) {
|
||||
scc_argparse_print_help(parser, ctx->current_cmd);
|
||||
ctx->parsing_done = true;
|
||||
return;
|
||||
return SCC_ARGPARSE_ERR_PNT_DEFAULT;
|
||||
}
|
||||
|
||||
if (opt->spec.flag_store_as_count) {
|
||||
@@ -190,16 +194,17 @@ static void handle_option(scc_argparse_context_t *ctx, scc_argparse_t *parser) {
|
||||
// // TODO
|
||||
// *org_opt->spec.store.str_store = opt_res.value;
|
||||
// }
|
||||
return SCC_ARGPARSE_ERR_NONE;
|
||||
}
|
||||
|
||||
static void handle_positional_arg(scc_argparse_context_t *ctx,
|
||||
scc_argparse_t *parser) {
|
||||
static int handle_positional_arg(scc_argparse_context_t *ctx,
|
||||
scc_argparse_t *parser) {
|
||||
scc_argparse_cmd_t *subcmd =
|
||||
is_subcommand(ctx->current_cmd, ctx->result.value);
|
||||
if (subcmd != NULL) {
|
||||
ctx->current_cmd = subcmd;
|
||||
parse_cmd(&ctx->optparse, &ctx->opts, ctx->current_cmd);
|
||||
return;
|
||||
return SCC_ARGPARSE_ERR_NONE;
|
||||
}
|
||||
|
||||
if (ctx->positional_index < scc_vec_size(ctx->current_cmd->args)) {
|
||||
@@ -231,11 +236,13 @@ static void handle_positional_arg(scc_argparse_context_t *ctx,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return SCC_ARGPARSE_ERR_NONE;
|
||||
}
|
||||
|
||||
int scc_argparse_parse(scc_argparse_t *parser, int argc, const char **argv) {
|
||||
scc_argparse_context_t ctx = {0};
|
||||
init_context(&ctx, parser, argc, argv); // 初始化上下文
|
||||
int errcode = SCC_ARGPARSE_ERR_NONE;
|
||||
|
||||
while (!ctx.parsing_done &&
|
||||
scc_optparse_parse(&ctx.optparse, &ctx.result)) {
|
||||
@@ -245,22 +252,22 @@ int scc_argparse_parse(scc_argparse_t *parser, int argc, const char **argv) {
|
||||
ctx.result.opt ? ctx.result.opt->long_name : "--",
|
||||
ctx.result.error, ctx.result.value);
|
||||
}
|
||||
|
||||
if (ctx.result.error) {
|
||||
handle_parse_error(parser, &ctx);
|
||||
return 1;
|
||||
errcode = handle_parse_error(parser, &ctx);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx.result.opt != null) {
|
||||
handle_option(&ctx, parser);
|
||||
errcode = handle_option(&ctx, parser);
|
||||
} else if (ctx.result.value != null) {
|
||||
handle_positional_arg(&ctx, parser);
|
||||
errcode = handle_positional_arg(&ctx, parser);
|
||||
} else {
|
||||
UNREACHABLE(); // 不应到达此处
|
||||
}
|
||||
}
|
||||
|
||||
validate_and_cleanup(&ctx, parser);
|
||||
return 0;
|
||||
return validate_and_cleanup(&ctx, parser, errcode);
|
||||
}
|
||||
|
||||
void scc_argparse_cmd_init(scc_argparse_cmd_t *cmd, const char *name,
|
||||
|
||||
@@ -174,6 +174,9 @@ void scc_argparse_print_help(scc_argparse_t *parser, scc_argparse_cmd_t *cmd) {
|
||||
|
||||
const char *scc_argparse_find_similar_arg(scc_argparse_cmd_t *cmd,
|
||||
const char *arg) {
|
||||
if (arg == null || cmd == null) {
|
||||
return null;
|
||||
}
|
||||
if (arg[0] == '-' && arg[1] == '-' && arg[2] != '\0') {
|
||||
// opt arg
|
||||
scc_vec_foreach(cmd->opts, i) {
|
||||
|
||||
@@ -43,7 +43,7 @@ scc_optparse_get_long_name(const scc_optparse_opt_t *opts, const char *name,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (name[i] == '\0' || name[i] == end)
|
||||
if (opt->long_name[i] == '\0' && (name[i] == '\0' || name[i] == end))
|
||||
return opt;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user