1 /*
2  * Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm dot org>
3  *
4  * This file is part of Zrythm
5  *
6  * Zrythm is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Zrythm is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 /**
21  * \file
22  *
23  * YAML utils.
24  */
25 
26 #ifndef __UTILS_YAML_H__
27 #define __UTILS_YAML_H__
28 
29 #include <gtk/gtk.h>
30 
31 #include <cyaml/cyaml.h>
32 
33 /**
34  * @addtogroup utils
35  *
36  * @{
37  */
38 
39 /**
40  * Mapping embedded inside the struct.
41  */
42 #define YAML_FIELD_MAPPING_EMBEDDED( \
43   owner,member,schema) \
44   CYAML_FIELD_MAPPING ( \
45     #member, CYAML_FLAG_DEFAULT, owner, member, \
46     schema)
47 
48 /**
49  * Mapping pointer to a struct.
50  */
51 #define YAML_FIELD_MAPPING_PTR( \
52   owner,member,schema) \
53   CYAML_FIELD_MAPPING_PTR ( \
54     #member, CYAML_FLAG_POINTER, owner, member, \
55     schema)
56 
57 /**
58  * Mapping pointer to a struct.
59  */
60 #define YAML_FIELD_MAPPING_PTR_OPTIONAL( \
61   owner,member,schema) \
62   CYAML_FIELD_MAPPING_PTR ( \
63     #member, \
64     CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, \
65     owner, member, schema)
66 
67 /**
68  * Fixed-width array of pointers with variable count.
69  *
70  * @code@
71  * MyStruct * my_structs[MAX_STRUCTS];
72  * int        num_my_structs;
73  * @endcode@
74  */
75 #define YAML_FIELD_FIXED_SIZE_PTR_ARRAY_VAR_COUNT( \
76   owner,member,schema) \
77   CYAML_FIELD_SEQUENCE_COUNT ( \
78     #member, CYAML_FLAG_DEFAULT, \
79     owner, member, num_##member, \
80     &schema, 0, CYAML_UNLIMITED)
81 
82 /**
83  * Fixed-width array of pointers with fixed count.
84  *
85  * @code@
86  * MyStruct * my_structs[MAX_STRUCTS_CONST];
87  * @endcode@
88  */
89 #define YAML_FIELD_FIXED_SIZE_PTR_ARRAY( \
90   owner,member,schema,size) \
91   CYAML_FIELD_SEQUENCE_FIXED ( \
92     #member, CYAML_FLAG_DEFAULT, \
93     owner, member, \
94     &schema, size)
95 
96 /**
97  * Dynamic-width (reallocated) array of pointers
98  * with variable count.
99  *
100  * @code@
101  * AutomationTrack ** ats;
102  * int                num_ats;
103  * int                ats_size;
104  * @endcode@
105  */
106 #define YAML_FIELD_DYN_PTR_ARRAY_VAR_COUNT( \
107   owner,member,schema) \
108   CYAML_FIELD_SEQUENCE_COUNT ( \
109     #member, CYAML_FLAG_POINTER, \
110     owner, member, num_##member, \
111     &schema, 0, CYAML_UNLIMITED)
112 
113 /**
114  * Dynamic-width (reallocated) array of structs
115  * with variable count.
116  *
117  * @code@
118  * RegionIdentifier * ids;
119  * int                num_ids;
120  * int                ids_size;
121  * @endcode@
122  *
123  * @note \ref schema must be declared as
124  *   CYAML_VALUE_MAPPING with the flag
125  *   CYAML_FLAG_DEFAULT.
126  */
127 #define YAML_FIELD_DYN_ARRAY_VAR_COUNT( \
128   owner,member,schema) \
129   CYAML_FIELD_SEQUENCE_COUNT ( \
130     #member, \
131     CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, \
132     owner, member, num_##member, \
133     &schema, 0, CYAML_UNLIMITED)
134 
135 /**
136  * Dynamic-width (reallocated) array of pointers
137  * with variable count, nullable.
138  *
139  * @code@
140  * AutomationTrack ** ats;
141  * int                num_ats;
142  * int                ats_size;
143  * @endcode@
144  */
145 #define YAML_FIELD_DYN_PTR_ARRAY_VAR_COUNT_OPT( \
146   owner,member,schema) \
147   YAML_FIELD_DYN_ARRAY_VAR_COUNT (\
148     owner,member,schema)
149 
150 /**
151  * Dynamic-width (reallocated) array of primitives
152  * with variable count.
153  *
154  * @code@
155  * int * ids;
156  * int   num_ids;
157  * int   ids_size;
158  * @endcode@
159  *
160  * @note \ref schema must be declared as
161  *   CYAML_VALUE_MAPPING with the flag
162  *   CYAML_FLAG_DEFAULT.
163  */
164 #define YAML_FIELD_DYN_ARRAY_VAR_COUNT_PRIMITIVES( \
165   owner,member,schema) \
166   YAML_FIELD_DYN_ARRAY_VAR_COUNT ( \
167     owner, member, schema)
168 
169 /**
170  * Fixed sequence of pointers.
171  */
172 #define YAML_FIELD_SEQUENCE_FIXED( \
173   owner,member,schema,size) \
174   CYAML_FIELD_SEQUENCE_FIXED ( \
175     #member, CYAML_FLAG_DEFAULT, \
176     owner, member, \
177     &schema, size)
178 
179 #define YAML_FIELD_INT(owner,member) \
180   CYAML_FIELD_INT ( \
181     #member, CYAML_FLAG_DEFAULT, \
182     owner, member)
183 
184 #define YAML_FIELD_UINT(owner,member) \
185   CYAML_FIELD_UINT ( \
186     #member, CYAML_FLAG_DEFAULT, \
187     owner, member)
188 
189 #define YAML_FIELD_FLOAT(owner,member) \
190   CYAML_FIELD_FLOAT ( \
191     #member, CYAML_FLAG_DEFAULT, \
192     owner, member)
193 
194 #define YAML_FIELD_STRING_PTR(owner,member) \
195   CYAML_FIELD_STRING_PTR ( \
196     #member, CYAML_FLAG_POINTER, \
197     owner, member, 0, CYAML_UNLIMITED)
198 
199 #define YAML_FIELD_STRING_PTR_OPTIONAL(owner,member) \
200   CYAML_FIELD_STRING_PTR ( \
201     #member, \
202     CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, \
203     owner, member, 0, CYAML_UNLIMITED)
204 
205 #define YAML_FIELD_ENUM(owner,member,strings) \
206   CYAML_FIELD_ENUM ( \
207     #member, CYAML_FLAG_DEFAULT, \
208     owner, member, strings, \
209     CYAML_ARRAY_LEN (strings))
210 
211 #define YAML_FIELD_BITFIELD(owner,member,bitvals) \
212   CYAML_FIELD_BITFIELD ( \
213     #member, CYAML_FLAG_DEFAULT, \
214     owner, member, bitvals, \
215     CYAML_ARRAY_LEN (bitvals))
216 
217 /**
218  * Schema to be used as a pointer.
219  */
220 #define YAML_VALUE_PTR( \
221   cc,fields_schema) \
222   CYAML_VALUE_MAPPING ( \
223     CYAML_FLAG_POINTER, cc, fields_schema)
224 
225 /**
226  * Schema to be used as a pointer that can be
227  * NULL.
228  */
229 #define YAML_VALUE_PTR_NULLABLE( \
230   cc,fields_schema) \
231   CYAML_VALUE_MAPPING ( \
232     CYAML_FLAG_POINTER_NULL_STR, cc, fields_schema)
233 
234 /**
235  * Schema to be used for arrays of structs directly
236  * (not as pointers).
237  *
238  * For every other case, use the PTR above.
239  */
240 #define YAML_VALUE_DEFAULT( \
241   cc,fields_schema) \
242   CYAML_VALUE_MAPPING ( \
243     CYAML_FLAG_DEFAULT, cc, fields_schema)
244 
245 #define YAML_BITVAL(_name,_offset) \
246   { .name = _name, .offset = _offset, .bits = 1 }
247 
248 /**
249  * Serializes to YAML.
250  *
251  * @return Newly allocated YAML string, or NULL if
252  *   error.
253  */
254 NONNULL
255 char *
256 yaml_serialize (
257   void *                       data,
258   const cyaml_schema_value_t * schema);
259 
260 NONNULL
261 void *
262 yaml_deserialize (
263   const char *                 yaml,
264   const cyaml_schema_value_t * schema);
265 
266 NONNULL
267 void
268 yaml_print (
269   void *                       data,
270   const cyaml_schema_value_t * schema);
271 
272 /**
273  * Custom logging function for libcyaml.
274  */
275 void yaml_cyaml_log_func (
276   cyaml_log_t  level,
277   void *       ctxt,
278   const char * format,
279   va_list      args);
280 
281 void
282 yaml_set_log_level (
283   cyaml_log_t level);
284 
285 void
286 yaml_get_cyaml_config (
287   cyaml_config_t * cyaml_config);
288 
289 static const cyaml_schema_value_t
290 int_schema = {
291   CYAML_VALUE_INT (
292     CYAML_FLAG_DEFAULT, int),
293 };
294 
295 static const cyaml_schema_value_t
296 unsigned_int_schema = {
297   CYAML_VALUE_UINT (
298     CYAML_FLAG_DEFAULT, unsigned int),
299 };
300 
301 static const cyaml_schema_value_t
302 uint8_t_schema = {
303   CYAML_VALUE_UINT (
304     CYAML_FLAG_DEFAULT, typeof (uint8_t)),
305 };
306 
307 static const cyaml_schema_value_t
308 float_schema = {
309   CYAML_VALUE_FLOAT (
310     CYAML_FLAG_DEFAULT,
311     typeof (float)),
312 };
313 
314 static const cyaml_schema_field_t
315 gdk_rgba_fields_schema[] =
316 {
317   CYAML_FIELD_FLOAT (
318     "red", CYAML_FLAG_DEFAULT,
319     GdkRGBA, red),
320   CYAML_FIELD_FLOAT (
321     "green", CYAML_FLAG_DEFAULT,
322     GdkRGBA, green),
323   CYAML_FIELD_FLOAT (
324     "blue", CYAML_FLAG_DEFAULT,
325     GdkRGBA, blue),
326   CYAML_FIELD_FLOAT (
327     "alpha", CYAML_FLAG_DEFAULT,
328     GdkRGBA, alpha),
329 
330   CYAML_FIELD_END
331 };
332 
333 static const cyaml_schema_value_t
334   gdk_rgba_schema_default =
335 {
336   YAML_VALUE_DEFAULT (
337     GdkRGBA, gdk_rgba_fields_schema),
338 };
339 
340 static const cyaml_schema_value_t
341   gdk_rgba_schema =
342 {
343   YAML_VALUE_PTR (
344     GdkRGBA, gdk_rgba_fields_schema),
345 };
346 
347 typedef enum YamlDummyEnum
348 {
349   YAML_DUMMY_ENUM1,
350 } YamlDummyEnum;
351 
352 /**
353  * @}
354  */
355 
356 #endif
357