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