string.c: Fix typos in comment.
[paraslash.git] / mp.h
1 /* Copyright (C) 2017 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
2
3 /**
4 * \file mp.h Internal mood parser API (backend).
5 *
6 * This header is included from the lexer, the parser, and from \ref mp.c, but
7 * not from \ref mood.c, the only user of the mood parser front end. It
8 * contains structures and function prototypes which are considered
9 * implementation details.
10 *
11 * There is one function for each keyword in the context-free grammar of the
12 * parser. These functions return the semantic value of the keyword.
13 *
14 * The functions declared here are defined either in mp.c or in mp.y.
15 */
16
17 /** Opaque, only known to mp.c. Passed to the generated mp_yyparse(). */
18 struct mp_context;
19
20 /**
21 * Since we use a reentrant lexer, all functions generated by flex(1)
22 * receive an additional argument of this type.
23 */
24 typedef void *mp_yyscan_t;
25
26 /** Parsed regex pattern. */
27 struct mp_re_pattern {
28 regex_t preg; /**< Pre-compiled regex. **/
29 unsigned flags; /**< Subset of the cflags described in regex(3). */
30 };
31
32 /** Parsed wildcard pattern. */
33 struct mp_wc_pattern {
34 char *pat; /**< Unescaped C string (without quotes and flags). */
35 unsigned flags; /**< For modifying matching behaviour. */
36 };
37
38 /**
39 * The possible values of a node in the abstract syntax tree (AST).
40 *
41 * Constant semantic values (string literals, numeric constants, wildcard and
42 * regex patterns which are part of the mood definition) are determined during
43 * \ref mp_init() while values which depend on the audio file (path, bitrate,
44 * etc.) are determined during mp_eval_row().
45 *
46 * This union, and the \ref mp_ast_node structure below are used extensively in
47 * mp.y. However, both need to be public because the lexer must be able to
48 * create AST nodes for the constant semantic values.
49 */
50 union mp_semantic_value {
51 bool boolval; /**< Comparators, =~ and =|. */
52 char *strval; /**< String literals, tags, path. */
53 int64_t intval; /**< Constants, bitrate, frequency, etc. */
54 struct mp_wc_pattern wc_pattern; /**< Right-hand side operand of =|. */
55 struct mp_re_pattern re_pattern; /**< Right-hand side operand of =~. */
56 };
57
58 /**
59 * Describes one node of the abstract syntax tree.
60 *
61 * A node is either interior or a leaf node. Interior nodes have at least one
62 * child while leaf nodes have a semantic value and no children.
63 *
64 * Examples: (a) STRING_LITERAL has a semantic value (the unescaped string
65 * literal) and no children, (b) NEG (unary minus) has no semantic value but
66 * one child (the numeric expression that is to be negated), (c) LESS_OR_EQUAL
67 * has no semantic value and two children (the two numeric expressions being
68 * compared).
69 */
70 struct mp_ast_node {
71 /** Corresponds to a token type, for example LESS_OR_EQUAL. */
72 int id;
73 union {
74 /** Pointers to the child nodes (interior nodes only). */
75 struct mp_ast_node **children;
76 /** Leaf nodes only. */
77 union mp_semantic_value sv;
78 };
79 /**
80 * The number of children is implicitly given by the id, but we include
81 * it here to avoid having to maintain a lookup table. The AST is
82 * usually small, so we can afford to waste a byte per node.
83 */
84 uint8_t num_children;
85 };
86
87 /* Called from both the lexer and the parser. */
88 __printf_3_4 void mp_parse_error(int line, struct mp_context *ctx,
89 const char *fmt, ...);
90
91 /* Helper functions for the lexer. */
92 unsigned parse_quoted_string(const char *src, const char quote_chars[2],
93 char **result);
94 int mp_parse_regex_pattern(const char *src, struct mp_re_pattern *result);
95 void mp_parse_wildcard_pattern(const char *src, struct mp_wc_pattern *result);
96
97 /*
98 * The functions below are implemented in mp.y. They are documented here
99 * because mp.y is not doxyfied.
100 */
101
102 /**
103 * Allocate a new leaf node for the abstract syntax tree.
104 *
105 * \param id Initial value for the ->id field of the new node
106 *
107 * \return Pointer to a node whose ->num_children field is initialized to zero.
108 * The caller is expected to initialize the ->sv field.
109 */
110 struct mp_ast_node *mp_new_ast_leaf_node(int id);
111
112 /**
113 * Evaluate an abstract syntax tree, starting at the root node.
114 *
115 * \param root As returned from \ref mp_init() via the context pointer.
116 * \param ctx Contains the aft row to evaluate.
117 *
118 * \return True if the AST evaluates to true, a non-empty string, or a
119 * non-zero number. False otherwise.
120 *
121 * \sa mp_eval_row().
122 */
123 bool mp_eval_ast(struct mp_ast_node *root, struct mp_context *ctx);
124
125 /**
126 * Deallocate an abstract syntax tree.
127 *
128 * This frees the memory occupied by the nodes of the AST, the child pointers
129 * of the internal nodes and the (constant) semantic values of the leaf nodes
130 * (string literals, unescaped wildcard patterns and pre-compiled regular
131 * expressions).
132 *
133 * \param root It's OK to pass NULL here.
134 */
135 void mp_free_ast(struct mp_ast_node *root);
136
137 /* Helper functions for the parser. */
138 bool mp_is_set(const char *attr, struct mp_context *ctx);
139 char *mp_path(struct mp_context *ctx);
140 int64_t mp_year(struct mp_context *ctx);
141 int64_t mp_num_attributes_set(struct mp_context *ctx);
142
143 /* Generated with MP_AFSI() */
144 /** \cond MP_AFSI */
145 int64_t mp_num_played(struct mp_context *ctx);
146 int64_t mp_image_id(struct mp_context *ctx);
147 int64_t mp_lyrics_id(struct mp_context *ctx);
148 /** \endcond */
149
150 /* Generated with MP_AFHI() */
151 /** \cond MP_AFHI */
152 int64_t mp_bitrate(struct mp_context *ctx);
153 int64_t mp_frequency(struct mp_context *ctx);
154 int64_t mp_channels(struct mp_context *ctx);
155 /** \endcond */
156
157 /* Generated with MP_TAG() */
158 /** \cond MP_TAG */
159 char *mp_artist(struct mp_context *ctx);
160 char *mp_title(struct mp_context *ctx);
161 char *mp_album(struct mp_context *ctx);
162 char *mp_comment(struct mp_context *ctx);
163 /** \endcond */