X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=play.c;h=4dab1cad58b3a989e96072c95e153b08cd18e24f;hp=ce10a56bb9001f6675c18d06ce60323bbfeccf7e;hb=fc8dfbb416ff07cca08fbf4e13efcaa25e17cc54;hpb=639f0dd92d1fc446eaa7c4747a7b132be5741f7e diff --git a/play.c b/play.c index ce10a56b..4dab1cad 100644 --- a/play.c +++ b/play.c @@ -7,11 +7,11 @@ /** \file play.c Paraslash's standalone player. */ #include -#include #include #include #include +#include "recv_cmd.lsg.h" #include "para.h" #include "list.h" #include "play.cmdline.h" @@ -111,14 +111,6 @@ struct play_command_info { .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. */ @@ -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 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) { @@ -243,12 +222,13 @@ static long unsigned get_play_time(struct play_task *pt) 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); - 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)); } @@ -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) - 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; - 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); - 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; @@ -421,9 +402,9 @@ static int load_file(struct play_task *pt) /* 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); @@ -666,23 +647,6 @@ static char **get_mapped_keyseqs(void) 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); @@ -728,13 +692,13 @@ static void detach_stdout(struct play_task *pt) 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; } +EXPORT_PLAY_CMD_HANDLER(quit); 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); } - 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) { @@ -794,14 +753,13 @@ static int com_help(struct play_task *pt, struct lls_parse_result *lpr) } 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]"; - 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); @@ -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; } +EXPORT_PLAY_CMD_HANDLER(info); 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); } -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; - 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); @@ -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; } +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; } +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; - 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); - if (argc == 1) { + if (lls_num_inputs(lpr) == 0) { 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; } - 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) @@ -883,14 +838,14 @@ static int com_play(struct play_task *pt, int argc, char **argv) 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; - if (argc != 1) - return -E_PLAY_SYNTAX; 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; } +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; - if (argc != 1) - return -E_PLAY_SYNTAX; 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; } +EXPORT_PLAY_CMD_HANDLER(prev); 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); -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; } +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; + 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) @@ -979,15 +940,22 @@ static int com_jmp(struct play_task *pt, int argc, char **argv) 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; + char *errctx; 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) @@ -1004,10 +972,11 @@ static int com_ff(struct play_task *pt, int argc, char **argv) kill_stream(pt); return 0; } +EXPORT_PLAY_CMD_HANDLER(ff); 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; @@ -1021,26 +990,16 @@ static int run_command(char *line, struct play_task *pt) if (ret == 0) goto out; argc = ret; - 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); @@ -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(); - check_afh_receiver_or_die(); - + AFH_RECV->init(); session_open(pt); if (conf.randomize_given) shuffle(conf.inputs, conf.inputs_num);