1#ifndef MPDSERVER_PARSER_H
2#define MPDSERVER_PARSER_H
3
4#include <assert.h>
5#include <stdlib.h>
6#include <string.h>
7
8#include "mpc.h"
9#include "mpdserver.h"
10
11#define LENGTH(X) (sizeof(X) / sizeof(X[0]))
12
13#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 }
34
35#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);
45
46#define mpd_opt_arg(ARG) \
47 if (n > i + 1) { \
48 ARG \
49 }
50
51#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)
58
59typedef struct {
60 char **ptr;
61 size_t len;
62} mpd_string_array_t;
63
64/* clang-format off */
65#define MPD_STRING_ARY(ARY) {ARY, LENGTH(ARY)}
66/* clang-format on */
67
68mpc_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);
75
76mpc_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);
91
92mpc_val_t *mpdf_lowercase(mpc_val_t *);
93mpc_val_t *mpdf_unescape(mpc_val_t *);
94
95void *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 *);
104
105#endif