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}