170 lines
3.4 KiB
C
170 lines
3.4 KiB
C
#include "backend.h"
|
|
#include "ctx.h"
|
|
#include "interface.h"
|
|
#include "lex.h"
|
|
#include "line-source.h"
|
|
#include "msg.h"
|
|
#include "parse.h"
|
|
|
|
#include <blue/cmd.h>
|
|
#include <blue/io/file.h>
|
|
#include <blue/io/path.h>
|
|
|
|
#define CMD_ID 0
|
|
|
|
enum {
|
|
ARG_SRCPATH,
|
|
OPT_BACKEND,
|
|
OPT_BACKEND_ARG_NAME,
|
|
};
|
|
|
|
int main(int argc, const char **argv)
|
|
{
|
|
return b_command_dispatch(CMD_ID, argc, argv);
|
|
}
|
|
|
|
static void print_msg(struct msg_definition *msg)
|
|
{
|
|
printf(" msg: %s\n", msg->msg_name);
|
|
|
|
b_queue_entry *entry = b_queue_first(&msg->msg_params);
|
|
while (entry) {
|
|
struct msg_parameter *param
|
|
= b_unbox(struct msg_parameter, entry, p_entry);
|
|
|
|
printf(" param:");
|
|
type_print(param->p_type);
|
|
printf(" %s\n", param->p_name);
|
|
|
|
entry = b_queue_next(entry);
|
|
}
|
|
|
|
entry = b_queue_first(&msg->msg_results);
|
|
while (entry) {
|
|
struct msg_parameter *param
|
|
= b_unbox(struct msg_parameter, entry, p_entry);
|
|
|
|
printf(" result:");
|
|
type_print(param->p_type);
|
|
printf(" %s\n", param->p_name);
|
|
|
|
entry = b_queue_next(entry);
|
|
}
|
|
}
|
|
|
|
static void print_interface(struct interface_definition *iface)
|
|
{
|
|
printf("interface: %s\n", iface->if_name);
|
|
b_queue_entry *entry = b_queue_first(&iface->if_msg);
|
|
while (entry) {
|
|
struct msg_definition *msg
|
|
= b_unbox(struct msg_definition, entry, msg_entry);
|
|
print_msg(msg);
|
|
entry = b_queue_next(entry);
|
|
}
|
|
}
|
|
|
|
static int xpcg(
|
|
const b_command *self,
|
|
const b_arglist *opt,
|
|
const b_array *args)
|
|
{
|
|
const char *path = NULL;
|
|
b_arglist_get_string(opt, B_COMMAND_INVALID_ID, ARG_SRCPATH, 0, &path);
|
|
if (!path) {
|
|
b_arglist_report_missing_args(
|
|
opt,
|
|
B_COMMAND_INVALID_ID,
|
|
ARG_SRCPATH,
|
|
0);
|
|
return -1;
|
|
}
|
|
|
|
b_file *file = NULL;
|
|
b_result result
|
|
= b_file_open(NULL, B_RV_PATH(path), B_FILE_READ_ONLY, &file);
|
|
if (b_result_is_error(result)) {
|
|
b_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;
|
|
}
|
|
|
|
B_COMMAND(CMD_ID, B_COMMAND_INVALID_ID)
|
|
{
|
|
B_COMMAND_NAME("xpcg");
|
|
B_COMMAND_DESC("xpc interface generator.");
|
|
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
|
B_COMMAND_FUNCTION(xpcg);
|
|
B_COMMAND_HELP_OPTION();
|
|
|
|
B_COMMAND_ARG(ARG_SRCPATH)
|
|
{
|
|
B_ARG_NAME("source-file");
|
|
B_ARG_DESC("the interface file to compile.");
|
|
B_ARG_NR_VALUES(1);
|
|
}
|
|
|
|
B_COMMAND_OPTION(OPT_BACKEND)
|
|
{
|
|
B_OPTION_LONG_NAME("backend");
|
|
B_OPTION_SHORT_NAME('b');
|
|
B_OPTION_DESC("which backend to use.");
|
|
B_OPTION_ARG(OPT_BACKEND_ARG_NAME)
|
|
{
|
|
B_ARG_NAME("backend-name");
|
|
B_ARG_NR_VALUES(1);
|
|
B_ARG_ALLOWED_VALUES("c-mpc");
|
|
}
|
|
}
|
|
|
|
B_COMMAND_USAGE()
|
|
{
|
|
B_COMMAND_USAGE_ARG(ARG_SRCPATH);
|
|
B_COMMAND_USAGE_OPT(OPT_BACKEND);
|
|
}
|
|
}
|