1 /*
2  * SPDX-License-Identifier: ISC
3  *
4  * Copyright (c) 2017-2021 Michael Drake <tlsa@netsurf-browser.org>
5  */
6 
7 /**
8  * \file
9  * \brief CYAML library public header.
10  *
11  * CYAML is a C library for parsing and serialising structured YAML documents.
12  */
13 
14 #ifndef CYAML_H
15 #define CYAML_H
16 
17 #ifdef __cplusplus
18 extern "C"
19 {
20 #endif
21 
22 #include <stdarg.h>
23 #include <stdint.h>
24 #include <stddef.h>
25 
26 /**
27  * CYAML library version string.
28  */
29 extern const char *cyaml_version_str;
30 
31 /**
32  * CYAML library version number suitable for comparisons.
33  *
34  * Version number binary composition is `0bRUUUUUUUJJJJJJJJNNNNNNNNPPPPPPPP`.
35  *
36  * | Character | Meaning                                |
37  * | --------- | -------------------------------------- |
38  * | `R`       | Release flag.  If set, it's a release. |
39  * | `U`       | Unused / reserved.                     |
40  * | `J`       | Major component of version.            |
41  * | `N`       | Minor component of version.            |
42  * | `P`       | Patch component of version.            |
43  */
44 extern const uint32_t cyaml_version;
45 
46 /**
47  * CYAML value types.
48  *
49  * These are the fundamental data types that apply to "values" in CYAML.
50  *
51  * CYAML "values" are represented in by \ref cyaml_schema_value.
52  */
53 typedef enum cyaml_type {
54 	CYAML_INT,      /**< Value is a signed integer. */
55 	CYAML_UINT,     /**< Value is an unsigned signed integer. */
56 	CYAML_BOOL,     /**< Value is a boolean. */
57 	/**
58 	 * Value is an enum.  Values of this type require a string / value
59 	 * mapping array in the schema entry, to define the list of valid
60 	 * enum values.
61 	 */
62 	CYAML_ENUM,
63 	/**
64 	 * Value is a flags bit field.  Values of this type require a string /
65 	 * value list in the schema entry, to define the list of valid flag
66 	 * values.  Each bit is a boolean flag.  To store values of various
67 	 * bit sizes, use a \ref CYAML_BITFIELD instead.
68 	 *
69 	 * In the YAML, a \ref CYAML_FLAGS value must be presented as a
70 	 * sequence of strings.
71 	 */
72 	CYAML_FLAGS,
73 	CYAML_FLOAT,    /**< Value is floating point. */
74 	CYAML_STRING,   /**< Value is a string. */
75 	/**
76 	 * Value is a mapping.  Values of this type require mapping schema
77 	 * array in the schema entry.
78 	 */
79 	CYAML_MAPPING,
80 	/**
81 	 * Value is a bit field.  Values of this type require an array of value
82 	 * definitions in the schema entry.  If the bit field is used to store
83 	 * only single-bit flags, it may be better to use \ref CYAML_FLAGS
84 	 * instead.
85 	 *
86 	 * In the YAML, a \ref CYAML_FLAGS value must be presented as a
87 	 * mapping of bit field entry names to their numerical values.
88 	 */
89 	CYAML_BITFIELD,
90 	/**
91 	 * Value is a sequence.  Values of this type must be the direct
92 	 * children of a mapping.  They require:
93 	 *
94 	 * - A schema describing the type of the sequence entries.
95 	 * - Offset to the array entry count member in the mapping structure.
96 	 * - Size in bytes of the count member in the mapping structure.
97 	 * - The minimum and maximum number of sequence count entries.
98 	 *   Set `max` to \ref CYAML_UNLIMITED to make array count
99 	 *   unconstrained.
100 	 */
101 	CYAML_SEQUENCE,
102 	/**
103 	 * Value is a **fixed length** sequence.  It is similar to \ref
104 	 * CYAML_SEQUENCE, however:
105 	 *
106 	 * - Values of this type do not need to be direct children of a mapping.
107 	 * - The minimum and maximum entry count must be the same.  If not
108 	 *   \ref CYAML_ERR_SEQUENCE_FIXED_COUNT will be returned.
109 	 * - Thee offset and size of the count structure member is unused.
110 	 *   Because the count is a schema-defined constant, it does not need
111 	 *   to be recorded.
112 	 */
113 	CYAML_SEQUENCE_FIXED,
114 	/**
115 	 * Value of this type is completely ignored.  This is most useful for
116 	 * ignoring particular keys in a mapping, when the LivCYAML client has
117 	 * not set a configuration of \ref CYAML_CFG_IGNORE_UNKNOWN_KEYS.
118 	 */
119 	CYAML_IGNORE,
120 	/**
121 	 * Count of the valid CYAML types.  This value is **not a valid type**
122 	 * itself.
123 	 */
124 	CYAML__TYPE_COUNT,
125 } cyaml_type_e;
126 
127 /**
128  * CYAML value flags.
129  *
130  * These may be bitwise-ORed together.
131  */
132 typedef enum cyaml_flag {
133 	CYAML_FLAG_DEFAULT  = 0,        /**< Default value flags (none set). */
134 	CYAML_FLAG_OPTIONAL = (1 << 0), /**< Mapping field is optional. */
135 	/**
136 	 * Value is a pointer to its type.
137 	 *
138 	 * With this there must be a non-NULL value.  Consider using
139 	 * \ref CYAML_FLAG_POINTER_NULL or \ref CYAML_FLAG_POINTER_NULL_STR
140 	 * if you want to allow NULL values.
141 	 */
142 	CYAML_FLAG_POINTER  = (1 << 1),
143 	/**
144 	 * Permit `NULL` values for \ref CYAML_FLAG_POINTER types.
145 	 *
146 	 * An empty value in the YAML is loaded as a NULL pointer, and NULL
147 	 * pointers are saved in YAML as empty values.
148 	 *
149 	 * Note, when you set \ref CYAML_FLAG_POINTER_NULL, then
150 	 * \ref CYAML_FLAG_POINTER is set automatically.
151 	 */
152 	CYAML_FLAG_POINTER_NULL = (1 << 2) | CYAML_FLAG_POINTER,
153 	/**
154 	 * Permit storage of `NULL` values as special NULL strings in YAML.
155 	 *
156 	 * This extends \ref CYAML_FLAG_POINTER_NULL, but in addition to
157 	 * treating empty values as NULL, any of the following are also treated
158 	 * as NULL:
159 	 *
160 	 * * `null`,
161 	 * * `Null`,
162 	 * * `NULL`,
163 	 * * `~`,
164 	 *
165 	 * Note that as a side effect, loading a \ref CYAML_STRING field with
166 	 * one of these values will not store the literal string, it will store
167 	 * NULL.
168 	 *
169 	 * When saving, a NULL value will be recorded in the YAML as `null`.
170 	 *
171 	 * Note, when you set \ref CYAML_FLAG_POINTER_NULL_STR, then both
172 	 * \ref CYAML_FLAG_POINTER and \ref CYAML_FLAG_POINTER_NULL are set
173 	 * automatically.
174 	 */
175 	CYAML_FLAG_POINTER_NULL_STR = (1 << 3) | CYAML_FLAG_POINTER_NULL,
176 	/**
177 	 * Make value handling strict.
178 	 *
179 	 * For \ref CYAML_ENUM and \ref CYAML_FLAGS types, in strict mode
180 	 * the YAML must contain a matching string.  Without strict, numerical
181 	 * values are also permitted.
182 	 *
183 	 * * For \ref CYAML_ENUM, the value becomes the value of the enum.
184 	 *   The numerical value is treated as signed.
185 	 * * For \ref CYAML_FLAGS, the values are bitwise ORed together.
186 	 *   The numerical values are treated as unsigned.
187 	 *
188 	 * For \ref CYAML_FLOAT types, in strict mode floating point values
189 	 * that would cause overflow or underflow are not permitted.
190 	 */
191 	CYAML_FLAG_STRICT   = (1 << 4),
192 	/**
193 	 * When saving, emit mapping / sequence value in block style.
194 	 *
195 	 * This can be used to override, for this value, any default style set
196 	 * in the \ref cyaml_cfg_flags CYAML behavioural configuration flags.
197 	 *
198 	 * \note This is ignored unless the value's type is \ref CYAML_MAPPING,
199 	 *       \ref CYAML_SEQUENCE, or \ref CYAML_SEQUENCE_FIXED.
200 	 *
201 	 * \note If both \ref CYAML_FLAG_BLOCK and \ref CYAML_FLAG_FLOW are set,
202 	 *       then block style takes precedence.
203 	 *
204 	 * \note If neither block nor flow style set either here, or in the
205 	 *       \ref cyaml_cfg_flags CYAML behavioural configuration flags,
206 	 *       then libyaml's default behaviour is used.
207 	 */
208 	CYAML_FLAG_BLOCK    = (1 << 5),
209 	/**
210 	 * When saving, emit mapping / sequence value in flow style.
211 	 *
212 	 * This can be used to override, for this value, any default style set
213 	 * in the \ref cyaml_cfg_flags CYAML behavioural configuration flags.
214 	 *
215 	 * \note This is ignored unless the value's type is \ref CYAML_MAPPING,
216 	 *       \ref CYAML_SEQUENCE, or \ref CYAML_SEQUENCE_FIXED.
217 	 *
218 	 * \note If both \ref CYAML_FLAG_BLOCK and \ref CYAML_FLAG_FLOW are set,
219 	 *       then block style takes precedence.
220 	 *
221 	 * \note If neither block nor flow style set either here, or in the
222 	 *       \ref cyaml_cfg_flags CYAML behavioural configuration flags,
223 	 *       then libyaml's default behaviour is used.
224 	 */
225 	CYAML_FLAG_FLOW     = (1 << 6),
226 	/**
227 	 * When comparing strings for this value, compare with case sensitivity.
228 	 *
229 	 * By default, strings are compared with case sensitivity.
230 	 * If \ref CYAML_CFG_CASE_INSENSITIVE is set, this can override
231 	 * the configured behaviour for this specific value.
232 	 *
233 	 * \note If both \ref CYAML_FLAG_CASE_SENSITIVE and
234 	 *       \ref CYAML_FLAG_CASE_INSENSITIVE are set,
235 	 *       then case insensitive takes precedence.
236 	 *
237 	 * \note This applies to values of types \ref CYAML_MAPPING,
238 	 *       \ref CYAML_ENUM, and \ref CYAML_FLAGS.  For mappings,
239 	 *       it applies to matching of the mappings' keys.  For
240 	 *       enums and flags it applies to the comparison of
241 	 *       \ref cyaml_strval strings.
242 	 */
243 	CYAML_FLAG_CASE_SENSITIVE   = (1 << 7),
244 	/**
245 	 * When comparing strings for this value, compare with case sensitivity.
246 	 *
247 	 * By default, strings are compared with case sensitivity.
248 	 * If \ref CYAML_CFG_CASE_INSENSITIVE is set, this can override
249 	 * the configured behaviour for this specific value.
250 	 *
251 	 * \note If both \ref CYAML_FLAG_CASE_SENSITIVE and
252 	 *       \ref CYAML_FLAG_CASE_INSENSITIVE are set,
253 	 *       then case insensitive takes precedence.
254 	 *
255 	 * \note This applies to values of types \ref CYAML_MAPPING,
256 	 *       \ref CYAML_ENUM, and \ref CYAML_FLAGS.  For mappings,
257 	 *       it applies to matching of the mappings' keys.  For
258 	 *       enums and flags it applies to the comparison of
259 	 *       \ref cyaml_strval strings.
260 	 */
261 	CYAML_FLAG_CASE_INSENSITIVE = (1 << 8),
262 	/**
263 	 * When saving, emit scalar value with plain style (no quotes).
264 	 *
265 	 * \note This is ignored if the value is non-scaler.
266 	 *
267 	 * \note In cases where conflicting scalar style flags are set, the
268 	 *       the one with the highest precedence is used.  From lowest to
269 	 *       highest precedence:
270 	 *       \ref CYAML_FLAG_SCALAR_PLAIN,
271 	 *       \ref CYAML_FLAG_SCALAR_FOLDED,
272 	 *       \ref CYAML_FLAG_SCALAR_LITERAL,
273 	 *       \ref CYAML_FLAG_SCALAR_QUOTE_SINGLE,
274 	 *       \ref CYAML_FLAG_SCALAR_QUOTE_DOUBLE,
275 	 *
276 	 * If none of these are set, libyaml's default behaviour is used.
277 	 */
278 	CYAML_FLAG_SCALAR_PLAIN        = (1 <<  9),
279 	/**
280 	 * When saving, emit scalar value with folded style:
281 	 *
282 	 * ```yaml
283 	 * string: >
284 	 *   This string
285 	 *   really has no line breaks!
286 	 * ```
287 	 *
288 	 * See the notes for \ref CYAML_FLAG_SCALAR_PLAIN for applicability
289 	 * and precedence.
290 	 */
291 	CYAML_FLAG_SCALAR_FOLDED       = (1 << 10),
292 	/**
293 	 * When saving, emit scalar value with literal style:
294 	 *
295 	 * ```yaml
296 	 * string: |
297 	 *   This is a
298 	 *   multi-line string!
299 	 * ```
300 	 *
301 	 * See the notes for \ref CYAML_FLAG_SCALAR_PLAIN for applicability
302 	 * and precedence.
303 	 */
304 	CYAML_FLAG_SCALAR_LITERAL      = (1 << 11),
305 	/**
306 	 * When saving, emit scalar value with single quotes (`'`).
307 	 *
308 	 * See the notes for \ref CYAML_FLAG_SCALAR_PLAIN for applicability
309 	 * and precedence.
310 	 */
311 	CYAML_FLAG_SCALAR_QUOTE_SINGLE = (1 << 12),
312 	/**
313 	 * When saving, emit scalar value with double quotes (`"`).
314 	 *
315 	 * See the notes for \ref CYAML_FLAG_SCALAR_PLAIN for applicability
316 	 * and precedence.
317 	 */
318 	CYAML_FLAG_SCALAR_QUOTE_DOUBLE = (1 << 13),
319 } cyaml_flag_e;
320 
321 /**
322  * Mapping between a string and a signed value.
323  *
324  * Used for \ref CYAML_ENUM and \ref CYAML_FLAGS types.
325  */
326 typedef struct cyaml_strval {
327 	const char *str; /**< String representing enum or flag value. */
328 	int64_t val;     /**< Value of given string. */
329 } cyaml_strval_t;
330 
331 /**
332  * Bitfield value info.
333  *
334  * Used for \ref CYAML_BITFIELD type.
335  */
336 typedef struct cyaml_bitdef {
337 	const char *name; /**< String representing the value's name. */
338 	uint8_t offset;   /**< Bit offset to value in bit field. */
339 	uint8_t bits;     /**< Maximum bits available for value. */
340 } cyaml_bitdef_t;
341 
342 /**
343  * Schema definition for a value.
344  *
345  * \note There are convenience macros for each of the types to assist in
346  *       building a CYAML schema data structure for your YAML documents.
347  *
348  * This is the fundamental building block of CYAML schemas.  The load, save and
349  * free functions take parameters of this type to explain what the top-level
350  * type of the YAML document should be.
351  *
352  * Values of type \ref CYAML_SEQUENCE and \ref CYAML_SEQUENCE_FIXED
353  * contain a reference to another \ref cyaml_schema_value representing
354  * the type of the entries of the sequence.  For example, if you want
355  * a sequence of integers, you'd have a \ref cyaml_schema_value for the
356  * for the sequence value type, and another for the integer value type.
357  *
358  * Values of type \ref CYAML_MAPPING contain an array of \ref cyaml_schema_field
359  * entries, defining the YAML keys allowed by the mapping.  Each field contains
360  * a \ref cyaml_schema_value representing the schema for the value.
361  */
362 typedef struct cyaml_schema_value {
363 	/**
364 	 * The type of the value defined by this schema entry.
365 	 */
366 	enum cyaml_type type;
367 	/** Flags indicating value's characteristics. */
368 	enum cyaml_flag flags;
369 	/**
370 	 * Size of the value's client data type in bytes.
371 	 *
372 	 * For example, `short` `int`, `long`, `int8_t`, etc are all signed
373 	 * integer types, so they would have the type \ref CYAML_INT,
374 	 * however, they have different sizes.
375 	 */
376 	uint32_t data_size;
377 	/** Anonymous union containing type-specific attributes. */
378 	union {
379 		/** \ref CYAML_STRING type-specific schema data. */
380 		struct {
381 			/**
382 			 * Minimum string length (bytes).
383 			 *
384 			 * \note Excludes trailing NUL.
385 			 */
386 			uint32_t min;
387 			/**
388 			 * Maximum string length (bytes).
389 			 *
390 			 * \note Excludes trailing NULL, so for character array
391 			 *       strings (rather than pointer strings), this
392 			 *       must be no more than `data_size - 1`.
393 			 */
394 			uint32_t max;
395 		} string;
396 		/** \ref CYAML_MAPPING type-specific schema data. */
397 		struct {
398 			/**
399 			 * Array of cyaml mapping field schema definitions.
400 			 *
401 			 * The array must be terminated by an entry with a
402 			 * NULL key.  See \ref cyaml_schema_field_t
403 			 * and \ref CYAML_FIELD_END for more info.
404 			 */
405 			const struct cyaml_schema_field *fields;
406 		} mapping;
407 		/** \ref CYAML_BITFIELD type-specific schema data. */
408 		struct {
409 			/** Array of bit definitions for the bit field. */
410 			const struct cyaml_bitdef *bitdefs;
411 			/** Entry count for bitdefs array. */
412 			uint32_t count;
413 		} bitfield;
414 		/**
415 		 * \ref CYAML_SEQUENCE and \ref CYAML_SEQUENCE_FIXED
416 		 * type-specific schema data.
417 		 */
418 		struct {
419 			/**
420 			 * Schema definition for the type of the entries in the
421 			 * sequence.
422 			 *
423 			 * All of a sequence's entries must be of the same
424 			 * type, and a sequence can not have an entry type of
425 			 * type \ref CYAML_SEQUENCE (although \ref
426 			 * CYAML_SEQUENCE_FIXED is allowed).  That is, you
427 			 * can't have a sequence of variable-length sequences.
428 			 */
429 			const struct cyaml_schema_value *entry;
430 			/**
431 			 * Minimum number of sequence entries.
432 			 *
433 			 * \note min and max must be the same for \ref
434 			 *       CYAML_SEQUENCE_FIXED.
435 			 */
436 			uint32_t min;
437 			/**
438 			 * Maximum number of sequence entries.
439 			 *
440 			 * \note min and max must be the same for \ref
441 			 *       CYAML_SEQUENCE_FIXED.
442 			 */
443 			uint32_t max;
444 		} sequence;
445 		/**
446 		 * \ref CYAML_ENUM and \ref CYAML_FLAGS type-specific schema
447 		 * data.
448 		 */
449 		struct {
450 			/** Array of string / value mappings defining enum. */
451 			const cyaml_strval_t *strings;
452 			/** Entry count for strings array. */
453 			uint32_t count;
454 		} enumeration;
455 	};
456 } cyaml_schema_value_t;
457 
458 /**
459  * Schema definition entry for mapping fields.
460  *
461  * YAML mappings are key:value pairs.  CYAML only supports scalar mapping keys,
462  * i.e. the keys must be strings.  Each mapping field schema contains a
463  * \ref cyaml_schema_value to define field's value.
464  *
465  * The schema for mappings is composed of an array of entries of this
466  * data structure.  It specifies the name of the key, and the type of
467  * the value.  It also specifies the offset into the data at which value
468  * data should be placed.  The array is terminated by an entry with a NULL key.
469  */
470 typedef struct cyaml_schema_field {
471 	/**
472 	 * String for YAML mapping key that his schema entry describes,
473 	 * or NULL to indicated the end of an array of \ref cyaml_schema_field
474 	 * entries.
475 	 */
476 	const char *key;
477 	/**
478 	 * Offset in data structure at which the value for this key should
479 	 * be placed / read from.
480 	 */
481 	uint32_t data_offset;
482 	/**
483 	 * \ref CYAML_SEQUENCE only: Offset to sequence
484 	 * entry count member in mapping's data structure.
485 	 */
486 	uint32_t count_offset;
487 	/**
488 	 * \ref CYAML_SEQUENCE only: Size in bytes of sequence
489 	 * entry count member in mapping's data structure.
490 	 */
491 	uint8_t count_size;
492 	/**
493 	 * Defines the schema for the mapping field's value.
494 	 */
495 	struct cyaml_schema_value value;
496 } cyaml_schema_field_t;
497 
498 /**
499  * CYAML behavioural configuration flags for clients
500  *
501  * These may be bitwise-ORed together.
502  */
503 typedef enum cyaml_cfg_flags {
504 	/**
505 	 * This indicates CYAML's default behaviour.
506 	 */
507 	CYAML_CFG_DEFAULT             = 0,
508 	/**
509 	 * When set, unknown mapping keys are ignored when loading YAML.
510 	 * Without this flag set, CYAML's default behaviour is to return
511 	 * with the error \ref CYAML_ERR_INVALID_KEY.
512 	 */
513 	CYAML_CFG_IGNORE_UNKNOWN_KEYS = (1 << 0),
514 	/**
515 	 * When saving, emit mapping / sequence values in block style.
516 	 *
517 	 * This setting can be overridden for specific values using schema
518 	 * value flags (\ref cyaml_flag).
519 	 *
520 	 * \note This only applies to values of type \ref CYAML_MAPPING,
521 	 *       \ref CYAML_SEQUENCE, or \ref CYAML_SEQUENCE_FIXED.
522 	 *
523 	 * \note If both \ref CYAML_CFG_STYLE_BLOCK and
524 	 *       \ref CYAML_CFG_STYLE_FLOW are set, then block style takes
525 	 *       precedence.
526 	 */
527 	CYAML_CFG_STYLE_BLOCK         = (1 << 1),
528 	/**
529 	 * When saving, emit mapping / sequence values in flow style.
530 	 *
531 	 * This setting can be overridden for specific values using schema
532 	 * value flags (\ref cyaml_flag).
533 	 *
534 	 * \note This only applies to values of type \ref CYAML_MAPPING,
535 	 *       \ref CYAML_SEQUENCE, or \ref CYAML_SEQUENCE_FIXED.
536 	 *
537 	 * \note If both \ref CYAML_CFG_STYLE_BLOCK and
538 	 *       \ref CYAML_CFG_STYLE_FLOW are set, then block style takes
539 	 *       precedence.
540 	 */
541 	CYAML_CFG_STYLE_FLOW          = (1 << 2),
542 	/**
543 	 * When saving, emit "---" at document start and "..." at document end.
544 	 *
545 	 * If this flag isn't set, these document delimiting marks will not
546 	 * be emitted.
547 	 */
548 	CYAML_CFG_DOCUMENT_DELIM      = (1 << 3),
549 	/**
550 	 * When comparing strings, compare without case sensitivity.
551 	 *
552 	 * By default, strings are compared with case sensitivity.
553 	 */
554 	CYAML_CFG_CASE_INSENSITIVE    = (1 << 4),
555 	/**
556 	 * When loading, don't allow YAML aliases in the document.
557 	 *
558 	 * If this option is enabled, anchors will be ignored, and the
559 	 * error code \ref CYAML_ERR_ALIAS will be returned if an alias
560 	 * is encountered.
561 	 *
562 	 * Setting this removes the overhead of recording anchors, so
563 	 * it may be worth setting if aliases are not required, and
564 	 * memory is constrained.
565 	 */
566 	CYAML_CFG_NO_ALIAS            = (1 << 5),
567 } cyaml_cfg_flags_t;
568 
569 /**
570  * CYAML function return codes indicating success or reason for failure.
571  *
572  * Use \ref cyaml_strerror() to convert an error code to a human-readable
573  * string.
574  */
575 typedef enum cyaml_err {
576 	CYAML_OK,                        /**< Success. */
577 	CYAML_ERR_OOM,                   /**< Memory allocation failed. */
578 	CYAML_ERR_ALIAS,                 /**< See \ref CYAML_CFG_NO_ALIAS. */
579 	CYAML_ERR_FILE_OPEN,             /**< Failed to open file. */
580 	CYAML_ERR_INVALID_KEY,           /**< Mapping key rejected by schema. */
581 	CYAML_ERR_INVALID_VALUE,         /**< Value rejected by schema. */
582 	CYAML_ERR_INVALID_ALIAS,         /**< No anchor found for alias. */
583 	CYAML_ERR_INTERNAL_ERROR,        /**< Internal error in LibCYAML. */
584 	CYAML_ERR_UNEXPECTED_EVENT,      /**< YAML event rejected by schema. */
585 	CYAML_ERR_STRING_LENGTH_MIN,     /**< String length too short. */
586 	CYAML_ERR_STRING_LENGTH_MAX,     /**< String length too long. */
587 	CYAML_ERR_INVALID_DATA_SIZE,     /**< Value's data size unsupported. */
588 	CYAML_ERR_TOP_LEVEL_NON_PTR,     /**< Top level type must be pointer. */
589 	CYAML_ERR_BAD_TYPE_IN_SCHEMA,    /**< Schema contains invalid type. */
590 	CYAML_ERR_BAD_MIN_MAX_SCHEMA,    /**< Schema minimum exceeds maximum. */
591 	CYAML_ERR_BAD_PARAM_SEQ_COUNT,   /**< Bad seq_count param for schema. */
592 	CYAML_ERR_BAD_PARAM_NULL_DATA,   /**< Client gave NULL data argument. */
593 	CYAML_ERR_BAD_BITVAL_IN_SCHEMA,  /**< Bit value beyond bit field size. */
594 	CYAML_ERR_SEQUENCE_ENTRIES_MIN,  /**< Too few sequence entries. */
595 	CYAML_ERR_SEQUENCE_ENTRIES_MAX,  /**< Too many sequence entries. */
596 	CYAML_ERR_SEQUENCE_FIXED_COUNT,  /**< Mismatch between min and max. */
597 	CYAML_ERR_SEQUENCE_IN_SEQUENCE,  /**< Non-fixed sequence in sequence. */
598 	CYAML_ERR_MAPPING_FIELD_MISSING, /**< Required mapping field missing. */
599 	CYAML_ERR_BAD_CONFIG_NULL_MEMFN, /**< Client gave NULL mem function. */
600 	CYAML_ERR_BAD_PARAM_NULL_CONFIG, /**< Client gave NULL config arg. */
601 	CYAML_ERR_BAD_PARAM_NULL_SCHEMA, /**< Client gave NULL schema arg. */
602 	CYAML_ERR_LIBYAML_EMITTER_INIT,  /**< Failed to initialise libyaml. */
603 	CYAML_ERR_LIBYAML_PARSER_INIT,   /**< Failed to initialise libyaml. */
604 	CYAML_ERR_LIBYAML_EVENT_INIT,    /**< Failed to initialise libyaml. */
605 	CYAML_ERR_LIBYAML_EMITTER,       /**< Error inside libyaml emitter. */
606 	CYAML_ERR_LIBYAML_PARSER,        /**< Error inside libyaml parser. */
607 	CYAML_ERR__COUNT,                /**< Count of CYAML return codes.
608 	                                  *   This is **not a valid return
609 	                                  *   code** itself.
610 	                                  */
611 } cyaml_err_t;
612 
613 /**
614  * Value schema helper macro for values with \ref CYAML_INT type.
615  *
616  * \param[in]  _flags         Any behavioural flags relevant to this value.
617  * \param[in]  _type          The C type for this value.
618  */
619 #define CYAML_VALUE_INT( \
620 		_flags, _type) \
621 	.type = CYAML_INT, \
622 	.flags = (enum cyaml_flag)(_flags), \
623 	.data_size = sizeof(_type)
624 
625 /**
626  * Mapping schema helper macro for keys with \ref CYAML_INT type.
627  *
628  * Use this for integers contained in structs.
629  *
630  * \param[in]  _key        String defining the YAML mapping key for this value.
631  * \param[in]  _flags      Any behavioural flags relevant to this value.
632  * \param[in]  _structure  The structure corresponding to the mapping.
633  * \param[in]  _member     The member in _structure for this mapping value.
634  */
635 #define CYAML_FIELD_INT( \
636 		_key, _flags, _structure, _member) \
637 { \
638 	.key = _key, \
639 	.data_offset = offsetof(_structure, _member), \
640 	.value = { \
641 		CYAML_VALUE_INT(((_flags) & (~CYAML_FLAG_POINTER)), \
642 				(((_structure *)NULL)->_member)), \
643 	}, \
644 }
645 
646 /**
647  * Mapping schema helper macro for keys with \ref CYAML_INT type.
648  *
649  * Use this for pointers to integers.
650  *
651  * \param[in]  _key        String defining the YAML mapping key for this value.
652  * \param[in]  _flags      Any behavioural flags relevant to this value.
653  * \param[in]  _structure  The structure corresponding to the mapping.
654  * \param[in]  _member     The member in _structure for this mapping value.
655  */
656 #define CYAML_FIELD_INT_PTR( \
657 		_key, _flags, _structure, _member) \
658 { \
659 	.key = _key, \
660 	.data_offset = offsetof(_structure, _member), \
661 	.value = { \
662 		CYAML_VALUE_INT(((_flags) | CYAML_FLAG_POINTER), \
663 				(*(((_structure *)NULL)->_member))), \
664 	}, \
665 }
666 
667 /**
668  * Value schema helper macro for values with \ref CYAML_UINT type.
669  *
670  * \param[in]  _flags         Any behavioural flags relevant to this value.
671  * \param[in]  _type          The C type for this value.
672  */
673 #define CYAML_VALUE_UINT( \
674 		_flags, _type) \
675 	.type = CYAML_UINT, \
676 	.flags = (enum cyaml_flag)(_flags), \
677 	.data_size = sizeof(_type)
678 
679 /**
680  * Mapping schema helper macro for keys with \ref CYAML_UINT type.
681  *
682  * Use this for unsigned integers contained in structs.
683  *
684  * \param[in]  _key        String defining the YAML mapping key for this value.
685  * \param[in]  _flags      Any behavioural flags relevant to this value.
686  * \param[in]  _structure  The structure corresponding to the mapping.
687  * \param[in]  _member     The member in _structure for this mapping value.
688  */
689 #define CYAML_FIELD_UINT( \
690 		_key, _flags, _structure, _member) \
691 { \
692 	.key = _key, \
693 	.data_offset = offsetof(_structure, _member), \
694 	.value = { \
695 		CYAML_VALUE_UINT(((_flags) & (~CYAML_FLAG_POINTER)), \
696 				(((_structure *)NULL)->_member)), \
697 	}, \
698 }
699 
700 /**
701  * Mapping schema helper macro for keys with \ref CYAML_UINT type.
702  *
703  * Use this for pointers to unsigned integers.
704  *
705  * \param[in]  _key        String defining the YAML mapping key for this value.
706  * \param[in]  _flags      Any behavioural flags relevant to this value.
707  * \param[in]  _structure  The structure corresponding to the mapping.
708  * \param[in]  _member     The member in _structure for this mapping value.
709  */
710 #define CYAML_FIELD_UINT_PTR( \
711 		_key, _flags, _structure, _member) \
712 { \
713 	.key = _key, \
714 	.data_offset = offsetof(_structure, _member), \
715 	.value = { \
716 		CYAML_VALUE_UINT(((_flags) | CYAML_FLAG_POINTER), \
717 				(*(((_structure *)NULL)->_member))), \
718 	}, \
719 }
720 
721 /**
722  * Value schema helper macro for values with \ref CYAML_BOOL type.
723  *
724  * \param[in]  _flags         Any behavioural flags relevant to this value.
725  * \param[in]  _type          The C type for this value.
726  */
727 #define CYAML_VALUE_BOOL( \
728 		_flags, _type) \
729 	.type = CYAML_BOOL, \
730 	.flags = (enum cyaml_flag)(_flags), \
731 	.data_size = sizeof(_type)
732 
733 /**
734  * Mapping schema helper macro for keys with \ref CYAML_BOOL type.
735  *
736  * Use this for boolean types contained in structs.
737  *
738  * \param[in]  _key        String defining the YAML mapping key for this value.
739  * \param[in]  _flags      Any behavioural flags relevant to this value.
740  * \param[in]  _structure  The structure corresponding to the mapping.
741  * \param[in]  _member     The member in _structure for this mapping value.
742  */
743 #define CYAML_FIELD_BOOL( \
744 		_key, _flags, _structure, _member) \
745 { \
746 	.key = _key, \
747 	.data_offset = offsetof(_structure, _member), \
748 	.value = { \
749 		CYAML_VALUE_BOOL(((_flags) & (~CYAML_FLAG_POINTER)), \
750 				(((_structure *)NULL)->_member)), \
751 	}, \
752 }
753 
754 /**
755  * Mapping schema helper macro for keys with \ref CYAML_BOOL type.
756  *
757  * Use this for pointers to boolean types.
758  *
759  * \param[in]  _key        String defining the YAML mapping key for this value.
760  * \param[in]  _flags      Any behavioural flags relevant to this value.
761  * \param[in]  _structure  The structure corresponding to the mapping.
762  * \param[in]  _member     The member in _structure for this mapping value.
763  */
764 #define CYAML_FIELD_BOOL_PTR( \
765 		_key, _flags, _structure, _member) \
766 { \
767 	.key = _key, \
768 	.data_offset = offsetof(_structure, _member), \
769 	.value = { \
770 		CYAML_VALUE_BOOL(((_flags) | CYAML_FLAG_POINTER), \
771 				(*(((_structure *)NULL)->_member))), \
772 	}, \
773 }
774 
775 /**
776  * Value schema helper macro for values with \ref CYAML_ENUM type.
777  *
778  * \param[in]  _flags         Any behavioural flags relevant to this value.
779  * \param[in]  _type          The C type for this value.
780  * \param[in]  _strings       Array of string data for enumeration values.
781  * \param[in]  _strings_count Number of entries in _strings.
782  */
783 #define CYAML_VALUE_ENUM( \
784 		_flags, _type, _strings, _strings_count) \
785 	.type = CYAML_ENUM, \
786 	.flags = (enum cyaml_flag)(_flags), \
787 	.data_size = sizeof(_type), \
788 	.enumeration = { \
789 		.strings = _strings, \
790 		.count = _strings_count, \
791 	}
792 
793 /**
794  * Mapping schema helper macro for keys with \ref CYAML_ENUM type.
795  *
796  * Use this for enumerated types contained in structs.
797  *
798  * \param[in]  _key        String defining the YAML mapping key for this value.
799  * \param[in]  _flags      Any behavioural flags relevant to this value.
800  * \param[in]  _structure  The structure corresponding to the mapping.
801  * \param[in]  _member     The member in _structure for this mapping value.
802  * \param[in]  _strings       Array of string data for enumeration values.
803  * \param[in]  _strings_count Number of entries in _strings.
804  */
805 #define CYAML_FIELD_ENUM( \
806 		_key, _flags, _structure, _member, _strings, _strings_count) \
807 { \
808 	.key = _key, \
809 	.data_offset = offsetof(_structure, _member), \
810 	.value = { \
811 		CYAML_VALUE_ENUM(((_flags) & (~CYAML_FLAG_POINTER)), \
812 				(((_structure *)NULL)->_member), \
813 				_strings, _strings_count), \
814 	}, \
815 }
816 
817 /**
818  * Mapping schema helper macro for keys with \ref CYAML_ENUM type.
819  *
820  * Use this for pointers to enumerated types.
821  *
822  * \param[in]  _key        String defining the YAML mapping key for this value.
823  * \param[in]  _flags      Any behavioural flags relevant to this value.
824  * \param[in]  _structure  The structure corresponding to the mapping.
825  * \param[in]  _member     The member in _structure for this mapping value.
826  * \param[in]  _strings       Array of string data for enumeration values.
827  * \param[in]  _strings_count Number of entries in _strings.
828  */
829 #define CYAML_FIELD_ENUM_PTR( \
830 		_key, _flags, _structure, _member, _strings, _strings_count) \
831 { \
832 	.key = _key, \
833 	.data_offset = offsetof(_structure, _member), \
834 	.value = { \
835 		CYAML_VALUE_ENUM(((_flags) | CYAML_FLAG_POINTER), \
836 				(*(((_structure *)NULL)->_member)), \
837 				_strings, _strings_count), \
838 	}, \
839 }
840 
841 /**
842  * Value schema helper macro for values with \ref CYAML_FLAGS type.
843  *
844  * \param[in]  _flags         Any behavioural flags relevant to this value.
845  * \param[in]  _type          The C type for this value.
846  * \param[in]  _strings       Array of string data for flag values.
847  * \param[in]  _strings_count Number of entries in _strings.
848  */
849 #define CYAML_VALUE_FLAGS( \
850 		_flags, _type, _strings, _strings_count) \
851 	.type = CYAML_FLAGS, \
852 	.flags = (enum cyaml_flag)(_flags), \
853 	.data_size = sizeof(_type), \
854 	.enumeration = { \
855 		.strings = _strings, \
856 		.count = _strings_count, \
857 	}
858 
859 /**
860  * Mapping schema helper macro for keys with \ref CYAML_FLAGS type.
861  *
862  * Use this for flag types contained in structs.
863  *
864  * \param[in]  _key        String defining the YAML mapping key for this value.
865  * \param[in]  _flags      Any behavioural flags relevant to this value.
866  * \param[in]  _structure  The structure corresponding to the mapping.
867  * \param[in]  _member     The member in _structure for this mapping value.
868  * \param[in]  _strings       Array of string data for flag values.
869  * \param[in]  _strings_count Number of entries in _strings.
870  */
871 #define CYAML_FIELD_FLAGS( \
872 		_key, _flags, _structure, _member, _strings, _strings_count) \
873 { \
874 	.key = _key, \
875 	.data_offset = offsetof(_structure, _member), \
876 	.value = { \
877 		CYAML_VALUE_FLAGS(((_flags) & (~CYAML_FLAG_POINTER)), \
878 				(((_structure *)NULL)->_member), \
879 				_strings, _strings_count), \
880 	}, \
881 }
882 
883 /**
884  * Mapping schema helper macro for keys with \ref CYAML_FLAGS type.
885  *
886  * Use this for pointers to flag types.
887  *
888  * \param[in]  _key        String defining the YAML mapping key for this value.
889  * \param[in]  _flags      Any behavioural flags relevant to this value.
890  * \param[in]  _structure  The structure corresponding to the mapping.
891  * \param[in]  _member     The member in _structure for this mapping value.
892  * \param[in]  _strings       Array of string data for flag values.
893  * \param[in]  _strings_count Number of entries in _strings.
894  */
895 #define CYAML_FIELD_FLAGS_PTR( \
896 		_key, _flags, _structure, _member, _strings, _strings_count) \
897 { \
898 	.key = _key, \
899 	.data_offset = offsetof(_structure, _member), \
900 	.value = { \
901 		CYAML_VALUE_FLAGS(((_flags) | CYAML_FLAG_POINTER), \
902 				(*(((_structure *)NULL)->_member)), \
903 				_strings, _strings_count), \
904 	}, \
905 }
906 
907 /**
908  * Value schema helper macro for values with \ref CYAML_BITFIELD type.
909  *
910  * \param[in]  _flags         Any behavioural flags relevant to this value.
911  * \param[in]  _type          The C type for this value.
912  * \param[in]  _bitvals       Array of bit field value data for the bit field.
913  * \param[in]  _bitvals_count Number of entries in _bitvals.
914  */
915 #define CYAML_VALUE_BITFIELD( \
916 		_flags, _type, _bitvals, _bitvals_count) \
917 	.type = CYAML_BITFIELD, \
918 	.flags = (enum cyaml_flag)(_flags), \
919 	.data_size = sizeof(_type), \
920 	.bitfield = { \
921 		.bitdefs = _bitvals, \
922 		.count = _bitvals_count, \
923 	}
924 
925 /**
926  * Mapping schema helper macro for keys with \ref CYAML_BITFIELD type.
927  *
928  * Use this for bit field types contained in structs.
929  *
930  * \param[in]  _key        String defining the YAML mapping key for this value.
931  * \param[in]  _flags      Any behavioural flags relevant to this value.
932  * \param[in]  _structure  The structure corresponding to the mapping.
933  * \param[in]  _member     The member in _structure for this mapping value.
934  * \param[in]  _bitvals       Array of bit field value data for the bit field.
935  * \param[in]  _bitvals_count Number of entries in _bitvals.
936  */
937 #define CYAML_FIELD_BITFIELD( \
938 		_key, _flags, _structure, _member, _bitvals, _bitvals_count) \
939 { \
940 	.key = _key, \
941 	.data_offset = offsetof(_structure, _member), \
942 	.value = { \
943 		CYAML_VALUE_BITFIELD(((_flags) & (~CYAML_FLAG_POINTER)), \
944 				(((_structure *)NULL)->_member), \
945 				_bitvals, _bitvals_count), \
946 	}, \
947 }
948 
949 /**
950  * Mapping schema helper macro for keys with \ref CYAML_BITFIELD type.
951  *
952  * Use this for pointers to bit field types.
953  *
954  * \param[in]  _key        String defining the YAML mapping key for this value.
955  * \param[in]  _flags      Any behavioural flags relevant to this value.
956  * \param[in]  _structure  The structure corresponding to the mapping.
957  * \param[in]  _member     The member in _structure for this mapping value.
958  * \param[in]  _bitvals       Array of bit field value data for the bit field.
959  * \param[in]  _bitvals_count Number of entries in _bitvals.
960  */
961 #define CYAML_FIELD_BITFIELD_PTR( \
962 		_key, _flags, _structure, _member, _bitvals, _bitvals_count) \
963 { \
964 	.key = _key, \
965 	.data_offset = offsetof(_structure, _member), \
966 	.value = { \
967 		CYAML_VALUE_BITFIELD(((_flags) | CYAML_FLAG_POINTER), \
968 				(*(((_structure *)NULL)->_member)), \
969 				_bitvals, _bitvals_count), \
970 	}, \
971 }
972 
973 /**
974  * Value schema helper macro for values with \ref CYAML_FLOAT type.
975  *
976  * \param[in]  _flags         Any behavioural flags relevant to this value.
977  * \param[in]  _type          The C type for this value.
978  */
979 #define CYAML_VALUE_FLOAT( \
980 		_flags, _type) \
981 	.type = CYAML_FLOAT, \
982 	.flags = (enum cyaml_flag)(_flags), \
983 	.data_size = sizeof(_type)
984 
985 /**
986  * Mapping schema helper macro for keys with \ref CYAML_FLOAT type.
987  *
988  * Use this for floating point types contained in structs.
989  *
990  * \param[in]  _key        String defining the YAML mapping key for this value.
991  * \param[in]  _flags      Any behavioural flags relevant to this value.
992  * \param[in]  _structure  The structure corresponding to the mapping.
993  * \param[in]  _member     The member in _structure for this mapping value.
994  */
995 #define CYAML_FIELD_FLOAT( \
996 		_key, _flags, _structure, _member) \
997 { \
998 	.key = _key, \
999 	.data_offset = offsetof(_structure, _member), \
1000 	.value = { \
1001 		CYAML_VALUE_FLOAT(((_flags) & (~CYAML_FLAG_POINTER)), \
1002 				(((_structure *)NULL)->_member)), \
1003 	}, \
1004 }
1005 
1006 /**
1007  * Mapping schema helper macro for keys with \ref CYAML_FLOAT type.
1008  *
1009  * Use this for pointers to floating point types.
1010  *
1011  * \param[in]  _key        String defining the YAML mapping key for this value.
1012  * \param[in]  _flags      Any behavioural flags relevant to this value.
1013  * \param[in]  _structure  The structure corresponding to the mapping.
1014  * \param[in]  _member     The member in _structure for this mapping value.
1015  */
1016 #define CYAML_FIELD_FLOAT_PTR( \
1017 		_key, _flags, _structure, _member) \
1018 { \
1019 	.key = _key, \
1020 	.data_offset = offsetof(_structure, _member), \
1021 	.value = { \
1022 		CYAML_VALUE_FLOAT(((_flags) | CYAML_FLAG_POINTER), \
1023 				(*(((_structure *)NULL)->_member))), \
1024 	}, \
1025 }
1026 
1027 /**
1028  * Value schema helper macro for values with \ref CYAML_STRING type.
1029  *
1030  * \note If the string is an array (`char str[N];`) then the \ref
1031  *       CYAML_FLAG_POINTER flag must **not** be set, and the max
1032  *       length must be no more than `N-1`.
1033  *
1034  *       If the string is a pointer (`char *str;`), then the \ref
1035  *       CYAML_FLAG_POINTER flag **must be set**.
1036  *
1037  * \param[in]  _flags         Any behavioural flags relevant to this value.
1038  * \param[in]  _type          The C type for this value.
1039  * \param[in]  _min           Minimum string length in bytes.
1040  *                            Excludes trailing '\0'.
1041  * \param[in]  _max           The C type for this value.
1042  *                            Excludes trailing '\0'.
1043  */
1044 #define CYAML_VALUE_STRING( \
1045 		_flags, _type, _min, _max) \
1046 	.type = CYAML_STRING, \
1047 	.flags = (enum cyaml_flag)(_flags), \
1048 	.data_size = sizeof(_type), \
1049 	.string = { \
1050 		.min = _min, \
1051 		.max = _max, \
1052 	}
1053 
1054 /**
1055  * Mapping schema helper macro for keys with \ref CYAML_STRING type.
1056  *
1057  * Use this for fields with C array type, e.g. `char str[N];`.  This fills the
1058  * maximum string length (`N-1`) out automatically.
1059  *
1060  * \param[in]  _key        String defining the YAML mapping key for this value.
1061  * \param[in]  _flags      Any behavioural flags relevant to this value.
1062  * \param[in]  _structure  The structure corresponding to the mapping.
1063  * \param[in]  _member     The member in _structure for this mapping value.
1064  * \param[in]  _min        Minimum string length in bytes.  Excludes '\0'.
1065  */
1066 #define CYAML_FIELD_STRING( \
1067 		_key, _flags, _structure, _member, _min) \
1068 { \
1069 	.key = _key, \
1070 	.data_offset = offsetof(_structure, _member), \
1071 	.value = { \
1072 		CYAML_VALUE_STRING(((_flags) & (~CYAML_FLAG_POINTER)), \
1073 				(((_structure *)NULL)->_member), _min, \
1074 				sizeof(((_structure *)NULL)->_member) - 1), \
1075 	}, \
1076 }
1077 
1078 /**
1079  * Mapping schema helper macro for keys with \ref CYAML_STRING type.
1080  *
1081  * Use this for fields with C pointer type, e.g. `char *str;`.  This creates
1082  * a separate allocation for the string data, and fills in the pointer.
1083  *
1084  * Use `0` for _min and \ref CYAML_UNLIMITED for _max for unconstrained string
1085  * lengths.
1086  *
1087  * \param[in]  _key        String defining the YAML mapping key for this value.
1088  * \param[in]  _flags      Any behavioural flags relevant to this value.
1089  * \param[in]  _structure  The structure corresponding to the mapping.
1090  * \param[in]  _member     The member in _structure for this mapping value.
1091  * \param[in]  _min        Minimum string length in bytes.  Excludes '\0'.
1092  * \param[in]  _max        Maximum string length in bytes.  Excludes '\0'.
1093  */
1094 #define CYAML_FIELD_STRING_PTR( \
1095 		_key, _flags, _structure, _member, _min, _max) \
1096 { \
1097 	.key = _key, \
1098 	.data_offset = offsetof(_structure, _member), \
1099 	.value = { \
1100 		CYAML_VALUE_STRING(((_flags) | CYAML_FLAG_POINTER), \
1101 				(((_structure *)NULL)->_member), \
1102 				_min, _max), \
1103 	}, \
1104 }
1105 
1106 /**
1107  * Value schema helper macro for values with \ref CYAML_MAPPING type.
1108  *
1109  * \param[in]  _flags         Any behavioural flags relevant to this value.
1110  * \param[in]  _type          The C type of structure corresponding to mapping.
1111  * \param[in]  _fields        Pointer to mapping fields schema array.
1112  */
1113 #define CYAML_VALUE_MAPPING( \
1114 		_flags, _type, _fields) \
1115 	.type = CYAML_MAPPING, \
1116 	.flags = (enum cyaml_flag)(_flags), \
1117 	.data_size = sizeof(_type), \
1118 	.mapping = { \
1119 		.fields = _fields, \
1120 	}
1121 
1122 /**
1123  * Mapping schema helper macro for keys with \ref CYAML_MAPPING type.
1124  *
1125  * Use this for structures contained within other structures.
1126  *
1127  * \param[in]  _key        String defining the YAML mapping key for this value.
1128  * \param[in]  _flags      Any behavioural flags relevant to this value.
1129  * \param[in]  _structure  The structure corresponding to the containing mapping.
1130  * \param[in]  _member     The member in _structure for this mapping value.
1131  * \param[in]  _fields     Pointer to mapping fields schema array.
1132  */
1133 #define CYAML_FIELD_MAPPING( \
1134 		_key, _flags, _structure, _member, _fields) \
1135 { \
1136 	.key = _key, \
1137 	.data_offset = offsetof(_structure, _member), \
1138 	.value = { \
1139 		CYAML_VALUE_MAPPING(((_flags) & (~CYAML_FLAG_POINTER)), \
1140 				(((_structure *)NULL)->_member), _fields), \
1141 	}, \
1142 }
1143 
1144 /**
1145  * Mapping schema helper macro for keys with \ref CYAML_MAPPING type.
1146  *
1147  * Use this for pointers to structures.
1148  *
1149  * \param[in]  _key        String defining the YAML mapping key for this value.
1150  * \param[in]  _flags      Any behavioural flags relevant to this value.
1151  * \param[in]  _structure  The structure corresponding to the containing mapping.
1152  * \param[in]  _member     The member in _structure for this mapping value.
1153  * \param[in]  _fields     Pointer to mapping fields schema array.
1154  */
1155 #define CYAML_FIELD_MAPPING_PTR( \
1156 		_key, _flags, _structure, _member, _fields) \
1157 { \
1158 	.key = _key, \
1159 	.data_offset = offsetof(_structure, _member), \
1160 	.value = { \
1161 		CYAML_VALUE_MAPPING(((_flags) | CYAML_FLAG_POINTER), \
1162 				(*(((_structure *)NULL)->_member)), _fields), \
1163 	}, \
1164 }
1165 
1166 /**
1167  * Value schema helper macro for values with \ref CYAML_SEQUENCE type.
1168  *
1169  * \param[in]  _flags      Any behavioural flags relevant to this value.
1170  * \param[in]  _type       The C type of sequence **entries**.
1171  * \param[in]  _entry      Pointer to schema for the **entries** in sequence.
1172  * \param[in]  _min        Minimum number of sequence entries required.
1173  * \param[in]  _max        Maximum number of sequence entries required.
1174  */
1175 #define CYAML_VALUE_SEQUENCE( \
1176 		_flags, _type, _entry, _min, _max) \
1177 	.type = CYAML_SEQUENCE, \
1178 	.flags = (enum cyaml_flag)(_flags), \
1179 	.data_size = sizeof(_type), \
1180 	.sequence = { \
1181 		.entry = _entry, \
1182 		.min = _min, \
1183 		.max = _max, \
1184 	}
1185 
1186 /**
1187  * Mapping schema helper macro for keys with \ref CYAML_SEQUENCE type.
1188  *
1189  * To use this, there must be a member in {_structure} called "{_member}_count",
1190  * for storing the number of entries in the sequence.
1191  *
1192  * For example, for the following structure:
1193  *
1194  * ```
1195  * struct my_structure {
1196  *         unsigned *my_sequence;
1197  *         unsigned  my_sequence_count;
1198  * };
1199  * ```
1200  *
1201  * Pass the following as parameters:
1202  *
1203  * | Parameter  | Value                 |
1204  * | ---------- | --------------------- |
1205  * | _structure | `struct my_structure` |
1206  * | _member    | `my_sequence`         |
1207  *
1208  * If you want to call the structure member for storing the sequence entry
1209  * count something else, then use \ref CYAML_FIELD_SEQUENCE_COUNT instead.
1210  *
1211  * \param[in]  _key        String defining the YAML mapping key for this value.
1212  * \param[in]  _flags      Any behavioural flags relevant to this value.
1213  * \param[in]  _structure  The structure corresponding to the mapping.
1214  * \param[in]  _member     The member in _structure for this mapping value.
1215  * \param[in]  _entry      Pointer to schema for the **entries** in sequence.
1216  * \param[in]  _min        Minimum number of sequence entries required.
1217  * \param[in]  _max        Maximum number of sequence entries required.
1218  */
1219 #define CYAML_FIELD_SEQUENCE( \
1220 		_key, _flags, _structure, _member, _entry, _min, _max) \
1221 { \
1222 	.key = _key, \
1223 	.data_offset = offsetof(_structure, _member), \
1224 	.count_offset = offsetof(_structure, _member ## _count), \
1225 	.count_size = sizeof(((_structure *)NULL)->_member ## _count), \
1226 	.value = { \
1227 		CYAML_VALUE_SEQUENCE((_flags), \
1228 				(*(((_structure *)NULL)->_member)), \
1229 				_entry, _min, _max), \
1230 	}, \
1231 }
1232 
1233 /**
1234  * Mapping schema helper macro for keys with \ref CYAML_SEQUENCE type.
1235  *
1236  * Compared to .\ref CYAML_FIELD_SEQUENCE, this macro takes an extra `_count`
1237  * parameter, allowing the structure member name for the sequence entry count
1238  * to be provided explicitly.
1239  *
1240  * For example, for the following structure:
1241  *
1242  * ```
1243  * struct my_structure {
1244  *         unsigned *things;
1245  *         unsigned  n_things;
1246  * };
1247  * ```
1248  *
1249  * Pass the following as parameters:
1250  *
1251  * | Parameter  | Value                 |
1252  * | ---------- | --------------------- |
1253  * | _structure | `struct my_structure` |
1254  * | _member    | `things`              |
1255  * | _count     | `n_things`            |
1256  *
1257  * \param[in]  _key        String defining the YAML mapping key for this value.
1258  * \param[in]  _flags      Any behavioural flags relevant to this value.
1259  * \param[in]  _structure  The structure corresponding to the mapping.
1260  * \param[in]  _member     The member in _structure for this mapping value.
1261  * \param[in]  _count      The member in _structure for this sequence's
1262  *                         entry count.
1263  * \param[in]  _entry      Pointer to schema for the **entries** in sequence.
1264  * \param[in]  _min        Minimum number of sequence entries required.
1265  * \param[in]  _max        Maximum number of sequence entries required.
1266  */
1267 #define CYAML_FIELD_SEQUENCE_COUNT( \
1268 		_key, _flags, _structure, _member, _count, _entry, _min, _max) \
1269 { \
1270 	.key = _key, \
1271 	.data_offset = offsetof(_structure, _member), \
1272 	.count_offset = offsetof(_structure, _count), \
1273 	.count_size = sizeof(((_structure *)NULL)->_count), \
1274 	.value = { \
1275 		CYAML_VALUE_SEQUENCE((_flags), \
1276 				(*(((_structure *)NULL)->_member)), \
1277 				_entry, _min, _max), \
1278 	}, \
1279 }
1280 
1281 /**
1282  * Value schema helper macro for values with \ref CYAML_SEQUENCE_FIXED type.
1283  *
1284  * \param[in]  _flags      Any behavioural flags relevant to this value.
1285  * \param[in]  _type       The C type of sequence **entries**.
1286  * \param[in]  _entry      Pointer to schema for the **entries** in sequence.
1287  * \param[in]  _count      Number of sequence entries required.
1288  */
1289 #define CYAML_VALUE_SEQUENCE_FIXED( \
1290 		_flags, _type, _entry, _count) \
1291 	.type = CYAML_SEQUENCE_FIXED, \
1292 	.flags = (enum cyaml_flag)(_flags), \
1293 	.data_size = sizeof(_type), \
1294 	.sequence = { \
1295 		.entry = _entry, \
1296 		.min = _count, \
1297 		.max = _count, \
1298 	}
1299 
1300 /**
1301  * Mapping schema helper macro for keys with \ref CYAML_SEQUENCE_FIXED type.
1302  *
1303  * \param[in]  _key        String defining the YAML mapping key for this value.
1304  * \param[in]  _flags      Any behavioural flags relevant to this value.
1305  * \param[in]  _structure  The structure corresponding to the mapping.
1306  * \param[in]  _member     The member in _structure for this mapping value.
1307  * \param[in]  _entry      Pointer to schema for the **entries** in sequence.
1308  * \param[in]  _count      Number of sequence entries required.
1309  */
1310 #define CYAML_FIELD_SEQUENCE_FIXED( \
1311 		_key, _flags, _structure, _member, _entry, _count) \
1312 { \
1313 	.key = _key, \
1314 	.data_offset = offsetof(_structure, _member), \
1315 	.value = { \
1316 		CYAML_VALUE_SEQUENCE_FIXED((_flags), \
1317 				(*(((_structure *)NULL)->_member)), \
1318 				_entry, _count), \
1319 	}, \
1320 }
1321 
1322 /**
1323  * Mapping schema helper macro for keys with \ref CYAML_IGNORE type.
1324  *
1325  * \param[in]  _key    String defining the YAML mapping key to ignore.
1326  * \param[in]  _flags  Any behavioural flags relevant to this key.
1327  */
1328 #define CYAML_FIELD_IGNORE( \
1329 		_key, _flags) \
1330 { \
1331 	.key = _key, \
1332 	.value = { \
1333 		.type = CYAML_IGNORE, \
1334 		.flags = (_flags), \
1335 	}, \
1336 }
1337 
1338 /**
1339  * Mapping schema helper macro for terminating an array of mapping fields.
1340  *
1341  * CYAML mapping schemas are formed from an array of \ref cyaml_schema_field
1342  * entries, and an entry with a NULL key indicates the end of the array.
1343  */
1344 #define CYAML_FIELD_END { .key = NULL }
1345 
1346 /**
1347  * Identifies that a \ref CYAML_SEQUENCE has unconstrained maximum entry
1348  * count.
1349  */
1350 #define CYAML_UNLIMITED 0xffffffff
1351 
1352 /**
1353  * Helper macro for counting array elements.
1354  *
1355  * \note Don't use this macro on pointers.
1356  *
1357  * \param[in] _a  A C array.
1358  * \return Array element count.
1359  */
1360 #define CYAML_ARRAY_LEN(_a) ((sizeof(_a)) / (sizeof(_a[0])))
1361 
1362 /**
1363  * Data loaded or saved by CYAML has this type.  CYAML schemas are used
1364  * to describe the data contained.
1365  */
1366 typedef void cyaml_data_t;
1367 
1368 /** CYAML logging levels. */
1369 typedef enum cyaml_log_e {
1370 	CYAML_LOG_DEBUG,   /**< Debug level logging. */
1371 	CYAML_LOG_INFO,    /**< Info level logging. */
1372 	CYAML_LOG_NOTICE,  /**< Notice level logging. */
1373 	CYAML_LOG_WARNING, /**< Warning level logging. */
1374 	CYAML_LOG_ERROR,   /**< Error level logging. */
1375 } cyaml_log_t;
1376 
1377 /**
1378  * CYAML logging function prototype.
1379  *
1380  * Clients may implement this to manage logging from CYAML themselves.
1381  * Otherwise, consider using the standard logging function, \ref cyaml_log.
1382  *
1383  * \param[in] level  Log level of message to log.
1384  * \param[in] ctx    Client's private logging context.
1385  * \param[in] fmt    Format string for message to log.
1386  * \param[in] args   Additional arguments used by fmt.
1387  */
1388 typedef void (*cyaml_log_fn_t)(
1389 		cyaml_log_t level,
1390 		void *ctx,
1391 		const char *fmt,
1392 		va_list args);
1393 
1394 /**
1395  * CYAML memory allocation / freeing function.
1396  *
1397  * Clients may implement this to handle memory allocation / freeing.
1398  *
1399  * \param[in] ctx    Client's private allocation context.
1400  * \param[in] ptr    Existing allocation to resize, or NULL.
1401  * \param[in] size   The new size for the allocation.  \note setting 0 must
1402  *                   be treated as free().
1403  * \return If `size == 0`, returns NULL.  If `size > 0`, returns NULL on failure,
1404  *         and any existing allocation is left untouched, or return non-NULL as
1405  *         the new allocation on success, and the original pointer becomes
1406  *         invalid.
1407  */
1408 typedef void * (*cyaml_mem_fn_t)(
1409 		void *ctx,
1410 		void *ptr,
1411 		size_t size);
1412 
1413 /**
1414  * Client CYAML configuration data.
1415  *
1416  * \todo Should provide facility for client to provide its own custom
1417  *       allocation functions.
1418  */
1419 typedef struct cyaml_config {
1420 	/**
1421 	 * Client function to use for logging.
1422 	 *
1423 	 * Clients can implement their own logging function and set it here.
1424 	 * Otherwise, set `log_fn` to \ref cyaml_log if CYAML's default
1425 	 * logging to `stderr` is suitable (see its documentation for more
1426 	 * details), or set to `NULL` to suppress all logging.
1427 	 *
1428 	 * \note Useful backtraces are issued through the `log_fn` at
1429 	 *       \ref CYAML_LOG_ERROR level.  If your application needs
1430 	 *       to load user YAML data, these backtraces can help users
1431 	 *       figure out what's wrong with their YAML, causing it to
1432 	 *       be rejected by your schema.
1433 	 */
1434 	cyaml_log_fn_t log_fn;
1435 	/**
1436 	 * Client logging function context pointer.
1437 	 *
1438 	 * Clients using their own custom logging function can pass their
1439 	 * context here, which will be passed through to their log_fn.
1440 	 *
1441 	 * The default logging function, \ref cyaml_log doesn't require a
1442 	 * logging context, so pass NULL for the log_ctx if using that.
1443 	 */
1444 	void *log_ctx;
1445 	/**
1446 	 * Client function to use for memory allocation handling.
1447 	 *
1448 	 * Clients can implement their own, or pass \ref cyaml_mem to use
1449 	 * CYAML's default allocator.
1450 	 *
1451 	 * \note Depending on platform, when using CYAML's default allocator,
1452 	 *       clients may need to take care to ensure any allocated memory
1453 	 *       is freed using \ref cyaml_mem too.
1454 	 */
1455 	cyaml_mem_fn_t mem_fn;
1456 	/**
1457 	 * Client memory function context pointer.
1458 	 *
1459 	 * Clients using their own custom allocation function can pass their
1460 	 * context here, which will be passed through to their mem_fn.
1461 	 *
1462 	 * The default allocation function, \ref cyaml_mem doesn't require an
1463 	 * allocation context, so pass NULL for the mem_ctx if using that.
1464 	 */
1465 	void *mem_ctx;
1466 	/**
1467 	 * Minimum logging priority level to be issued.
1468 	 *
1469 	 * Specifying e.g. \ref CYAML_LOG_WARNING will cause only warnings and
1470 	 * errors to emerge.
1471 	 */
1472 	cyaml_log_t log_level;
1473 	/** CYAML behaviour flags. */
1474 	cyaml_cfg_flags_t flags;
1475 } cyaml_config_t;
1476 
1477 /**
1478  * Standard CYAML logging function.
1479  *
1480  * This logs to `stderr`.  It clients want to log elsewhere they must
1481  * implement their own logging function, and pass it to CYAML in the
1482  * \ref cyaml_config_t structure.
1483  *
1484  * \note This default logging function composes single log messages from
1485  *       multiple separate fprintfs to `stderr`.  If the client application
1486  *       writes to `stderr` from multiple threads, individual \ref cyaml_log
1487  *       messages may get broken up by the client applications logging.  To
1488  *       avoid this, clients should implement their own \ref cyaml_log_fn_t and
1489  *       pass it in via \ref cyaml_config_t.
1490  *
1491  * \param[in] level  Log level of message to log.
1492  * \param[in] ctx    Logging context, unused.
1493  * \param[in] fmt    Format string for message to log.
1494  * \param[in] args   Additional arguments used by fmt.
1495  */
1496 extern void cyaml_log(
1497 		cyaml_log_t level,
1498 		void *ctx,
1499 		const char *fmt,
1500 		va_list args);
1501 
1502 /**
1503  * CYAML default memory allocation / freeing function.
1504  *
1505  * This is used when clients don't supply their own.  It is exposed to
1506  * enable clients to use the same allocator as libcyaml used internally
1507  * to allocate/free memory when they have not provided their own allocation
1508  * function.
1509  *
1510  * \param[in] ctx    Allocation context, unused.
1511  * \param[in] ptr    Existing allocation to resize, or NULL.
1512  * \param[in] size   The new size for the allocation.  \note When `size == 0`
1513  *                   this frees `ptr`.
1514  * \return If `size == 0`, returns NULL.  If `size > 0`, returns NULL on failure,
1515  *         and any existing allocation is left untouched, or return non-NULL as
1516  *         the new allocation on success, and the original pointer becomes
1517  *         invalid.
1518  */
1519 extern void * cyaml_mem(
1520 		void *ctx,
1521 		void *ptr,
1522 		size_t size);
1523 
1524 /**
1525  * Load a YAML document from a file at the given path.
1526  *
1527  * \note In the event of the top-level mapping having only optional fields,
1528  *       and the YAML not setting any of them, this function can return \ref
1529  *       CYAML_OK, and `NULL` in the `data_out` parameter.
1530  *
1531  * \param[in]  path           Path to YAML file to load.
1532  * \param[in]  config         Client's CYAML configuration structure.
1533  * \param[in]  schema         CYAML schema for the YAML to be loaded.
1534  * \param[out] data_out       Returns the caller-owned loaded data on success.
1535  *                            Untouched on failure.
1536  * \param[out] seq_count_out  On success, returns the sequence entry count.
1537  *                            Untouched on failure.
1538  *                            Must be non-NULL if top-level schema type is
1539  *                            \ref CYAML_SEQUENCE, otherwise, must be NULL.
1540  * \return \ref CYAML_OK on success, or appropriate error code otherwise.
1541  */
1542 extern cyaml_err_t cyaml_load_file(
1543 		const char *path,
1544 		const cyaml_config_t *config,
1545 		const cyaml_schema_value_t *schema,
1546 		cyaml_data_t **data_out,
1547 		unsigned *seq_count_out);
1548 
1549 /**
1550  * Load a YAML document from a data buffer.
1551  *
1552  * \note In the event of the top-level mapping having only optional fields,
1553  *       and the YAML not setting any of them, this function can return \ref
1554  *       CYAML_OK, and `NULL` in the `data_out` parameter.
1555  *
1556  * \param[in]  input          Buffer to load YAML data from.
1557  * \param[in]  input_len      Length of input in bytes.
1558  * \param[in]  config         Client's CYAML configuration structure.
1559  * \param[in]  schema         CYAML schema for the YAML to be loaded.
1560  * \param[out] data_out       Returns the caller-owned loaded data on success.
1561  *                            Untouched on failure.
1562  * \param[out] seq_count_out  On success, returns the sequence entry count.
1563  *                            Untouched on failure.
1564  *                            Must be non-NULL if top-level schema type is
1565  *                            \ref CYAML_SEQUENCE, otherwise, must be NULL.
1566  * \return \ref CYAML_OK on success, or appropriate error code otherwise.
1567  */
1568 extern cyaml_err_t cyaml_load_data(
1569 		const uint8_t *input,
1570 		size_t input_len,
1571 		const cyaml_config_t *config,
1572 		const cyaml_schema_value_t *schema,
1573 		cyaml_data_t **data_out,
1574 		unsigned *seq_count_out);
1575 
1576 /**
1577  * Save a YAML document to a file at the given path.
1578  *
1579  * \param[in] path       Path to YAML file to write.
1580  * \param[in] config     Client's CYAML configuration structure.
1581  * \param[in] schema     CYAML schema for the YAML to be saved.
1582  * \param[in] data       The caller-owned data to be saved.
1583  * \param[in] seq_count  If top level type is sequence, this should be the
1584  *                       entry count, otherwise it is ignored.
1585  * \return \ref CYAML_OK on success, or appropriate error code otherwise.
1586  */
1587 extern cyaml_err_t cyaml_save_file(
1588 		const char *path,
1589 		const cyaml_config_t *config,
1590 		const cyaml_schema_value_t *schema,
1591 		const cyaml_data_t *data,
1592 		unsigned seq_count);
1593 
1594 /**
1595  * Save a YAML document into a string in memory.
1596  *
1597  * This allocates a buffer containing the serialised YAML data.
1598  *
1599  * To free the returned YAML string, clients should use the \ref cyaml_mem_fn_t
1600  * function set in the \ref cyaml_config_t passed to this function.
1601  * For example:
1602  *
1603  * ```
1604  * char *yaml;
1605  * size_t len;
1606  * err = cyaml_save_file(&yaml, &len, &config, &client_schema, client_data, 0);
1607  * if (err == CYAML_OK) {
1608  *         // Use `yaml`:
1609  *         printf("%*s\n", len, yaml);
1610  *         // Free `yaml`:
1611  *         config.mem_fn(config.mem_ctx, yaml, 0);
1612  * }
1613  * ```
1614  *
1615  * \note The returned YAML string does not have a trailing '\0'.
1616  *
1617  * \param[out] output     Returns the caller-owned serialised YAML data on
1618  *                        success, untouched on failure.  Clients should use
1619  *                        the \ref cyaml_mem_fn_t function set in the \ref
1620  *                        cyaml_config_t to free the data.
1621  * \param[out] len        Returns the length of the data in output on success,
1622  *                        untouched on failure.
1623  * \param[in]  config     Client's CYAML configuration structure.
1624  * \param[in]  schema     CYAML schema for the YAML to be saved.
1625  * \param[in]  data       The caller-owned data to be saved.
1626  * \param[in]  seq_count  If top level type is sequence, this should be the
1627  *                        entry count, otherwise it is ignored.
1628  * \return \ref CYAML_OK on success, or appropriate error code otherwise.
1629  */
1630 extern cyaml_err_t cyaml_save_data(
1631 		char **output,
1632 		size_t *len,
1633 		const cyaml_config_t *config,
1634 		const cyaml_schema_value_t *schema,
1635 		const cyaml_data_t *data,
1636 		unsigned seq_count);
1637 
1638 /**
1639  * Free data returned by a CYAML load function.
1640  *
1641  * This is a convenience function, which is here purely to minimise the
1642  * amount of code required in clients.  Clients would be better off writing
1643  * their own free function for the specific data once loaded.
1644  *
1645  * \note This is a recursive operation, freeing all nested data.
1646  *
1647  * \param[in] config     The client's CYAML library config.
1648  * \param[in] schema     The schema describing the content of data.  Must match
1649  *                       the schema given to the CYAML load function used to
1650  *                       load the data.
1651  * \param[in] data       The data structure to free.
1652  * \param[in] seq_count  If top level type is sequence, this should be the
1653  *                       entry count, otherwise it is ignored.
1654  * \return \ref CYAML_OK on success, or appropriate error code otherwise.
1655  */
1656 extern cyaml_err_t cyaml_free(
1657 		const cyaml_config_t *config,
1658 		const cyaml_schema_value_t *schema,
1659 		cyaml_data_t *data,
1660 		unsigned seq_count);
1661 
1662 /**
1663  * Convert a cyaml error code to a human-readable string.
1664  *
1665  * \param[in] err  Error code code to convert.
1666  * \return String representing err.  The string is '\0' terminated, and owned
1667  *         by libcyaml.
1668  */
1669 extern const char * cyaml_strerror(
1670 		cyaml_err_t err);
1671 
1672 #ifdef __cplusplus
1673 }
1674 #endif
1675 
1676 #endif
1677