1#include <assert.h>
2#include <stddef.h>
3
4#include "fns.h"
5#include "mpc.h"
6
7static mpc_val_t *
8mpdf_fold_command(int n, mpc_val_t **xs)
9{
10 int i;
11 mpd_command_t *cmd;
12
13 assert(n > 0);
14
15 cmd = mpd_new_command(NULL, (size_t)n);
16 for (i = 0; i < n; i++) {
17 cmd->argv[i] = xmalloc(sizeof(mpd_argument_t));
18 cmd->argv[i]->type = MPD_VAL_CMD;
19 cmd->argv[i]->v.cmdval = (mpd_command_t *)xs[i];
20 }
21
22 return cmd;
23}
24
25static mpc_val_t *
26mpdf_fold_list(int n, mpc_val_t **xs)
27{
28 mpd_command_t *cmd;
29 char *lstart;
30
31 assert(n == 3);
32 assert(!strcmp(xs[n - 1], "command_list_end"));
33
34 lstart = (char *)xs[0];
35 assert(!strcmp(lstart, "command_list_begin") ||
36 !strcmp(lstart, "command_list_ok_begin"));
37
38 free(xs[n - 1]);
39
40 cmd = (mpd_command_t *)xs[1];
41 assert(!cmd->name);
42 cmd->name = lstart;
43
44 return cmd;
45}
46
47mpc_parser_t *
48mpd_list_cmds(void)
49{
50 mpc_parser_t *endstr, *startstrs, *lbeg, *lend, *cmds;
51
52 startstrs = mpc_or(2, mpc_string("command_list_begin"),
53 mpc_string("command_list_ok_begin"));
54 endstr = mpc_string("command_list_end");
55
56 lbeg = mpc_and(2, mpcf_fst_free, startstrs, mpc_newline(), free);
57 lend = mpc_and(2, mpcf_fst_free, endstr, mpc_newline(), free);
58
59 cmds = mpc_many1(mpdf_fold_command, mpd_command_primitive());
60 return mpc_and(3, mpdf_fold_list, lbeg, cmds, lend, free,
61 mpd_free_command);
62}