1#ifndef MPDSERVER_PARSER_H2#define MPDSERVER_PARSER_H34#include <assert.h>5#include <stdlib.h>6#include <string.h>78#include "mpc.h"9#include "mpdserver.h"1011#define LENGTH(X) (sizeof(X) / sizeof(X[0]))1213#define mpdf_fold(I, ...) \14 static mpc_val_t *mpdf_##I(int n, mpc_val_t **xs) \15 { \16 int i, j; \17 mpd_command_t *cmd; \18 \19 /* Remove optional mpc_maybe() arguments */ \20 for (j = n - 1; j >= 0; j--) \21 if (!xs[j]) \22 --n; \23 \24 assert(n > 0); \25 assert(!strcmp(xs[0], #I)); \26 \27 cmd = mpd_new_command(xs[0], (size_t)n - 1); \28 \29 i = 0; \30 __VA_ARGS__ \31 \32 return cmd; \33 }3435#define mpd_arg(TYPE, MEMBER, CONV, FREE) \36 do { \37 cmd->argv[i] = xmalloc(sizeof(mpd_argument_t)); \38 cmd->argv[i]->type = TYPE; \39 cmd->argv[i]->v.MEMBER = CONV xs[i + 1]; \40 \41 i++; \42 if (FREE) \43 free(xs[i]); \44 } while (0);4546#define mpd_opt_arg(ARG) \47 if (n > i + 1) { \48 ARG \49 }5051#define MPD_ARG_INT mpd_arg(MPD_VAL_INT, ival, *(int *), 1)52#define MPD_ARG_UINT mpd_arg(MPD_VAL_UINT, uval, *(unsigned int *), 1)53#define MPD_ARG_FLOAT mpd_arg(MPD_VAL_FLOAT, fval, *(float *), 1)54#define MPD_ARG_BOOL mpd_arg(MPD_VAL_BOOL, bval, *(int *), 1)55#define MPD_ARG_RANGE mpd_arg(MPD_VAL_RANGE, rval, *(mpd_range_t *), 1)56#define MPD_ARG_STRING mpd_arg(MPD_VAL_STR, sval, (char *), 0)57#define MPD_ARG_EXPR mpd_arg(MPD_VAL_EXPR_STR, sval, (char *), 0)5859typedef struct {60 char **ptr;61 size_t len;62} mpd_string_array_t;6364/* clang-format off */65#define MPD_STRING_ARY(ARY) {ARY, LENGTH(ARY)}66/* clang-format on */6768mpc_parser_t *mpd_playback_cmds(void);69mpc_parser_t *mpd_status_cmds(void);70mpc_parser_t *mpd_list_cmds(void);71mpc_parser_t *mpd_control_cmds(void);72mpc_parser_t *mpd_queue_cmds(void);73mpc_parser_t *mpd_database_cmds(void);74mpc_parser_t *mpd_connection_cmds(void);7576mpc_parser_t *mpd_argument(mpc_parser_t *);77mpc_parser_t *mpd_int(void);78mpc_parser_t *mpd_uint(void);79mpc_parser_t *mpd_binary(void);80mpc_parser_t *mpd_float_digits(void);81mpc_parser_t *mpd_float(void);82mpc_parser_t *mpd_range(void);83mpc_parser_t *mpd_range_with_single(void);84mpc_parser_t *mpd_string(void);85mpc_parser_t *mpd_string_case(void);86mpc_parser_t *mpd_uri(void);87mpc_parser_t *mpd_command_primitive(void);88mpc_parser_t *mpd_cmd_noarg(char *);89mpc_parser_t *mpd_whitespace(void);90mpc_parser_t *mpd_tag_name(void);9192mpc_val_t *mpdf_lowercase(mpc_val_t *);93mpc_val_t *mpdf_unescape(mpc_val_t *);9495void *xmalloc(size_t);96char *xstrdup(char *);97void *xrealloc(void *, size_t);98char *lowercase(char *);99mpd_range_t *mpd_new_range(size_t, ssize_t);100mpd_command_t *mpd_new_command(char *, size_t);101void mpd_free_expression(void *);102mpd_expression_t *mpd_expression(char *);103int mpd_check_array(mpc_val_t **, void *);104105#endif