summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2021-03-22 14:07:18 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2021-03-22 14:07:18 +0000
commit3c319408d0de2d2de0c19b24e1a41c0a0e4a823b (patch)
treede0b27939e96ed7a8b3554a149b321ef719cc875 /include
parent8392e70f8a07e517fab31f8300cfaf5f02bea0f5 (diff)
libucl: import latest snapshot from 2021-03-14vendor/libucl/20210314
Diffstat (limited to 'include')
-rw-r--r--include/lua_ucl.h20
-rw-r--r--include/ucl++.h189
-rw-r--r--include/ucl.h191
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*/ > > &macros,
+ 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*/ > > &macros,
+ 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, &macros] (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*/ > > &macros,
+ 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, &macros] (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*/ > > &macros,
+ 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*/ > > &macros,
+ 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*/ > > &macros,
+ 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_ */