libmpdserver

Parser combinator library for MPD client commands

git clone https://git.8pit.net/libmpdserver.git

 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}