diff options
| author | Baptiste Daroussin <bapt@FreeBSD.org> | 2021-03-22 14:07:18 +0000 |
|---|---|---|
| committer | Baptiste Daroussin <bapt@FreeBSD.org> | 2021-03-22 14:07:18 +0000 |
| commit | 3c319408d0de2d2de0c19b24e1a41c0a0e4a823b (patch) | |
| tree | de0b27939e96ed7a8b3554a149b321ef719cc875 /include | |
| parent | 8392e70f8a07e517fab31f8300cfaf5f02bea0f5 (diff) | |
libucl: import latest snapshot from 2021-03-14vendor/libucl/20210314
Diffstat (limited to 'include')
| -rw-r--r-- | include/lua_ucl.h | 20 | ||||
| -rw-r--r-- | include/ucl++.h | 189 | ||||
| -rw-r--r-- | include/ucl.h | 191 |
3 files changed, 351 insertions, 49 deletions
diff --git a/include/lua_ucl.h b/include/lua_ucl.h index 38e74d3f619d..5b7f88e031e1 100644 --- a/include/lua_ucl.h +++ b/include/lua_ucl.h @@ -55,6 +55,14 @@ UCL_EXTERN int luaopen_ucl (lua_State *L); UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx); /** + * Import UCL object from lua state, escaping JSON strings + * @param L lua state + * @param idx index of object at the lua stack to convert to UCL + * @return new UCL object or NULL, the caller should unref object after using + */ +UCL_EXTERN ucl_object_t* ucl_object_lua_import_escape (lua_State *L, int idx); + +/** * Push an object to lua * @param L lua state * @param obj object to push @@ -62,8 +70,16 @@ UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx); */ UCL_EXTERN int ucl_object_push_lua (lua_State *L, const ucl_object_t *obj, bool allow_array); +/** + * Push an object to lua replacing all ucl.null with `false` + * @param L lua state + * @param obj object to push + * @param allow_array traverse over implicit arrays + */ +UCL_EXTERN int ucl_object_push_lua_filter_nil (lua_State *L, + const ucl_object_t *obj, + bool allow_array); -UCL_EXTERN struct ucl_lua_funcdata* ucl_object_toclosure ( - const ucl_object_t *obj); +UCL_EXTERN struct ucl_lua_funcdata* ucl_object_toclosure (const ucl_object_t *obj); #endif /* LUA_UCL_H_ */ diff --git a/include/ucl++.h b/include/ucl++.h index 2c2bdde51559..fb63430d400d 100644 --- a/include/ucl++.h +++ b/include/ucl++.h @@ -29,6 +29,7 @@ #include <set> #include <memory> #include <iostream> +#include <tuple> #include "ucl.h" @@ -106,7 +107,7 @@ private: static bool ucl_variable_getter(const unsigned char *data, size_t len, unsigned char ** /*replace*/, size_t * /*replace_len*/, bool *need_free, void* ud) { - *need_free = false; + *need_free = false; auto vars = reinterpret_cast<std::set<std::string> *>(ud); if (vars && data && len != 0) { @@ -123,17 +124,17 @@ private: auto replacer = reinterpret_cast<variable_replacer *>(ud); if (!replacer) { return false; - } + } std::string var_name (data, data + len); if (!replacer->is_variable (var_name)) { return false; - } + } std::string var_value = replacer->replace (var_name); if (var_value.empty ()) { return false; - } + } *replace = (unsigned char *)UCL_ALLOC (var_value.size ()); memcpy (*replace, var_value.data (), var_value.size ()); @@ -152,7 +153,8 @@ private: config_func (parser); if (!parse_func (parser)) { - err.assign (ucl_parser_get_error (parser)); + const char *error = ucl_parser_get_error (parser); //Assigning here without checking result first causes a + if( error != NULL ) err.assign(error); // crash if ucl_parser_get_error returns NULL ucl_parser_free (parser); return nullptr; @@ -168,6 +170,16 @@ private: std::unique_ptr<ucl_object_t, ucl_deleter> obj; public: + struct macro_handler_s { + ucl_macro_handler handler; + ucl_context_macro_handler ctx_handler; + }; + + struct macro_userdata_s { + ucl_parser *parser; + void *userdata; + }; + class const_iterator { private: struct ucl_iter_deleter { @@ -184,7 +196,7 @@ public: it = std::shared_ptr<void>(ucl_object_iterate_new (obj.obj.get()), ucl_iter_deleter()); cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true))); - if (cur->type() == UCL_NULL) { + if (!cur->obj) { it.reset (); cur.reset (); } @@ -218,7 +230,7 @@ public: cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true))); } - if (cur && cur->type() == UCL_NULL) { + if (cur && !cur->obj) { it.reset (); cur.reset (); } @@ -330,7 +342,7 @@ public: return UCL_NULL; } - const std::string key () const { + std::string key () const { std::string res; if (obj->key) { @@ -373,7 +385,7 @@ public: return default_val; } - const std::string string_value (const std::string& default_val = "") const + std::string string_value (const std::string& default_val = "") const { const char* res = nullptr; @@ -384,7 +396,16 @@ public: return default_val; } - const Ucl at (size_t i) const + size_t size () const + { + if (type () == UCL_ARRAY) { + return ucl_array_size (obj.get()); + } + + return 0; + } + + Ucl at (size_t i) const { if (type () == UCL_ARRAY) { return Ucl (ucl_array_find_index (obj.get(), i)); @@ -393,7 +414,7 @@ public: return Ucl (nullptr); } - const Ucl lookup (const std::string &key) const + Ucl lookup (const std::string &key) const { if (type () == UCL_OBJECT) { return Ucl (ucl_object_lookup_len (obj.get(), @@ -403,12 +424,12 @@ public: return Ucl (nullptr); } - inline const Ucl operator[] (size_t i) const + inline Ucl operator[] (size_t i) const { return at(i); } - inline const Ucl operator[](const std::string &key) const + inline Ucl operator[](const std::string &key) const { return lookup(key); } @@ -432,43 +453,116 @@ public: return out; } - static Ucl parse (const std::string &in, std::string &err) + static Ucl parse (const std::string &in, std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - return parse (in, std::map<std::string, std::string>(), err); + return parse (in, std::map<std::string, std::string>(), err, duplicate_strategy); } - static Ucl parse (const std::string &in, const std::map<std::string, std::string> &vars, std::string &err) + static Ucl parse (const std::string &in, const std::map<std::string, std::string> &vars, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - auto config_func = [&vars] (ucl_parser *parser) { + std::vector< std::tuple< std::string, macro_handler_s, void * > > emptyVector; + return parse ( in, vars, emptyVector, err, duplicate_strategy ); + } + + //Macro handler will receive a macro_userdata_s as void *ud + static Ucl parse (const std::string &in, + std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + { + return parse (in, std::map<std::string, std::string>(), macros, err, duplicate_strategy); + } + + //Macro handler will receive a macro_userdata_s as void *ud + static Ucl parse (const std::string &in, const std::map<std::string, std::string> &vars, + std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + { + //Preserve macro_userdata_s memory for later use in parse_with_strategy_function() + std::vector<macro_userdata_s> userdata_list; + userdata_list.reserve (macros.size()); + auto config_func = [&userdata_list, &vars, ¯os] (ucl_parser *parser) { for (const auto & item : vars) { ucl_parser_register_variable (parser, item.first.c_str (), item.second.c_str ()); - } + } + for (auto & macro : macros) { + userdata_list.push_back ({parser, std::get<2>(macro)}); + if (std::get<1>(macro).handler != NULL) { + ucl_parser_register_macro (parser, + std::get<0>(macro).c_str(), + std::get<1>(macro).handler, + reinterpret_cast<void*>(&userdata_list.back())); + } + else if (std::get<1>(macro).ctx_handler != NULL) { + ucl_parser_register_context_macro (parser, + std::get<0>(macro).c_str(), + std::get<1>(macro).ctx_handler, + reinterpret_cast<void*>(&userdata_list.back())); + } + } }; - auto parse_func = [&in] (ucl_parser *parser) { - return ucl_parser_add_chunk (parser, (unsigned char *)in.data (), in.size ()); + auto parse_func = [&in, &duplicate_strategy] (struct ucl_parser *parser) -> bool { + return ucl_parser_add_chunk_full (parser, + (unsigned char *) in.data (), + in.size (), + (unsigned int)ucl_parser_get_default_priority (parser), + duplicate_strategy, + UCL_PARSE_UCL); }; return parse_with_strategy_function (config_func, parse_func, err); } - static Ucl parse (const std::string &in, const variable_replacer &replacer, std::string &err) + static Ucl parse (const std::string &in, const variable_replacer &replacer, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - auto config_func = [&replacer] (ucl_parser *parser) { - ucl_parser_set_variables_handler (parser, ucl_variable_replacer, - &const_cast<variable_replacer &>(replacer)); + std::vector< std::tuple< std::string, macro_handler_s, void * > > emptyVector; + return parse ( in, replacer, emptyVector, err, duplicate_strategy ); + } + + //Macro handler will receive a macro_userdata_s as void *ud + static Ucl parse (const std::string &in, const variable_replacer &replacer, + std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + { + //Preserve macro_userdata_s memory for later use in parse_with_strategy_function() + std::vector<macro_userdata_s> userdata_list; + userdata_list.reserve (macros.size()); + auto config_func = [&userdata_list, &replacer, ¯os] (ucl_parser *parser) { + ucl_parser_set_variables_handler (parser, ucl_variable_replacer, &const_cast<variable_replacer &>(replacer)); + for (auto & macro : macros) { + userdata_list.push_back ({parser, std::get<2>(macro)}); + if (std::get<1>(macro).handler != NULL) { + ucl_parser_register_macro (parser, + std::get<0>(macro).c_str(), + std::get<1>(macro).handler, + reinterpret_cast<void*>(&userdata_list.back())); + } + else if (std::get<1>(macro).ctx_handler != NULL) { + ucl_parser_register_context_macro (parser, + std::get<0>(macro).c_str(), + std::get<1>(macro).ctx_handler, + reinterpret_cast<void*>(&userdata_list.back())); + } + } }; - auto parse_func = [&in] (ucl_parser *parser) { - return ucl_parser_add_chunk (parser, (unsigned char *) in.data (), in.size ()); + auto parse_func = [&in, &duplicate_strategy] (struct ucl_parser *parser) -> bool { + return ucl_parser_add_chunk_full (parser, + (unsigned char *) in.data (), + in.size (), + (unsigned int)ucl_parser_get_default_priority (parser), + duplicate_strategy, + UCL_PARSE_UCL); }; return parse_with_strategy_function (config_func, parse_func, err); } - static Ucl parse (const char *in, std::string &err) + static Ucl parse (const char *in, std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - return parse (in, std::map<std::string, std::string>(), err); + return parse (in, std::map<std::string, std::string>(), err, duplicate_strategy); } static Ucl parse (const char *in, const std::map<std::string, std::string> &vars, std::string &err) @@ -480,13 +574,46 @@ public: return parse (std::string (in), vars, err); } - static Ucl parse (const char *in, const variable_replacer &replacer, std::string &err) + //Macro handler will receive a macro_userdata_s as void *ud + static Ucl parse (const char *in, + std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + { + return parse (in, std::map<std::string, std::string>(), macros, err, duplicate_strategy); + } + + //Macro handler will receive a macro_userdata_s as void *ud + static Ucl parse (const char *in, const std::map<std::string, std::string> &vars, + std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + { + if (!in) { + err = "null input"; + return nullptr; + } + return parse (std::string (in), vars, macros, err, duplicate_strategy); + } + + static Ucl parse (const char *in, const variable_replacer &replacer, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + { + if (!in) { + err = "null input"; + return nullptr; + } + return parse (std::string(in), replacer, err, duplicate_strategy); + } + + //Macro handler will receive a macro_userdata_s as void *ud + static Ucl parse (const char *in, const variable_replacer &replacer, + std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { if (!in) { err = "null input"; return nullptr; } - return parse (std::string(in), replacer, err); + return parse (std::string (in), replacer, macros, err, duplicate_strategy); } static Ucl parse_from_file (const std::string &filename, std::string &err) @@ -556,7 +683,7 @@ public: std::vector<std::string> result; std::move (vars.begin (), vars.end (), std::back_inserter (result)); - return std::move (result); + return result; } Ucl& operator= (Ucl rhs) diff --git a/include/ucl.h b/include/ucl.h index fccf6fcb2237..39da2593648d 100644 --- a/include/ucl.h +++ b/include/ucl.h @@ -105,10 +105,11 @@ typedef enum ucl_error { UCL_EIO, /**< IO error occurred during parsing */ UCL_ESTATE, /**< Invalid state machine state */ UCL_ENESTED, /**< Input has too many recursion levels */ + UCL_EUNPAIRED, /**< Input has too many recursion levels */ UCL_EMACRO, /**< Error processing a macro */ UCL_EINTERNAL, /**< Internal unclassified error */ UCL_ESSL, /**< SSL error */ - UCL_EMERGE /**< A merge error occured */ + UCL_EMERGE /**< A merge error occurred */ } ucl_error_t; /** @@ -177,7 +178,8 @@ typedef enum ucl_string_flags { } ucl_string_flags_t; /** - * Basic flags for an object + * Basic flags for an object (can use up to 12 bits as higher 4 bits are used + * for priorities) */ typedef enum ucl_object_flags { UCL_OBJECT_ALLOCATED_KEY = (1 << 0), /**< An object has key allocated internally */ @@ -187,7 +189,8 @@ typedef enum ucl_object_flags { UCL_OBJECT_MULTILINE = (1 << 4), /**< String should be displayed as multiline string */ UCL_OBJECT_MULTIVALUE = (1 << 5), /**< Object is a key with multiple values */ UCL_OBJECT_INHERITED = (1 << 6), /**< Object has been inherited from another */ - UCL_OBJECT_BINARY = (1 << 7) /**< Object contains raw binary data */ + UCL_OBJECT_BINARY = (1 << 7), /**< Object contains raw binary data */ + UCL_OBJECT_SQUOTED = (1 << 8) /**< Object has been enclosed in single quotes */ } ucl_object_flags_t; /** @@ -463,6 +466,14 @@ UCL_EXTERN bool ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *e const char *key, size_t keylen, bool copy_key); /** + * Reserve space in ucl array or object for `elt` elements + * @param obj object to reserve + * @param reserved size to reserve in an object + * @return 0 on success, -1 on failure (i.e. ENOMEM) + */ +UCL_EXTERN bool ucl_object_reserve (ucl_object_t *obj, size_t reserved); + +/** * Append an element to the end of array object * @param top destination object (must NOT be NULL) * @param elt element to append (must NOT be NULL) @@ -534,6 +545,13 @@ UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top); UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top); /** + * Return size of the array `top` + * @param top object to get size from (must be of type UCL_ARRAY) + * @return size of the array + */ +UCL_EXTERN unsigned int ucl_array_size (const ucl_object_t *top); + +/** * Return object identified by index of the array `top` * @param top object to get a key from (must be of type UCL_ARRAY) * @param index array index to return @@ -782,6 +800,19 @@ UCL_EXTERN int ucl_object_compare_qsort (const ucl_object_t **o1, UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar, int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2)); +enum ucl_object_keys_sort_flags { + UCL_SORT_KEYS_DEFAULT = 0, + UCL_SORT_KEYS_ICASE = (1u << 0u), + UCL_SORT_KEYS_RECURSIVE = (1u << 1u), +}; +/*** + * Sorts keys in object in place + * @param obj + * @param how + */ +UCL_EXTERN void ucl_object_sort_keys (ucl_object_t *obj, + enum ucl_object_keys_sort_flags how); + /** * Get the priority for specific UCL object * @param obj any ucl object @@ -808,11 +839,14 @@ typedef void* ucl_object_iter_t; * @param iter opaque iterator, must be set to NULL on the first call: * ucl_object_iter_t it = NULL; * while ((cur = ucl_iterate_object (obj, &it)) != NULL) ... + * @param ep pointer record exception (such as ENOMEM), could be NULL * @return the next object or NULL */ -UCL_EXTERN const ucl_object_t* ucl_object_iterate (const ucl_object_t *obj, - ucl_object_iter_t *iter, bool expand_values); +UCL_EXTERN const ucl_object_t* ucl_object_iterate_with_error (const ucl_object_t *obj, + ucl_object_iter_t *iter, bool expand_values, int *ep); + #define ucl_iterate_object ucl_object_iterate +#define ucl_object_iterate(ob, it, ev) ucl_object_iterate_with_error((ob), (it), (ev), NULL) /** * Create new safe iterator for the specified object @@ -822,6 +856,15 @@ UCL_EXTERN const ucl_object_t* ucl_object_iterate (const ucl_object_t *obj, UCL_EXTERN ucl_object_iter_t ucl_object_iterate_new (const ucl_object_t *obj) UCL_WARN_UNUSED_RESULT; /** + * Check safe iterator object after performing some operations on it + * (such as ucl_object_iterate_safe()) to see if operation has encountered + * fatal exception while performing that operation (e.g. ENOMEM). + * @param iter opaque iterator + * @return true if exception has occured, false otherwise + */ +UCL_EXTERN bool ucl_object_iter_chk_excpn(ucl_object_iter_t *it); + +/** * Reset initialized iterator to a new object * @param obj new object to iterate * @return modified iterator object @@ -830,7 +873,7 @@ UCL_EXTERN ucl_object_iter_t ucl_object_iterate_reset (ucl_object_iter_t it, const ucl_object_t *obj); /** - * Get the next object from the `obj`. This fucntion iterates over arrays, objects + * Get the next object from the `obj`. This function iterates over arrays, objects * and implicit arrays * @param iter safe iterator * @param expand_values expand explicit arrays and objects @@ -848,7 +891,7 @@ enum ucl_iterate_type { }; /** - * Get the next object from the `obj`. This fucntion iterates over arrays, objects + * Get the next object from the `obj`. This function iterates over arrays, objects * and implicit arrays if needed * @param iter safe iterator * @param @@ -912,7 +955,7 @@ struct ucl_parser; UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags); /** - * Sets the default priority for the parser applied to chunks that does not + * Sets the default priority for the parser applied to chunks that do not * specify priority explicitly * @param parser parser object * @param prio default priority (0 .. 16) @@ -921,13 +964,22 @@ UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags); UCL_EXTERN bool ucl_parser_set_default_priority (struct ucl_parser *parser, unsigned prio); /** + * Gets the default priority for the parser applied to chunks that do not + * specify priority explicitly + * @param parser parser object + * @return true default priority (0 .. 16), -1 for failure + */ +UCL_EXTERN int ucl_parser_get_default_priority (struct ucl_parser *parser); + +/** * Register new handler for a macro * @param parser parser object * @param macro macro name (without leading dot) * @param handler handler (it is called immediately after macro is parsed) * @param ud opaque user data for a handler + * @return true on success, false on failure (i.e. ENOMEM) */ -UCL_EXTERN void ucl_parser_register_macro (struct ucl_parser *parser, +UCL_EXTERN bool ucl_parser_register_macro (struct ucl_parser *parser, const char *macro, ucl_macro_handler handler, void* ud); @@ -937,8 +989,9 @@ UCL_EXTERN void ucl_parser_register_macro (struct ucl_parser *parser, * @param macro macro name (without leading dot) * @param handler handler (it is called immediately after macro is parsed) * @param ud opaque user data for a handler + * @return true on success, false on failure (i.e. ENOMEM) */ -UCL_EXTERN void ucl_parser_register_context_macro (struct ucl_parser *parser, +UCL_EXTERN bool ucl_parser_register_context_macro (struct ucl_parser *parser, const char *macro, ucl_context_macro_handler handler, void* ud); @@ -997,6 +1050,16 @@ UCL_EXTERN bool ucl_parser_add_chunk_priority (struct ucl_parser *parser, const unsigned char *data, size_t len, unsigned priority); /** + * Insert new chunk to a parser (must have previously processed data with an existing top object) + * @param parser parser structure + * @param data the pointer to the beginning of a chunk + * @param len the length of a chunk + * @return true if chunk has been added and false in case of error + */ +UCL_EXTERN bool ucl_parser_insert_chunk (struct ucl_parser *parser, + const unsigned char *data, size_t len); + +/** * Full version of ucl_add_chunk with priority and duplicate strategy * @param parser parser structure * @param data the pointer to the beginning of a chunk @@ -1019,7 +1082,7 @@ UCL_EXTERN bool ucl_parser_add_chunk_full (struct ucl_parser *parser, * @return true if string has been added and false in case of error */ UCL_EXTERN bool ucl_parser_add_string (struct ucl_parser *parser, - const char *data,size_t len); + const char *data, size_t len); /** * Load ucl object from a string @@ -1125,6 +1188,29 @@ UCL_EXTERN bool ucl_set_include_path (struct ucl_parser *parser, UCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser); /** + * Get the current stack object as stack accessor function for use in macro + * functions (refcount is increased) + * @param parser parser object + * @param depth depth of stack to retrieve (top is 0) + * @return current stack object or NULL + */ +UCL_EXTERN ucl_object_t* ucl_parser_get_current_stack_object (struct ucl_parser *parser, unsigned int depth); + +/** + * Peek at the character at the current chunk position + * @param parser parser structure + * @return current chunk position character + */ +UCL_EXTERN unsigned char ucl_parser_chunk_peek (struct ucl_parser *parser); + +/** + * Skip the character at the current chunk position + * @param parser parser structure + * @return success boolean + */ +UCL_EXTERN bool ucl_parser_chunk_skip (struct ucl_parser *parser); + +/** * Get the error string if parsing has been failed * @param parser parser object * @return error description @@ -1185,7 +1271,7 @@ UCL_EXTERN const ucl_object_t * ucl_comments_find (const ucl_object_t *comments, * Move comment from `from` object to `to` object * @param comments comments object * @param what source object - * @param whith destination object + * @param with destination object * @return `true` if `from` has comment and it has been moved to `to` */ UCL_EXTERN bool ucl_comments_move (ucl_object_t *comments, @@ -1221,6 +1307,76 @@ UCL_EXTERN bool ucl_parser_pubkey_add (struct ucl_parser *parser, UCL_EXTERN bool ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, bool need_expand); +/** + * Returns current file for the parser + * @param parser parser object + * @return current file or NULL if parsing memory + */ +UCL_EXTERN const char *ucl_parser_get_cur_file (struct ucl_parser *parser); + +/** + * Defines special handler for certain types of data (identified by magic) + */ +typedef bool (*ucl_parser_special_handler_t) (struct ucl_parser *parser, + const unsigned char *source, size_t source_len, + unsigned char **destination, size_t *dest_len, + void *user_data); + +/** + * Special handler flags + */ +enum ucl_special_handler_flags { + UCL_SPECIAL_HANDLER_DEFAULT = 0, + UCL_SPECIAL_HANDLER_PREPROCESS_ALL = (1u << 0), +}; + +/** + * Special handler structure + */ +struct ucl_parser_special_handler { + const unsigned char *magic; + size_t magic_len; + enum ucl_special_handler_flags flags; + ucl_parser_special_handler_t handler; + void (*free_function) (unsigned char *data, size_t len, void *user_data); + void *user_data; + struct ucl_parser_special_handler *next; /* Used internally */ +}; + +/** + * Add special handler for a parser, handles special sequences identified by magic + * @param parser parser structure + * @param handler handler structure + */ +UCL_EXTERN void ucl_parser_add_special_handler (struct ucl_parser *parser, + struct ucl_parser_special_handler *handler); + +/** + * Handler for include traces: + * @param parser parser object + * @param parent where include is done from + * @param args arguments to an include + * @param path path of the include + * @param pathlen length of the path + * @param user_data opaque userdata + */ +typedef void (ucl_include_trace_func_t) (struct ucl_parser *parser, + const ucl_object_t *parent, + const ucl_object_t *args, + const char *path, + size_t pathlen, + void *user_data); + +/** + * Register trace function for an include handler + * @param parser parser object + * @param func function to trace includes + * @param user_data opaque data + */ +UCL_EXTERN void ucl_parser_set_include_tracer (struct ucl_parser *parser, + ucl_include_trace_func_t func, + void *user_data); + /** @} */ /** @@ -1420,7 +1576,7 @@ enum ucl_schema_error_code { struct ucl_schema_error { enum ucl_schema_error_code code; /**< error code */ char msg[128]; /**< error message */ - const ucl_object_t *obj; /**< object where error occured */ + const ucl_object_t *obj; /**< object where error occurred */ }; /** @@ -1428,7 +1584,7 @@ struct ucl_schema_error { * @param schema schema object * @param obj object to validate * @param err error pointer, if this parameter is not NULL and error has been - * occured, then `err` is filled with the exact error definition. + * occurred, then `err` is filled with the exact error definition. * @return true if `obj` is valid using `schema` */ UCL_EXTERN bool ucl_object_validate (const ucl_object_t *schema, @@ -1440,7 +1596,7 @@ UCL_EXTERN bool ucl_object_validate (const ucl_object_t *schema, * @param obj object to validate * @param root root schema object * @param err error pointer, if this parameter is not NULL and error has been - * occured, then `err` is filled with the exact error definition. + * occurred, then `err` is filled with the exact error definition. * @return true if `obj` is valid using `schema` */ UCL_EXTERN bool ucl_object_validate_root (const ucl_object_t *schema, @@ -1456,7 +1612,7 @@ UCL_EXTERN bool ucl_object_validate_root (const ucl_object_t *schema, * @param root root schema object * @param ext_refs external references (might be modified during validation) * @param err error pointer, if this parameter is not NULL and error has been - * occured, then `err` is filled with the exact error definition. + * occurred, then `err` is filled with the exact error definition. * @return true if `obj` is valid using `schema` */ UCL_EXTERN bool ucl_object_validate_root_ext (const ucl_object_t *schema, @@ -1491,4 +1647,7 @@ UCL_EXTERN bool ucl_object_validate_root_ext (const ucl_object_t *schema, #define ucl_obj_ref ucl_object_ref #define ucl_obj_free ucl_object_free +#define UCL_PRIORITY_MIN 0 +#define UCL_PRIORITY_MAX 15 + #endif /* UCL_H_ */ |
