]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - play.c
Convert receivers to lopsub.
[paraslash.git] / play.c
diff --git a/play.c b/play.c
index ce10a56bb9001f6675c18d06ce60323bbfeccf7e..4dab1cad58b3a989e96072c95e153b08cd18e24f 100644 (file)
--- a/play.c
+++ b/play.c
@@ -7,11 +7,11 @@
 /** \file play.c Paraslash's standalone player. */
 
 #include <regex.h>
 /** \file play.c Paraslash's standalone player. */
 
 #include <regex.h>
-#include <fnmatch.h>
 #include <signal.h>
 #include <inttypes.h>
 #include <lopsub.h>
 
 #include <signal.h>
 #include <inttypes.h>
 #include <lopsub.h>
 
+#include "recv_cmd.lsg.h"
 #include "para.h"
 #include "list.h"
 #include "play.cmdline.h"
 #include "para.h"
 #include "list.h"
 #include "play.cmdline.h"
@@ -111,14 +111,6 @@ struct play_command_info {
                .handler = com_ ## _cmd \
        };
 
                .handler = com_ ## _cmd \
        };
 
-/* Activate the afh receiver. */
-extern void afh_recv_init(struct receiver *r);
-#undef AFH_RECEIVER
-/** Initialization code for a receiver struct. */
-#define AFH_RECEIVER {.name = "afh", .init = afh_recv_init},
-/** This expands to the array of all receivers. */
-DEFINE_RECEIVER_ARRAY;
-
 static int loglevel = LL_WARNING;
 
 /** The log function which writes log messages to stderr. */
 static int loglevel = LL_WARNING;
 
 /** The log function which writes log messages to stderr. */
@@ -132,22 +124,9 @@ static struct play_args_info conf;
 
 static struct sched sched = {.max_fileno = 0};
 static struct play_task play_task;
 
 static struct sched sched = {.max_fileno = 0};
 static struct play_task play_task;
-static struct receiver *afh_recv;
 
 
-static void check_afh_receiver_or_die(void)
-{
-       int i;
-
-       FOR_EACH_RECEIVER(i) {
-               struct receiver *r = receivers + i;
-               if (strcmp(r->name, "afh"))
-                       continue;
-               afh_recv = r;
-               return;
-       }
-       PARA_EMERG_LOG("fatal: afh receiver not found\n");
-       exit(EXIT_FAILURE);
-}
+#define AFH_RECV_CMD (lls_cmd(LSG_RECV_CMD_CMD_AFH, recv_cmd_suite))
+#define AFH_RECV ((struct receiver *)lls_user_data(AFH_RECV_CMD))
 
 __noreturn static void print_help_and_die(void)
 {
 
 __noreturn static void print_help_and_die(void)
 {
@@ -243,12 +222,13 @@ static long unsigned get_play_time(struct play_task *pt)
        return result;
 }
 
        return result;
 }
 
+
 static void wipe_receiver_node(struct play_task *pt)
 {
        PARA_NOTICE_LOG("cleaning up receiver node\n");
        btr_remove_node(&pt->rn.btrn);
 static void wipe_receiver_node(struct play_task *pt)
 {
        PARA_NOTICE_LOG("cleaning up receiver node\n");
        btr_remove_node(&pt->rn.btrn);
-       afh_recv->close(&pt->rn);
-       afh_recv->free_config(pt->rn.conf);
+       AFH_RECV->close(&pt->rn);
+       lls_free_parse_result(pt->rn.lpr, AFH_RECV_CMD);
        memset(&pt->rn, 0, sizeof(struct receiver_node));
 }
 
        memset(&pt->rn, 0, sizeof(struct receiver_node));
 }
 
@@ -321,25 +301,26 @@ static void shuffle(char **base, size_t num)
 static struct btr_node *new_recv_btrn(struct receiver_node *rn)
 {
        return btr_new_node(&(struct btr_node_description)
 static struct btr_node *new_recv_btrn(struct receiver_node *rn)
 {
        return btr_new_node(&(struct btr_node_description)
-               EMBRACE(.name = afh_recv->name, .context = rn,
-                       .handler = afh_recv->execute));
+               EMBRACE(.name = lls_command_name(AFH_RECV_CMD), .context = rn,
+                       .handler = AFH_RECV->execute));
 }
 
 static int open_new_file(struct play_task *pt)
 {
        int ret;
 }
 
 static int open_new_file(struct play_task *pt)
 {
        int ret;
-       char *tmp, *path = conf.inputs[pt->next_file], *afh_recv_conf[] =
-               {"play", "-f", path, "-b", "0", NULL};
+       char *tmp, *path = conf.inputs[pt->next_file], *errctx = NULL,
+               *argv[] = {"play", "-f", path, "-b", "0", NULL};
 
        PARA_NOTICE_LOG("next file: %s\n", path);
        wipe_receiver_node(pt);
        pt->start_chunk = 0;
        pt->rn.btrn = new_recv_btrn(&pt->rn);
 
        PARA_NOTICE_LOG("next file: %s\n", path);
        wipe_receiver_node(pt);
        pt->start_chunk = 0;
        pt->rn.btrn = new_recv_btrn(&pt->rn);
-       pt->rn.conf = afh_recv->parse_config(ARRAY_SIZE(afh_recv_conf) - 1,
-               afh_recv_conf);
-       assert(pt->rn.conf);
-       pt->rn.receiver = afh_recv;
-       ret = afh_recv->open(&pt->rn);
+       ret = lls(lls_parse(ARRAY_SIZE(argv) - 1, argv, AFH_RECV_CMD,
+               &pt->rn.lpr, &errctx));
+       free(tmp);
+       assert(ret >= 0);
+       pt->rn.receiver = AFH_RECV;
+       ret = AFH_RECV->open(&pt->rn);
        if (ret < 0) {
                PARA_ERROR_LOG("could not open %s\n", path);
                goto fail;
        if (ret < 0) {
                PARA_ERROR_LOG("could not open %s\n", path);
                goto fail;
@@ -421,9 +402,9 @@ static int load_file(struct play_task *pt)
        /* success, register tasks */
        pt->rn.task = task_register(
                &(struct task_info) {
        /* success, register tasks */
        pt->rn.task = task_register(
                &(struct task_info) {
-                       .name = afh_recv->name,
-                       .pre_select = afh_recv->pre_select,
-                       .post_select = afh_recv->post_select,
+                       .name = lls_command_name(AFH_RECV_CMD),
+                       .pre_select = AFH_RECV->pre_select,
+                       .post_select = AFH_RECV->post_select,
                        .context = &pt->rn
                }, &sched);
        sprintf(buf, "%s decoder", af);
                        .context = &pt->rn
                }, &sched);
        sprintf(buf, "%s decoder", af);
@@ -666,23 +647,6 @@ static char **get_mapped_keyseqs(void)
        return result;
 }
 
        return result;
 }
 
-#include "play.command_list.h"
-
-typedef int play_command_handler_t(struct play_task *, int, char**);
-static play_command_handler_t PLAY_COMMAND_HANDLERS;
-
-/* defines one command of para_play */
-struct pp_command {
-       const char *name;
-       play_command_handler_t *handler;
-       const char *description;
-       const char *usage;
-       const char *help;
-};
-
-static struct pp_command pp_cmds[] = {DEFINE_PLAY_CMD_ARRAY};
-#define FOR_EACH_COMMAND(c) for (c = 0; pp_cmds[c].name; c++)
-
 static struct i9e_completer pp_completers[];
 
 I9E_DUMMY_COMPLETER(jmp);
 static struct i9e_completer pp_completers[];
 
 I9E_DUMMY_COMPLETER(jmp);
@@ -728,13 +692,13 @@ static void detach_stdout(struct play_task *pt)
        btr_remove_node(&pt->btrn);
 }
 
        btr_remove_node(&pt->btrn);
 }
 
-static int com_quit(struct play_task *pt, int argc, __a_unused char **argv)
+static int com_quit(struct play_task *pt,
+               __a_unused struct lls_parse_result *lpr)
 {
 {
-       if (argc != 1)
-               return -E_PLAY_SYNTAX;
        pt->rq = CRT_TERM_RQ;
        return 0;
 }
        pt->rq = CRT_TERM_RQ;
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(quit);
 
 static int com_help(struct play_task *pt, struct lls_parse_result *lpr)
 {
 
 static int com_help(struct play_task *pt, struct lls_parse_result *lpr)
 {
@@ -757,11 +721,6 @@ static int com_help(struct play_task *pt, struct lls_parse_result *lpr)
                                        lls_command_name(cmd), lls_purpose(cmd));
                                btr_add_output(buf, sz, pt->btrn);
                        }
                                        lls_command_name(cmd), lls_purpose(cmd));
                                btr_add_output(buf, sz, pt->btrn);
                        }
-                       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);
-                       }
                        return 0;
                }
                FOR_EACH_MAPPED_KEY(i) {
                        return 0;
                }
                FOR_EACH_MAPPED_KEY(i) {
@@ -794,14 +753,13 @@ static int com_help(struct play_task *pt, struct lls_parse_result *lpr)
 }
 EXPORT_PLAY_CMD_HANDLER(help);
 
 }
 EXPORT_PLAY_CMD_HANDLER(help);
 
-static int com_info(struct play_task *pt, int argc, __a_unused char **argv)
+static int com_info(struct play_task *pt,
+               __a_unused struct lls_parse_result *lpr)
 {
        char *buf;
        size_t sz;
        static char dflt[] = "[no information available]";
 
 {
        char *buf;
        size_t sz;
        static char dflt[] = "[no information available]";
 
-       if (argc != 1)
-               return -E_PLAY_SYNTAX;
        sz = xasprintf(&buf, "playlist_pos: %u\npath: %s\n",
                pt->current_file, conf.inputs[pt->current_file]);
        btr_add_output(buf, sz, pt->btrn);
        sz = xasprintf(&buf, "playlist_pos: %u\npath: %s\n",
                pt->current_file, conf.inputs[pt->current_file]);
        btr_add_output(buf, sz, pt->btrn);
@@ -809,6 +767,7 @@ static int com_info(struct play_task *pt, int argc, __a_unused char **argv)
        btr_add_output_dont_free(buf, strlen(buf), pt->btrn);
        return 0;
 }
        btr_add_output_dont_free(buf, strlen(buf), pt->btrn);
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(info);
 
 static void list_file(struct play_task *pt, int num)
 {
 
 static void list_file(struct play_task *pt, int num)
 {
@@ -820,15 +779,13 @@ static void list_file(struct play_task *pt, int num)
        btr_add_output(buf, sz, pt->btrn);
 }
 
        btr_add_output(buf, sz, pt->btrn);
 }
 
-static int com_tasks(struct play_task *pt, int argc, __a_unused char **argv)
+static int com_tasks(struct play_task *pt,
+               __a_unused struct lls_parse_result *lpr)
 {
        static char state;
        char *buf;
        size_t sz;
 
 {
        static char state;
        char *buf;
        size_t sz;
 
-       if (argc != 1)
-               return -E_PLAY_SYNTAX;
-
        buf = get_task_list(&sched);
        btr_add_output(buf, strlen(buf), pt->btrn);
        state = get_playback_state(pt);
        buf = get_task_list(&sched);
        btr_add_output(buf, strlen(buf), pt->btrn);
        state = get_playback_state(pt);
@@ -836,36 +793,34 @@ static int com_tasks(struct play_task *pt, int argc, __a_unused char **argv)
        btr_add_output(buf, sz, pt->btrn);
        return 0;
 }
        btr_add_output(buf, sz, pt->btrn);
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(tasks);
 
 
-static int com_ls(struct play_task *pt, int argc, char **argv)
+static int com_ls(struct play_task *pt,
+       __a_unused struct lls_parse_result *lpr)
 {
 {
-       int i, j, ret;
+       int i;
 
 
-       if (argc == 1) {
-               FOR_EACH_PLAYLIST_FILE(i)
-                       list_file(pt, i);
-               return 0;
-       }
-       for (j = 1; j < argc; j++) {
-               FOR_EACH_PLAYLIST_FILE(i) {
-                       ret = fnmatch(argv[j], conf.inputs[i], 0);
-                       if (ret == 0) /* match */
-                               list_file(pt, i);
-               }
-       }
+       FOR_EACH_PLAYLIST_FILE(i)
+               list_file(pt, i);
        return 0;
 }
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(ls);
 
 
-static int com_play(struct play_task *pt, int argc, char **argv)
+static int com_play(struct play_task *pt, struct lls_parse_result *lpr)
 {
        int32_t x;
        int ret;
 {
        int32_t x;
        int ret;
-       char state;
+       char state, *errctx;
 
 
-       if (argc > 2)
-               return -E_PLAY_SYNTAX;
+       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;
+       }
        state = get_playback_state(pt);
        state = get_playback_state(pt);
-       if (argc == 1) {
+       if (lls_num_inputs(lpr) == 0) {
                if (state == 'P')
                        return 0;
                pt->next_file = pt->current_file;
                if (state == 'P')
                        return 0;
                pt->next_file = pt->current_file;
@@ -873,7 +828,7 @@ static int com_play(struct play_task *pt, int argc, char **argv)
                pt->playing = true;
                return 0;
        }
                pt->playing = true;
                return 0;
        }
-       ret = para_atoi32(argv[1], &x);
+       ret = para_atoi32(lls_input(0, lpr), &x);
        if (ret < 0)
                return ret;
        if (x < 0 || x >= conf.inputs_num)
        if (ret < 0)
                return ret;
        if (x < 0 || x >= conf.inputs_num)
@@ -883,14 +838,14 @@ static int com_play(struct play_task *pt, int argc, char **argv)
        pt->rq = CRT_FILE_CHANGE;
        return 0;
 }
        pt->rq = CRT_FILE_CHANGE;
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(play);
 
 
-static int com_pause(struct play_task *pt, int argc, __a_unused char **argv)
+static int com_pause(struct play_task *pt,
+               __a_unused struct lls_parse_result *lpr)
 {
        char state;
        long unsigned seconds, ss;
 
 {
        char state;
        long unsigned seconds, ss;
 
-       if (argc != 1)
-               return -E_PLAY_SYNTAX;
        state = get_playback_state(pt);
        pt->playing = false;
        if (state != 'P')
        state = get_playback_state(pt);
        pt->playing = false;
        if (state != 'P')
@@ -906,14 +861,13 @@ static int com_pause(struct play_task *pt, int argc, __a_unused char **argv)
        kill_stream(pt);
        return 0;
 }
        kill_stream(pt);
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(pause);
 
 
-static int com_prev(struct play_task *pt, int argc, __a_unused char **argv)
-
+static int com_prev(struct play_task *pt,
+       __a_unused struct lls_parse_result *lpr)
 {
        int ret;
 
 {
        int ret;
 
-       if (argc != 1)
-               return -E_PLAY_SYNTAX;
        ret = previous_valid_file(pt);
        if (ret < 0)
                return ret;
        ret = previous_valid_file(pt);
        if (ret < 0)
                return ret;
@@ -923,6 +877,7 @@ static int com_prev(struct play_task *pt, int argc, __a_unused char **argv)
        pt->start_chunk = 0;
        return 0;
 }
        pt->start_chunk = 0;
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(prev);
 
 static int com_next(struct play_task *pt,
                __a_unused struct lls_parse_result *lpr)
 
 static int com_next(struct play_task *pt,
                __a_unused struct lls_parse_result *lpr)
@@ -948,22 +903,28 @@ static int com_fg(struct play_task *pt,
 }
 EXPORT_PLAY_CMD_HANDLER(fg);
 
 }
 EXPORT_PLAY_CMD_HANDLER(fg);
 
-static int com_bg(struct play_task *pt, int argc, __a_unused char **argv)
+static int com_bg(struct play_task *pt,
+       __a_unused struct lls_parse_result *lpr)
 {
 {
-       if (argc != 1)
-               return -E_PLAY_SYNTAX;
        pt->background = true;
        return 0;
 }
        pt->background = true;
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(bg);
 
 
-static int com_jmp(struct play_task *pt, int argc, char **argv)
+static int com_jmp(struct play_task *pt, struct lls_parse_result *lpr)
 {
        int32_t percent;
        int ret;
 {
        int32_t percent;
        int ret;
+       char *errctx;
 
 
-       if (argc != 2)
-               return -E_PLAY_SYNTAX;
-       ret = para_atoi32(argv[1], &percent);
+       ret = lls(lls_check_arg_count(lpr, 1, 1, &errctx));
+       if (ret < 0) {
+               if (errctx)
+                       PARA_ERROR_LOG("%s\n", errctx);
+               free(errctx);
+               return ret;
+       }
+       ret = para_atoi32(lls_input(0, lpr), &percent);
        if (ret < 0)
                return ret;
        if (percent < 0 || percent > 100)
        if (ret < 0)
                return ret;
        if (percent < 0 || percent > 100)
@@ -979,15 +940,22 @@ static int com_jmp(struct play_task *pt, int argc, char **argv)
        kill_stream(pt);
        return 0;
 }
        kill_stream(pt);
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(jmp);
 
 
-static int com_ff(struct play_task *pt, int argc, char **argv)
+static int com_ff(struct play_task *pt, struct lls_parse_result *lpr)
 {
        int32_t seconds;
 {
        int32_t seconds;
+       char *errctx;
        int ret;
 
        int ret;
 
-       if (argc != 2)
-               return -E_PLAY_SYNTAX;
-       ret = para_atoi32(argv[1], &seconds);
+       ret = lls(lls_check_arg_count(lpr, 1, 1, &errctx));
+       if (ret < 0) {
+               if (errctx)
+                       PARA_ERROR_LOG("%s\n", errctx);
+               free(errctx);
+               return ret;
+       }
+       ret = para_atoi32(lls_input(0, lpr), &seconds);
        if (ret < 0)
                return ret;
        if (pt->playing && !pt->fn.btrn)
        if (ret < 0)
                return ret;
        if (pt->playing && !pt->fn.btrn)
@@ -1004,10 +972,11 @@ static int com_ff(struct play_task *pt, int argc, char **argv)
        kill_stream(pt);
        return 0;
 }
        kill_stream(pt);
        return 0;
 }
+EXPORT_PLAY_CMD_HANDLER(ff);
 
 static int run_command(char *line, struct play_task *pt)
 {
 
 static int run_command(char *line, struct play_task *pt)
 {
-       int i, ret, argc;
+       int ret, argc;
        char **argv = NULL;
        char *errctx = NULL;
        const struct play_command_info *pci;
        char **argv = NULL;
        char *errctx = NULL;
        const struct play_command_info *pci;
@@ -1021,26 +990,16 @@ static int run_command(char *line, struct play_task *pt)
        if (ret == 0)
                goto out;
        argc = ret;
        if (ret == 0)
                goto out;
        argc = ret;
-
        ret = lls(lls_lookup_subcmd(argv[0], play_cmd_suite, &errctx));
        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)
-                       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;
-               }
-       }
+       if (ret < 0)
+               goto out;
+       cmd = lls_cmd(ret, play_cmd_suite);
+       ret = lls(lls_parse(argc, argv, cmd, &lpr, &errctx));
+       if (ret < 0)
+               goto out;
+       pci = lls_user_data(cmd);
+       ret = pci->handler(pt, lpr);
+       lls_free_parse_result(lpr, cmd);
 out:
        if (errctx)
                PARA_ERROR_LOG("%s\n", errctx);
 out:
        if (errctx)
                PARA_ERROR_LOG("%s\n", errctx);
@@ -1310,8 +1269,7 @@ int main(int argc, char *argv[])
        parse_config_or_die(argc, argv);
        if (conf.inputs_num == 0)
                print_help_and_die();
        parse_config_or_die(argc, argv);
        if (conf.inputs_num == 0)
                print_help_and_die();
-       check_afh_receiver_or_die();
-
+       AFH_RECV->init();
        session_open(pt);
        if (conf.randomize_given)
                shuffle(conf.inputs, conf.inputs_num);
        session_open(pt);
        if (conf.randomize_given)
                shuffle(conf.inputs, conf.inputs_num);