1#include "fns.h"2#include "mpc.h"34static char *mpd_gain_modes[] = {5 "off",6 "track",7 "album",8 "auto",9};1011static mpc_val_t *12mpdf_nan(mpc_val_t *val)13{14 int *ptr;1516 free(val);17 ptr = xmalloc(sizeof(*ptr));18 *ptr = -1;19 return ptr;20}2122static int23mpd_check_volume(mpc_val_t **val)24{25 unsigned int *ptr;2627 ptr = *(unsigned **)val;28 return *ptr <= 100;29}3031mpdf_fold(consume, MPD_ARG_BOOL)3233static mpc_parser_t *34mpd_consume(void)35{36 return mpc_and(2, mpdf_consume, mpc_string("consume"),37 mpd_argument(mpd_binary()), free);38}3940mpdf_fold(crossfade, MPD_ARG_UINT)4142static mpc_parser_t *43mpd_crossfade(void)44{45 return mpc_and(2, mpdf_crossfade, mpc_string("crossfade"),46 mpd_argument(mpd_uint()), free);47}4849mpdf_fold(mixrampdb, MPD_ARG_FLOAT)5051static mpc_parser_t *52mpd_mixrampdb(void)53{54 mpc_parser_t *neg, *val;5556 neg = mpc_and(2, mpcf_strfold, mpc_char('-'), mpd_float_digits(), free);57 val = mpc_or(2, mpd_float(), mpc_apply(neg, mpcf_float));5859 return mpc_and(2, mpdf_mixrampdb, mpc_string("mixrampdb"),60 mpd_argument(val), free);61}6263mpdf_fold(mixrampdelay, MPD_ARG_INT)6465static mpc_parser_t *66mpd_mixrampdelay(void)67{68 mpc_parser_t *val;6970 /* 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}7576mpdf_fold(random, MPD_ARG_BOOL)7778static mpc_parser_t *79mpd_random(void)80{81 return mpc_and(2, mpdf_random, mpc_string("random"),82 mpd_argument(mpd_binary()), free);83}8485mpdf_fold(repeat, MPD_ARG_BOOL)8687static mpc_parser_t *88mpd_repeat(void)89{90 return mpc_and(2, mpdf_repeat, mpc_string("repeat"),91 mpd_argument(mpd_binary()), free);92}9394mpdf_fold(setvol, MPD_ARG_UINT)9596static mpc_parser_t *97mpd_setvol(void)98{99 mpc_parser_t *vol;100101 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}105106mpdf_fold(single, MPD_ARG_STRING)107108static mpc_parser_t *109mpd_single(void)110{111 mpc_parser_t *val;112113 /* 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}119120mpdf_fold(replay_gain_mode, MPD_ARG_STRING)121122static 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);127128 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}133134static mpc_parser_t *135mpd_replay_gain_status(void)136{137 return mpd_cmd_noarg("replay_gain_status");138}139140mpdf_fold(volume, MPD_ARG_INT)141142static 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}149150mpc_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}