libmpdserver

Parser combinator library for MPD client commands

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

  1#include "fns.h"
  2#include "mpc.h"
  3
  4static char *mpd_gain_modes[] = {
  5    "off",
  6    "track",
  7    "album",
  8    "auto",
  9};
 10
 11static mpc_val_t *
 12mpdf_nan(mpc_val_t *val)
 13{
 14	int *ptr;
 15
 16	free(val);
 17	ptr = xmalloc(sizeof(*ptr));
 18	*ptr = -1;
 19	return ptr;
 20}
 21
 22static int
 23mpd_check_volume(mpc_val_t **val)
 24{
 25	unsigned int *ptr;
 26
 27	ptr = *(unsigned **)val;
 28	return *ptr <= 100;
 29}
 30
 31mpdf_fold(consume, MPD_ARG_BOOL)
 32
 33static mpc_parser_t *
 34mpd_consume(void)
 35{
 36	return mpc_and(2, mpdf_consume, mpc_string("consume"),
 37	               mpd_argument(mpd_binary()), free);
 38}
 39
 40mpdf_fold(crossfade, MPD_ARG_UINT)
 41
 42static mpc_parser_t *
 43mpd_crossfade(void)
 44{
 45	return mpc_and(2, mpdf_crossfade, mpc_string("crossfade"),
 46	               mpd_argument(mpd_uint()), free);
 47}
 48
 49mpdf_fold(mixrampdb, MPD_ARG_FLOAT)
 50
 51static mpc_parser_t *
 52mpd_mixrampdb(void)
 53{
 54	mpc_parser_t *neg, *val;
 55
 56	neg = mpc_and(2, mpcf_strfold, mpc_char('-'), mpd_float_digits(), free);
 57	val = mpc_or(2, mpd_float(), mpc_apply(neg, mpcf_float));
 58
 59	return mpc_and(2, mpdf_mixrampdb, mpc_string("mixrampdb"),
 60	               mpd_argument(val), free);
 61}
 62
 63mpdf_fold(mixrampdelay, MPD_ARG_INT)
 64
 65static mpc_parser_t *
 66mpd_mixrampdelay(void)
 67{
 68	mpc_parser_t *val;
 69
 70	/* TODO: document that nan is canonicalized as -1 */
 71	val = mpc_or(2, mpc_int(), mpc_apply(mpc_string("nan"), mpdf_nan));
 72	return mpc_and(2, mpdf_mixrampdelay, mpc_string("mixrampdelay"),
 73	               mpd_argument(val), free);
 74}
 75
 76mpdf_fold(random, MPD_ARG_BOOL)
 77
 78static mpc_parser_t *
 79mpd_random(void)
 80{
 81	return mpc_and(2, mpdf_random, mpc_string("random"),
 82	               mpd_argument(mpd_binary()), free);
 83}
 84
 85mpdf_fold(repeat, MPD_ARG_BOOL)
 86
 87static mpc_parser_t *
 88mpd_repeat(void)
 89{
 90	return mpc_and(2, mpdf_repeat, mpc_string("repeat"),
 91	               mpd_argument(mpd_binary()), free);
 92}
 93
 94mpdf_fold(setvol, MPD_ARG_UINT)
 95
 96static mpc_parser_t *
 97mpd_setvol(void)
 98{
 99	mpc_parser_t *vol;
100
101	vol = mpc_check(mpd_uint(), free, mpd_check_volume, "invalid volume");
102	return mpc_and(2, mpdf_setvol, mpc_string("setvol"), mpd_argument(vol),
103	               free);
104}
105
106mpdf_fold(single, MPD_ARG_STRING)
107
108static mpc_parser_t *
109mpd_single(void)
110{
111	mpc_parser_t *val;
112
113	/* TODO: don't canonicalize value as string */
114	val =
115	    mpc_or(3, mpc_string("0"), mpc_string("1"), mpc_string("oneshot"));
116	return mpc_and(2, mpdf_single, mpc_string("single"), mpd_argument(val),
117	               free);
118}
119
120mpdf_fold(replay_gain_mode, MPD_ARG_STRING)
121
122static mpc_parser_t *
123mpd_replay_gain_mode(void)
124{
125	mpc_parser_t *mode;
126	static mpd_string_array_t ary = MPD_STRING_ARY(mpd_gain_modes);
127
128	mode = mpc_check_with(mpd_string_case(), free, mpd_check_array, &ary,
129	                      "invalid gain mode");
130	return mpc_and(2, mpdf_replay_gain_mode, mpc_string("replay_gain_mode"),
131	               mpd_argument(mode), free);
132}
133
134static mpc_parser_t *
135mpd_replay_gain_status(void)
136{
137	return mpd_cmd_noarg("replay_gain_status");
138}
139
140mpdf_fold(volume, MPD_ARG_INT)
141
142static mpc_parser_t *
143mpd_volume(void)
144{
145	/* XXX: This is deprecated */
146	return mpc_and(2, mpdf_volume, mpc_string("volume"),
147	               mpd_argument(mpd_int()), free);
148}
149
150mpc_parser_t *
151mpd_playback_cmds(void)
152{
153	return mpc_or(11, mpd_consume(), mpd_crossfade(), mpd_mixrampdb(),
154	              mpd_mixrampdelay(), mpd_setvol(), mpd_single(),
155	              mpd_random(), mpd_repeat(), mpd_replay_gain_mode(),
156	              mpd_replay_gain_status(), mpd_volume());
157}