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