#include <regex.h>
#include <fnmatch.h>
#include <signal.h>
+#include <inttypes.h>
+#include <lopsub.h>
#include "para.h"
#include "list.h"
#include "play.cmdline.h"
+#include "play_cmd.lsg.h"
#include "error.h"
#include "ggo.h"
#include "buffer_tree.h"
char *afhi_txt;
};
+typedef int (*play_cmd_handler_t)(struct play_task *pt,
+ struct lls_parse_result *lpr);
+struct play_command_info {
+ play_cmd_handler_t handler;
+};
+#define EXPORT_PLAY_CMD_HANDLER(_cmd) \
+ const struct play_command_info lsg_play_cmd_com_ ## _cmd ## _user_data = { \
+ .handler = com_ ## _cmd \
+ };
+
/* Activate the afh receiver. */
extern void afh_recv_init(struct receiver *r);
#undef AFH_RECEIVER
static struct pp_command pp_cmds[] = {DEFINE_PLAY_CMD_ARRAY};
#define FOR_EACH_COMMAND(c) for (c = 0; pp_cmds[c].name; c++)
-#include "play.completion.h"
static struct i9e_completer pp_completers[];
I9E_DUMMY_COMPLETER(jmp);
result->matches = i9e_complete_commands(ci->word, pp_completers);
}
-static struct i9e_completer pp_completers[] = {PLAY_COMPLETERS {.name = NULL}};
+I9E_DUMMY_COMPLETER(SUPERCOMMAND_UNAVAILABLE);
+static struct i9e_completer pp_completers[] = {
+#define LSG_PLAY_CMD_CMD(_name) {.name = #_name, \
+ .completer = _name ## _completer}
+ LSG_PLAY_CMD_SUBCOMMANDS
+#undef LSG_PLAY_CMD_CMD
+ {.name = NULL}
+};
static void attach_stdout(struct play_task *pt, const char *name)
{
return 0;
}
-static int com_help(struct play_task *pt, int argc, char **argv)
+static int com_help(struct play_task *pt, struct lls_parse_result *lpr)
{
- int i;
- char *buf;
+ int i, ret;
+ char *buf, *errctx;
size_t sz;
+ const struct lls_command *cmd;
- if (argc > 2)
- return -E_PLAY_SYNTAX;
- if (argc < 2) {
- if (pt->background)
- FOR_EACH_COMMAND(i) {
- sz = xasprintf(&buf, "%s\t%s\n", pp_cmds[i].name,
- pp_cmds[i].description);
+ ret = lls(lls_check_arg_count(lpr, 0, 1, &errctx));
+ if (ret < 0) {
+ if (errctx)
+ PARA_ERROR_LOG("%s\n", errctx);
+ free(errctx);
+ return ret;
+ }
+ if (lls_num_inputs(lpr) == 0) {
+ if (pt->background) {
+ for (i = 1; (cmd = lls_cmd(i, play_cmd_suite)); i++) {
+ sz = xasprintf(&buf, "%s\t%s\n",
+ lls_command_name(cmd), lls_purpose(cmd));
btr_add_output(buf, sz, pt->btrn);
}
- else {
- FOR_EACH_MAPPED_KEY(i) {
- bool internal = is_internal_key(i);
- int idx = get_key_map_idx(i);
- char *seq = get_key_map_seq_safe(i);
- char *cmd = get_key_map_cmd(i);
- sz = xasprintf(&buf,
- "%s key #%d: %s -> %s\n",
- internal? "internal" : "user-defined",
- idx, seq, cmd);
+ FOR_EACH_COMMAND(i) {
+ sz = xasprintf(&buf, "%s\t%s\n", pp_cmds[i].name,
+ pp_cmds[i].description);
btr_add_output(buf, sz, pt->btrn);
- free(seq);
- free(cmd);
}
+ return 0;
+ }
+ FOR_EACH_MAPPED_KEY(i) {
+ bool internal = is_internal_key(i);
+ int idx = get_key_map_idx(i);
+ char *seq = get_key_map_seq_safe(i);
+ char *kmc = get_key_map_cmd(i);
+ sz = xasprintf(&buf, "%s key #%d: %s -> %s\n",
+ internal? "internal" : "user-defined",
+ idx, seq, kmc);
+ btr_add_output(buf, sz, pt->btrn);
+ free(seq);
+ free(kmc);
}
return 0;
}
- FOR_EACH_COMMAND(i) {
- if (strcmp(pp_cmds[i].name, argv[1]))
- continue;
- sz = xasprintf(&buf,
- "NAME\n\t%s -- %s\n"
- "SYNOPSIS\n\t%s\n"
- "DESCRIPTION\n%s\n",
- argv[1],
- pp_cmds[i].description,
- pp_cmds[i].usage,
- pp_cmds[i].help
- );
- btr_add_output(buf, sz, pt->btrn);
- return 0;
+ ret = lls(lls_lookup_subcmd(lls_input(0, lpr), play_cmd_suite,
+ &errctx));
+ if (ret < 0) {
+ if (errctx)
+ PARA_ERROR_LOG("%s\n", errctx);
+ free(errctx);
+ return ret;
}
- return -E_BAD_PLAY_CMD;
+ cmd = lls_cmd(ret, play_cmd_suite);
+ buf = lls_long_help(cmd);
+ assert(buf);
+ btr_add_output(buf, strlen(buf), pt->btrn);
+ return 0;
}
+EXPORT_PLAY_CMD_HANDLER(help);
static int com_info(struct play_task *pt, int argc, __a_unused char **argv)
{
{
int i, ret, argc;
char **argv = NULL;
+ char *errctx = NULL;
+ const struct play_command_info *pci;
+ struct lls_parse_result *lpr;
+ const struct lls_command *cmd;
attach_stdout(pt, __FUNCTION__);
ret = create_argv(line, " ", &argv);
- if (ret < 0) {
- PARA_ERROR_LOG("parse error: %s\n", para_strerror(-ret));
- return 0;
- }
+ if (ret < 0)
+ goto out;
if (ret == 0)
goto out;
argc = ret;
- FOR_EACH_COMMAND(i) {
- if (strcmp(pp_cmds[i].name, argv[0]))
- continue;
- ret = pp_cmds[i].handler(pt, argc, argv);
+
+ ret = lls(lls_lookup_subcmd(argv[0], play_cmd_suite, &errctx));
+ if (ret >= 0) {
+ cmd = lls_cmd(ret, play_cmd_suite);
+ ret = lls(lls_parse(argc, argv, cmd, &lpr, &errctx));
if (ret < 0)
- PARA_WARNING_LOG("%s: %s\n", pt->background?
- "" : argv[0], para_strerror(-ret));
- ret = 1;
- goto out;
+ goto out;
+ pci = lls_user_data(cmd);
+ ret = pci->handler(pt, lpr);
+ lls_free_parse_result(lpr, cmd);
+ } else {
+ FOR_EACH_COMMAND(i) {
+ if (strcmp(pp_cmds[i].name, argv[0]))
+ continue;
+ free(errctx);
+ errctx = NULL;
+ ret = pp_cmds[i].handler(pt, argc, argv);
+ break;
+ }
}
- PARA_WARNING_LOG("invalid command: %s\n", argv[0]);
- ret = 0;
out:
+ if (errctx)
+ PARA_ERROR_LOG("%s\n", errctx);
+ free(errctx);
free_argv(argv);
return ret;
}