/src/libucl/include/ucl.h
Line | Count | Source |
1 | | /* Copyright (c) 2013-2015, Vsevolod Stakhov |
2 | | * All rights reserved. |
3 | | * |
4 | | * Redistribution and use in source and binary forms, with or without |
5 | | * modification, are permitted provided that the following conditions are met: |
6 | | * * Redistributions of source code must retain the above copyright |
7 | | * notice, this list of conditions and the following disclaimer. |
8 | | * * Redistributions in binary form must reproduce the above copyright |
9 | | * notice, this list of conditions and the following disclaimer in the |
10 | | * documentation and/or other materials provided with the distribution. |
11 | | * |
12 | | * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY |
13 | | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
14 | | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
15 | | * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY |
16 | | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
17 | | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
18 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
19 | | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
20 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
21 | | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
22 | | */ |
23 | | |
24 | | #ifndef UCL_H_ |
25 | | #define UCL_H_ |
26 | | |
27 | | #include <string.h> |
28 | | #include <stddef.h> |
29 | | #include <stdlib.h> |
30 | | #include <stdint.h> |
31 | | #include <stdbool.h> |
32 | | #include <stdarg.h> |
33 | | #include <stdio.h> |
34 | | |
35 | | #ifdef _WIN32 |
36 | | #define UCL_EXTERN __declspec(dllexport) |
37 | | #else |
38 | | #define UCL_EXTERN |
39 | | #endif |
40 | | |
41 | | /** |
42 | | * @mainpage |
43 | | * This is a reference manual for UCL API. You may find the description of UCL format by following this |
44 | | * [github repository](https://github.com/vstakhov/libucl). |
45 | | * |
46 | | * This manual has several main sections: |
47 | | * - @ref structures |
48 | | * - @ref utils |
49 | | * - @ref parser |
50 | | * - @ref emitter |
51 | | */ |
52 | | |
53 | | /** |
54 | | * @file ucl.h |
55 | | * @brief UCL parsing and emitting functions |
56 | | * |
57 | | * UCL is universal configuration language, which is a form of |
58 | | * JSON with less strict rules that make it more comfortable for |
59 | | * using as a configuration language |
60 | | */ |
61 | | #ifdef __cplusplus |
62 | | extern "C" { |
63 | | #endif |
64 | | /* |
65 | | * Memory allocation utilities |
66 | | * UCL_ALLOC(size) - allocate memory for UCL |
67 | | * UCL_FREE(size, ptr) - free memory of specified size at ptr |
68 | | * Default: malloc and free |
69 | | */ |
70 | | #ifndef UCL_ALLOC |
71 | 12.5M | #define UCL_ALLOC(size) malloc(size) |
72 | | #endif |
73 | | #ifndef UCL_FREE |
74 | 6.40M | #define UCL_FREE(size, ptr) free(ptr) |
75 | | #endif |
76 | | #ifndef UCL_REALLOC |
77 | | #define UCL_REALLOC(ptr, size) realloc(ptr, size) |
78 | | #endif |
79 | | #ifndef UCL_STRDUP |
80 | | static inline char *ucl_strdup_impl(const char *s) |
81 | 1.81M | { |
82 | 1.81M | size_t len = strlen(s) + 1; |
83 | 1.81M | char *p = (char *) UCL_ALLOC(len); |
84 | 1.81M | if (p) memcpy(p, s, len); |
85 | 1.81M | return p; |
86 | 1.81M | } Unexecuted instantiation: ucl_add_string_fuzzer.c:ucl_strdup_impl ucl_parser.c:ucl_strdup_impl Line | Count | Source | 81 | 1.41M | { | 82 | 1.41M | size_t len = strlen(s) + 1; | 83 | 1.41M | char *p = (char *) UCL_ALLOC(len); | 84 | 1.41M | if (p) memcpy(p, s, len); | 85 | 1.41M | return p; | 86 | 1.41M | } |
ucl_util.c:ucl_strdup_impl Line | Count | Source | 81 | 394k | { | 82 | 394k | size_t len = strlen(s) + 1; | 83 | 394k | char *p = (char *) UCL_ALLOC(len); | 84 | 394k | if (p) memcpy(p, s, len); | 85 | 394k | return p; | 86 | 394k | } |
Unexecuted instantiation: ucl_msgpack.c:ucl_strdup_impl Unexecuted instantiation: ucl_sexp.c:ucl_strdup_impl Unexecuted instantiation: ucl_emitter_utils.c:ucl_strdup_impl Unexecuted instantiation: ucl_hash.c:ucl_strdup_impl Unexecuted instantiation: ucl_emitter.c:ucl_strdup_impl |
87 | 1.81M | #define UCL_STRDUP(str) ucl_strdup_impl(str) |
88 | | #endif |
89 | | |
90 | | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) |
91 | | #define UCL_WARN_UNUSED_RESULT \ |
92 | | __attribute__((warn_unused_result)) |
93 | | #else |
94 | | #define UCL_WARN_UNUSED_RESULT |
95 | | #endif |
96 | | |
97 | | #ifdef __GNUC__ |
98 | | #define UCL_DEPRECATED(func) func __attribute__((deprecated)) |
99 | | #elif defined(_MSC_VER) |
100 | | #define UCL_DEPRECATED(func) __declspec(deprecated) func |
101 | | #else |
102 | | #define UCL_DEPRECATED(func) func |
103 | | #endif |
104 | | |
105 | | /** |
106 | | * @defgroup structures Structures and types |
107 | | * UCL defines several enumeration types used for error reporting or specifying flags and attributes. |
108 | | * |
109 | | * @{ |
110 | | */ |
111 | | |
112 | | /** |
113 | | * The common error codes returned by ucl parser |
114 | | */ |
115 | | typedef enum ucl_error { |
116 | | UCL_EOK = 0, /**< No error */ |
117 | | UCL_ESYNTAX, /**< Syntax error occurred during parsing */ |
118 | | UCL_EIO, /**< IO error occurred during parsing */ |
119 | | UCL_ESTATE, /**< Invalid state machine state */ |
120 | | UCL_ENESTED, /**< Input has too many recursion levels */ |
121 | | UCL_EUNPAIRED, /**< Input has too many recursion levels */ |
122 | | UCL_EMACRO, /**< Error processing a macro */ |
123 | | UCL_EINTERNAL, /**< Internal unclassified error */ |
124 | | UCL_ESSL, /**< SSL error */ |
125 | | UCL_EMERGE /**< A merge error occurred */ |
126 | | } ucl_error_t; |
127 | | |
128 | | /** |
129 | | * #ucl_object_t may have one of specified types, some types are compatible with each other and some are not. |
130 | | * For example, you can always convert #UCL_TIME to #UCL_FLOAT. Also you can convert #UCL_FLOAT to #UCL_INTEGER |
131 | | * by loosing floating point. Every object may be converted to a string by #ucl_object_tostring_forced() function. |
132 | | * |
133 | | */ |
134 | | typedef enum ucl_type { |
135 | | UCL_OBJECT = 0, /**< UCL object - key/value pairs */ |
136 | | UCL_ARRAY, /**< UCL array */ |
137 | | UCL_INT, /**< Integer number */ |
138 | | UCL_FLOAT, /**< Floating point number */ |
139 | | UCL_STRING, /**< Null terminated string */ |
140 | | UCL_BOOLEAN, /**< Boolean value */ |
141 | | UCL_TIME, /**< Time value (floating point number of seconds) */ |
142 | | UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */ |
143 | | UCL_NULL /**< Null value */ |
144 | | } ucl_type_t; |
145 | | |
146 | | /** |
147 | | * You can use one of these types to serialise #ucl_object_t by using ucl_object_emit(). |
148 | | */ |
149 | | typedef enum ucl_emitter { |
150 | | UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */ |
151 | | UCL_EMIT_JSON_COMPACT, /**< Emit compacted JSON */ |
152 | | UCL_EMIT_CONFIG, /**< Emit human readable config format */ |
153 | | UCL_EMIT_YAML, /**< Emit embedded YAML format */ |
154 | | UCL_EMIT_MSGPACK, /**< Emit msgpack output */ |
155 | | UCL_EMIT_MAX /**< Unsupported emitter type */ |
156 | | } ucl_emitter_t; |
157 | | |
158 | | /** |
159 | | * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure |
160 | | * that the input memory is not freed if an object is in use. Moreover, if you want to use |
161 | | * zero-terminated keys and string values then you should not use zero-copy mode, as in this case |
162 | | * UCL still has to perform copying implicitly. |
163 | | */ |
164 | | typedef enum ucl_parser_flags { |
165 | | UCL_PARSER_DEFAULT = 0, /**< No special flags */ |
166 | | UCL_PARSER_KEY_LOWERCASE = (1 << 0), /**< Convert all keys to lower case */ |
167 | | UCL_PARSER_ZEROCOPY = (1 << 1), /**< Parse input in zero-copy mode if possible */ |
168 | | UCL_PARSER_NO_TIME = (1 << 2), /**< Do not parse time and treat time values as strings */ |
169 | | UCL_PARSER_NO_IMPLICIT_ARRAYS = (1 << 3), /** Create explicit arrays instead of implicit ones */ |
170 | | UCL_PARSER_SAVE_COMMENTS = (1 << 4), /** Save comments in the parser context */ |
171 | | UCL_PARSER_DISABLE_MACRO = (1 << 5), /** Treat macros as comments */ |
172 | | UCL_PARSER_NO_FILEVARS = (1 << 6) /** Do not set file vars */ |
173 | | } ucl_parser_flags_t; |
174 | | |
175 | | /** |
176 | | * String conversion flags, that are used in #ucl_object_fromstring_common function. |
177 | | */ |
178 | | typedef enum ucl_string_flags { |
179 | | UCL_STRING_RAW = 0x0, /**< Treat string as is */ |
180 | | UCL_STRING_ESCAPE = (1 << 0), /**< Perform JSON escape */ |
181 | | UCL_STRING_TRIM = (1 << 1), /**< Trim leading and trailing whitespaces */ |
182 | | UCL_STRING_PARSE_BOOLEAN = (1 << 2), /**< Parse passed string and detect boolean */ |
183 | | UCL_STRING_PARSE_INT = (1 << 3), /**< Parse passed string and detect integer number */ |
184 | | UCL_STRING_PARSE_DOUBLE = (1 << 4), /**< Parse passed string and detect integer or float number */ |
185 | | UCL_STRING_PARSE_TIME = (1 << 5), /**< Parse time strings */ |
186 | | UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT | UCL_STRING_PARSE_DOUBLE | UCL_STRING_PARSE_TIME, /**< |
187 | | Parse passed string and detect number */ |
188 | | UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN | UCL_STRING_PARSE_NUMBER, /**< |
189 | | Parse passed string (and detect booleans and numbers) */ |
190 | | UCL_STRING_PARSE_BYTES = (1 << 6) /**< Treat numbers as bytes */ |
191 | | } ucl_string_flags_t; |
192 | | |
193 | | /** |
194 | | * Basic flags for an object (can use up to 12 bits as higher 4 bits are used |
195 | | * for priorities) |
196 | | */ |
197 | | typedef enum ucl_object_flags { |
198 | | UCL_OBJECT_ALLOCATED_KEY = (1 << 0), /**< An object has key allocated internally */ |
199 | | UCL_OBJECT_ALLOCATED_VALUE = (1 << 1), /**< An object has a string value allocated internally */ |
200 | | UCL_OBJECT_NEED_KEY_ESCAPE = (1 << 2), /**< The key of an object need to be escaped on output */ |
201 | | UCL_OBJECT_EPHEMERAL = (1 << 3), /**< Temporary object that does not need to be freed really */ |
202 | | UCL_OBJECT_MULTILINE = (1 << 4), /**< String should be displayed as multiline string */ |
203 | | UCL_OBJECT_MULTIVALUE = (1 << 5), /**< Object is a key with multiple values */ |
204 | | UCL_OBJECT_INHERITED = (1 << 6), /**< Object has been inherited from another */ |
205 | | UCL_OBJECT_BINARY = (1 << 7), /**< Object contains raw binary data */ |
206 | | UCL_OBJECT_SQUOTED = (1 << 8) /**< Object has been enclosed in single quotes */ |
207 | | } ucl_object_flags_t; |
208 | | |
209 | | /** |
210 | | * Duplicate policy types |
211 | | */ |
212 | | enum ucl_duplicate_strategy { |
213 | | UCL_DUPLICATE_APPEND = 0, /**< Default policy to merge based on priorities */ |
214 | | UCL_DUPLICATE_MERGE, /**< Merge new object with old one */ |
215 | | UCL_DUPLICATE_REWRITE, /**< Rewrite old keys */ |
216 | | UCL_DUPLICATE_ERROR /**< Stop parsing on duplicate found */ |
217 | | }; |
218 | | |
219 | | /** |
220 | | * Input format type |
221 | | */ |
222 | | enum ucl_parse_type { |
223 | | UCL_PARSE_UCL = 0, /**< Default ucl format */ |
224 | | UCL_PARSE_MSGPACK, /**< Message pack input format */ |
225 | | UCL_PARSE_CSEXP, /**< Canonical S-expressions */ |
226 | | UCL_PARSE_AUTO /**< Try to detect parse type */ |
227 | | }; |
228 | | |
229 | | /** |
230 | | * UCL object structure. Please mention that the most of fields should not be touched by |
231 | | * UCL users. In future, this structure may be converted to private one. |
232 | | */ |
233 | | typedef struct ucl_object_s { |
234 | | /** |
235 | | * Variant value type |
236 | | */ |
237 | | union { |
238 | | int64_t iv; /**< Int value of an object */ |
239 | | const char *sv; /**< String value of an object */ |
240 | | double dv; /**< Double value of an object */ |
241 | | void *av; /**< Array */ |
242 | | void *ov; /**< Object */ |
243 | | void *ud; /**< Opaque user data */ |
244 | | } value; |
245 | | const char *key; /**< Key of an object */ |
246 | | struct ucl_object_s *next; /**< Array handle */ |
247 | | struct ucl_object_s *prev; /**< Array handle */ |
248 | | uint32_t keylen; /**< Length of a key */ |
249 | | uint32_t len; /**< Size of an object */ |
250 | | uint32_t ref; /**< Reference count */ |
251 | | uint16_t flags; /**< Object flags */ |
252 | | uint16_t type; /**< Real type */ |
253 | | unsigned char *trash_stack[2]; /**< Pointer to allocated chunks */ |
254 | | } ucl_object_t; |
255 | | |
256 | | /** |
257 | | * Destructor type for userdata objects |
258 | | * @param ud user specified data pointer |
259 | | */ |
260 | | typedef void (*ucl_userdata_dtor)(void *ud); |
261 | | typedef const char *(*ucl_userdata_emitter)(void *ud); |
262 | | |
263 | | /** @} */ |
264 | | |
265 | | /** |
266 | | * @defgroup utils Utility functions |
267 | | * A number of utility functions simplify handling of UCL objects |
268 | | * |
269 | | * @{ |
270 | | */ |
271 | | /** |
272 | | * Copy and return a key of an object, returned key is zero-terminated |
273 | | * @param obj CL object |
274 | | * @return zero terminated key |
275 | | */ |
276 | | UCL_EXTERN char *ucl_copy_key_trash(const ucl_object_t *obj); |
277 | | |
278 | | /** |
279 | | * Copy and return a string value of an object, returned key is zero-terminated |
280 | | * @param obj CL object |
281 | | * @return zero terminated string representation of object value |
282 | | */ |
283 | | UCL_EXTERN char *ucl_copy_value_trash(const ucl_object_t *obj); |
284 | | |
285 | | /** |
286 | | * Creates a new object |
287 | | * @return new object |
288 | | */ |
289 | | UCL_EXTERN ucl_object_t *ucl_object_new(void) UCL_WARN_UNUSED_RESULT; |
290 | | |
291 | | /** |
292 | | * Create new object with type specified |
293 | | * @param type type of a new object |
294 | | * @return new object |
295 | | */ |
296 | | UCL_EXTERN ucl_object_t *ucl_object_typed_new(ucl_type_t type) UCL_WARN_UNUSED_RESULT; |
297 | | |
298 | | /** |
299 | | * Create new object with type and priority specified |
300 | | * @param type type of a new object |
301 | | * @param priority priority of an object |
302 | | * @return new object |
303 | | */ |
304 | | UCL_EXTERN ucl_object_t *ucl_object_new_full(ucl_type_t type, unsigned priority) |
305 | | UCL_WARN_UNUSED_RESULT; |
306 | | |
307 | | /** |
308 | | * Create new object with userdata dtor |
309 | | * @param dtor destructor function |
310 | | * @param emitter emitter for userdata |
311 | | * @param ptr opaque pointer |
312 | | * @return new object |
313 | | */ |
314 | | UCL_EXTERN ucl_object_t *ucl_object_new_userdata(ucl_userdata_dtor dtor, |
315 | | ucl_userdata_emitter emitter, void *ptr) UCL_WARN_UNUSED_RESULT; |
316 | | |
317 | | /** |
318 | | * Perform deep copy of an object copying everything |
319 | | * @param other object to copy |
320 | | * @return new object with refcount equal to 1 |
321 | | */ |
322 | | UCL_EXTERN ucl_object_t *ucl_object_copy(const ucl_object_t *other) |
323 | | UCL_WARN_UNUSED_RESULT; |
324 | | |
325 | | /** |
326 | | * Return the type of an object |
327 | | * @return the object type |
328 | | */ |
329 | | UCL_EXTERN ucl_type_t ucl_object_type(const ucl_object_t *obj); |
330 | | |
331 | | /** |
332 | | * Converts ucl object type to its string representation |
333 | | * @param type type of object |
334 | | * @return constant string describing type |
335 | | */ |
336 | | UCL_EXTERN const char *ucl_object_type_to_string(ucl_type_t type); |
337 | | |
338 | | /** |
339 | | * Converts string that represents ucl type to real ucl type enum |
340 | | * @param input C string with name of type |
341 | | * @param res resulting target |
342 | | * @return true if `input` is a name of type stored in `res` |
343 | | */ |
344 | | UCL_EXTERN bool ucl_object_string_to_type(const char *input, ucl_type_t *res); |
345 | | |
346 | | /** |
347 | | * Convert any string to an ucl object making the specified transformations |
348 | | * @param str fixed size or NULL terminated string |
349 | | * @param len length (if len is zero, than str is treated as NULL terminated) |
350 | | * @param flags conversion flags |
351 | | * @return new object |
352 | | */ |
353 | | UCL_EXTERN ucl_object_t *ucl_object_fromstring_common(const char *str, size_t len, |
354 | | enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT; |
355 | | |
356 | | /** |
357 | | * Create a UCL object from the specified string |
358 | | * @param str NULL terminated string, will be json escaped |
359 | | * @return new object |
360 | | */ |
361 | | UCL_EXTERN ucl_object_t *ucl_object_fromstring(const char *str) UCL_WARN_UNUSED_RESULT; |
362 | | |
363 | | /** |
364 | | * Create a UCL object from the specified string |
365 | | * @param str fixed size string, will be json escaped |
366 | | * @param len length of a string |
367 | | * @return new object |
368 | | */ |
369 | | UCL_EXTERN ucl_object_t *ucl_object_fromlstring(const char *str, |
370 | | size_t len) UCL_WARN_UNUSED_RESULT; |
371 | | |
372 | | /** |
373 | | * Create an object from an integer number |
374 | | * @param iv number |
375 | | * @return new object |
376 | | */ |
377 | | UCL_EXTERN ucl_object_t *ucl_object_fromint(int64_t iv) UCL_WARN_UNUSED_RESULT; |
378 | | |
379 | | /** |
380 | | * Create an object from a float number |
381 | | * @param dv number |
382 | | * @return new object |
383 | | */ |
384 | | UCL_EXTERN ucl_object_t *ucl_object_fromdouble(double dv) UCL_WARN_UNUSED_RESULT; |
385 | | |
386 | | /** |
387 | | * Create an object from a boolean |
388 | | * @param bv bool value |
389 | | * @return new object |
390 | | */ |
391 | | UCL_EXTERN ucl_object_t *ucl_object_frombool(bool bv) UCL_WARN_UNUSED_RESULT; |
392 | | |
393 | | /** |
394 | | * Insert a object 'elt' to the hash 'top' and associate it with key 'key' |
395 | | * @param top destination object (must be of type UCL_OBJECT) |
396 | | * @param elt element to insert (must NOT be NULL) |
397 | | * @param key key to associate with this object (either const or preallocated) |
398 | | * @param keylen length of the key (or 0 for NULL terminated keys) |
399 | | * @param copy_key make an internal copy of key |
400 | | * @return true if key has been inserted |
401 | | */ |
402 | | UCL_EXTERN bool ucl_object_insert_key(ucl_object_t *top, ucl_object_t *elt, |
403 | | const char *key, size_t keylen, bool copy_key); |
404 | | |
405 | | /** |
406 | | * Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed, |
407 | | * if no object has been found this function works like ucl_object_insert_key() |
408 | | * @param top destination object (must be of type UCL_OBJECT) |
409 | | * @param elt element to insert (must NOT be NULL) |
410 | | * @param key key to associate with this object (either const or preallocated) |
411 | | * @param keylen length of the key (or 0 for NULL terminated keys) |
412 | | * @param copy_key make an internal copy of key |
413 | | * @return true if key has been inserted |
414 | | */ |
415 | | UCL_EXTERN bool ucl_object_replace_key(ucl_object_t *top, ucl_object_t *elt, |
416 | | const char *key, size_t keylen, bool copy_key); |
417 | | |
418 | | /** |
419 | | * Merge the keys from one object to another object. Overwrite on conflict |
420 | | * @param top destination object (must be of type UCL_OBJECT) |
421 | | * @param elt element to insert (must be of type UCL_OBJECT) |
422 | | * @param copy copy rather than reference the elements |
423 | | * @return true if all keys have been merged |
424 | | */ |
425 | | UCL_EXTERN bool ucl_object_merge(ucl_object_t *top, ucl_object_t *elt, bool copy); |
426 | | |
427 | | /** |
428 | | * Delete a object associated with key 'key', old object will be unrefered, |
429 | | * @param top object |
430 | | * @param key key associated to the object to remove |
431 | | * @param keylen length of the key (or 0 for NULL terminated keys) |
432 | | */ |
433 | | UCL_EXTERN bool ucl_object_delete_keyl(ucl_object_t *top, |
434 | | const char *key, size_t keylen); |
435 | | |
436 | | /** |
437 | | * Delete a object associated with key 'key', old object will be unrefered, |
438 | | * @param top object |
439 | | * @param key key associated to the object to remove |
440 | | */ |
441 | | UCL_EXTERN bool ucl_object_delete_key(ucl_object_t *top, |
442 | | const char *key); |
443 | | |
444 | | |
445 | | /** |
446 | | * Removes `key` from `top` object, returning the object that was removed. This |
447 | | * object is not released, caller must unref the returned object when it is no |
448 | | * longer needed. |
449 | | * @param top object |
450 | | * @param key key to remove |
451 | | * @param keylen length of the key (or 0 for NULL terminated keys) |
452 | | * @return removed object or NULL if object has not been found |
453 | | */ |
454 | | UCL_EXTERN ucl_object_t *ucl_object_pop_keyl(ucl_object_t *top, const char *key, |
455 | | size_t keylen) UCL_WARN_UNUSED_RESULT; |
456 | | |
457 | | /** |
458 | | * Removes `key` from `top` object returning the object that was removed. This |
459 | | * object is not released, caller must unref the returned object when it is no |
460 | | * longer needed. |
461 | | * @param top object |
462 | | * @param key key to remove |
463 | | * @return removed object or NULL if object has not been found |
464 | | */ |
465 | | UCL_EXTERN ucl_object_t *ucl_object_pop_key(ucl_object_t *top, const char *key) |
466 | | UCL_WARN_UNUSED_RESULT; |
467 | | |
468 | | /** |
469 | | * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if |
470 | | * the specified key exist, try to merge its content |
471 | | * @param top destination object (must be of type UCL_OBJECT) |
472 | | * @param elt element to insert (must NOT be NULL) |
473 | | * @param key key to associate with this object (either const or preallocated) |
474 | | * @param keylen length of the key (or 0 for NULL terminated keys) |
475 | | * @param copy_key make an internal copy of key |
476 | | * @return true if key has been inserted |
477 | | */ |
478 | | UCL_EXTERN bool ucl_object_insert_key_merged(ucl_object_t *top, ucl_object_t *elt, |
479 | | const char *key, size_t keylen, bool copy_key); |
480 | | |
481 | | /** |
482 | | * Reserve space in ucl array or object for `elt` elements |
483 | | * @param obj object to reserve |
484 | | * @param reserved size to reserve in an object |
485 | | * @return 0 on success, -1 on failure (i.e. ENOMEM) |
486 | | */ |
487 | | UCL_EXTERN bool ucl_object_reserve(ucl_object_t *obj, size_t reserved); |
488 | | |
489 | | /** |
490 | | * Append an element to the end of array object |
491 | | * @param top destination object (must NOT be NULL) |
492 | | * @param elt element to append (must NOT be NULL) |
493 | | * @return true if value has been inserted |
494 | | */ |
495 | | UCL_EXTERN bool ucl_array_append(ucl_object_t *top, |
496 | | ucl_object_t *elt); |
497 | | |
498 | | /** |
499 | | * Append an element to the start of array object |
500 | | * @param top destination object (must NOT be NULL) |
501 | | * @param elt element to append (must NOT be NULL) |
502 | | * @return true if value has been inserted |
503 | | */ |
504 | | UCL_EXTERN bool ucl_array_prepend(ucl_object_t *top, |
505 | | ucl_object_t *elt); |
506 | | |
507 | | /** |
508 | | * Merge all elements of second array into the first array |
509 | | * @param top destination array (must be of type UCL_ARRAY) |
510 | | * @param elt array to copy elements from (must be of type UCL_ARRAY) |
511 | | * @param copy copy elements instead of referencing them |
512 | | * @return true if arrays were merged |
513 | | */ |
514 | | UCL_EXTERN bool ucl_array_merge(ucl_object_t *top, ucl_object_t *elt, |
515 | | bool copy); |
516 | | |
517 | | /** |
518 | | * Removes an element `elt` from the array `top`, returning the object that was |
519 | | * removed. This object is not released, caller must unref the returned object |
520 | | * when it is no longer needed. |
521 | | * @param top array ucl object |
522 | | * @param elt element to remove |
523 | | * @return removed element or NULL if `top` is NULL or not an array |
524 | | */ |
525 | | UCL_EXTERN ucl_object_t *ucl_array_delete(ucl_object_t *top, |
526 | | ucl_object_t *elt); |
527 | | |
528 | | /** |
529 | | * Returns the first element of the array `top` |
530 | | * @param top array ucl object |
531 | | * @return element or NULL if `top` is NULL or not an array |
532 | | */ |
533 | | UCL_EXTERN const ucl_object_t *ucl_array_head(const ucl_object_t *top); |
534 | | |
535 | | /** |
536 | | * Returns the last element of the array `top` |
537 | | * @param top array ucl object |
538 | | * @return element or NULL if `top` is NULL or not an array |
539 | | */ |
540 | | UCL_EXTERN const ucl_object_t *ucl_array_tail(const ucl_object_t *top); |
541 | | |
542 | | /** |
543 | | * Removes the last element from the array `top`, returning the object that was |
544 | | * removed. This object is not released, caller must unref the returned object |
545 | | * when it is no longer needed. |
546 | | * @param top array ucl object |
547 | | * @return removed element or NULL if `top` is NULL or not an array |
548 | | */ |
549 | | UCL_EXTERN ucl_object_t *ucl_array_pop_last(ucl_object_t *top); |
550 | | |
551 | | /** |
552 | | * Removes the first element from the array `top`, returning the object that was |
553 | | * removed. This object is not released, caller must unref the returned object |
554 | | * when it is no longer needed. |
555 | | * @param top array ucl object |
556 | | * @return removed element or NULL if `top` is NULL or not an array |
557 | | */ |
558 | | UCL_EXTERN ucl_object_t *ucl_array_pop_first(ucl_object_t *top); |
559 | | |
560 | | /** |
561 | | * Return size of the array `top` |
562 | | * @param top object to get size from (must be of type UCL_ARRAY) |
563 | | * @return size of the array |
564 | | */ |
565 | | UCL_EXTERN unsigned int ucl_array_size(const ucl_object_t *top); |
566 | | |
567 | | /** |
568 | | * Return object identified by index of the array `top` |
569 | | * @param top object to get a key from (must be of type UCL_ARRAY) |
570 | | * @param index array index to return |
571 | | * @return object at the specified index or NULL if index is not found |
572 | | */ |
573 | | UCL_EXTERN const ucl_object_t *ucl_array_find_index(const ucl_object_t *top, |
574 | | unsigned int index); |
575 | | |
576 | | /** |
577 | | * Return the index of `elt` in the array `top` |
578 | | * @param top object to get a key from (must be of type UCL_ARRAY) |
579 | | * @param elt element to find index of (must NOT be NULL) |
580 | | * @return index of `elt` in the array `top or (unsigned int)-1 if `elt` is not found |
581 | | */ |
582 | | UCL_EXTERN unsigned int ucl_array_index_of(ucl_object_t *top, |
583 | | ucl_object_t *elt); |
584 | | |
585 | | /** |
586 | | * Replace an element in an array with a different element, returning the object |
587 | | * that was replaced. This object is not released, caller must unref the |
588 | | * returned object when it is no longer needed. |
589 | | * @param top destination object (must be of type UCL_ARRAY) |
590 | | * @param elt element to append (must NOT be NULL) |
591 | | * @param index array index in destination to overwrite with elt |
592 | | * @return object that was replaced or NULL if index is not found |
593 | | */ |
594 | | ucl_object_t * |
595 | | ucl_array_replace_index(ucl_object_t *top, ucl_object_t *elt, |
596 | | unsigned int index); |
597 | | |
598 | | /** |
599 | | * Append a element to another element forming an implicit array |
600 | | * @param head head to append (may be NULL) |
601 | | * @param elt new element |
602 | | * @return the new implicit array |
603 | | */ |
604 | | UCL_EXTERN ucl_object_t *ucl_elt_append(ucl_object_t *head, |
605 | | ucl_object_t *elt); |
606 | | |
607 | | /** |
608 | | * Converts an object to double value |
609 | | * @param obj CL object |
610 | | * @param target target double variable |
611 | | * @return true if conversion was successful |
612 | | */ |
613 | | UCL_EXTERN bool ucl_object_todouble_safe(const ucl_object_t *obj, double *target); |
614 | | |
615 | | /** |
616 | | * Unsafe version of \ref ucl_obj_todouble_safe |
617 | | * @param obj CL object |
618 | | * @return double value |
619 | | */ |
620 | | UCL_EXTERN double ucl_object_todouble(const ucl_object_t *obj); |
621 | | |
622 | | /** |
623 | | * Converts an object to integer value |
624 | | * @param obj CL object |
625 | | * @param target target integer variable |
626 | | * @return true if conversion was successful |
627 | | */ |
628 | | UCL_EXTERN bool ucl_object_toint_safe(const ucl_object_t *obj, int64_t *target); |
629 | | |
630 | | /** |
631 | | * Unsafe version of \ref ucl_obj_toint_safe |
632 | | * @param obj CL object |
633 | | * @return int value |
634 | | */ |
635 | | UCL_EXTERN int64_t ucl_object_toint(const ucl_object_t *obj); |
636 | | |
637 | | /** |
638 | | * Converts an object to boolean value |
639 | | * @param obj CL object |
640 | | * @param target target boolean variable |
641 | | * @return true if conversion was successful |
642 | | */ |
643 | | UCL_EXTERN bool ucl_object_toboolean_safe(const ucl_object_t *obj, bool *target); |
644 | | |
645 | | /** |
646 | | * Unsafe version of \ref ucl_obj_toboolean_safe |
647 | | * @param obj CL object |
648 | | * @return boolean value |
649 | | */ |
650 | | UCL_EXTERN bool ucl_object_toboolean(const ucl_object_t *obj); |
651 | | |
652 | | /** |
653 | | * Converts an object to string value |
654 | | * @param obj CL object |
655 | | * @param target target string variable, no need to free value |
656 | | * @return true if conversion was successful |
657 | | */ |
658 | | UCL_EXTERN bool ucl_object_tostring_safe(const ucl_object_t *obj, const char **target); |
659 | | |
660 | | /** |
661 | | * Unsafe version of \ref ucl_obj_tostring_safe |
662 | | * @param obj CL object |
663 | | * @return string value |
664 | | */ |
665 | | UCL_EXTERN const char *ucl_object_tostring(const ucl_object_t *obj); |
666 | | |
667 | | /** |
668 | | * Convert any object to a string in JSON notation if needed |
669 | | * @param obj CL object |
670 | | * @return string value |
671 | | */ |
672 | | UCL_EXTERN const char *ucl_object_tostring_forced(const ucl_object_t *obj); |
673 | | |
674 | | /** |
675 | | * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it |
676 | | * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing) |
677 | | * @param obj CL object |
678 | | * @param target target string variable, no need to free value |
679 | | * @param tlen target length |
680 | | * @return true if conversion was successful |
681 | | */ |
682 | | UCL_EXTERN bool ucl_object_tolstring_safe(const ucl_object_t *obj, |
683 | | const char **target, size_t *tlen); |
684 | | |
685 | | /** |
686 | | * Unsafe version of \ref ucl_obj_tolstring_safe |
687 | | * @param obj CL object |
688 | | * @return string value |
689 | | */ |
690 | | UCL_EXTERN const char *ucl_object_tolstring(const ucl_object_t *obj, size_t *tlen); |
691 | | |
692 | | /** |
693 | | * Return object identified by a key in the specified object |
694 | | * @param obj object to get a key from (must be of type UCL_OBJECT) |
695 | | * @param key key to search |
696 | | * @return object matching the specified key or NULL if key was not found |
697 | | */ |
698 | | UCL_EXTERN const ucl_object_t *ucl_object_lookup(const ucl_object_t *obj, |
699 | | const char *key); |
700 | | #define ucl_object_find_key ucl_object_lookup |
701 | | |
702 | | /** |
703 | | * Return object identified by a key in the specified object, if the first key is |
704 | | * not found then look for the next one. This process is repeated unless |
705 | | * the next argument in the list is not NULL. So, `ucl_object_find_any_key(obj, key, NULL)` |
706 | | * is equal to `ucl_object_find_key(obj, key)` |
707 | | * @param obj object to get a key from (must be of type UCL_OBJECT) |
708 | | * @param key key to search |
709 | | * @param ... list of alternative keys to search (NULL terminated) |
710 | | * @return object matching the specified key or NULL if key was not found |
711 | | */ |
712 | | UCL_EXTERN const ucl_object_t *ucl_object_lookup_any(const ucl_object_t *obj, |
713 | | const char *key, ...); |
714 | | #define ucl_object_find_any_key ucl_object_lookup_any |
715 | | |
716 | | /** |
717 | | * Return object identified by a fixed size key in the specified object |
718 | | * @param obj object to get a key from (must be of type UCL_OBJECT) |
719 | | * @param key key to search |
720 | | * @param klen length of a key |
721 | | * @return object matching the specified key or NULL if key was not found |
722 | | */ |
723 | | UCL_EXTERN const ucl_object_t *ucl_object_lookup_len(const ucl_object_t *obj, |
724 | | const char *key, size_t klen); |
725 | | #define ucl_object_find_keyl ucl_object_lookup_len |
726 | | |
727 | | /** |
728 | | * Return object identified by dot notation string |
729 | | * @param obj object to search in |
730 | | * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays |
731 | | * @return object matched the specified path or NULL if path is not found |
732 | | */ |
733 | | UCL_EXTERN const ucl_object_t *ucl_object_lookup_path(const ucl_object_t *obj, |
734 | | const char *path); |
735 | | #define ucl_lookup_path ucl_object_lookup_path |
736 | | |
737 | | /** |
738 | | * Return object identified by object notation string using arbitrary delimiter |
739 | | * @param obj object to search in |
740 | | * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays |
741 | | * @param sep the sepatorator to use in place of . (incase keys have . in them) |
742 | | * @return object matched the specified path or NULL if path is not found |
743 | | */ |
744 | | UCL_EXTERN const ucl_object_t *ucl_object_lookup_path_char(const ucl_object_t *obj, |
745 | | const char *path, char sep); |
746 | | #define ucl_lookup_path_char ucl_object_lookup_path_char |
747 | | |
748 | | /** |
749 | | * Returns a key of an object as a NULL terminated string |
750 | | * @param obj CL object |
751 | | * @return key or NULL if there is no key |
752 | | */ |
753 | | UCL_EXTERN const char *ucl_object_key(const ucl_object_t *obj); |
754 | | |
755 | | /** |
756 | | * Returns a key of an object as a fixed size string (may be more efficient) |
757 | | * @param obj CL object |
758 | | * @param len target key length |
759 | | * @return key pointer |
760 | | */ |
761 | | UCL_EXTERN const char *ucl_object_keyl(const ucl_object_t *obj, size_t *len); |
762 | | |
763 | | /** |
764 | | * Increase reference count for an object |
765 | | * @param obj object to ref |
766 | | * @return the referenced object |
767 | | */ |
768 | | UCL_EXTERN ucl_object_t *ucl_object_ref(const ucl_object_t *obj); |
769 | | |
770 | | /** |
771 | | * Free ucl object |
772 | | * @param obj ucl object to free |
773 | | */ |
774 | | UCL_DEPRECATED(UCL_EXTERN void ucl_object_free(ucl_object_t *obj)); |
775 | | |
776 | | /** |
777 | | * Decrease reference count for an object |
778 | | * @param obj object to unref |
779 | | */ |
780 | | UCL_EXTERN void ucl_object_unref(ucl_object_t *obj); |
781 | | |
782 | | /** |
783 | | * Compare objects `o1` and `o2` |
784 | | * @param o1 the first object |
785 | | * @param o2 the second object |
786 | | * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`. |
787 | | * The order of comparison: |
788 | | * 1) Type of objects |
789 | | * 2) Size of objects |
790 | | * 3) Content of objects |
791 | | */ |
792 | | UCL_EXTERN int ucl_object_compare(const ucl_object_t *o1, |
793 | | const ucl_object_t *o2); |
794 | | |
795 | | /** |
796 | | * Compare objects `o1` and `o2` useful for sorting |
797 | | * @param o1 the first object |
798 | | * @param o2 the second object |
799 | | * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`. |
800 | | * The order of comparison: |
801 | | * 1) Type of objects |
802 | | * 2) Size of objects |
803 | | * 3) Content of objects |
804 | | */ |
805 | | UCL_EXTERN int ucl_object_compare_qsort(const ucl_object_t **o1, |
806 | | const ucl_object_t **o2); |
807 | | |
808 | | /** |
809 | | * Sort UCL array using `cmp` compare function |
810 | | * @param ar |
811 | | * @param cmp |
812 | | */ |
813 | | UCL_EXTERN void ucl_object_array_sort(ucl_object_t *ar, |
814 | | int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2)); |
815 | | |
816 | | enum ucl_object_keys_sort_flags { |
817 | | UCL_SORT_KEYS_DEFAULT = 0, |
818 | | UCL_SORT_KEYS_ICASE = (1u << 0u), |
819 | | UCL_SORT_KEYS_RECURSIVE = (1u << 1u), |
820 | | }; |
821 | | /*** |
822 | | * Sorts keys in object in place |
823 | | * @param obj |
824 | | * @param how |
825 | | */ |
826 | | UCL_EXTERN void ucl_object_sort_keys(ucl_object_t *obj, |
827 | | enum ucl_object_keys_sort_flags how); |
828 | | |
829 | | /** |
830 | | * Get the priority for specific UCL object |
831 | | * @param obj any ucl object |
832 | | * @return priority of an object |
833 | | */ |
834 | | UCL_EXTERN unsigned int ucl_object_get_priority(const ucl_object_t *obj); |
835 | | |
836 | | /** |
837 | | * Set explicit priority of an object. |
838 | | * @param obj any ucl object |
839 | | * @param priority new priroity value (only 4 least significant bits are considred) |
840 | | */ |
841 | | UCL_EXTERN void ucl_object_set_priority(ucl_object_t *obj, |
842 | | unsigned int priority); |
843 | | |
844 | | /** |
845 | | * Opaque iterator object |
846 | | */ |
847 | | typedef void *ucl_object_iter_t; |
848 | | |
849 | | /** |
850 | | * Get next key from an object |
851 | | * @param obj object to iterate |
852 | | * @param iter opaque iterator, must be set to NULL on the first call: |
853 | | * ucl_object_iter_t it = NULL; |
854 | | * while ((cur = ucl_iterate_object (obj, &it)) != NULL) ... |
855 | | * @param ep pointer record exception (such as ENOMEM), could be NULL |
856 | | * @return the next object or NULL |
857 | | */ |
858 | | UCL_EXTERN const ucl_object_t *ucl_object_iterate_with_error(const ucl_object_t *obj, |
859 | | ucl_object_iter_t *iter, bool expand_values, int *ep); |
860 | | |
861 | | #define ucl_iterate_object ucl_object_iterate |
862 | 6.14M | #define ucl_object_iterate(ob, it, ev) ucl_object_iterate_with_error((ob), (it), (ev), NULL) |
863 | | |
864 | | /** |
865 | | * Create new safe iterator for the specified object |
866 | | * @param obj object to iterate |
867 | | * @return new iterator object that should be used with safe iterators API only |
868 | | */ |
869 | | UCL_EXTERN ucl_object_iter_t ucl_object_iterate_new(const ucl_object_t *obj) |
870 | | UCL_WARN_UNUSED_RESULT; |
871 | | /** |
872 | | * Check safe iterator object after performing some operations on it |
873 | | * (such as ucl_object_iterate_safe()) to see if operation has encountered |
874 | | * fatal exception while performing that operation (e.g. ENOMEM). |
875 | | * @param iter opaque iterator |
876 | | * @return true if exception has occured, false otherwise |
877 | | */ |
878 | | UCL_EXTERN bool ucl_object_iter_chk_excpn(ucl_object_iter_t *it); |
879 | | |
880 | | /** |
881 | | * Reset initialized iterator to a new object |
882 | | * @param obj new object to iterate |
883 | | * @return modified iterator object |
884 | | */ |
885 | | UCL_EXTERN ucl_object_iter_t ucl_object_iterate_reset(ucl_object_iter_t it, |
886 | | const ucl_object_t *obj); |
887 | | |
888 | | /** |
889 | | * Get the next object from the `obj`. This function iterates over arrays, objects |
890 | | * and implicit arrays |
891 | | * @param iter safe iterator |
892 | | * @param expand_values expand explicit arrays and objects |
893 | | * @return the next object in sequence |
894 | | */ |
895 | | UCL_EXTERN const ucl_object_t *ucl_object_iterate_safe(ucl_object_iter_t iter, |
896 | | bool expand_values); |
897 | | /** |
898 | | * Iteration type enumerator |
899 | | */ |
900 | | enum ucl_iterate_type { |
901 | | UCL_ITERATE_EXPLICIT = 1 << 0, /**< Iterate just explicit arrays and objects */ |
902 | | UCL_ITERATE_IMPLICIT = 1 << 1, /**< Iterate just implicit arrays */ |
903 | | UCL_ITERATE_BOTH = (1 << 0) | (1 << 1), /**< Iterate both explicit and implicit arrays*/ |
904 | | }; |
905 | | |
906 | | /** |
907 | | * Get the next object from the `obj`. This function iterates over arrays, objects |
908 | | * and implicit arrays if needed |
909 | | * @param iter safe iterator |
910 | | * @param |
911 | | * @return the next object in sequence |
912 | | */ |
913 | | UCL_EXTERN const ucl_object_t *ucl_object_iterate_full(ucl_object_iter_t iter, |
914 | | enum ucl_iterate_type type); |
915 | | |
916 | | /** |
917 | | * Free memory associated with the safe iterator |
918 | | * @param it safe iterator object |
919 | | */ |
920 | | UCL_EXTERN void ucl_object_iterate_free(ucl_object_iter_t it); |
921 | | |
922 | | /** @} */ |
923 | | |
924 | | |
925 | | /** |
926 | | * @defgroup parser Parsing functions |
927 | | * These functions are used to parse UCL objects |
928 | | * |
929 | | * @{ |
930 | | */ |
931 | | |
932 | | /** |
933 | | * Macro handler for a parser |
934 | | * @param data the content of macro |
935 | | * @param len the length of content |
936 | | * @param arguments arguments object |
937 | | * @param ud opaque user data |
938 | | * @param err error pointer |
939 | | * @return true if macro has been parsed |
940 | | */ |
941 | | typedef bool (*ucl_macro_handler)(const unsigned char *data, size_t len, |
942 | | const ucl_object_t *arguments, |
943 | | void *ud); |
944 | | |
945 | | /** |
946 | | * Context dependent macro handler for a parser |
947 | | * @param data the content of macro |
948 | | * @param len the length of content |
949 | | * @param arguments arguments object |
950 | | * @param context previously parsed context |
951 | | * @param ud opaque user data |
952 | | * @param err error pointer |
953 | | * @return true if macro has been parsed |
954 | | */ |
955 | | typedef bool (*ucl_context_macro_handler)(const unsigned char *data, size_t len, |
956 | | const ucl_object_t *arguments, |
957 | | const ucl_object_t *context, |
958 | | void *ud); |
959 | | |
960 | | /* Opaque parser */ |
961 | | struct ucl_parser; |
962 | | |
963 | | /** |
964 | | * Creates new parser object |
965 | | * @param pool pool to allocate memory from |
966 | | * @return new parser object |
967 | | */ |
968 | | UCL_EXTERN struct ucl_parser *ucl_parser_new(int flags); |
969 | | |
970 | | /** |
971 | | * Sets the default priority for the parser applied to chunks that do not |
972 | | * specify priority explicitly |
973 | | * @param parser parser object |
974 | | * @param prio default priority (0 .. 16) |
975 | | * @return true if parser's default priority was set |
976 | | */ |
977 | | UCL_EXTERN bool ucl_parser_set_default_priority(struct ucl_parser *parser, |
978 | | unsigned prio); |
979 | | /** |
980 | | * Gets the default priority for the parser applied to chunks that do not |
981 | | * specify priority explicitly |
982 | | * @param parser parser object |
983 | | * @return true default priority (0 .. 16), -1 for failure |
984 | | */ |
985 | | UCL_EXTERN int ucl_parser_get_default_priority(struct ucl_parser *parser); |
986 | | |
987 | | /** |
988 | | * Register new handler for a macro |
989 | | * @param parser parser object |
990 | | * @param macro macro name (without leading dot) |
991 | | * @param handler handler (it is called immediately after macro is parsed) |
992 | | * @param ud opaque user data for a handler |
993 | | * @return true on success, false on failure (i.e. ENOMEM) |
994 | | */ |
995 | | UCL_EXTERN bool ucl_parser_register_macro(struct ucl_parser *parser, |
996 | | const char *macro, |
997 | | ucl_macro_handler handler, void *ud); |
998 | | |
999 | | /** |
1000 | | * Register new context dependent handler for a macro |
1001 | | * @param parser parser object |
1002 | | * @param macro macro name (without leading dot) |
1003 | | * @param handler handler (it is called immediately after macro is parsed) |
1004 | | * @param ud opaque user data for a handler |
1005 | | * @return true on success, false on failure (i.e. ENOMEM) |
1006 | | */ |
1007 | | UCL_EXTERN bool ucl_parser_register_context_macro(struct ucl_parser *parser, |
1008 | | const char *macro, |
1009 | | ucl_context_macro_handler handler, |
1010 | | void *ud); |
1011 | | |
1012 | | /** |
1013 | | * Handler to detect unregistered variables |
1014 | | * @param data variable data |
1015 | | * @param len length of variable |
1016 | | * @param replace (out) replace value for variable |
1017 | | * @param replace_len (out) replace length for variable |
1018 | | * @param need_free (out) UCL will free `dest` after usage |
1019 | | * @param ud opaque userdata |
1020 | | * @return true if variable |
1021 | | */ |
1022 | | typedef bool (*ucl_variable_handler)(const unsigned char *data, size_t len, |
1023 | | unsigned char **replace, size_t *replace_len, bool *need_free, void *ud); |
1024 | | |
1025 | | /** |
1026 | | * Register new parser variable |
1027 | | * @param parser parser object |
1028 | | * @param var variable name |
1029 | | * @param value variable value |
1030 | | */ |
1031 | | UCL_EXTERN void ucl_parser_register_variable(struct ucl_parser *parser, const char *var, |
1032 | | const char *value); |
1033 | | |
1034 | | /** |
1035 | | * Set handler for unknown variables |
1036 | | * @param parser parser structure |
1037 | | * @param handler desired handler |
1038 | | * @param ud opaque data for the handler |
1039 | | */ |
1040 | | UCL_EXTERN void ucl_parser_set_variables_handler(struct ucl_parser *parser, |
1041 | | ucl_variable_handler handler, void *ud); |
1042 | | |
1043 | | /** |
1044 | | * Load new chunk to a parser |
1045 | | * @param parser parser structure |
1046 | | * @param data the pointer to the beginning of a chunk |
1047 | | * @param len the length of a chunk |
1048 | | * @return true if chunk has been added and false in case of error |
1049 | | */ |
1050 | | UCL_EXTERN bool ucl_parser_add_chunk(struct ucl_parser *parser, |
1051 | | const unsigned char *data, size_t len); |
1052 | | |
1053 | | /** |
1054 | | * Load new chunk to a parser with the specified priority |
1055 | | * @param parser parser structure |
1056 | | * @param data the pointer to the beginning of a chunk |
1057 | | * @param len the length of a chunk |
1058 | | * @param priority the desired priority of a chunk (only 4 least significant bits |
1059 | | * are considered for this parameter) |
1060 | | * @return true if chunk has been added and false in case of error |
1061 | | */ |
1062 | | UCL_EXTERN bool ucl_parser_add_chunk_priority(struct ucl_parser *parser, |
1063 | | const unsigned char *data, size_t len, unsigned priority); |
1064 | | |
1065 | | /** |
1066 | | * Insert new chunk to a parser (must have previously processed data with an existing top object) |
1067 | | * @param parser parser structure |
1068 | | * @param data the pointer to the beginning of a chunk |
1069 | | * @param len the length of a chunk |
1070 | | * @return true if chunk has been added and false in case of error |
1071 | | */ |
1072 | | UCL_EXTERN bool ucl_parser_insert_chunk(struct ucl_parser *parser, |
1073 | | const unsigned char *data, size_t len); |
1074 | | |
1075 | | /** |
1076 | | * Full version of ucl_add_chunk with priority and duplicate strategy |
1077 | | * @param parser parser structure |
1078 | | * @param data the pointer to the beginning of a chunk |
1079 | | * @param len the length of a chunk |
1080 | | * @param priority the desired priority of a chunk (only 4 least significant bits |
1081 | | * are considered for this parameter) |
1082 | | * @param strat duplicates merging strategy |
1083 | | * @param parse_type input format |
1084 | | * @return true if chunk has been added and false in case of error |
1085 | | */ |
1086 | | UCL_EXTERN bool ucl_parser_add_chunk_full(struct ucl_parser *parser, |
1087 | | const unsigned char *data, size_t len, unsigned priority, |
1088 | | enum ucl_duplicate_strategy strat, enum ucl_parse_type parse_type); |
1089 | | |
1090 | | /** |
1091 | | * Load ucl object from a string |
1092 | | * @param parser parser structure |
1093 | | * @param data the pointer to the string |
1094 | | * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string |
1095 | | * @return true if string has been added and false in case of error |
1096 | | */ |
1097 | | UCL_EXTERN bool ucl_parser_add_string(struct ucl_parser *parser, |
1098 | | const char *data, size_t len); |
1099 | | |
1100 | | /** |
1101 | | * Load ucl object from a string |
1102 | | * @param parser parser structure |
1103 | | * @param data the pointer to the string |
1104 | | * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string |
1105 | | * @param priority the desired priority of a chunk (only 4 least significant bits |
1106 | | * are considered for this parameter) |
1107 | | * @return true if string has been added and false in case of error |
1108 | | */ |
1109 | | UCL_EXTERN bool ucl_parser_add_string_priority(struct ucl_parser *parser, |
1110 | | const char *data, size_t len, unsigned priority); |
1111 | | |
1112 | | /** |
1113 | | * Load and add data from a file |
1114 | | * @param parser parser structure |
1115 | | * @param filename the name of file |
1116 | | * @param err if *err is NULL it is set to parser error |
1117 | | * @return true if chunk has been added and false in case of error |
1118 | | */ |
1119 | | UCL_EXTERN bool ucl_parser_add_file(struct ucl_parser *parser, |
1120 | | const char *filename); |
1121 | | |
1122 | | /** |
1123 | | * Load and add data from a file |
1124 | | * @param parser parser structure |
1125 | | * @param filename the name of file |
1126 | | * @param err if *err is NULL it is set to parser error |
1127 | | * @param priority the desired priority of a chunk (only 4 least significant bits |
1128 | | * are considered for this parameter) |
1129 | | * @return true if chunk has been added and false in case of error |
1130 | | */ |
1131 | | UCL_EXTERN bool ucl_parser_add_file_priority(struct ucl_parser *parser, |
1132 | | const char *filename, unsigned priority); |
1133 | | |
1134 | | /** |
1135 | | * Load and add data from a file |
1136 | | * @param parser parser structure |
1137 | | * @param filename the name of file |
1138 | | * @param priority the desired priority of a chunk (only 4 least significant bits |
1139 | | * are considered for this parameter) |
1140 | | * @param strat Merge strategy to use while parsing this file |
1141 | | * @param parse_type Parser type to use while parsing this file |
1142 | | * @return true if chunk has been added and false in case of error |
1143 | | */ |
1144 | | UCL_EXTERN bool ucl_parser_add_file_full(struct ucl_parser *parser, const char *filename, |
1145 | | unsigned priority, enum ucl_duplicate_strategy strat, |
1146 | | enum ucl_parse_type parse_type); |
1147 | | |
1148 | | /** |
1149 | | * Load and add data from a file descriptor |
1150 | | * @param parser parser structure |
1151 | | * @param filename the name of file |
1152 | | * @param err if *err is NULL it is set to parser error |
1153 | | * @return true if chunk has been added and false in case of error |
1154 | | */ |
1155 | | UCL_EXTERN bool ucl_parser_add_fd(struct ucl_parser *parser, |
1156 | | int fd); |
1157 | | |
1158 | | /** |
1159 | | * Load and add data from a file descriptor |
1160 | | * @param parser parser structure |
1161 | | * @param filename the name of file |
1162 | | * @param err if *err is NULL it is set to parser error |
1163 | | * @param priority the desired priority of a chunk (only 4 least significant bits |
1164 | | * are considered for this parameter) |
1165 | | * @return true if chunk has been added and false in case of error |
1166 | | */ |
1167 | | UCL_EXTERN bool ucl_parser_add_fd_priority(struct ucl_parser *parser, |
1168 | | int fd, unsigned priority); |
1169 | | |
1170 | | /** |
1171 | | * Load and add data from a file descriptor |
1172 | | * @param parser parser structure |
1173 | | * @param filename the name of file |
1174 | | * @param err if *err is NULL it is set to parser error |
1175 | | * @param priority the desired priority of a chunk (only 4 least significant bits |
1176 | | * are considered for this parameter) |
1177 | | * @param strat Merge strategy to use while parsing this file |
1178 | | * @param parse_type Parser type to use while parsing this file |
1179 | | * @return true if chunk has been added and false in case of error |
1180 | | */ |
1181 | | UCL_EXTERN bool ucl_parser_add_fd_full(struct ucl_parser *parser, int fd, |
1182 | | unsigned priority, enum ucl_duplicate_strategy strat, |
1183 | | enum ucl_parse_type parse_type); |
1184 | | |
1185 | | /** |
1186 | | * Provide a UCL_ARRAY of paths to search for include files. The object is |
1187 | | * copied so caller must unref the object. |
1188 | | * @param parser parser structure |
1189 | | * @param paths UCL_ARRAY of paths to search |
1190 | | * @return true if the path search array was replaced in the parser |
1191 | | */ |
1192 | | UCL_EXTERN bool ucl_set_include_path(struct ucl_parser *parser, |
1193 | | ucl_object_t *paths); |
1194 | | |
1195 | | /** |
1196 | | * Get a top object for a parser (refcount is increased) |
1197 | | * @param parser parser structure |
1198 | | * @param err if *err is NULL it is set to parser error |
1199 | | * @return top parser object or NULL |
1200 | | */ |
1201 | | UCL_EXTERN ucl_object_t *ucl_parser_get_object(struct ucl_parser *parser); |
1202 | | |
1203 | | /** |
1204 | | * Get the current stack object as stack accessor function for use in macro |
1205 | | * functions (refcount is increased) |
1206 | | * @param parser parser object |
1207 | | * @param depth depth of stack to retrieve (top is 0) |
1208 | | * @return current stack object or NULL |
1209 | | */ |
1210 | | UCL_EXTERN ucl_object_t *ucl_parser_get_current_stack_object(struct ucl_parser *parser, unsigned int depth); |
1211 | | |
1212 | | /** |
1213 | | * Peek at the character at the current chunk position |
1214 | | * @param parser parser structure |
1215 | | * @return current chunk position character |
1216 | | */ |
1217 | | UCL_EXTERN unsigned char ucl_parser_chunk_peek(struct ucl_parser *parser); |
1218 | | |
1219 | | /** |
1220 | | * Skip the character at the current chunk position |
1221 | | * @param parser parser structure |
1222 | | * @return success boolean |
1223 | | */ |
1224 | | UCL_EXTERN bool ucl_parser_chunk_skip(struct ucl_parser *parser); |
1225 | | |
1226 | | /** |
1227 | | * Get the error string if parsing has been failed |
1228 | | * @param parser parser object |
1229 | | * @return error description |
1230 | | */ |
1231 | | UCL_EXTERN const char *ucl_parser_get_error(struct ucl_parser *parser); |
1232 | | |
1233 | | /** |
1234 | | * Get the code of the last error |
1235 | | * @param parser parser object |
1236 | | * @return error code |
1237 | | */ |
1238 | | UCL_EXTERN int ucl_parser_get_error_code(struct ucl_parser *parser); |
1239 | | |
1240 | | /** |
1241 | | * Get the current column number within parser |
1242 | | * @param parser parser object |
1243 | | * @return current column number |
1244 | | */ |
1245 | | UCL_EXTERN unsigned ucl_parser_get_column(struct ucl_parser *parser); |
1246 | | |
1247 | | /** |
1248 | | * Get the current line number within parser |
1249 | | * @param parser parser object |
1250 | | * @return current line number |
1251 | | */ |
1252 | | UCL_EXTERN unsigned ucl_parser_get_linenum(struct ucl_parser *parser); |
1253 | | |
1254 | | /** |
1255 | | * Clear the error in the parser |
1256 | | * @param parser parser object |
1257 | | */ |
1258 | | UCL_EXTERN void ucl_parser_clear_error(struct ucl_parser *parser); |
1259 | | |
1260 | | /** |
1261 | | * Free ucl parser object |
1262 | | * @param parser parser object |
1263 | | */ |
1264 | | UCL_EXTERN void ucl_parser_free(struct ucl_parser *parser); |
1265 | | |
1266 | | /** |
1267 | | * Get constant opaque pointer to comments structure for this parser. Increase |
1268 | | * refcount to prevent this object to be destroyed on parser's destruction |
1269 | | * @param parser parser structure |
1270 | | * @return ucl comments pointer or NULL |
1271 | | */ |
1272 | | UCL_EXTERN const ucl_object_t *ucl_parser_get_comments(struct ucl_parser *parser); |
1273 | | |
1274 | | /** |
1275 | | * Utility function to find a comment object for the specified object in the input |
1276 | | * @param comments comments object |
1277 | | * @param srch search object |
1278 | | * @return string comment enclosed in ucl_object_t |
1279 | | */ |
1280 | | UCL_EXTERN const ucl_object_t *ucl_comments_find(const ucl_object_t *comments, |
1281 | | const ucl_object_t *srch); |
1282 | | |
1283 | | /** |
1284 | | * Move comment from `from` object to `to` object |
1285 | | * @param comments comments object |
1286 | | * @param what source object |
1287 | | * @param with destination object |
1288 | | * @return `true` if `from` has comment and it has been moved to `to` |
1289 | | */ |
1290 | | UCL_EXTERN bool ucl_comments_move(ucl_object_t *comments, |
1291 | | const ucl_object_t *from, const ucl_object_t *to); |
1292 | | |
1293 | | /** |
1294 | | * Adds a new comment for an object |
1295 | | * @param comments comments object |
1296 | | * @param obj object to add comment to |
1297 | | * @param comment string representation of a comment |
1298 | | */ |
1299 | | UCL_EXTERN void ucl_comments_add(ucl_object_t *comments, |
1300 | | const ucl_object_t *obj, const char *comment); |
1301 | | |
1302 | | /** |
1303 | | * Add new public key to parser for signatures check |
1304 | | * @param parser parser object |
1305 | | * @param key PEM representation of a key |
1306 | | * @param len length of the key |
1307 | | * @param err if *err is NULL it is set to parser error |
1308 | | * @return true if a key has been successfully added |
1309 | | */ |
1310 | | UCL_EXTERN bool ucl_parser_pubkey_add(struct ucl_parser *parser, |
1311 | | const unsigned char *key, size_t len); |
1312 | | |
1313 | | /** |
1314 | | * Set FILENAME and CURDIR variables in parser |
1315 | | * @param parser parser object |
1316 | | * @param filename filename to set or NULL to set FILENAME to "undef" and CURDIR to getcwd() |
1317 | | * @param need_expand perform realpath() if this variable is true and filename is not NULL |
1318 | | * @return true if variables has been set |
1319 | | */ |
1320 | | UCL_EXTERN bool ucl_parser_set_filevars(struct ucl_parser *parser, const char *filename, |
1321 | | bool need_expand); |
1322 | | |
1323 | | /** |
1324 | | * Returns current file for the parser |
1325 | | * @param parser parser object |
1326 | | * @return current file or NULL if parsing memory |
1327 | | */ |
1328 | | UCL_EXTERN const char *ucl_parser_get_cur_file(struct ucl_parser *parser); |
1329 | | |
1330 | | /** |
1331 | | * Defines special handler for certain types of data (identified by magic) |
1332 | | */ |
1333 | | typedef bool (*ucl_parser_special_handler_t)(struct ucl_parser *parser, |
1334 | | const unsigned char *source, size_t source_len, |
1335 | | unsigned char **destination, size_t *dest_len, |
1336 | | void *user_data); |
1337 | | |
1338 | | /** |
1339 | | * Special handler flags |
1340 | | */ |
1341 | | enum ucl_special_handler_flags { |
1342 | | UCL_SPECIAL_HANDLER_DEFAULT = 0, |
1343 | | UCL_SPECIAL_HANDLER_PREPROCESS_ALL = (1u << 0), |
1344 | | }; |
1345 | | |
1346 | | /** |
1347 | | * Special handler structure |
1348 | | */ |
1349 | | struct ucl_parser_special_handler { |
1350 | | const unsigned char *magic; |
1351 | | size_t magic_len; |
1352 | | enum ucl_special_handler_flags flags; |
1353 | | ucl_parser_special_handler_t handler; |
1354 | | void (*free_function)(unsigned char *data, size_t len, void *user_data); |
1355 | | void *user_data; |
1356 | | struct ucl_parser_special_handler *next; /* Used internally */ |
1357 | | }; |
1358 | | |
1359 | | /** |
1360 | | * Add special handler for a parser, handles special sequences identified by magic |
1361 | | * @param parser parser structure |
1362 | | * @param handler handler structure |
1363 | | */ |
1364 | | UCL_EXTERN void ucl_parser_add_special_handler(struct ucl_parser *parser, |
1365 | | struct ucl_parser_special_handler *handler); |
1366 | | |
1367 | | /** |
1368 | | * Handler for include traces: |
1369 | | * @param parser parser object |
1370 | | * @param parent where include is done from |
1371 | | * @param args arguments to an include |
1372 | | * @param path path of the include |
1373 | | * @param pathlen length of the path |
1374 | | * @param user_data opaque userdata |
1375 | | */ |
1376 | | typedef void(ucl_include_trace_func_t)(struct ucl_parser *parser, |
1377 | | const ucl_object_t *parent, |
1378 | | const ucl_object_t *args, |
1379 | | const char *path, |
1380 | | size_t pathlen, |
1381 | | void *user_data); |
1382 | | |
1383 | | /** |
1384 | | * Register trace function for an include handler |
1385 | | * @param parser parser object |
1386 | | * @param func function to trace includes |
1387 | | * @param user_data opaque data |
1388 | | */ |
1389 | | UCL_EXTERN void ucl_parser_set_include_tracer(struct ucl_parser *parser, |
1390 | | ucl_include_trace_func_t func, |
1391 | | void *user_data); |
1392 | | |
1393 | | /** @} */ |
1394 | | |
1395 | | /** |
1396 | | * @defgroup emitter Emitting functions |
1397 | | * These functions are used to serialise UCL objects to some string representation. |
1398 | | * |
1399 | | * @{ |
1400 | | */ |
1401 | | |
1402 | | struct ucl_emitter_context; |
1403 | | /** |
1404 | | * Structure using for emitter callbacks |
1405 | | */ |
1406 | | struct ucl_emitter_functions { |
1407 | | /** Append a single character */ |
1408 | | int (*ucl_emitter_append_character)(unsigned char c, size_t nchars, void *ud); |
1409 | | /** Append a string of a specified length */ |
1410 | | int (*ucl_emitter_append_len)(unsigned const char *str, size_t len, void *ud); |
1411 | | /** Append a 64 bit integer */ |
1412 | | int (*ucl_emitter_append_int)(int64_t elt, void *ud); |
1413 | | /** Append floating point element */ |
1414 | | int (*ucl_emitter_append_double)(double elt, void *ud); |
1415 | | /** Free userdata */ |
1416 | | void (*ucl_emitter_free_func)(void *ud); |
1417 | | /** Opaque userdata pointer */ |
1418 | | void *ud; |
1419 | | }; |
1420 | | |
1421 | | struct ucl_emitter_operations { |
1422 | | /** Write a primitive element */ |
1423 | | void (*ucl_emitter_write_elt)(struct ucl_emitter_context *ctx, |
1424 | | const ucl_object_t *obj, bool first, bool print_key); |
1425 | | /** Start ucl object */ |
1426 | | void (*ucl_emitter_start_object)(struct ucl_emitter_context *ctx, |
1427 | | const ucl_object_t *obj, bool first, bool print_key); |
1428 | | /** End ucl object */ |
1429 | | void (*ucl_emitter_end_object)(struct ucl_emitter_context *ctx, |
1430 | | const ucl_object_t *obj); |
1431 | | /** Start ucl array */ |
1432 | | void (*ucl_emitter_start_array)(struct ucl_emitter_context *ctx, |
1433 | | const ucl_object_t *obj, bool first, bool print_key); |
1434 | | void (*ucl_emitter_end_array)(struct ucl_emitter_context *ctx, |
1435 | | const ucl_object_t *obj); |
1436 | | }; |
1437 | | |
1438 | | /** |
1439 | | * Structure that defines emitter functions |
1440 | | */ |
1441 | | struct ucl_emitter_context { |
1442 | | /** Name of emitter (e.g. json, compact_json) */ |
1443 | | const char *name; |
1444 | | /** Unique id (e.g. UCL_EMIT_JSON for standard emitters */ |
1445 | | int id; |
1446 | | /** A set of output functions */ |
1447 | | const struct ucl_emitter_functions *func; |
1448 | | /** A set of output operations */ |
1449 | | const struct ucl_emitter_operations *ops; |
1450 | | /** Current amount of indent tabs */ |
1451 | | unsigned int indent; |
1452 | | /** Top level object */ |
1453 | | const ucl_object_t *top; |
1454 | | /** Optional comments */ |
1455 | | const ucl_object_t *comments; |
1456 | | }; |
1457 | | |
1458 | | /** |
1459 | | * Emit object to a string |
1460 | | * @param obj object |
1461 | | * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is |
1462 | | * #UCL_EMIT_CONFIG then emit config like object |
1463 | | * @return dump of an object (must be freed after using) or NULL in case of error |
1464 | | */ |
1465 | | UCL_EXTERN unsigned char *ucl_object_emit(const ucl_object_t *obj, |
1466 | | enum ucl_emitter emit_type); |
1467 | | |
1468 | | /** |
1469 | | * Emit object to a string that can contain `\0` inside |
1470 | | * @param obj object |
1471 | | * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is |
1472 | | * #UCL_EMIT_CONFIG then emit config like object |
1473 | | * @param len the resulting length |
1474 | | * @return dump of an object (must be freed after using) or NULL in case of error |
1475 | | */ |
1476 | | UCL_EXTERN unsigned char *ucl_object_emit_len(const ucl_object_t *obj, |
1477 | | enum ucl_emitter emit_type, size_t *len); |
1478 | | |
1479 | | /** |
1480 | | * Emit object to a string |
1481 | | * @param obj object |
1482 | | * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is |
1483 | | * #UCL_EMIT_CONFIG then emit config like object |
1484 | | * @param emitter a set of emitter functions |
1485 | | * @param comments optional comments for the parser |
1486 | | * @return dump of an object (must be freed after using) or NULL in case of error |
1487 | | */ |
1488 | | UCL_EXTERN bool ucl_object_emit_full(const ucl_object_t *obj, |
1489 | | enum ucl_emitter emit_type, |
1490 | | struct ucl_emitter_functions *emitter, |
1491 | | const ucl_object_t *comments); |
1492 | | |
1493 | | /** |
1494 | | * Start streamlined UCL object emitter |
1495 | | * @param obj top UCL object |
1496 | | * @param emit_type emit type |
1497 | | * @param emitter a set of emitter functions |
1498 | | * @return new streamlined context that should be freed by |
1499 | | * `ucl_object_emit_streamline_finish` |
1500 | | */ |
1501 | | UCL_EXTERN struct ucl_emitter_context *ucl_object_emit_streamline_new( |
1502 | | const ucl_object_t *obj, enum ucl_emitter emit_type, |
1503 | | struct ucl_emitter_functions *emitter); |
1504 | | |
1505 | | /** |
1506 | | * Start object or array container for the streamlined output |
1507 | | * @param ctx streamlined context |
1508 | | * @param obj container object |
1509 | | */ |
1510 | | UCL_EXTERN bool ucl_object_emit_streamline_start_container( |
1511 | | struct ucl_emitter_context *ctx, const ucl_object_t *obj); |
1512 | | /** |
1513 | | * Add a complete UCL object to streamlined output |
1514 | | * @param ctx streamlined context |
1515 | | * @param obj object to output |
1516 | | */ |
1517 | | UCL_EXTERN void ucl_object_emit_streamline_add_object( |
1518 | | struct ucl_emitter_context *ctx, const ucl_object_t *obj); |
1519 | | /** |
1520 | | * End previously added container |
1521 | | * @param ctx streamlined context |
1522 | | */ |
1523 | | UCL_EXTERN void ucl_object_emit_streamline_end_container( |
1524 | | struct ucl_emitter_context *ctx); |
1525 | | /** |
1526 | | * Terminate streamlined container finishing all containers in it |
1527 | | * @param ctx streamlined context |
1528 | | */ |
1529 | | UCL_EXTERN void ucl_object_emit_streamline_finish( |
1530 | | struct ucl_emitter_context *ctx); |
1531 | | |
1532 | | /** |
1533 | | * Returns functions to emit object to memory |
1534 | | * @param pmem target pointer (should be freed by caller) |
1535 | | * @return emitter functions structure |
1536 | | */ |
1537 | | UCL_EXTERN struct ucl_emitter_functions *ucl_object_emit_memory_funcs( |
1538 | | void **pmem); |
1539 | | |
1540 | | /** |
1541 | | * Returns functions to emit object to FILE * |
1542 | | * @param fp FILE * object |
1543 | | * @return emitter functions structure |
1544 | | */ |
1545 | | UCL_EXTERN struct ucl_emitter_functions *ucl_object_emit_file_funcs( |
1546 | | FILE *fp); |
1547 | | /** |
1548 | | * Returns functions to emit object to a file descriptor |
1549 | | * @param fd file descriptor |
1550 | | * @return emitter functions structure |
1551 | | */ |
1552 | | UCL_EXTERN struct ucl_emitter_functions *ucl_object_emit_fd_funcs( |
1553 | | int fd); |
1554 | | |
1555 | | /** |
1556 | | * Free emitter functions |
1557 | | * @param f pointer to functions |
1558 | | */ |
1559 | | UCL_EXTERN void ucl_object_emit_funcs_free(struct ucl_emitter_functions *f); |
1560 | | |
1561 | | /** @} */ |
1562 | | |
1563 | | /** |
1564 | | * @defgroup schema Schema functions |
1565 | | * These functions are used to validate UCL objects using json schema format |
1566 | | * |
1567 | | * @{ |
1568 | | */ |
1569 | | |
1570 | | /** |
1571 | | * Used to define UCL schema error |
1572 | | */ |
1573 | | enum ucl_schema_error_code { |
1574 | | UCL_SCHEMA_OK = 0, /**< no error */ |
1575 | | UCL_SCHEMA_TYPE_MISMATCH, /**< type of object is incorrect */ |
1576 | | UCL_SCHEMA_INVALID_SCHEMA, /**< schema is invalid */ |
1577 | | UCL_SCHEMA_MISSING_PROPERTY, /**< one or more missing properties */ |
1578 | | UCL_SCHEMA_CONSTRAINT, /**< constraint found */ |
1579 | | UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */ |
1580 | | UCL_SCHEMA_EXTERNAL_REF_MISSING, /**< cannot fetch external ref */ |
1581 | | UCL_SCHEMA_EXTERNAL_REF_INVALID, /**< invalid external ref */ |
1582 | | UCL_SCHEMA_INTERNAL_ERROR, /**< something bad happened */ |
1583 | | UCL_SCHEMA_UNKNOWN /**< generic error */ |
1584 | | }; |
1585 | | |
1586 | | /** |
1587 | | * Generic ucl schema error |
1588 | | */ |
1589 | | struct ucl_schema_error { |
1590 | | enum ucl_schema_error_code code; /**< error code */ |
1591 | | char msg[128]; /**< error message */ |
1592 | | const ucl_object_t *obj; /**< object where error occurred */ |
1593 | | }; |
1594 | | |
1595 | | /** |
1596 | | * Validate object `obj` using schema object `schema`. |
1597 | | * @param schema schema object |
1598 | | * @param obj object to validate |
1599 | | * @param err error pointer, if this parameter is not NULL and error has been |
1600 | | * occurred, then `err` is filled with the exact error definition. |
1601 | | * @return true if `obj` is valid using `schema` |
1602 | | */ |
1603 | | UCL_EXTERN bool ucl_object_validate(const ucl_object_t *schema, |
1604 | | const ucl_object_t *obj, struct ucl_schema_error *err); |
1605 | | |
1606 | | /** |
1607 | | * Validate object `obj` using schema object `schema` and root schema at `root`. |
1608 | | * @param schema schema object |
1609 | | * @param obj object to validate |
1610 | | * @param root root schema object |
1611 | | * @param err error pointer, if this parameter is not NULL and error has been |
1612 | | * occurred, then `err` is filled with the exact error definition. |
1613 | | * @return true if `obj` is valid using `schema` |
1614 | | */ |
1615 | | UCL_EXTERN bool ucl_object_validate_root(const ucl_object_t *schema, |
1616 | | const ucl_object_t *obj, |
1617 | | const ucl_object_t *root, |
1618 | | struct ucl_schema_error *err); |
1619 | | |
1620 | | /** |
1621 | | * Validate object `obj` using schema object `schema` and root schema at `root` |
1622 | | * using some external references provided. |
1623 | | * @param schema schema object |
1624 | | * @param obj object to validate |
1625 | | * @param root root schema object |
1626 | | * @param ext_refs external references (might be modified during validation) |
1627 | | * @param err error pointer, if this parameter is not NULL and error has been |
1628 | | * occurred, then `err` is filled with the exact error definition. |
1629 | | * @return true if `obj` is valid using `schema` |
1630 | | */ |
1631 | | UCL_EXTERN bool ucl_object_validate_root_ext(const ucl_object_t *schema, |
1632 | | const ucl_object_t *obj, |
1633 | | const ucl_object_t *root, |
1634 | | ucl_object_t *ext_refs, |
1635 | | struct ucl_schema_error *err); |
1636 | | |
1637 | | /** @} */ |
1638 | | |
1639 | | #ifdef __cplusplus |
1640 | | } |
1641 | | #endif |
1642 | | /* |
1643 | | * XXX: Poorly named API functions, need to replace them with the appropriate |
1644 | | * named function. All API functions *must* use naming ucl_object_*. Usage of |
1645 | | * ucl_obj* should be avoided. |
1646 | | */ |
1647 | | #define ucl_obj_todouble_safe ucl_object_todouble_safe |
1648 | | #define ucl_obj_todouble ucl_object_todouble |
1649 | | #define ucl_obj_tostring ucl_object_tostring |
1650 | | #define ucl_obj_tostring_safe ucl_object_tostring_safe |
1651 | | #define ucl_obj_tolstring ucl_object_tolstring |
1652 | | #define ucl_obj_tolstring_safe ucl_object_tolstring_safe |
1653 | | #define ucl_obj_toint ucl_object_toint |
1654 | | #define ucl_obj_toint_safe ucl_object_toint_safe |
1655 | | #define ucl_obj_toboolean ucl_object_toboolean |
1656 | | #define ucl_obj_toboolean_safe ucl_object_toboolean_safe |
1657 | | #define ucl_obj_get_key ucl_object_find_key |
1658 | | #define ucl_obj_get_keyl ucl_object_find_keyl |
1659 | | #define ucl_obj_unref ucl_object_unref |
1660 | | #define ucl_obj_ref ucl_object_ref |
1661 | | #define ucl_obj_free ucl_object_free |
1662 | | |
1663 | | #define UCL_PRIORITY_MIN 0 |
1664 | | #define UCL_PRIORITY_MAX 15 |
1665 | | |
1666 | | #endif /* UCL_H_ */ |