libmpdserver

Parser combinator library for MPD client commands

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

  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