#include "backend.h" #include "ctx.h" #include "interface.h" #include "lex.h" #include "line-source.h" #include "msg.h" #include "parse.h" #include #include #include #define CMD_ID 0 enum { ARG_SRCPATH, OPT_BACKEND, OPT_BACKEND_ARG_NAME, }; int main(int argc, const char **argv) { return fx_command_dispatch(CMD_ID, argc, argv); } static void print_msg(struct msg_definition *msg) { printf(" msg: %s\n", msg->msg_name); fx_queue_entry *entry = fx_queue_first(&msg->msg_params); while (entry) { struct msg_parameter *param = fx_unbox(struct msg_parameter, entry, p_entry); printf(" param:"); type_print(param->p_type); printf(" %s\n", param->p_name); entry = fx_queue_next(entry); } entry = fx_queue_first(&msg->msg_results); while (entry) { struct msg_parameter *param = fx_unbox(struct msg_parameter, entry, p_entry); printf(" result:"); type_print(param->p_type); printf(" %s\n", param->p_name); entry = fx_queue_next(entry); } } static void print_interface(struct interface_definition *iface) { printf("interface: %s\n", iface->if_name); fx_queue_entry *entry = fx_queue_first(&iface->if_msg); while (entry) { struct msg_definition *msg = fx_unbox(struct msg_definition, entry, msg_entry); print_msg(msg); entry = fx_queue_next(entry); } } static int xpcg( const fx_command *self, const fx_arglist *opt, const fx_array *args) { const char *path = NULL; fx_arglist_get_string(opt, FX_COMMAND_INVALID_ID, ARG_SRCPATH, 0, &path); if (!path) { fx_arglist_report_missing_args( opt, FX_COMMAND_INVALID_ID, ARG_SRCPATH, 0); return -1; } fx_file *file = NULL; fx_result result = fx_file_open(NULL, FX_RV_PATH(path), FX_FILE_READ_ONLY, &file); if (fx_result_is_error(result)) { fx_throw(result); return -1; } struct line_source src; line_source_init(&src, path, file); struct ctx *ctx = ctx_create(); struct lex *lex = lex_create(&src); #if 0 struct token *tok = lex_peek(lex); while (tok) { printf("%s", token_type_to_string(tok->tok_type)); switch (tok->tok_value_type) { case TOK_V_INT: printf(" %lld", tok->tok_int); break; case TOK_V_STRING: printf(" %s", tok->tok_str); break; case TOK_V_SYMBOL: printf(" %s", token_symbol_to_string(tok->tok_sym)); break; case TOK_V_KEYWORD: printf(" %s", token_keyword_to_string(tok->tok_kw)); break; default: break; } printf("\n"); lex_advance(lex); tok = lex_peek(lex); } #endif struct interface_definition *iface = parse_interface_definition(ctx, lex); if (!iface) { return -1; } const struct backend *backend = c_mpc_backend(); int err = backend->b_emit(iface); return err; } FX_COMMAND(CMD_ID, FX_COMMAND_INVALID_ID) { FX_COMMAND_NAME("xpcg"); FX_COMMAND_DESC("xpc interface generator."); FX_COMMAND_FLAGS(FX_COMMAND_SHOW_HELP_BY_DEFAULT); FX_COMMAND_FUNCTION(xpcg); FX_COMMAND_HELP_OPTION(); FX_COMMAND_ARG(ARG_SRCPATH) { FX_ARG_NAME("source-file"); FX_ARG_DESC("the interface file to compile."); FX_ARG_NR_VALUES(1); } FX_COMMAND_OPTION(OPT_BACKEND) { FX_OPTION_LONG_NAME("backend"); FX_OPTION_SHORT_NAME('b'); FX_OPTION_DESC("which backend to use."); FX_OPTION_ARG(OPT_BACKEND_ARG_NAME) { FX_ARG_NAME("backend-name"); FX_ARG_NR_VALUES(1); FX_ARG_ALLOWED_VALUES("c-mpc"); } } FX_COMMAND_USAGE() { FX_COMMAND_USAGE_ARG(ARG_SRCPATH); FX_COMMAND_USAGE_OPT(OPT_BACKEND); } }