diff --git a/contrib/libucl/.clang-format b/contrib/libucl/.clang-format new file mode 100644 index 000000000000..89beadc23900 --- /dev/null +++ b/contrib/libucl/.clang-format @@ -0,0 +1,67 @@ +# Generated from CLion C/C++ Code Style settings +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: None +AlignOperands: Align +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Always +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Always +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterUnion: false + BeforeCatch: false + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +ColumnLimit: 0 +CompactNamespaces: false +ContinuationIndentWidth: 4 +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: true +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: None +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PointerAlignment: Right +ReflowComments: false +SortIncludes: Never +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 0 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: ForContinuationAndIndentation diff --git a/contrib/libucl/include/lua_ucl.h b/contrib/libucl/include/lua_ucl.h index 5b7f88e031e1..30dd87f7520d 100644 --- a/contrib/libucl/include/lua_ucl.h +++ b/contrib/libucl/include/lua_ucl.h @@ -1,85 +1,85 @@ /* Copyright (c) 2014, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LUA_UCL_H_ #define LUA_UCL_H_ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "ucl.h" /** * Closure structure for lua function storing inside UCL */ struct ucl_lua_funcdata { lua_State *L; int idx; char *ret; }; /** * Initialize lua UCL API */ -UCL_EXTERN int luaopen_ucl (lua_State *L); +UCL_EXTERN int luaopen_ucl(lua_State *L); /** * Import UCL object from lua state * @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 (lua_State *L, int idx); +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); +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 * @param allow_array traverse over implicit arrays */ -UCL_EXTERN int ucl_object_push_lua (lua_State *L, - const ucl_object_t *obj, bool allow_array); +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 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/contrib/libucl/include/ucl++.h b/contrib/libucl/include/ucl++.h index 1cd17eac0c75..9591085f6676 100644 --- a/contrib/libucl/include/ucl++.h +++ b/contrib/libucl/include/ucl++.h @@ -1,744 +1,781 @@ /* * Copyright (c) 2015, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include #include #include #include #include #include #include #include "ucl.h" // C++11 API inspired by json11: https://github.com/dropbox/json11/ namespace ucl { -struct ucl_map_construct_t { }; +struct ucl_map_construct_t {}; constexpr ucl_map_construct_t ucl_map_construct = ucl_map_construct_t(); -struct ucl_array_construct_t { }; +struct ucl_array_construct_t {}; constexpr ucl_array_construct_t ucl_array_construct = ucl_array_construct_t(); class Ucl final { private: - struct ucl_deleter { - void operator() (ucl_object_t *obj) { - ucl_object_unref (obj); + void operator()(ucl_object_t *obj) + { + ucl_object_unref(obj); } }; static int - append_char (unsigned char c, size_t nchars, void *ud) + append_char(unsigned char c, size_t nchars, void *ud) { std::string *out = reinterpret_cast(ud); - out->append (nchars, (char)c); + out->append(nchars, (char) c); return nchars; } static int - append_len (unsigned const char *str, size_t len, void *ud) + append_len(unsigned const char *str, size_t len, void *ud) { std::string *out = reinterpret_cast(ud); - out->append ((const char *)str, len); + out->append((const char *) str, len); return len; } static int - append_int (int64_t elt, void *ud) + append_int(int64_t elt, void *ud) { std::string *out = reinterpret_cast(ud); - auto nstr = std::to_string (elt); + auto nstr = std::to_string(elt); - out->append (nstr); + out->append(nstr); - return nstr.size (); + return nstr.size(); } static int - append_double (double elt, void *ud) + append_double(double elt, void *ud) { std::string *out = reinterpret_cast(ud); - auto nstr = std::to_string (elt); + auto nstr = std::to_string(elt); - out->append (nstr); + out->append(nstr); - return nstr.size (); + return nstr.size(); } static struct ucl_emitter_functions default_emit_funcs() { struct ucl_emitter_functions func = { Ucl::append_char, Ucl::append_len, Ucl::append_int, Ucl::append_double, nullptr, - nullptr - }; + nullptr}; return func; }; static bool ucl_variable_getter(const unsigned char *data, size_t len, - unsigned char ** /*replace*/, size_t * /*replace_len*/, bool *need_free, void* ud) + unsigned char ** /*replace*/, size_t * /*replace_len*/, bool *need_free, void *ud) { *need_free = false; auto vars = reinterpret_cast *>(ud); if (vars && data && len != 0) { - vars->emplace (data, data + len); + vars->emplace(data, data + len); } return false; } - static bool ucl_variable_replacer (const unsigned char *data, size_t len, - unsigned char **replace, size_t *replace_len, bool *need_free, void* ud) + static bool ucl_variable_replacer(const unsigned char *data, size_t len, + unsigned char **replace, size_t *replace_len, bool *need_free, void *ud) { *need_free = false; auto replacer = reinterpret_cast(ud); if (!replacer) { return false; } - std::string var_name (data, data + len); - if (!replacer->is_variable (var_name)) { + 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 ()) { + 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 ()); + *replace = (unsigned char *) UCL_ALLOC(var_value.size()); + memcpy(*replace, var_value.data(), var_value.size()); - *replace_len = var_value.size (); + *replace_len = var_value.size(); *need_free = true; return true; } - template - static Ucl parse_with_strategy_function (C config_func, P parse_func, std::string &err) + template + static Ucl parse_with_strategy_function(C config_func, P parse_func, std::string &err) { - auto parser = ucl_parser_new (UCL_PARSER_DEFAULT); + auto parser = ucl_parser_new(UCL_PARSER_DEFAULT); - config_func (parser); + config_func(parser); - if (!parse_func (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); + if (!parse_func(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; } - auto obj = ucl_parser_get_object (parser); - ucl_parser_free (parser); + auto obj = ucl_parser_get_object(parser); + ucl_parser_free(parser); // Obj will handle ownership - return Ucl (obj); + return Ucl(obj); } std::unique_ptr obj; public: struct macro_handler_s { - ucl_macro_handler handler; + ucl_macro_handler handler; ucl_context_macro_handler ctx_handler; }; struct macro_userdata_s { - ucl_parser *parser; - void *userdata; + ucl_parser *parser; + void *userdata; }; class const_iterator { private: struct ucl_iter_deleter { - void operator() (ucl_object_iter_t it) { - ucl_object_iterate_free (it); + void operator()(ucl_object_iter_t it) + { + ucl_object_iterate_free(it); } }; std::shared_ptr it; std::unique_ptr cur; + public: typedef std::forward_iterator_tag iterator_category; - const_iterator(const Ucl &obj) { - it = std::shared_ptr(ucl_object_iterate_new (obj.obj.get()), - ucl_iter_deleter()); - cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true))); + const_iterator(const Ucl &obj) + { + it = std::shared_ptr(ucl_object_iterate_new(obj.obj.get()), + ucl_iter_deleter()); + cur.reset(new Ucl(ucl_object_iterate_safe(it.get(), true))); if (!cur->obj) { - it.reset (); - cur.reset (); + it.reset(); + cur.reset(); } } - const_iterator() {} + const_iterator() + { + } const_iterator(const const_iterator &other) = delete; const_iterator(const_iterator &&other) = default; - ~const_iterator() {} + ~const_iterator() + { + } - const_iterator& operator=(const const_iterator &other) = delete; - const_iterator& operator=(const_iterator &&other) = default; + const_iterator &operator=(const const_iterator &other) = delete; + const_iterator &operator=(const_iterator &&other) = default; bool operator==(const const_iterator &other) const { if (cur && other.cur) { return cur->obj.get() == other.cur->obj.get(); } return !cur && !other.cur; } bool operator!=(const const_iterator &other) const { return !(*this == other); } - const_iterator& operator++() + const_iterator &operator++() { if (it) { - cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true))); + cur.reset(new Ucl(ucl_object_iterate_safe(it.get(), true))); } if (cur && !cur->obj) { - it.reset (); - cur.reset (); + it.reset(); + cur.reset(); } return *this; } - const Ucl& operator*() const + const Ucl &operator*() const { return *cur; } - const Ucl* operator->() const + const Ucl *operator->() const { return cur.get(); } }; struct variable_replacer { - virtual ~variable_replacer() {} + virtual ~variable_replacer() + { + } - virtual bool is_variable (const std::string &str) const + virtual bool is_variable(const std::string &str) const { - return !str.empty (); + return !str.empty(); } - virtual std::string replace (const std::string &var) const = 0; + virtual std::string replace(const std::string &var) const = 0; }; // We grab ownership if get non-const ucl_object_t - Ucl(ucl_object_t *other) { - obj.reset (other); + Ucl(ucl_object_t *other) + { + obj.reset(other); } // Shared ownership - Ucl(const ucl_object_t *other) { - obj.reset (ucl_object_ref (other)); + Ucl(const ucl_object_t *other) + { + obj.reset(ucl_object_ref(other)); } - Ucl(const Ucl &other) { - obj.reset (ucl_object_ref (other.obj.get())); + Ucl(const Ucl &other) + { + obj.reset(ucl_object_ref(other.obj.get())); } - Ucl(Ucl &&other) { - obj.swap (other.obj); + Ucl(Ucl &&other) + { + obj.swap(other.obj); } - Ucl() noexcept { - obj.reset (ucl_object_typed_new (UCL_NULL)); + Ucl() noexcept + { + obj.reset(ucl_object_typed_new(UCL_NULL)); } - Ucl(std::nullptr_t) noexcept { - obj.reset (ucl_object_typed_new (UCL_NULL)); + Ucl(std::nullptr_t) noexcept + { + obj.reset(ucl_object_typed_new(UCL_NULL)); } - Ucl(double value) { - obj.reset (ucl_object_typed_new (UCL_FLOAT)); + Ucl(double value) + { + obj.reset(ucl_object_typed_new(UCL_FLOAT)); obj->value.dv = value; } - Ucl(int64_t value) { - obj.reset (ucl_object_typed_new (UCL_INT)); + Ucl(int64_t value) + { + obj.reset(ucl_object_typed_new(UCL_INT)); obj->value.iv = value; } - Ucl(bool value) { - obj.reset (ucl_object_typed_new (UCL_BOOLEAN)); + Ucl(bool value) + { + obj.reset(ucl_object_typed_new(UCL_BOOLEAN)); obj->value.iv = static_cast(value); } - Ucl(const std::string &value) { - obj.reset (ucl_object_fromstring_common (value.data (), value.size (), - UCL_STRING_RAW)); + Ucl(const std::string &value) + { + obj.reset(ucl_object_fromstring_common(value.data(), value.size(), + UCL_STRING_RAW)); } - Ucl(const char *value) { - obj.reset (ucl_object_fromstring_common (value, 0, UCL_STRING_RAW)); + Ucl(const char *value) + { + obj.reset(ucl_object_fromstring_common(value, 0, UCL_STRING_RAW)); } // Implicit constructor: anything with a to_json() function. - template - Ucl(const T &t) : Ucl(t.to_ucl()) {} + template + Ucl(const T &t) + : Ucl(t.to_ucl()) + { + } // Implicit constructor: map-like objects (std::map, std::unordered_map, etc) - template ::value - && std::is_constructible::value, - int>::type = 0> - Ucl(const M &m) { - obj.reset (ucl_object_typed_new (UCL_OBJECT)); - auto cobj = obj.get (); + template::value && std::is_constructible::value, + int>::type = 0> + Ucl(const M &m) + { + obj.reset(ucl_object_typed_new(UCL_OBJECT)); + auto cobj = obj.get(); - for (const auto &e : m) { - ucl_object_insert_key (cobj, ucl_object_ref (e.second.obj.get()), - e.first.data (), e.first.size (), true); + for (const auto &e: m) { + ucl_object_insert_key(cobj, ucl_object_ref(e.second.obj.get()), + e.first.data(), e.first.size(), true); } } // Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc) - template ::value, - int>::type = 0> - Ucl(const V &v) { - obj.reset (ucl_object_typed_new (UCL_ARRAY)); - auto cobj = obj.get (); + template::value, + int>::type = 0> + Ucl(const V &v) + { + obj.reset(ucl_object_typed_new(UCL_ARRAY)); + auto cobj = obj.get(); - for (const auto &e : v) { - ucl_array_append (cobj, ucl_object_ref (e.obj.get())); + for (const auto &e: v) { + ucl_array_append(cobj, ucl_object_ref(e.obj.get())); } } - ucl_type_t type () const { + ucl_type_t type() const + { if (obj) { - return ucl_object_type (obj.get ()); + return ucl_object_type(obj.get()); } return UCL_NULL; } - std::string key () const { + std::string key() const + { std::string res; if (obj->key) { - res.assign (obj->key, obj->keylen); + res.assign(obj->key, obj->keylen); } return res; } - double number_value (const double default_val = 0.0) const + double number_value(const double default_val = 0.0) const { double res; if (ucl_object_todouble_safe(obj.get(), &res)) { return res; } return default_val; } - int64_t int_value (const int64_t default_val = 0) const + int64_t int_value(const int64_t default_val = 0) const { int64_t res; if (ucl_object_toint_safe(obj.get(), &res)) { return res; } return default_val; } - bool bool_value (const bool default_val = false) const + bool bool_value(const bool default_val = false) const { bool res; if (ucl_object_toboolean_safe(obj.get(), &res)) { return res; } return default_val; } - std::string string_value (const std::string& default_val = "") const + std::string string_value(const std::string &default_val = "") const { - const char* res = nullptr; + const char *res = nullptr; if (ucl_object_tostring_safe(obj.get(), &res)) { return res; } return default_val; } std::string forced_string_value () const { return ucl_object_tostring_forced(obj.get()); } - size_t size () const + size_t size() const { - if (type () == UCL_ARRAY) { - return ucl_array_size (obj.get()); + if (type() == UCL_ARRAY) { + return ucl_array_size(obj.get()); } return 0; } - Ucl at (size_t i) const + Ucl at(size_t i) const { - if (type () == UCL_ARRAY) { - return Ucl (ucl_array_find_index (obj.get(), i)); + if (type() == UCL_ARRAY) { + return Ucl(ucl_array_find_index(obj.get(), i)); } - return Ucl (nullptr); + return Ucl(nullptr); } - 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(), - key.data (), key.size ())); + if (type() == UCL_OBJECT) { + return Ucl(ucl_object_lookup_len(obj.get(), + key.data(), key.size())); } - return Ucl (nullptr); + return Ucl(nullptr); } - inline Ucl operator[] (size_t i) const + inline Ucl operator[](size_t i) const { return at(i); } inline Ucl operator[](const std::string &key) const { return lookup(key); } // Serialize. - void dump (std::string &out, ucl_emitter_t type = UCL_EMIT_JSON) const + void dump(std::string &out, ucl_emitter_t type = UCL_EMIT_JSON) const { struct ucl_emitter_functions cbdata; cbdata = Ucl::default_emit_funcs(); cbdata.ud = reinterpret_cast(&out); - ucl_object_emit_full (obj.get(), type, &cbdata, nullptr); + ucl_object_emit_full(obj.get(), type, &cbdata, nullptr); } - std::string dump (ucl_emitter_t type = UCL_EMIT_JSON) const + std::string dump(ucl_emitter_t type = UCL_EMIT_JSON) const { std::string out; - dump (out, type); + dump(out, type); return out; } - static Ucl parse (const std::string &in, std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + static Ucl parse(const std::string &in, std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - return parse (in, std::map(), err, duplicate_strategy); + return parse(in, std::map(), err, duplicate_strategy); } - static Ucl parse (const std::string &in, const std::map &vars, - std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + static Ucl parse(const std::string &in, const std::map &vars, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - std::vector< std::tuple< std::string, macro_handler_s, void * > > emptyVector; - return parse ( in, vars, emptyVector, err, duplicate_strategy ); + std::vector> 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) + static Ucl parse(const std::string &in, + std::vector> ¯os, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - return parse (in, std::map(), macros, err, duplicate_strategy); + return parse(in, std::map(), 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 &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) + static Ucl parse(const std::string &in, const std::map &vars, + std::vector> ¯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 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 ()); + 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)}); + for (auto ¯o: 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(&userdata_list.back())); + ucl_parser_register_macro(parser, + std::get<0>(macro).c_str(), + std::get<1>(macro).handler, + reinterpret_cast(&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(&userdata_list.back())); + ucl_parser_register_context_macro(parser, + std::get<0>(macro).c_str(), + std::get<1>(macro).ctx_handler, + reinterpret_cast(&userdata_list.back())); } } }; - 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); + 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); + return parse_with_strategy_function(config_func, parse_func, err); } - static Ucl parse (const std::string &in, const variable_replacer &replacer, - std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + static Ucl parse(const std::string &in, const variable_replacer &replacer, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - std::vector< std::tuple< std::string, macro_handler_s, void * > > emptyVector; - return parse ( in, replacer, emptyVector, err, duplicate_strategy ); + std::vector> 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) + static Ucl parse(const std::string &in, const variable_replacer &replacer, + std::vector> ¯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 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(replacer)); - for (auto & macro : macros) { - userdata_list.push_back ({parser, std::get<2>(macro)}); + 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(replacer)); + for (auto ¯o: 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(&userdata_list.back())); + ucl_parser_register_macro(parser, + std::get<0>(macro).c_str(), + std::get<1>(macro).handler, + reinterpret_cast(&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(&userdata_list.back())); + ucl_parser_register_context_macro(parser, + std::get<0>(macro).c_str(), + std::get<1>(macro).ctx_handler, + reinterpret_cast(&userdata_list.back())); } } }; - 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); + 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); + return parse_with_strategy_function(config_func, parse_func, err); } - static Ucl parse (const char *in, std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) + static Ucl parse(const char *in, std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - return parse (in, std::map(), err, duplicate_strategy); + return parse(in, std::map(), err, duplicate_strategy); } - static Ucl parse (const char *in, const std::map &vars, std::string &err) + static Ucl parse(const char *in, const std::map &vars, std::string &err) { if (!in) { err = "null input"; return nullptr; } - return parse (std::string (in), vars, err); + return parse(std::string(in), vars, 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) + static Ucl parse(const char *in, + std::vector> ¯os, + std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) { - return parse (in, std::map(), macros, err, duplicate_strategy); + return parse(in, std::map(), macros, err, duplicate_strategy); } //Macro handler will receive a macro_userdata_s as void *ud - static Ucl parse (const char *in, const std::map &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) + static Ucl parse(const char *in, const std::map &vars, + std::vector> ¯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); + 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) + 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); + 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) + static Ucl parse(const char *in, const variable_replacer &replacer, + std::vector> ¯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, macros, err, duplicate_strategy); + return parse(std::string(in), replacer, macros, err, duplicate_strategy); } - static Ucl parse_from_file (const std::string &filename, std::string &err) + static Ucl parse_from_file(const std::string &filename, std::string &err) { - return parse_from_file (filename, std::map(), err); + return parse_from_file(filename, std::map(), err); } - static Ucl parse_from_file (const std::string &filename, const std::map &vars, std::string &err) + static Ucl parse_from_file(const std::string &filename, const std::map &vars, std::string &err) { - auto config_func = [&vars] (ucl_parser *parser) { - for (const auto & item : vars) { - ucl_parser_register_variable (parser, item.first.c_str (), item.second.c_str ()); - } + auto config_func = [&vars](ucl_parser *parser) { + for (const auto &item: vars) { + ucl_parser_register_variable(parser, item.first.c_str(), item.second.c_str()); + } }; - auto parse_func = [&filename] (ucl_parser *parser) { - return ucl_parser_add_file (parser, filename.c_str ()); + auto parse_func = [&filename](ucl_parser *parser) { + return ucl_parser_add_file(parser, filename.c_str()); }; - return parse_with_strategy_function (config_func, parse_func, err); + return parse_with_strategy_function(config_func, parse_func, err); } - static Ucl parse_from_file (const std::string &filename, const variable_replacer &replacer, std::string &err) + static Ucl parse_from_file(const std::string &filename, const variable_replacer &replacer, std::string &err) { - auto config_func = [&replacer] (ucl_parser *parser) { - ucl_parser_set_variables_handler (parser, ucl_variable_replacer, - &const_cast(replacer)); + auto config_func = [&replacer](ucl_parser *parser) { + ucl_parser_set_variables_handler(parser, ucl_variable_replacer, + &const_cast(replacer)); }; - auto parse_func = [&filename] (ucl_parser *parser) { - return ucl_parser_add_file (parser, filename.c_str ()); + auto parse_func = [&filename](ucl_parser *parser) { + return ucl_parser_add_file(parser, filename.c_str()); }; - return parse_with_strategy_function (config_func, parse_func, err); + return parse_with_strategy_function(config_func, parse_func, err); } - static std::vector find_variable (const std::string &in) + static std::vector find_variable(const std::string &in) { - auto parser = ucl_parser_new (UCL_PARSER_DEFAULT); + auto parser = ucl_parser_new(UCL_PARSER_DEFAULT); std::set vars; - ucl_parser_set_variables_handler (parser, ucl_variable_getter, &vars); - ucl_parser_add_chunk (parser, (const unsigned char *)in.data (), in.size ()); - ucl_parser_free (parser); + ucl_parser_set_variables_handler(parser, ucl_variable_getter, &vars); + ucl_parser_add_chunk(parser, (const unsigned char *) in.data(), in.size()); + ucl_parser_free(parser); std::vector result; - std::move (vars.begin (), vars.end (), std::back_inserter (result)); + std::move(vars.begin(), vars.end(), std::back_inserter(result)); return result; } - static std::vector find_variable (const char *in) + static std::vector find_variable(const char *in) { if (!in) { return std::vector(); } - return find_variable (std::string (in)); + return find_variable(std::string(in)); } - static std::vector find_variable_from_file (const std::string &filename) + static std::vector find_variable_from_file(const std::string &filename) { - auto parser = ucl_parser_new (UCL_PARSER_DEFAULT); + auto parser = ucl_parser_new(UCL_PARSER_DEFAULT); std::set vars; - ucl_parser_set_variables_handler (parser, ucl_variable_getter, &vars); - ucl_parser_add_file (parser, filename.c_str ()); - ucl_parser_free (parser); + ucl_parser_set_variables_handler(parser, ucl_variable_getter, &vars); + ucl_parser_add_file(parser, filename.c_str()); + ucl_parser_free(parser); std::vector result; - std::move (vars.begin (), vars.end (), std::back_inserter (result)); + std::move(vars.begin(), vars.end(), std::back_inserter(result)); return result; } - Ucl& operator= (Ucl rhs) + Ucl &operator=(Ucl rhs) { - obj.swap (rhs.obj); + obj.swap(rhs.obj); return *this; } - bool operator== (const Ucl &rhs) const + bool operator==(const Ucl &rhs) const { - return ucl_object_compare (obj.get(), rhs.obj.get ()) == 0; + return ucl_object_compare(obj.get(), rhs.obj.get()) == 0; } - bool operator< (const Ucl &rhs) const + bool operator<(const Ucl &rhs) const { - return ucl_object_compare (obj.get(), rhs.obj.get ()) < 0; + return ucl_object_compare(obj.get(), rhs.obj.get()) < 0; + } + bool operator!=(const Ucl &rhs) const + { + return !(*this == rhs); + } + bool operator<=(const Ucl &rhs) const + { + return !(rhs < *this); + } + bool operator>(const Ucl &rhs) const + { + return (rhs < *this); + } + bool operator>=(const Ucl &rhs) const + { + return !(*this < rhs); } - bool operator!= (const Ucl &rhs) const { return !(*this == rhs); } - bool operator<= (const Ucl &rhs) const { return !(rhs < *this); } - bool operator> (const Ucl &rhs) const { return (rhs < *this); } - bool operator>= (const Ucl &rhs) const { return !(*this < rhs); } - explicit operator bool () const + explicit operator bool() const { if (!obj || type() == UCL_NULL) { return false; } - if (type () == UCL_BOOLEAN) { - return bool_value (); + if (type() == UCL_BOOLEAN) { + return bool_value(); } return true; } const_iterator begin() const { return const_iterator(*this); } const_iterator cbegin() const { return const_iterator(*this); } const_iterator end() const { return const_iterator(); } const_iterator cend() const { return const_iterator(); } }; -}; +};// namespace ucl diff --git a/contrib/libucl/include/ucl.h b/contrib/libucl/include/ucl.h index b8625b9fce2f..96ddaa9cb987 100644 --- a/contrib/libucl/include/ucl.h +++ b/contrib/libucl/include/ucl.h @@ -1,1653 +1,1666 @@ /* Copyright (c) 2013-2015, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UCL_H_ #define UCL_H_ #include #include #include #include #include #include #include #ifdef _WIN32 -# define UCL_EXTERN __declspec(dllexport) +#define UCL_EXTERN __declspec(dllexport) #else -# define UCL_EXTERN +#define UCL_EXTERN #endif /** * @mainpage * This is a reference manual for UCL API. You may find the description of UCL format by following this * [github repository](https://github.com/vstakhov/libucl). * * This manual has several main sections: * - @ref structures * - @ref utils * - @ref parser * - @ref emitter */ /** * @file ucl.h * @brief UCL parsing and emitting functions * * UCL is universal configuration language, which is a form of * JSON with less strict rules that make it more comfortable for * using as a configuration language */ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif /* * Memory allocation utilities * UCL_ALLOC(size) - allocate memory for UCL * UCL_FREE(size, ptr) - free memory of specified size at ptr * Default: malloc and free */ #ifndef UCL_ALLOC #define UCL_ALLOC(size) malloc(size) #endif #ifndef UCL_FREE #define UCL_FREE(size, ptr) free(ptr) #endif +#ifndef UCL_REALLOC +#define UCL_REALLOC(ptr, size) realloc(ptr, size) +#endif +#ifndef UCL_STRDUP +static inline char *ucl_strdup_impl(const char *s) +{ + size_t len = strlen(s) + 1; + char *p = (char *) UCL_ALLOC(len); + if (p) memcpy(p, s, len); + return p; +} +#define UCL_STRDUP(str) ucl_strdup_impl(str) +#endif -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -#define UCL_WARN_UNUSED_RESULT \ - __attribute__((warn_unused_result)) +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define UCL_WARN_UNUSED_RESULT \ + __attribute__((warn_unused_result)) #else #define UCL_WARN_UNUSED_RESULT #endif #ifdef __GNUC__ -#define UCL_DEPRECATED(func) func __attribute__ ((deprecated)) +#define UCL_DEPRECATED(func) func __attribute__((deprecated)) #elif defined(_MSC_VER) #define UCL_DEPRECATED(func) __declspec(deprecated) func #else #define UCL_DEPRECATED(func) func #endif /** * @defgroup structures Structures and types * UCL defines several enumeration types used for error reporting or specifying flags and attributes. * * @{ */ /** * The common error codes returned by ucl parser */ typedef enum ucl_error { - UCL_EOK = 0, /**< No error */ - UCL_ESYNTAX, /**< Syntax error occurred during parsing */ - UCL_EIO, /**< IO error occurred during parsing */ - UCL_ESTATE, /**< Invalid state machine state */ - UCL_ENESTED, /**< Input has too many recursion levels */ + UCL_EOK = 0, /**< No error */ + UCL_ESYNTAX, /**< Syntax error occurred during parsing */ + 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_EMACRO, /**< Error processing a macro */ UCL_EINTERNAL, /**< Internal unclassified error */ - UCL_ESSL, /**< SSL error */ - UCL_EMERGE /**< A merge error occurred */ + UCL_ESSL, /**< SSL error */ + UCL_EMERGE /**< A merge error occurred */ } ucl_error_t; /** * #ucl_object_t may have one of specified types, some types are compatible with each other and some are not. * For example, you can always convert #UCL_TIME to #UCL_FLOAT. Also you can convert #UCL_FLOAT to #UCL_INTEGER * by loosing floating point. Every object may be converted to a string by #ucl_object_tostring_forced() function. * */ typedef enum ucl_type { UCL_OBJECT = 0, /**< UCL object - key/value pairs */ - UCL_ARRAY, /**< UCL array */ - UCL_INT, /**< Integer number */ - UCL_FLOAT, /**< Floating point number */ - UCL_STRING, /**< Null terminated string */ - UCL_BOOLEAN, /**< Boolean value */ - UCL_TIME, /**< Time value (floating point number of seconds) */ - UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */ - UCL_NULL /**< Null value */ + UCL_ARRAY, /**< UCL array */ + UCL_INT, /**< Integer number */ + UCL_FLOAT, /**< Floating point number */ + UCL_STRING, /**< Null terminated string */ + UCL_BOOLEAN, /**< Boolean value */ + UCL_TIME, /**< Time value (floating point number of seconds) */ + UCL_USERDATA, /**< Opaque userdata pointer (may be used in macros) */ + UCL_NULL /**< Null value */ } ucl_type_t; /** * You can use one of these types to serialise #ucl_object_t by using ucl_object_emit(). */ typedef enum ucl_emitter { - UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */ + UCL_EMIT_JSON = 0, /**< Emit fine formatted JSON */ UCL_EMIT_JSON_COMPACT, /**< Emit compacted JSON */ - UCL_EMIT_CONFIG, /**< Emit human readable config format */ - UCL_EMIT_YAML, /**< Emit embedded YAML format */ - UCL_EMIT_MSGPACK, /**< Emit msgpack output */ - UCL_EMIT_MAX /**< Unsupported emitter type */ + UCL_EMIT_CONFIG, /**< Emit human readable config format */ + UCL_EMIT_YAML, /**< Emit embedded YAML format */ + UCL_EMIT_MSGPACK, /**< Emit msgpack output */ + UCL_EMIT_MAX /**< Unsupported emitter type */ } ucl_emitter_t; /** * These flags defines parser behaviour. If you specify #UCL_PARSER_ZEROCOPY you must ensure * that the input memory is not freed if an object is in use. Moreover, if you want to use * zero-terminated keys and string values then you should not use zero-copy mode, as in this case * UCL still has to perform copying implicitly. */ typedef enum ucl_parser_flags { - UCL_PARSER_DEFAULT = 0, /**< No special flags */ - UCL_PARSER_KEY_LOWERCASE = (1 << 0), /**< Convert all keys to lower case */ - UCL_PARSER_ZEROCOPY = (1 << 1), /**< Parse input in zero-copy mode if possible */ - UCL_PARSER_NO_TIME = (1 << 2), /**< Do not parse time and treat time values as strings */ + UCL_PARSER_DEFAULT = 0, /**< No special flags */ + UCL_PARSER_KEY_LOWERCASE = (1 << 0), /**< Convert all keys to lower case */ + UCL_PARSER_ZEROCOPY = (1 << 1), /**< Parse input in zero-copy mode if possible */ + UCL_PARSER_NO_TIME = (1 << 2), /**< Do not parse time and treat time values as strings */ UCL_PARSER_NO_IMPLICIT_ARRAYS = (1 << 3), /** Create explicit arrays instead of implicit ones */ - UCL_PARSER_SAVE_COMMENTS = (1 << 4), /** Save comments in the parser context */ - UCL_PARSER_DISABLE_MACRO = (1 << 5), /** Treat macros as comments */ - UCL_PARSER_NO_FILEVARS = (1 << 6) /** Do not set file vars */ + UCL_PARSER_SAVE_COMMENTS = (1 << 4), /** Save comments in the parser context */ + UCL_PARSER_DISABLE_MACRO = (1 << 5), /** Treat macros as comments */ + UCL_PARSER_NO_FILEVARS = (1 << 6) /** Do not set file vars */ } ucl_parser_flags_t; /** * String conversion flags, that are used in #ucl_object_fromstring_common function. */ typedef enum ucl_string_flags { - UCL_STRING_RAW = 0x0, /**< Treat string as is */ - UCL_STRING_ESCAPE = (1 << 0), /**< Perform JSON escape */ - UCL_STRING_TRIM = (1 << 1), /**< Trim leading and trailing whitespaces */ - UCL_STRING_PARSE_BOOLEAN = (1 << 2), /**< Parse passed string and detect boolean */ - UCL_STRING_PARSE_INT = (1 << 3), /**< Parse passed string and detect integer number */ - UCL_STRING_PARSE_DOUBLE = (1 << 4), /**< Parse passed string and detect integer or float number */ - UCL_STRING_PARSE_TIME = (1 << 5), /**< Parse time strings */ - UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT|UCL_STRING_PARSE_DOUBLE|UCL_STRING_PARSE_TIME, /**< + UCL_STRING_RAW = 0x0, /**< Treat string as is */ + UCL_STRING_ESCAPE = (1 << 0), /**< Perform JSON escape */ + UCL_STRING_TRIM = (1 << 1), /**< Trim leading and trailing whitespaces */ + UCL_STRING_PARSE_BOOLEAN = (1 << 2), /**< Parse passed string and detect boolean */ + UCL_STRING_PARSE_INT = (1 << 3), /**< Parse passed string and detect integer number */ + UCL_STRING_PARSE_DOUBLE = (1 << 4), /**< Parse passed string and detect integer or float number */ + UCL_STRING_PARSE_TIME = (1 << 5), /**< Parse time strings */ + UCL_STRING_PARSE_NUMBER = UCL_STRING_PARSE_INT | UCL_STRING_PARSE_DOUBLE | UCL_STRING_PARSE_TIME, /**< Parse passed string and detect number */ - UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN|UCL_STRING_PARSE_NUMBER, /**< + UCL_STRING_PARSE = UCL_STRING_PARSE_BOOLEAN | UCL_STRING_PARSE_NUMBER, /**< Parse passed string (and detect booleans and numbers) */ - UCL_STRING_PARSE_BYTES = (1 << 6) /**< Treat numbers as bytes */ + UCL_STRING_PARSE_BYTES = (1 << 6) /**< Treat numbers as bytes */ } ucl_string_flags_t; /** * 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 */ + UCL_OBJECT_ALLOCATED_KEY = (1 << 0), /**< An object has key allocated internally */ UCL_OBJECT_ALLOCATED_VALUE = (1 << 1), /**< An object has a string value allocated internally */ UCL_OBJECT_NEED_KEY_ESCAPE = (1 << 2), /**< The key of an object need to be escaped on output */ - UCL_OBJECT_EPHEMERAL = (1 << 3), /**< Temporary object that does not need to be freed really */ - 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_SQUOTED = (1 << 8) /**< Object has been enclosed in single quotes */ + UCL_OBJECT_EPHEMERAL = (1 << 3), /**< Temporary object that does not need to be freed really */ + 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_SQUOTED = (1 << 8) /**< Object has been enclosed in single quotes */ } ucl_object_flags_t; /** * Duplicate policy types */ enum ucl_duplicate_strategy { UCL_DUPLICATE_APPEND = 0, /**< Default policy to merge based on priorities */ - UCL_DUPLICATE_MERGE, /**< Merge new object with old one */ - UCL_DUPLICATE_REWRITE, /**< Rewrite old keys */ - UCL_DUPLICATE_ERROR /**< Stop parsing on duplicate found */ + UCL_DUPLICATE_MERGE, /**< Merge new object with old one */ + UCL_DUPLICATE_REWRITE, /**< Rewrite old keys */ + UCL_DUPLICATE_ERROR /**< Stop parsing on duplicate found */ }; /** * Input format type */ enum ucl_parse_type { UCL_PARSE_UCL = 0, /**< Default ucl format */ UCL_PARSE_MSGPACK, /**< Message pack input format */ - UCL_PARSE_CSEXP, /**< Canonical S-expressions */ - UCL_PARSE_AUTO /**< Try to detect parse type */ + UCL_PARSE_CSEXP, /**< Canonical S-expressions */ + UCL_PARSE_AUTO /**< Try to detect parse type */ }; /** * UCL object structure. Please mention that the most of fields should not be touched by * UCL users. In future, this structure may be converted to private one. */ typedef struct ucl_object_s { /** * Variant value type */ union { - int64_t iv; /**< Int value of an object */ - const char *sv; /**< String value of an object */ - double dv; /**< Double value of an object */ - void *av; /**< Array */ - void *ov; /**< Object */ - void* ud; /**< Opaque user data */ + int64_t iv; /**< Int value of an object */ + const char *sv; /**< String value of an object */ + double dv; /**< Double value of an object */ + void *av; /**< Array */ + void *ov; /**< Object */ + void *ud; /**< Opaque user data */ } value; - const char *key; /**< Key of an object */ - struct ucl_object_s *next; /**< Array handle */ - struct ucl_object_s *prev; /**< Array handle */ - uint32_t keylen; /**< Length of a key */ - uint32_t len; /**< Size of an object */ - uint32_t ref; /**< Reference count */ - uint16_t flags; /**< Object flags */ - uint16_t type; /**< Real type */ - unsigned char* trash_stack[2]; /**< Pointer to allocated chunks */ + const char *key; /**< Key of an object */ + struct ucl_object_s *next; /**< Array handle */ + struct ucl_object_s *prev; /**< Array handle */ + uint32_t keylen; /**< Length of a key */ + uint32_t len; /**< Size of an object */ + uint32_t ref; /**< Reference count */ + uint16_t flags; /**< Object flags */ + uint16_t type; /**< Real type */ + unsigned char *trash_stack[2]; /**< Pointer to allocated chunks */ } ucl_object_t; /** * Destructor type for userdata objects * @param ud user specified data pointer */ typedef void (*ucl_userdata_dtor)(void *ud); -typedef const char* (*ucl_userdata_emitter)(void *ud); +typedef const char *(*ucl_userdata_emitter)(void *ud); /** @} */ /** * @defgroup utils Utility functions * A number of utility functions simplify handling of UCL objects * * @{ */ /** * Copy and return a key of an object, returned key is zero-terminated * @param obj CL object * @return zero terminated key */ -UCL_EXTERN char* ucl_copy_key_trash (const ucl_object_t *obj); +UCL_EXTERN char *ucl_copy_key_trash(const ucl_object_t *obj); /** * Copy and return a string value of an object, returned key is zero-terminated * @param obj CL object * @return zero terminated string representation of object value */ -UCL_EXTERN char* ucl_copy_value_trash (const ucl_object_t *obj); +UCL_EXTERN char *ucl_copy_value_trash(const ucl_object_t *obj); /** * Creates a new object * @return new object */ -UCL_EXTERN ucl_object_t* ucl_object_new (void) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_new(void) UCL_WARN_UNUSED_RESULT; /** * Create new object with type specified * @param type type of a new object * @return new object */ -UCL_EXTERN ucl_object_t* ucl_object_typed_new (ucl_type_t type) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_typed_new(ucl_type_t type) UCL_WARN_UNUSED_RESULT; /** * Create new object with type and priority specified * @param type type of a new object * @param priority priority of an object * @return new object */ -UCL_EXTERN ucl_object_t* ucl_object_new_full (ucl_type_t type, unsigned priority) +UCL_EXTERN ucl_object_t *ucl_object_new_full(ucl_type_t type, unsigned priority) UCL_WARN_UNUSED_RESULT; /** * Create new object with userdata dtor * @param dtor destructor function * @param emitter emitter for userdata * @param ptr opaque pointer * @return new object */ -UCL_EXTERN ucl_object_t* ucl_object_new_userdata (ucl_userdata_dtor dtor, - ucl_userdata_emitter emitter, void *ptr) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_new_userdata(ucl_userdata_dtor dtor, + ucl_userdata_emitter emitter, void *ptr) UCL_WARN_UNUSED_RESULT; /** * Perform deep copy of an object copying everything * @param other object to copy * @return new object with refcount equal to 1 */ -UCL_EXTERN ucl_object_t * ucl_object_copy (const ucl_object_t *other) +UCL_EXTERN ucl_object_t *ucl_object_copy(const ucl_object_t *other) UCL_WARN_UNUSED_RESULT; /** * Return the type of an object * @return the object type */ -UCL_EXTERN ucl_type_t ucl_object_type (const ucl_object_t *obj); +UCL_EXTERN ucl_type_t ucl_object_type(const ucl_object_t *obj); /** * Converts ucl object type to its string representation * @param type type of object * @return constant string describing type */ -UCL_EXTERN const char * ucl_object_type_to_string (ucl_type_t type); +UCL_EXTERN const char *ucl_object_type_to_string(ucl_type_t type); /** * Converts string that represents ucl type to real ucl type enum * @param input C string with name of type * @param res resulting target * @return true if `input` is a name of type stored in `res` */ -UCL_EXTERN bool ucl_object_string_to_type (const char *input, ucl_type_t *res); +UCL_EXTERN bool ucl_object_string_to_type(const char *input, ucl_type_t *res); /** * Convert any string to an ucl object making the specified transformations * @param str fixed size or NULL terminated string * @param len length (if len is zero, than str is treated as NULL terminated) * @param flags conversion flags * @return new object */ -UCL_EXTERN ucl_object_t * ucl_object_fromstring_common (const char *str, size_t len, - enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_fromstring_common(const char *str, size_t len, + enum ucl_string_flags flags) UCL_WARN_UNUSED_RESULT; /** * Create a UCL object from the specified string * @param str NULL terminated string, will be json escaped * @return new object */ -UCL_EXTERN ucl_object_t *ucl_object_fromstring (const char *str) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_fromstring(const char *str) UCL_WARN_UNUSED_RESULT; /** * Create a UCL object from the specified string * @param str fixed size string, will be json escaped * @param len length of a string * @return new object */ -UCL_EXTERN ucl_object_t *ucl_object_fromlstring (const char *str, - size_t len) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_fromlstring(const char *str, + size_t len) UCL_WARN_UNUSED_RESULT; /** * Create an object from an integer number * @param iv number * @return new object */ -UCL_EXTERN ucl_object_t* ucl_object_fromint (int64_t iv) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_fromint(int64_t iv) UCL_WARN_UNUSED_RESULT; /** * Create an object from a float number * @param dv number * @return new object */ -UCL_EXTERN ucl_object_t* ucl_object_fromdouble (double dv) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_fromdouble(double dv) UCL_WARN_UNUSED_RESULT; /** * Create an object from a boolean * @param bv bool value * @return new object */ -UCL_EXTERN ucl_object_t* ucl_object_frombool (bool bv) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_frombool(bool bv) UCL_WARN_UNUSED_RESULT; /** * Insert a object 'elt' to the hash 'top' and associate it with key 'key' * @param top destination object (must be of type UCL_OBJECT) * @param elt element to insert (must NOT be NULL) * @param key key to associate with this object (either const or preallocated) * @param keylen length of the key (or 0 for NULL terminated keys) * @param copy_key make an internal copy of key * @return true if key has been inserted */ -UCL_EXTERN bool ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, - const char *key, size_t keylen, bool copy_key); +UCL_EXTERN bool ucl_object_insert_key(ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key); /** * Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed, * if no object has been found this function works like ucl_object_insert_key() * @param top destination object (must be of type UCL_OBJECT) * @param elt element to insert (must NOT be NULL) * @param key key to associate with this object (either const or preallocated) * @param keylen length of the key (or 0 for NULL terminated keys) * @param copy_key make an internal copy of key * @return true if key has been inserted */ -UCL_EXTERN bool ucl_object_replace_key (ucl_object_t *top, ucl_object_t *elt, - const char *key, size_t keylen, bool copy_key); +UCL_EXTERN bool ucl_object_replace_key(ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key); /** * Merge the keys from one object to another object. Overwrite on conflict * @param top destination object (must be of type UCL_OBJECT) * @param elt element to insert (must be of type UCL_OBJECT) * @param copy copy rather than reference the elements * @return true if all keys have been merged */ -UCL_EXTERN bool ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy); +UCL_EXTERN bool ucl_object_merge(ucl_object_t *top, ucl_object_t *elt, bool copy); /** * Delete a object associated with key 'key', old object will be unrefered, * @param top object * @param key key associated to the object to remove * @param keylen length of the key (or 0 for NULL terminated keys) */ -UCL_EXTERN bool ucl_object_delete_keyl (ucl_object_t *top, - const char *key, size_t keylen); +UCL_EXTERN bool ucl_object_delete_keyl(ucl_object_t *top, + const char *key, size_t keylen); /** * Delete a object associated with key 'key', old object will be unrefered, * @param top object * @param key key associated to the object to remove */ -UCL_EXTERN bool ucl_object_delete_key (ucl_object_t *top, - const char *key); +UCL_EXTERN bool ucl_object_delete_key(ucl_object_t *top, + const char *key); /** * Removes `key` from `top` object, returning the object that was removed. This * object is not released, caller must unref the returned object when it is no * longer needed. * @param top object * @param key key to remove * @param keylen length of the key (or 0 for NULL terminated keys) * @return removed object or NULL if object has not been found */ -UCL_EXTERN ucl_object_t* ucl_object_pop_keyl (ucl_object_t *top, const char *key, - size_t keylen) UCL_WARN_UNUSED_RESULT; +UCL_EXTERN ucl_object_t *ucl_object_pop_keyl(ucl_object_t *top, const char *key, + size_t keylen) UCL_WARN_UNUSED_RESULT; /** * Removes `key` from `top` object returning the object that was removed. This * object is not released, caller must unref the returned object when it is no * longer needed. * @param top object * @param key key to remove * @return removed object or NULL if object has not been found */ -UCL_EXTERN ucl_object_t* ucl_object_pop_key (ucl_object_t *top, const char *key) +UCL_EXTERN ucl_object_t *ucl_object_pop_key(ucl_object_t *top, const char *key) UCL_WARN_UNUSED_RESULT; /** * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if * the specified key exist, try to merge its content * @param top destination object (must be of type UCL_OBJECT) * @param elt element to insert (must NOT be NULL) * @param key key to associate with this object (either const or preallocated) * @param keylen length of the key (or 0 for NULL terminated keys) * @param copy_key make an internal copy of key * @return true if key has been inserted */ -UCL_EXTERN bool ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt, - const char *key, size_t keylen, bool copy_key); +UCL_EXTERN bool ucl_object_insert_key_merged(ucl_object_t *top, ucl_object_t *elt, + 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); +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) * @return true if value has been inserted */ -UCL_EXTERN bool ucl_array_append (ucl_object_t *top, - ucl_object_t *elt); +UCL_EXTERN bool ucl_array_append(ucl_object_t *top, + ucl_object_t *elt); /** * Append an element to the start of array object * @param top destination object (must NOT be NULL) * @param elt element to append (must NOT be NULL) * @return true if value has been inserted */ -UCL_EXTERN bool ucl_array_prepend (ucl_object_t *top, - ucl_object_t *elt); +UCL_EXTERN bool ucl_array_prepend(ucl_object_t *top, + ucl_object_t *elt); /** * Merge all elements of second array into the first array * @param top destination array (must be of type UCL_ARRAY) * @param elt array to copy elements from (must be of type UCL_ARRAY) * @param copy copy elements instead of referencing them * @return true if arrays were merged */ -UCL_EXTERN bool ucl_array_merge (ucl_object_t *top, ucl_object_t *elt, - bool copy); +UCL_EXTERN bool ucl_array_merge(ucl_object_t *top, ucl_object_t *elt, + bool copy); /** * Removes an element `elt` from the array `top`, returning the object that was * removed. This object is not released, caller must unref the returned object * when it is no longer needed. * @param top array ucl object * @param elt element to remove * @return removed element or NULL if `top` is NULL or not an array */ -UCL_EXTERN ucl_object_t* ucl_array_delete (ucl_object_t *top, - ucl_object_t *elt); +UCL_EXTERN ucl_object_t *ucl_array_delete(ucl_object_t *top, + ucl_object_t *elt); /** * Returns the first element of the array `top` * @param top array ucl object * @return element or NULL if `top` is NULL or not an array */ -UCL_EXTERN const ucl_object_t* ucl_array_head (const ucl_object_t *top); +UCL_EXTERN const ucl_object_t *ucl_array_head(const ucl_object_t *top); /** * Returns the last element of the array `top` * @param top array ucl object * @return element or NULL if `top` is NULL or not an array */ -UCL_EXTERN const ucl_object_t* ucl_array_tail (const ucl_object_t *top); +UCL_EXTERN const ucl_object_t *ucl_array_tail(const ucl_object_t *top); /** * Removes the last element from the array `top`, returning the object that was * removed. This object is not released, caller must unref the returned object * when it is no longer needed. * @param top array ucl object * @return removed element or NULL if `top` is NULL or not an array */ -UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top); +UCL_EXTERN ucl_object_t *ucl_array_pop_last(ucl_object_t *top); /** * Removes the first element from the array `top`, returning the object that was * removed. This object is not released, caller must unref the returned object * when it is no longer needed. * @param top array ucl object * @return removed element or NULL if `top` is NULL or not an array */ -UCL_EXTERN ucl_object_t* ucl_array_pop_first (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); +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 * @return object at the specified index or NULL if index is not found */ -UCL_EXTERN const ucl_object_t* ucl_array_find_index (const ucl_object_t *top, - unsigned int index); +UCL_EXTERN const ucl_object_t *ucl_array_find_index(const ucl_object_t *top, + unsigned int index); /** * Return the index of `elt` in the array `top` * @param top object to get a key from (must be of type UCL_ARRAY) * @param elt element to find index of (must NOT be NULL) * @return index of `elt` in the array `top or (unsigned int)-1 if `elt` is not found */ -UCL_EXTERN unsigned int ucl_array_index_of (ucl_object_t *top, - ucl_object_t *elt); +UCL_EXTERN unsigned int ucl_array_index_of(ucl_object_t *top, + ucl_object_t *elt); /** * Replace an element in an array with a different element, returning the object * that was replaced. This object is not released, caller must unref the * returned object when it is no longer needed. * @param top destination object (must be of type UCL_ARRAY) * @param elt element to append (must NOT be NULL) * @param index array index in destination to overwrite with elt * @return object that was replaced or NULL if index is not found */ ucl_object_t * -ucl_array_replace_index (ucl_object_t *top, ucl_object_t *elt, - unsigned int index); +ucl_array_replace_index(ucl_object_t *top, ucl_object_t *elt, + unsigned int index); /** * Append a element to another element forming an implicit array * @param head head to append (may be NULL) * @param elt new element * @return the new implicit array */ -UCL_EXTERN ucl_object_t * ucl_elt_append (ucl_object_t *head, - ucl_object_t *elt); +UCL_EXTERN ucl_object_t *ucl_elt_append(ucl_object_t *head, + ucl_object_t *elt); /** * Converts an object to double value * @param obj CL object * @param target target double variable * @return true if conversion was successful */ -UCL_EXTERN bool ucl_object_todouble_safe (const ucl_object_t *obj, double *target); +UCL_EXTERN bool ucl_object_todouble_safe(const ucl_object_t *obj, double *target); /** * Unsafe version of \ref ucl_obj_todouble_safe * @param obj CL object * @return double value */ -UCL_EXTERN double ucl_object_todouble (const ucl_object_t *obj); +UCL_EXTERN double ucl_object_todouble(const ucl_object_t *obj); /** * Converts an object to integer value * @param obj CL object * @param target target integer variable * @return true if conversion was successful */ -UCL_EXTERN bool ucl_object_toint_safe (const ucl_object_t *obj, int64_t *target); +UCL_EXTERN bool ucl_object_toint_safe(const ucl_object_t *obj, int64_t *target); /** * Unsafe version of \ref ucl_obj_toint_safe * @param obj CL object * @return int value */ -UCL_EXTERN int64_t ucl_object_toint (const ucl_object_t *obj); +UCL_EXTERN int64_t ucl_object_toint(const ucl_object_t *obj); /** * Converts an object to boolean value * @param obj CL object * @param target target boolean variable * @return true if conversion was successful */ -UCL_EXTERN bool ucl_object_toboolean_safe (const ucl_object_t *obj, bool *target); +UCL_EXTERN bool ucl_object_toboolean_safe(const ucl_object_t *obj, bool *target); /** * Unsafe version of \ref ucl_obj_toboolean_safe * @param obj CL object * @return boolean value */ -UCL_EXTERN bool ucl_object_toboolean (const ucl_object_t *obj); +UCL_EXTERN bool ucl_object_toboolean(const ucl_object_t *obj); /** * Converts an object to string value * @param obj CL object * @param target target string variable, no need to free value * @return true if conversion was successful */ -UCL_EXTERN bool ucl_object_tostring_safe (const ucl_object_t *obj, const char **target); +UCL_EXTERN bool ucl_object_tostring_safe(const ucl_object_t *obj, const char **target); /** * Unsafe version of \ref ucl_obj_tostring_safe * @param obj CL object * @return string value */ -UCL_EXTERN const char* ucl_object_tostring (const ucl_object_t *obj); +UCL_EXTERN const char *ucl_object_tostring(const ucl_object_t *obj); /** * Convert any object to a string in JSON notation if needed * @param obj CL object * @return string value */ -UCL_EXTERN const char* ucl_object_tostring_forced (const ucl_object_t *obj); +UCL_EXTERN const char *ucl_object_tostring_forced(const ucl_object_t *obj); /** * Return string as char * and len, string may be not zero terminated, more efficient that \ref ucl_obj_tostring as it * allows zero-copy (if #UCL_PARSER_ZEROCOPY has been used during parsing) * @param obj CL object * @param target target string variable, no need to free value * @param tlen target length * @return true if conversion was successful */ -UCL_EXTERN bool ucl_object_tolstring_safe (const ucl_object_t *obj, - const char **target, size_t *tlen); +UCL_EXTERN bool ucl_object_tolstring_safe(const ucl_object_t *obj, + const char **target, size_t *tlen); /** * Unsafe version of \ref ucl_obj_tolstring_safe * @param obj CL object * @return string value */ -UCL_EXTERN const char* ucl_object_tolstring (const ucl_object_t *obj, size_t *tlen); +UCL_EXTERN const char *ucl_object_tolstring(const ucl_object_t *obj, size_t *tlen); /** * Return object identified by a key in the specified object * @param obj object to get a key from (must be of type UCL_OBJECT) * @param key key to search * @return object matching the specified key or NULL if key was not found */ -UCL_EXTERN const ucl_object_t* ucl_object_lookup (const ucl_object_t *obj, - const char *key); +UCL_EXTERN const ucl_object_t *ucl_object_lookup(const ucl_object_t *obj, + const char *key); #define ucl_object_find_key ucl_object_lookup /** * Return object identified by a key in the specified object, if the first key is * not found then look for the next one. This process is repeated unless * the next argument in the list is not NULL. So, `ucl_object_find_any_key(obj, key, NULL)` * is equal to `ucl_object_find_key(obj, key)` * @param obj object to get a key from (must be of type UCL_OBJECT) * @param key key to search * @param ... list of alternative keys to search (NULL terminated) * @return object matching the specified key or NULL if key was not found */ -UCL_EXTERN const ucl_object_t* ucl_object_lookup_any (const ucl_object_t *obj, - const char *key, ...); +UCL_EXTERN const ucl_object_t *ucl_object_lookup_any(const ucl_object_t *obj, + const char *key, ...); #define ucl_object_find_any_key ucl_object_lookup_any /** * Return object identified by a fixed size key in the specified object * @param obj object to get a key from (must be of type UCL_OBJECT) * @param key key to search * @param klen length of a key * @return object matching the specified key or NULL if key was not found */ -UCL_EXTERN const ucl_object_t* ucl_object_lookup_len (const ucl_object_t *obj, - const char *key, size_t klen); +UCL_EXTERN const ucl_object_t *ucl_object_lookup_len(const ucl_object_t *obj, + const char *key, size_t klen); #define ucl_object_find_keyl ucl_object_lookup_len /** * Return object identified by dot notation string * @param obj object to search in * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays * @return object matched the specified path or NULL if path is not found */ -UCL_EXTERN const ucl_object_t *ucl_object_lookup_path (const ucl_object_t *obj, - const char *path); +UCL_EXTERN const ucl_object_t *ucl_object_lookup_path(const ucl_object_t *obj, + const char *path); #define ucl_lookup_path ucl_object_lookup_path /** * Return object identified by object notation string using arbitrary delimiter * @param obj object to search in * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays * @param sep the sepatorator to use in place of . (incase keys have . in them) * @return object matched the specified path or NULL if path is not found */ -UCL_EXTERN const ucl_object_t *ucl_object_lookup_path_char (const ucl_object_t *obj, - const char *path, char sep); +UCL_EXTERN const ucl_object_t *ucl_object_lookup_path_char(const ucl_object_t *obj, + const char *path, char sep); #define ucl_lookup_path_char ucl_object_lookup_path_char /** * Returns a key of an object as a NULL terminated string * @param obj CL object * @return key or NULL if there is no key */ -UCL_EXTERN const char* ucl_object_key (const ucl_object_t *obj); +UCL_EXTERN const char *ucl_object_key(const ucl_object_t *obj); /** * Returns a key of an object as a fixed size string (may be more efficient) * @param obj CL object * @param len target key length * @return key pointer */ -UCL_EXTERN const char* ucl_object_keyl (const ucl_object_t *obj, size_t *len); +UCL_EXTERN const char *ucl_object_keyl(const ucl_object_t *obj, size_t *len); /** * Increase reference count for an object * @param obj object to ref * @return the referenced object */ -UCL_EXTERN ucl_object_t* ucl_object_ref (const ucl_object_t *obj); +UCL_EXTERN ucl_object_t *ucl_object_ref(const ucl_object_t *obj); /** * Free ucl object * @param obj ucl object to free */ -UCL_DEPRECATED(UCL_EXTERN void ucl_object_free (ucl_object_t *obj)); +UCL_DEPRECATED(UCL_EXTERN void ucl_object_free(ucl_object_t *obj)); /** * Decrease reference count for an object * @param obj object to unref */ -UCL_EXTERN void ucl_object_unref (ucl_object_t *obj); +UCL_EXTERN void ucl_object_unref(ucl_object_t *obj); /** * Compare objects `o1` and `o2` * @param o1 the first object * @param o2 the second object * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`. * The order of comparison: * 1) Type of objects * 2) Size of objects * 3) Content of objects */ -UCL_EXTERN int ucl_object_compare (const ucl_object_t *o1, - const ucl_object_t *o2); +UCL_EXTERN int ucl_object_compare(const ucl_object_t *o1, + const ucl_object_t *o2); /** * Compare objects `o1` and `o2` useful for sorting * @param o1 the first object * @param o2 the second object * @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`. * The order of comparison: * 1) Type of objects * 2) Size of objects * 3) Content of objects */ -UCL_EXTERN int ucl_object_compare_qsort (const ucl_object_t **o1, - const ucl_object_t **o2); +UCL_EXTERN int ucl_object_compare_qsort(const ucl_object_t **o1, + const ucl_object_t **o2); /** * Sort UCL array using `cmp` compare function * @param ar * @param cmp */ -UCL_EXTERN void ucl_object_array_sort (ucl_object_t *ar, - int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2)); +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); +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 * @return priority of an object */ -UCL_EXTERN unsigned int ucl_object_get_priority (const ucl_object_t *obj); +UCL_EXTERN unsigned int ucl_object_get_priority(const ucl_object_t *obj); /** * Set explicit priority of an object. * @param obj any ucl object * @param priority new priroity value (only 4 least significant bits are considred) */ -UCL_EXTERN void ucl_object_set_priority (ucl_object_t *obj, - unsigned int priority); +UCL_EXTERN void ucl_object_set_priority(ucl_object_t *obj, + unsigned int priority); /** * Opaque iterator object */ -typedef void* ucl_object_iter_t; +typedef void *ucl_object_iter_t; /** * Get next key from an object * @param obj object to iterate * @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_with_error (const ucl_object_t *obj, - ucl_object_iter_t *iter, bool expand_values, int *ep); +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 * @param obj object to iterate * @return new iterator object that should be used with safe iterators API only */ -UCL_EXTERN ucl_object_iter_t ucl_object_iterate_new (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 */ -UCL_EXTERN ucl_object_iter_t ucl_object_iterate_reset (ucl_object_iter_t it, - const ucl_object_t *obj); +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 function iterates over arrays, objects * and implicit arrays * @param iter safe iterator * @param expand_values expand explicit arrays and objects * @return the next object in sequence */ -UCL_EXTERN const ucl_object_t* ucl_object_iterate_safe (ucl_object_iter_t iter, - bool expand_values); +UCL_EXTERN const ucl_object_t *ucl_object_iterate_safe(ucl_object_iter_t iter, + bool expand_values); /** * Iteration type enumerator */ enum ucl_iterate_type { - UCL_ITERATE_EXPLICIT = 1 << 0, /**< Iterate just explicit arrays and objects */ - UCL_ITERATE_IMPLICIT = 1 << 1, /**< Iterate just implicit arrays */ - UCL_ITERATE_BOTH = (1 << 0) | (1 << 1), /**< Iterate both explicit and implicit arrays*/ + UCL_ITERATE_EXPLICIT = 1 << 0, /**< Iterate just explicit arrays and objects */ + UCL_ITERATE_IMPLICIT = 1 << 1, /**< Iterate just implicit arrays */ + UCL_ITERATE_BOTH = (1 << 0) | (1 << 1), /**< Iterate both explicit and implicit arrays*/ }; /** * Get the next object from the `obj`. This function iterates over arrays, objects * and implicit arrays if needed * @param iter safe iterator * @param * @return the next object in sequence */ -UCL_EXTERN const ucl_object_t* ucl_object_iterate_full (ucl_object_iter_t iter, - enum ucl_iterate_type type); +UCL_EXTERN const ucl_object_t *ucl_object_iterate_full(ucl_object_iter_t iter, + enum ucl_iterate_type type); /** * Free memory associated with the safe iterator * @param it safe iterator object */ -UCL_EXTERN void ucl_object_iterate_free (ucl_object_iter_t it); +UCL_EXTERN void ucl_object_iterate_free(ucl_object_iter_t it); /** @} */ /** * @defgroup parser Parsing functions * These functions are used to parse UCL objects * * @{ */ /** * Macro handler for a parser * @param data the content of macro * @param len the length of content * @param arguments arguments object * @param ud opaque user data * @param err error pointer * @return true if macro has been parsed */ -typedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len, - const ucl_object_t *arguments, - void* ud); +typedef bool (*ucl_macro_handler)(const unsigned char *data, size_t len, + const ucl_object_t *arguments, + void *ud); /** * Context dependent macro handler for a parser * @param data the content of macro * @param len the length of content * @param arguments arguments object * @param context previously parsed context * @param ud opaque user data * @param err error pointer * @return true if macro has been parsed */ -typedef bool (*ucl_context_macro_handler) (const unsigned char *data, size_t len, - const ucl_object_t *arguments, - const ucl_object_t *context, - void* ud); +typedef bool (*ucl_context_macro_handler)(const unsigned char *data, size_t len, + const ucl_object_t *arguments, + const ucl_object_t *context, + void *ud); /* Opaque parser */ struct ucl_parser; /** * Creates new parser object * @param pool pool to allocate memory from * @return new parser object */ -UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags); +UCL_EXTERN struct ucl_parser *ucl_parser_new(int flags); /** * 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) * @return true if parser's default priority was set */ -UCL_EXTERN bool ucl_parser_set_default_priority (struct ucl_parser *parser, - unsigned prio); +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); +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 bool ucl_parser_register_macro (struct ucl_parser *parser, - const char *macro, - ucl_macro_handler handler, void* ud); +UCL_EXTERN bool ucl_parser_register_macro(struct ucl_parser *parser, + const char *macro, + ucl_macro_handler handler, void *ud); /** * Register new context dependent 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 bool ucl_parser_register_context_macro (struct ucl_parser *parser, - const char *macro, - ucl_context_macro_handler handler, - void* ud); +UCL_EXTERN bool ucl_parser_register_context_macro(struct ucl_parser *parser, + const char *macro, + ucl_context_macro_handler handler, + void *ud); /** * Handler to detect unregistered variables * @param data variable data * @param len length of variable * @param replace (out) replace value for variable * @param replace_len (out) replace length for variable * @param need_free (out) UCL will free `dest` after usage * @param ud opaque userdata * @return true if variable */ -typedef bool (*ucl_variable_handler) (const unsigned char *data, size_t len, - unsigned char **replace, size_t *replace_len, bool *need_free, void* ud); +typedef bool (*ucl_variable_handler)(const unsigned char *data, size_t len, + unsigned char **replace, size_t *replace_len, bool *need_free, void *ud); /** * Register new parser variable * @param parser parser object * @param var variable name * @param value variable value */ -UCL_EXTERN void ucl_parser_register_variable (struct ucl_parser *parser, const char *var, - const char *value); +UCL_EXTERN void ucl_parser_register_variable(struct ucl_parser *parser, const char *var, + const char *value); /** * Set handler for unknown variables * @param parser parser structure * @param handler desired handler * @param ud opaque data for the handler */ -UCL_EXTERN void ucl_parser_set_variables_handler (struct ucl_parser *parser, - ucl_variable_handler handler, void *ud); +UCL_EXTERN void ucl_parser_set_variables_handler(struct ucl_parser *parser, + ucl_variable_handler handler, void *ud); /** * Load new chunk to a parser * @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_add_chunk (struct ucl_parser *parser, - const unsigned char *data, size_t len); +UCL_EXTERN bool ucl_parser_add_chunk(struct ucl_parser *parser, + const unsigned char *data, size_t len); /** * Load new chunk to a parser with the specified priority * @param parser parser structure * @param data the pointer to the beginning of a chunk * @param len the length of a chunk * @param priority the desired priority of a chunk (only 4 least significant bits * are considered for this parameter) * @return true if chunk has been added and false in case of error */ -UCL_EXTERN bool ucl_parser_add_chunk_priority (struct ucl_parser *parser, - const unsigned char *data, size_t len, unsigned priority); +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); +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 * @param len the length of a chunk * @param priority the desired priority of a chunk (only 4 least significant bits * are considered for this parameter) * @param strat duplicates merging strategy * @param parse_type input format * @return true if chunk has been added and false in case of error */ -UCL_EXTERN bool ucl_parser_add_chunk_full (struct ucl_parser *parser, - const unsigned char *data, size_t len, unsigned priority, - enum ucl_duplicate_strategy strat, enum ucl_parse_type parse_type); +UCL_EXTERN bool ucl_parser_add_chunk_full(struct ucl_parser *parser, + const unsigned char *data, size_t len, unsigned priority, + enum ucl_duplicate_strategy strat, enum ucl_parse_type parse_type); /** * Load ucl object from a string * @param parser parser structure * @param data the pointer to the string * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string * @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); +UCL_EXTERN bool ucl_parser_add_string(struct ucl_parser *parser, + const char *data, size_t len); /** * Load ucl object from a string * @param parser parser structure * @param data the pointer to the string * @param len the length of the string, if `len` is 0 then `data` must be zero-terminated string * @param priority the desired priority of a chunk (only 4 least significant bits * are considered for this parameter) * @return true if string has been added and false in case of error */ -UCL_EXTERN bool ucl_parser_add_string_priority (struct ucl_parser *parser, - const char *data, size_t len, unsigned priority); +UCL_EXTERN bool ucl_parser_add_string_priority(struct ucl_parser *parser, + const char *data, size_t len, unsigned priority); /** * Load and add data from a file * @param parser parser structure * @param filename the name of file * @param err if *err is NULL it is set to parser error * @return true if chunk has been added and false in case of error */ -UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser, - const char *filename); +UCL_EXTERN bool ucl_parser_add_file(struct ucl_parser *parser, + const char *filename); /** * Load and add data from a file * @param parser parser structure * @param filename the name of file * @param err if *err is NULL it is set to parser error * @param priority the desired priority of a chunk (only 4 least significant bits * are considered for this parameter) * @return true if chunk has been added and false in case of error */ -UCL_EXTERN bool ucl_parser_add_file_priority (struct ucl_parser *parser, - const char *filename, unsigned priority); +UCL_EXTERN bool ucl_parser_add_file_priority(struct ucl_parser *parser, + const char *filename, unsigned priority); /** * Load and add data from a file * @param parser parser structure * @param filename the name of file * @param priority the desired priority of a chunk (only 4 least significant bits * are considered for this parameter) * @param strat Merge strategy to use while parsing this file * @param parse_type Parser type to use while parsing this file * @return true if chunk has been added and false in case of error */ -UCL_EXTERN bool ucl_parser_add_file_full (struct ucl_parser *parser, const char *filename, - unsigned priority, enum ucl_duplicate_strategy strat, - enum ucl_parse_type parse_type); +UCL_EXTERN bool ucl_parser_add_file_full(struct ucl_parser *parser, const char *filename, + unsigned priority, enum ucl_duplicate_strategy strat, + enum ucl_parse_type parse_type); /** * Load and add data from a file descriptor * @param parser parser structure * @param filename the name of file * @param err if *err is NULL it is set to parser error * @return true if chunk has been added and false in case of error */ -UCL_EXTERN bool ucl_parser_add_fd (struct ucl_parser *parser, - int fd); +UCL_EXTERN bool ucl_parser_add_fd(struct ucl_parser *parser, + int fd); /** * Load and add data from a file descriptor * @param parser parser structure * @param filename the name of file * @param err if *err is NULL it is set to parser error * @param priority the desired priority of a chunk (only 4 least significant bits * are considered for this parameter) * @return true if chunk has been added and false in case of error */ -UCL_EXTERN bool ucl_parser_add_fd_priority (struct ucl_parser *parser, - int fd, unsigned priority); +UCL_EXTERN bool ucl_parser_add_fd_priority(struct ucl_parser *parser, + int fd, unsigned priority); /** * Load and add data from a file descriptor * @param parser parser structure * @param filename the name of file * @param err if *err is NULL it is set to parser error * @param priority the desired priority of a chunk (only 4 least significant bits * are considered for this parameter) * @param strat Merge strategy to use while parsing this file * @param parse_type Parser type to use while parsing this file * @return true if chunk has been added and false in case of error */ -UCL_EXTERN bool ucl_parser_add_fd_full (struct ucl_parser *parser, int fd, - unsigned priority, enum ucl_duplicate_strategy strat, - enum ucl_parse_type parse_type); +UCL_EXTERN bool ucl_parser_add_fd_full(struct ucl_parser *parser, int fd, + unsigned priority, enum ucl_duplicate_strategy strat, + enum ucl_parse_type parse_type); /** * Provide a UCL_ARRAY of paths to search for include files. The object is * copied so caller must unref the object. * @param parser parser structure * @param paths UCL_ARRAY of paths to search * @return true if the path search array was replaced in the parser */ -UCL_EXTERN bool ucl_set_include_path (struct ucl_parser *parser, - ucl_object_t *paths); +UCL_EXTERN bool ucl_set_include_path(struct ucl_parser *parser, + ucl_object_t *paths); /** * Get a top object for a parser (refcount is increased) * @param parser parser structure * @param err if *err is NULL it is set to parser error * @return top parser object or NULL */ -UCL_EXTERN ucl_object_t* ucl_parser_get_object (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); +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); +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); +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 */ -UCL_EXTERN const char *ucl_parser_get_error (struct ucl_parser *parser); +UCL_EXTERN const char *ucl_parser_get_error(struct ucl_parser *parser); /** * Get the code of the last error * @param parser parser object * @return error code */ -UCL_EXTERN int ucl_parser_get_error_code (struct ucl_parser *parser); +UCL_EXTERN int ucl_parser_get_error_code(struct ucl_parser *parser); /** * Get the current column number within parser * @param parser parser object * @return current column number */ -UCL_EXTERN unsigned ucl_parser_get_column (struct ucl_parser *parser); +UCL_EXTERN unsigned ucl_parser_get_column(struct ucl_parser *parser); /** * Get the current line number within parser * @param parser parser object * @return current line number */ -UCL_EXTERN unsigned ucl_parser_get_linenum (struct ucl_parser *parser); +UCL_EXTERN unsigned ucl_parser_get_linenum(struct ucl_parser *parser); /** * Clear the error in the parser * @param parser parser object */ -UCL_EXTERN void ucl_parser_clear_error (struct ucl_parser *parser); +UCL_EXTERN void ucl_parser_clear_error(struct ucl_parser *parser); /** * Free ucl parser object * @param parser parser object */ -UCL_EXTERN void ucl_parser_free (struct ucl_parser *parser); +UCL_EXTERN void ucl_parser_free(struct ucl_parser *parser); /** * Get constant opaque pointer to comments structure for this parser. Increase * refcount to prevent this object to be destroyed on parser's destruction * @param parser parser structure * @return ucl comments pointer or NULL */ -UCL_EXTERN const ucl_object_t * ucl_parser_get_comments (struct ucl_parser *parser); +UCL_EXTERN const ucl_object_t *ucl_parser_get_comments(struct ucl_parser *parser); /** * Utility function to find a comment object for the specified object in the input * @param comments comments object * @param srch search object * @return string comment enclosed in ucl_object_t */ -UCL_EXTERN const ucl_object_t * ucl_comments_find (const ucl_object_t *comments, - const ucl_object_t *srch); +UCL_EXTERN const ucl_object_t *ucl_comments_find(const ucl_object_t *comments, + const ucl_object_t *srch); /** * Move comment from `from` object to `to` object * @param comments comments object * @param what source 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, - const ucl_object_t *from, const ucl_object_t *to); +UCL_EXTERN bool ucl_comments_move(ucl_object_t *comments, + const ucl_object_t *from, const ucl_object_t *to); /** * Adds a new comment for an object * @param comments comments object * @param obj object to add comment to * @param comment string representation of a comment */ -UCL_EXTERN void ucl_comments_add (ucl_object_t *comments, - const ucl_object_t *obj, const char *comment); +UCL_EXTERN void ucl_comments_add(ucl_object_t *comments, + const ucl_object_t *obj, const char *comment); /** * Add new public key to parser for signatures check * @param parser parser object * @param key PEM representation of a key * @param len length of the key * @param err if *err is NULL it is set to parser error * @return true if a key has been successfully added */ -UCL_EXTERN bool ucl_parser_pubkey_add (struct ucl_parser *parser, - const unsigned char *key, size_t len); +UCL_EXTERN bool ucl_parser_pubkey_add(struct ucl_parser *parser, + const unsigned char *key, size_t len); /** * Set FILENAME and CURDIR variables in parser * @param parser parser object * @param filename filename to set or NULL to set FILENAME to "undef" and CURDIR to getcwd() * @param need_expand perform realpath() if this variable is true and filename is not NULL * @return true if variables has been set */ -UCL_EXTERN bool ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, - bool need_expand); +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); +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); +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 (*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); +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); +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); +UCL_EXTERN void ucl_parser_set_include_tracer(struct ucl_parser *parser, + ucl_include_trace_func_t func, + void *user_data); /** @} */ /** * @defgroup emitter Emitting functions * These functions are used to serialise UCL objects to some string representation. * * @{ */ struct ucl_emitter_context; /** * Structure using for emitter callbacks */ struct ucl_emitter_functions { /** Append a single character */ - int (*ucl_emitter_append_character) (unsigned char c, size_t nchars, void *ud); + int (*ucl_emitter_append_character)(unsigned char c, size_t nchars, void *ud); /** Append a string of a specified length */ - int (*ucl_emitter_append_len) (unsigned const char *str, size_t len, void *ud); + int (*ucl_emitter_append_len)(unsigned const char *str, size_t len, void *ud); /** Append a 64 bit integer */ - int (*ucl_emitter_append_int) (int64_t elt, void *ud); + int (*ucl_emitter_append_int)(int64_t elt, void *ud); /** Append floating point element */ - int (*ucl_emitter_append_double) (double elt, void *ud); + int (*ucl_emitter_append_double)(double elt, void *ud); /** Free userdata */ void (*ucl_emitter_free_func)(void *ud); /** Opaque userdata pointer */ void *ud; }; struct ucl_emitter_operations { /** Write a primitive element */ - void (*ucl_emitter_write_elt) (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool first, bool print_key); + void (*ucl_emitter_write_elt)(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool first, bool print_key); /** Start ucl object */ - void (*ucl_emitter_start_object) (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool first, bool print_key); + void (*ucl_emitter_start_object)(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool first, bool print_key); /** End ucl object */ - void (*ucl_emitter_end_object) (struct ucl_emitter_context *ctx, - const ucl_object_t *obj); + void (*ucl_emitter_end_object)(struct ucl_emitter_context *ctx, + const ucl_object_t *obj); /** Start ucl array */ - void (*ucl_emitter_start_array) (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool first, bool print_key); - void (*ucl_emitter_end_array) (struct ucl_emitter_context *ctx, - const ucl_object_t *obj); + void (*ucl_emitter_start_array)(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool first, bool print_key); + void (*ucl_emitter_end_array)(struct ucl_emitter_context *ctx, + const ucl_object_t *obj); }; /** * Structure that defines emitter functions */ struct ucl_emitter_context { /** Name of emitter (e.g. json, compact_json) */ const char *name; /** Unique id (e.g. UCL_EMIT_JSON for standard emitters */ int id; /** A set of output functions */ const struct ucl_emitter_functions *func; /** A set of output operations */ const struct ucl_emitter_operations *ops; /** Current amount of indent tabs */ unsigned int indent; /** Top level object */ const ucl_object_t *top; /** Optional comments */ const ucl_object_t *comments; }; /** * Emit object to a string * @param obj object * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is * #UCL_EMIT_CONFIG then emit config like object * @return dump of an object (must be freed after using) or NULL in case of error */ -UCL_EXTERN unsigned char *ucl_object_emit (const ucl_object_t *obj, - enum ucl_emitter emit_type); +UCL_EXTERN unsigned char *ucl_object_emit(const ucl_object_t *obj, + enum ucl_emitter emit_type); /** * Emit object to a string that can contain `\0` inside * @param obj object * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is * #UCL_EMIT_CONFIG then emit config like object * @param len the resulting length * @return dump of an object (must be freed after using) or NULL in case of error */ -UCL_EXTERN unsigned char *ucl_object_emit_len (const ucl_object_t *obj, - enum ucl_emitter emit_type, size_t *len); +UCL_EXTERN unsigned char *ucl_object_emit_len(const ucl_object_t *obj, + enum ucl_emitter emit_type, size_t *len); /** * Emit object to a string * @param obj object * @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is * #UCL_EMIT_CONFIG then emit config like object * @param emitter a set of emitter functions * @param comments optional comments for the parser * @return dump of an object (must be freed after using) or NULL in case of error */ -UCL_EXTERN bool ucl_object_emit_full (const ucl_object_t *obj, - enum ucl_emitter emit_type, - struct ucl_emitter_functions *emitter, - const ucl_object_t *comments); +UCL_EXTERN bool ucl_object_emit_full(const ucl_object_t *obj, + enum ucl_emitter emit_type, + struct ucl_emitter_functions *emitter, + const ucl_object_t *comments); /** * Start streamlined UCL object emitter * @param obj top UCL object * @param emit_type emit type * @param emitter a set of emitter functions * @return new streamlined context that should be freed by * `ucl_object_emit_streamline_finish` */ -UCL_EXTERN struct ucl_emitter_context* ucl_object_emit_streamline_new ( - const ucl_object_t *obj, enum ucl_emitter emit_type, - struct ucl_emitter_functions *emitter); +UCL_EXTERN struct ucl_emitter_context *ucl_object_emit_streamline_new( + const ucl_object_t *obj, enum ucl_emitter emit_type, + struct ucl_emitter_functions *emitter); /** * Start object or array container for the streamlined output * @param ctx streamlined context * @param obj container object */ -UCL_EXTERN void ucl_object_emit_streamline_start_container ( - struct ucl_emitter_context *ctx, const ucl_object_t *obj); +UCL_EXTERN bool ucl_object_emit_streamline_start_container( + struct ucl_emitter_context *ctx, const ucl_object_t *obj); /** * Add a complete UCL object to streamlined output * @param ctx streamlined context * @param obj object to output */ -UCL_EXTERN void ucl_object_emit_streamline_add_object ( - struct ucl_emitter_context *ctx, const ucl_object_t *obj); +UCL_EXTERN void ucl_object_emit_streamline_add_object( + struct ucl_emitter_context *ctx, const ucl_object_t *obj); /** * End previously added container * @param ctx streamlined context */ -UCL_EXTERN void ucl_object_emit_streamline_end_container ( - struct ucl_emitter_context *ctx); +UCL_EXTERN void ucl_object_emit_streamline_end_container( + struct ucl_emitter_context *ctx); /** * Terminate streamlined container finishing all containers in it * @param ctx streamlined context */ -UCL_EXTERN void ucl_object_emit_streamline_finish ( - struct ucl_emitter_context *ctx); +UCL_EXTERN void ucl_object_emit_streamline_finish( + struct ucl_emitter_context *ctx); /** * Returns functions to emit object to memory * @param pmem target pointer (should be freed by caller) * @return emitter functions structure */ -UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_memory_funcs ( - void **pmem); +UCL_EXTERN struct ucl_emitter_functions *ucl_object_emit_memory_funcs( + void **pmem); /** * Returns functions to emit object to FILE * * @param fp FILE * object * @return emitter functions structure */ -UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_file_funcs ( - FILE *fp); +UCL_EXTERN struct ucl_emitter_functions *ucl_object_emit_file_funcs( + FILE *fp); /** * Returns functions to emit object to a file descriptor * @param fd file descriptor * @return emitter functions structure */ -UCL_EXTERN struct ucl_emitter_functions* ucl_object_emit_fd_funcs ( - int fd); +UCL_EXTERN struct ucl_emitter_functions *ucl_object_emit_fd_funcs( + int fd); /** * Free emitter functions * @param f pointer to functions */ -UCL_EXTERN void ucl_object_emit_funcs_free (struct ucl_emitter_functions *f); +UCL_EXTERN void ucl_object_emit_funcs_free(struct ucl_emitter_functions *f); /** @} */ /** * @defgroup schema Schema functions * These functions are used to validate UCL objects using json schema format * * @{ */ /** * Used to define UCL schema error */ enum ucl_schema_error_code { - UCL_SCHEMA_OK = 0, /**< no error */ - UCL_SCHEMA_TYPE_MISMATCH, /**< type of object is incorrect */ - UCL_SCHEMA_INVALID_SCHEMA, /**< schema is invalid */ - UCL_SCHEMA_MISSING_PROPERTY,/**< one or more missing properties */ - UCL_SCHEMA_CONSTRAINT, /**< constraint found */ - UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */ + UCL_SCHEMA_OK = 0, /**< no error */ + UCL_SCHEMA_TYPE_MISMATCH, /**< type of object is incorrect */ + UCL_SCHEMA_INVALID_SCHEMA, /**< schema is invalid */ + UCL_SCHEMA_MISSING_PROPERTY, /**< one or more missing properties */ + UCL_SCHEMA_CONSTRAINT, /**< constraint found */ + UCL_SCHEMA_MISSING_DEPENDENCY, /**< missing dependency */ UCL_SCHEMA_EXTERNAL_REF_MISSING, /**< cannot fetch external ref */ UCL_SCHEMA_EXTERNAL_REF_INVALID, /**< invalid external ref */ - UCL_SCHEMA_INTERNAL_ERROR, /**< something bad happened */ - UCL_SCHEMA_UNKNOWN /**< generic error */ + UCL_SCHEMA_INTERNAL_ERROR, /**< something bad happened */ + UCL_SCHEMA_UNKNOWN /**< generic error */ }; /** * Generic ucl schema error */ 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 occurred */ + enum ucl_schema_error_code code; /**< error code */ + char msg[128]; /**< error message */ + const ucl_object_t *obj; /**< object where error occurred */ }; /** * Validate object `obj` using schema object `schema`. * @param schema schema object * @param obj object to validate * @param err error pointer, if this parameter is not NULL and error has been * 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, - const ucl_object_t *obj, struct ucl_schema_error *err); +UCL_EXTERN bool ucl_object_validate(const ucl_object_t *schema, + const ucl_object_t *obj, struct ucl_schema_error *err); /** * Validate object `obj` using schema object `schema` and root schema at `root`. * @param schema schema object * @param obj object to validate * @param root root schema object * @param err error pointer, if this parameter is not NULL and error has been * 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, - const ucl_object_t *obj, - const ucl_object_t *root, - struct ucl_schema_error *err); +UCL_EXTERN bool ucl_object_validate_root(const ucl_object_t *schema, + const ucl_object_t *obj, + const ucl_object_t *root, + struct ucl_schema_error *err); /** * Validate object `obj` using schema object `schema` and root schema at `root` * using some external references provided. * @param schema schema object * @param obj object to validate * @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 * 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, - const ucl_object_t *obj, - const ucl_object_t *root, - ucl_object_t *ext_refs, - struct ucl_schema_error *err); +UCL_EXTERN bool ucl_object_validate_root_ext(const ucl_object_t *schema, + const ucl_object_t *obj, + const ucl_object_t *root, + ucl_object_t *ext_refs, + struct ucl_schema_error *err); /** @} */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif /* * XXX: Poorly named API functions, need to replace them with the appropriate * named function. All API functions *must* use naming ucl_object_*. Usage of * ucl_obj* should be avoided. */ #define ucl_obj_todouble_safe ucl_object_todouble_safe #define ucl_obj_todouble ucl_object_todouble #define ucl_obj_tostring ucl_object_tostring #define ucl_obj_tostring_safe ucl_object_tostring_safe #define ucl_obj_tolstring ucl_object_tolstring #define ucl_obj_tolstring_safe ucl_object_tolstring_safe #define ucl_obj_toint ucl_object_toint #define ucl_obj_toint_safe ucl_object_toint_safe #define ucl_obj_toboolean ucl_object_toboolean #define ucl_obj_toboolean_safe ucl_object_toboolean_safe #define ucl_obj_get_key ucl_object_find_key #define ucl_obj_get_keyl ucl_object_find_keyl #define ucl_obj_unref ucl_object_unref #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_ */ diff --git a/contrib/libucl/lua/lua_ucl.c b/contrib/libucl/lua/lua_ucl.c index 1b3f9dfd111c..0420ad87e26f 100644 --- a/contrib/libucl/lua/lua_ucl.c +++ b/contrib/libucl/lua/lua_ucl.c @@ -1,1577 +1,1583 @@ /* Copyright (c) 2014, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file lua ucl bindings */ #include "ucl.h" #include "ucl_internal.h" #include "lua_ucl.h" #include #include "bootstrap.h" /*** * @module ucl * This lua module allows to parse objects from strings and to store data into * ucl objects. It uses `libucl` C library to parse and manipulate with ucl objects. * @example local ucl = require("ucl") local parser = ucl.parser() local res,err = parser:parse_string('{key=value}') if not res then print('parser error: ' .. err) else local obj = parser:get_object() local got = ucl.to_format(obj, 'json') endif local table = { str = 'value', num = 100500, null = ucl.null, func = function () return 'huh' end } print(ucl.to_format(table, 'ucl')) -- Output: --[[ num = 100500; str = "value"; null = null; func = "huh"; --]] */ #define PARSER_META "ucl.parser.meta" #define EMITTER_META "ucl.emitter.meta" #define NULL_META "ucl.null.meta" #define OBJECT_META "ucl.object.meta" #define UCL_OBJECT_TYPE_META "ucl.type.object" #define UCL_ARRAY_TYPE_META "ucl.type.array" #define UCL_IMPL_ARRAY_TYPE_META "ucl.type.impl_array" static int ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj, int flags); static int ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, int flags); static int ucl_object_push_lua_common (lua_State *L, const ucl_object_t *obj, int flags); static ucl_object_t* ucl_object_lua_fromtable (lua_State *L, int idx, ucl_string_flags_t flags); static ucl_object_t* ucl_object_lua_fromelt (lua_State *L, int idx, ucl_string_flags_t flags); static void *ucl_null; struct _rspamd_lua_text { const char *start; unsigned int len; unsigned int flags; }; enum lua_ucl_push_flags { LUA_UCL_DEFAULT_FLAGS = 0, LUA_UCL_ALLOW_ARRAY = (1u << 0u), LUA_UCL_CONVERT_NIL = (1u << 1u), }; /** * Push a single element of an object to lua * @param L * @param key * @param obj */ static void ucl_object_lua_push_element (lua_State *L, const char *key, const ucl_object_t *obj, int flags) { lua_pushstring (L, key); ucl_object_push_lua_common (L, obj, flags|LUA_UCL_ALLOW_ARRAY); lua_settable (L, -3); } static void lua_ucl_userdata_dtor (void *ud) { struct ucl_lua_funcdata *fd = (struct ucl_lua_funcdata *)ud; luaL_unref (fd->L, LUA_REGISTRYINDEX, fd->idx); if (fd->ret != NULL) { free (fd->ret); } free (fd); } static const char * lua_ucl_userdata_emitter (void *ud) { struct ucl_lua_funcdata *fd = (struct ucl_lua_funcdata *)ud; const char *out = ""; lua_rawgeti (fd->L, LUA_REGISTRYINDEX, fd->idx); lua_pcall (fd->L, 0, 1, 0); out = lua_tostring (fd->L, -1); if (out != NULL) { /* We need to store temporary string in a more appropriate place */ if (fd->ret) { free (fd->ret); } fd->ret = strdup (out); } lua_settop (fd->L, 0); return fd->ret; } /** * Push a single object to lua * @param L * @param obj * @return */ static int ucl_object_lua_push_object (lua_State *L, const ucl_object_t *obj, int flags) { const ucl_object_t *cur; ucl_object_iter_t it = NULL; if ((flags & LUA_UCL_ALLOW_ARRAY) && obj->next != NULL) { /* Actually we need to push this as an array */ return ucl_object_lua_push_array (L, obj, flags); } lua_createtable (L, 0, obj->len); it = NULL; while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) { ucl_object_lua_push_element (L, ucl_object_key (cur), cur, flags); } luaL_getmetatable (L, UCL_OBJECT_TYPE_META); lua_setmetatable (L, -2); return 1; } /** * Push an array to lua as table indexed by integers * @param L * @param obj * @return */ static int ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj, int flags) { const ucl_object_t *cur; ucl_object_iter_t it; int i = 1, nelt = 0; if (obj->type == UCL_ARRAY) { nelt = obj->len; it = ucl_object_iterate_new (obj); lua_createtable (L, nelt, 0); while ((cur = ucl_object_iterate_safe (it, true))) { ucl_object_push_lua (L, cur, (flags & ~LUA_UCL_ALLOW_ARRAY)); lua_rawseti (L, -2, i); i ++; } luaL_getmetatable (L, UCL_ARRAY_TYPE_META); lua_setmetatable (L, -2); ucl_object_iterate_free (it); } else { /* Optimize allocation by preallocation of table */ LL_FOREACH (obj, cur) { nelt ++; } lua_createtable (L, nelt, 0); LL_FOREACH (obj, cur) { ucl_object_push_lua (L, cur, (flags & ~LUA_UCL_ALLOW_ARRAY)); lua_rawseti (L, -2, i); i ++; } luaL_getmetatable (L, UCL_IMPL_ARRAY_TYPE_META); lua_setmetatable (L, -2); } return 1; } /** * Push a simple object to lua depending on its actual type */ static int ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, int flags) { struct ucl_lua_funcdata *fd; if ((flags & LUA_UCL_ALLOW_ARRAY) && obj->next != NULL) { /* Actually we need to push this as an array */ return ucl_object_lua_push_array (L, obj, flags); } switch (obj->type) { case UCL_BOOLEAN: lua_pushboolean (L, ucl_obj_toboolean (obj)); break; case UCL_STRING: lua_pushlstring (L, ucl_obj_tostring (obj), obj->len); break; case UCL_INT: #if LUA_VERSION_NUM >= 501 lua_pushinteger (L, ucl_obj_toint (obj)); #else lua_pushnumber (L, ucl_obj_toint (obj)); #endif break; case UCL_FLOAT: case UCL_TIME: lua_pushnumber (L, ucl_obj_todouble (obj)); break; case UCL_NULL: if (flags & LUA_UCL_CONVERT_NIL) { lua_pushboolean (L, false); } else { lua_getfield (L, LUA_REGISTRYINDEX, "ucl.null"); } break; case UCL_USERDATA: fd = (struct ucl_lua_funcdata *)obj->value.ud; lua_rawgeti (L, LUA_REGISTRYINDEX, fd->idx); break; default: lua_pushnil (L); break; } return 1; } static int ucl_object_push_lua_common (lua_State *L, const ucl_object_t *obj, int flags) { switch (obj->type) { case UCL_OBJECT: return ucl_object_lua_push_object (L, obj, flags); case UCL_ARRAY: return ucl_object_lua_push_array (L, obj, flags); default: return ucl_object_lua_push_scalar (L, obj, flags); } } /*** * @function ucl_object_push_lua(L, obj, allow_array) * This is a `C` function to push `UCL` object as lua variable. This function * converts `obj` to lua representation using the following conversions: * * - *scalar* values are directly presented by lua objects * - *userdata* values are converted to lua function objects using `LUA_REGISTRYINDEX`, * this can be used to pass functions from lua to c and vice-versa * - *arrays* are converted to lua tables with numeric indicies suitable for `ipairs` iterations * - *objects* are converted to lua tables with string indicies * @param {lua_State} L lua state pointer * @param {ucl_object_t} obj object to push * @param {bool} allow_array expand implicit arrays (should be true for all but partial arrays) * @return {int} `1` if an object is pushed to lua */ int ucl_object_push_lua (lua_State *L, const ucl_object_t *obj, bool allow_array) { return ucl_object_push_lua_common (L, obj, allow_array ? LUA_UCL_ALLOW_ARRAY : LUA_UCL_DEFAULT_FLAGS); } int ucl_object_push_lua_filter_nil (lua_State *L, const ucl_object_t *obj, bool allow_array) { return ucl_object_push_lua_common (L, obj, allow_array ? (LUA_UCL_ALLOW_ARRAY|LUA_UCL_CONVERT_NIL) : (LUA_UCL_DEFAULT_FLAGS|LUA_UCL_CONVERT_NIL)); } /** * Parse lua table into object top * @param L * @param top * @param idx */ static ucl_object_t * ucl_object_lua_fromtable (lua_State *L, int idx, ucl_string_flags_t flags) { ucl_object_t *obj, *top = NULL, *cur; size_t keylen; const char *k; bool is_array = true, is_implicit = false, found_mt = false; size_t max = 0, nelts = 0; if (idx < 0) { /* For negative indicies we want to invert them */ idx = lua_gettop (L) + idx + 1; } /* First, we check from metatable */ if (luaL_getmetafield (L, idx, "class") != 0) { if (lua_type (L, -1) == LUA_TSTRING) { const char *classname = lua_tostring (L, -1); if (strcmp (classname, UCL_OBJECT_TYPE_META) == 0) { is_array = false; found_mt = true; } else if (strcmp (classname, UCL_ARRAY_TYPE_META) == 0) { is_array = true; found_mt = true; #if LUA_VERSION_NUM >= 502 max = lua_rawlen (L, idx); #else max = lua_objlen (L, idx); #endif nelts = max; } else if (strcmp (classname, UCL_IMPL_ARRAY_TYPE_META) == 0) { is_array = true; is_implicit = true; found_mt = true; #if LUA_VERSION_NUM >= 502 max = lua_rawlen (L, idx); #else max = lua_objlen (L, idx); #endif nelts = max; } } lua_pop (L, 1); } if (!found_mt) { /* Check for array (it is all inefficient) */ lua_pushnil (L); while (lua_next (L, idx) != 0) { lua_pushvalue (L, -2); if (lua_type (L, -1) == LUA_TNUMBER) { double num = lua_tonumber (L, -1); if (num == (int) num) { if (num > max) { max = num; } } else { /* Keys are not integer */ is_array = false; } } else { /* Keys are not numeric */ is_array = false; } lua_pop (L, 2); nelts ++; } } /* Table iterate */ if (is_array) { if (!is_implicit) { top = ucl_object_typed_new (UCL_ARRAY); ucl_object_reserve (top, nelts); } else { top = NULL; } for (size_t i = 1; i <= max; i ++) { lua_pushinteger (L, i); lua_gettable (L, idx); obj = ucl_object_lua_fromelt (L, lua_gettop (L), flags); if (obj != NULL) { if (is_implicit) { DL_APPEND (top, obj); } else { ucl_array_append (top, obj); } } lua_pop (L, 1); } } else { lua_pushnil (L); top = ucl_object_typed_new (UCL_OBJECT); ucl_object_reserve (top, nelts); while (lua_next (L, idx) != 0) { /* copy key to avoid modifications */ lua_pushvalue (L, -2); k = lua_tolstring (L, -1, &keylen); obj = ucl_object_lua_fromelt (L, lua_gettop (L) - 1, flags); if (obj != NULL) { ucl_object_insert_key (top, obj, k, keylen, true); DL_FOREACH (obj, cur) { if (cur->keylen == 0) { cur->keylen = obj->keylen; cur->key = obj->key; } } } lua_pop (L, 2); } } return top; } /** * Get a single element from lua to object obj * @param L * @param obj * @param idx */ static ucl_object_t * ucl_object_lua_fromelt (lua_State *L, int idx, ucl_string_flags_t flags) { int type; double num; ucl_object_t *obj = NULL; struct ucl_lua_funcdata *fd; const char *str; size_t sz; type = lua_type (L, idx); switch (type) { case LUA_TSTRING: str = lua_tolstring (L, idx, &sz); if (str) { /* * ucl_object_fromstring_common has a `logic` to use strlen if sz is zero * which is totally broken... */ if (sz > 0) { obj = ucl_object_fromstring_common(str, sz, flags); } else { obj = ucl_object_fromstring_common("", sz, flags); } } else { obj = ucl_object_typed_new (UCL_NULL); } break; case LUA_TNUMBER: num = lua_tonumber (L, idx); if (num == (int64_t)num) { obj = ucl_object_fromint (num); } else { obj = ucl_object_fromdouble (num); } break; case LUA_TBOOLEAN: obj = ucl_object_frombool (lua_toboolean (L, idx)); break; case LUA_TUSERDATA: if (lua_topointer (L, idx) == ucl_null) { obj = ucl_object_typed_new (UCL_NULL); } else { /* Assume it is a text like object */ struct _rspamd_lua_text *t = lua_touserdata (L, idx); if (t) { if (t->len >0) { obj = ucl_object_fromstring_common(t->start, t->len, 0); } else { obj = ucl_object_fromstring_common("", 0, 0); } /* Binary text */ if (t->flags & (1u << 5u)) { obj->flags |= UCL_OBJECT_BINARY; } } } break; case LUA_TTABLE: case LUA_TFUNCTION: case LUA_TTHREAD: if (luaL_getmetafield (L, idx, "__gen_ucl")) { if (lua_isfunction (L, -1)) { lua_settop (L, 3); /* gen, obj, func */ lua_insert (L, 1); /* func, gen, obj */ lua_insert (L, 2); /* func, obj, gen */ lua_call(L, 2, 1); obj = ucl_object_lua_fromelt (L, 1, flags); } lua_pop (L, 2); } else { if (type == LUA_TTABLE) { obj = ucl_object_lua_fromtable (L, idx, flags); } else if (type == LUA_TFUNCTION) { fd = malloc (sizeof (*fd)); if (fd != NULL) { lua_pushvalue (L, idx); fd->L = L; fd->ret = NULL; fd->idx = luaL_ref (L, LUA_REGISTRYINDEX); obj = ucl_object_new_userdata (lua_ucl_userdata_dtor, lua_ucl_userdata_emitter, (void *)fd); } } } break; } return obj; } /** * @function ucl_object_lua_import(L, idx) * Extracts ucl object from lua variable at `idx` position, * @see ucl_object_push_lua for conversion definitions * @param {lua_state} L lua state machine pointer * @param {int} idx index where the source variable is placed * @return {ucl_object_t} new ucl object extracted from lua variable. Reference count of this object is 1, * this object thus needs to be unref'ed after usage. */ ucl_object_t * ucl_object_lua_import (lua_State *L, int idx) { ucl_object_t *obj; int t; t = lua_type (L, idx); switch (t) { case LUA_TTABLE: obj = ucl_object_lua_fromtable (L, idx, UCL_STRING_RAW); break; default: obj = ucl_object_lua_fromelt (L, idx, UCL_STRING_RAW); break; } return obj; } /** * @function ucl_object_lua_import_escape(L, idx) * Extracts ucl object from lua variable at `idx` position escaping JSON strings * @see ucl_object_push_lua for conversion definitions * @param {lua_state} L lua state machine pointer * @param {int} idx index where the source variable is placed * @return {ucl_object_t} new ucl object extracted from lua variable. Reference count of this object is 1, * this object thus needs to be unref'ed after usage. */ ucl_object_t * ucl_object_lua_import_escape (lua_State *L, int idx) { ucl_object_t *obj; int t; t = lua_type (L, idx); switch (t) { case LUA_TTABLE: obj = ucl_object_lua_fromtable (L, idx, UCL_STRING_ESCAPE); break; default: obj = ucl_object_lua_fromelt (L, idx, UCL_STRING_ESCAPE); break; } return obj; } static int lua_ucl_to_string (lua_State *L, const ucl_object_t *obj, enum ucl_emitter type) { unsigned char *result; size_t outlen; result = ucl_object_emit_len (obj, type, &outlen); if (result != NULL) { lua_pushlstring (L, (const char *)result, outlen); free (result); } else { lua_pushnil (L); } return 1; } static int lua_ucl_parser_init (lua_State *L) { struct ucl_parser *parser, **pparser; - int flags = UCL_PARSER_NO_FILEVARS; + /* + * We disable file variables and macros by default, as + * the most use cases are parsing of JSON and not of the real + * files. Macros in the parser are very dangerous and should be used + * for trusted data only. + */ + int flags = UCL_PARSER_NO_FILEVARS|UCL_PARSER_DISABLE_MACRO; if (lua_gettop (L) >= 1) { flags = lua_tonumber (L, 1); } parser = ucl_parser_new (flags); if (parser == NULL) { lua_pushnil (L); } pparser = lua_newuserdata (L, sizeof (parser)); *pparser = parser; luaL_getmetatable (L, PARSER_META); lua_setmetatable (L, -2); return 1; } static struct ucl_parser * lua_ucl_parser_get (lua_State *L, int index) { return *((struct ucl_parser **) luaL_checkudata(L, index, PARSER_META)); } static ucl_object_t * lua_ucl_object_get (lua_State *L, int index) { return *((ucl_object_t **) luaL_checkudata(L, index, OBJECT_META)); } static void lua_ucl_push_opaque (lua_State *L, ucl_object_t *obj) { ucl_object_t **pobj; pobj = lua_newuserdata (L, sizeof (*pobj)); *pobj = obj; luaL_getmetatable (L, OBJECT_META); lua_setmetatable (L, -2); } static inline enum ucl_parse_type lua_ucl_str_to_parse_type (const char *str) { enum ucl_parse_type type = UCL_PARSE_UCL; if (str != NULL) { if (strcasecmp (str, "msgpack") == 0) { type = UCL_PARSE_MSGPACK; } else if (strcasecmp (str, "sexp") == 0 || strcasecmp (str, "csexp") == 0) { type = UCL_PARSE_CSEXP; } else if (strcasecmp (str, "auto") == 0) { type = UCL_PARSE_AUTO; } } return type; } /*** * @method parser:parse_file(name) * Parse UCL object from file. * @param {string} name filename to parse * @return {bool[, string]} if res is `true` then file has been parsed successfully, otherwise an error string is also returned @example local parser = ucl.parser() local res,err = parser:parse_file('/some/file.conf') if not res then print('parser error: ' .. err) else -- Do something with object end */ static int lua_ucl_parser_parse_file (lua_State *L) { struct ucl_parser *parser; const char *file; int ret = 2; parser = lua_ucl_parser_get (L, 1); file = luaL_checkstring (L, 2); if (parser != NULL && file != NULL) { if (ucl_parser_add_file (parser, file)) { lua_pushboolean (L, true); ret = 1; } else { lua_pushboolean (L, false); lua_pushstring (L, ucl_parser_get_error (parser)); } } else { lua_pushboolean (L, false); lua_pushstring (L, "invalid arguments"); } return ret; } /*** * @method parser:register_variable(name, value) * Register parser variable * @param {string} name name of variable * @param {string} value value of variable * @return {bool} success @example local parser = ucl.parser() local res = parser:register_variable('CONFDIR', '/etc/foo') */ static int lua_ucl_parser_register_variable (lua_State *L) { struct ucl_parser *parser; const char *name, *value; int ret = 2; parser = lua_ucl_parser_get (L, 1); name = luaL_checkstring (L, 2); value = luaL_checkstring (L, 3); if (parser != NULL && name != NULL && value != NULL) { ucl_parser_register_variable (parser, name, value); lua_pushboolean (L, true); ret = 1; } else { return luaL_error (L, "invalid arguments"); } return ret; } /*** * @method parser:register_variables(vars) * Register parser variables * @param {table} vars names/values of variables * @return {bool} success @example local parser = ucl.parser() local res = parser:register_variables({CONFDIR = '/etc/foo', VARDIR = '/var'}) */ static int lua_ucl_parser_register_variables (lua_State *L) { struct ucl_parser *parser; const char *name, *value; int ret = 2; parser = lua_ucl_parser_get (L, 1); if (parser != NULL && lua_type (L, 2) == LUA_TTABLE) { for (lua_pushnil (L); lua_next (L, 2); lua_pop (L, 1)) { lua_pushvalue (L, -2); name = luaL_checkstring (L, -1); value = luaL_checkstring (L, -2); ucl_parser_register_variable (parser, name, value); lua_pop (L, 1); } lua_pushboolean (L, true); ret = 1; } else { return luaL_error (L, "invalid arguments"); } return ret; } /*** * @method parser:parse_string(input) * Parse UCL object from file. * @param {string} input string to parse * @return {bool[, string]} if res is `true` then file has been parsed successfully, otherwise an error string is also returned */ static int lua_ucl_parser_parse_string (lua_State *L) { struct ucl_parser *parser; const char *string; size_t llen; enum ucl_parse_type type = UCL_PARSE_UCL; int ret = 2; parser = lua_ucl_parser_get (L, 1); string = luaL_checklstring (L, 2, &llen); if (lua_type (L, 3) == LUA_TSTRING) { type = lua_ucl_str_to_parse_type (lua_tostring (L, 3)); } if (parser != NULL && string != NULL) { if (ucl_parser_add_chunk_full (parser, (const unsigned char *)string, llen, 0, UCL_DUPLICATE_APPEND, type)) { lua_pushboolean (L, true); ret = 1; } else { lua_pushboolean (L, false); lua_pushstring (L, ucl_parser_get_error (parser)); } } else { lua_pushboolean (L, false); lua_pushstring (L, "invalid arguments"); } return ret; } /*** * @method parser:parse_text(input) * Parse UCL object from text object (Rspamd specific). * @param {rspamd_text} input text to parse * @return {bool[, string]} if res is `true` then file has been parsed successfully, otherwise an error string is also returned */ static int lua_ucl_parser_parse_text (lua_State *L) { struct ucl_parser *parser; struct _rspamd_lua_text *t; enum ucl_parse_type type = UCL_PARSE_UCL; int ret = 2; parser = lua_ucl_parser_get (L, 1); if (lua_type (L, 2) == LUA_TUSERDATA) { t = lua_touserdata (L, 2); } else if (lua_type (L, 2) == LUA_TSTRING) { const char *s; size_t len; static struct _rspamd_lua_text st_t; s = lua_tolstring (L, 2, &len); st_t.start = s; st_t.len = len; t = &st_t; } else { return luaL_error(L, "invalid argument as input, expected userdata or a string"); } if (lua_type (L, 3) == LUA_TSTRING) { type = lua_ucl_str_to_parse_type (lua_tostring (L, 3)); } if (parser != NULL && t != NULL) { if (ucl_parser_add_chunk_full (parser, (const unsigned char *)t->start, t->len, 0, UCL_DUPLICATE_APPEND, type)) { lua_pushboolean (L, true); ret = 1; } else { lua_pushboolean (L, false); lua_pushstring (L, ucl_parser_get_error (parser)); } } else { lua_pushboolean (L, false); lua_pushstring (L, "invalid arguments"); } return ret; } /*** * @method parser:get_object() * Get top object from parser and export it to lua representation. * @return {variant or nil} ucl object as lua native variable */ static int lua_ucl_parser_get_object (lua_State *L) { struct ucl_parser *parser; ucl_object_t *obj; int ret = 1; parser = lua_ucl_parser_get (L, 1); obj = ucl_parser_get_object (parser); if (obj != NULL) { ret = ucl_object_push_lua (L, obj, false); /* no need to keep reference */ ucl_object_unref (obj); } else { lua_pushnil (L); } return ret; } /*** * @method parser:get_object_wrapped() * Get top object from parser and export it to userdata object without * unwrapping to lua. * @return {ucl.object or nil} ucl object wrapped variable */ static int lua_ucl_parser_get_object_wrapped (lua_State *L) { struct ucl_parser *parser; ucl_object_t *obj; int ret = 1; parser = lua_ucl_parser_get (L, 1); obj = ucl_parser_get_object (parser); if (obj != NULL) { lua_ucl_push_opaque (L, obj); } else { lua_pushnil (L); } return ret; } /*** * @method parser:validate(schema) * Validates the top object in the parser against schema. Schema might be * another object or a string that represents file to load schema from. * * @param {string/table} schema input schema * @return {result,err} two values: boolean result and the corresponding error * */ static int lua_ucl_parser_validate (lua_State *L) { struct ucl_parser *parser, *schema_parser; ucl_object_t *schema; const char *schema_file; struct ucl_schema_error err; parser = lua_ucl_parser_get (L, 1); if (parser && parser->top_obj) { if (lua_type (L, 2) == LUA_TTABLE) { schema = ucl_object_lua_import (L, 2); if (schema == NULL) { lua_pushboolean (L, false); lua_pushstring (L, "cannot load schema from lua table"); return 2; } } else if (lua_type (L, 2) == LUA_TSTRING) { schema_parser = ucl_parser_new (0); schema_file = luaL_checkstring (L, 2); if (!ucl_parser_add_file (schema_parser, schema_file)) { lua_pushboolean (L, false); lua_pushfstring (L, "cannot parse schema file \"%s\": " "%s", schema_file, ucl_parser_get_error (parser)); ucl_parser_free (schema_parser); return 2; } schema = ucl_parser_get_object (schema_parser); ucl_parser_free (schema_parser); } else { lua_pushboolean (L, false); lua_pushstring (L, "invalid schema argument"); return 2; } if (!ucl_object_validate (schema, parser->top_obj, &err)) { lua_pushboolean (L, false); lua_pushfstring (L, "validation error: " "%s", err.msg); } else { lua_pushboolean (L, true); lua_pushnil (L); } ucl_object_unref (schema); } else { lua_pushboolean (L, false); lua_pushstring (L, "invalid parser or empty top object"); } return 2; } static int lua_ucl_parser_gc (lua_State *L) { struct ucl_parser *parser; parser = lua_ucl_parser_get (L, 1); ucl_parser_free (parser); return 0; } /*** * @method object:unwrap() * Unwraps opaque ucl object to the native lua object (performing copying) * @return {variant} any lua object */ static int lua_ucl_object_unwrap (lua_State *L) { ucl_object_t *obj; obj = lua_ucl_object_get (L, 1); if (obj) { ucl_object_push_lua (L, obj, true); } else { lua_pushnil (L); } return 1; } static inline enum ucl_emitter lua_ucl_str_to_emit_type (const char *strtype) { enum ucl_emitter format = UCL_EMIT_JSON_COMPACT; if (strcasecmp (strtype, "json") == 0) { format = UCL_EMIT_JSON; } else if (strcasecmp (strtype, "json-compact") == 0) { format = UCL_EMIT_JSON_COMPACT; } else if (strcasecmp (strtype, "yaml") == 0) { format = UCL_EMIT_YAML; } else if (strcasecmp (strtype, "config") == 0 || strcasecmp (strtype, "ucl") == 0) { format = UCL_EMIT_CONFIG; } return format; } /*** * @method object:tostring(type) * Unwraps opaque ucl object to string (json by default). Optionally you can * specify output format: * * - `json` - fine printed json * - `json-compact` - compacted json * - `config` - fine printed configuration * - `ucl` - same as `config` * - `yaml` - embedded yaml * @param {string} type optional * @return {string} string representation of the opaque ucl object */ static int lua_ucl_object_tostring (lua_State *L) { ucl_object_t *obj; enum ucl_emitter format = UCL_EMIT_JSON_COMPACT; obj = lua_ucl_object_get (L, 1); if (obj) { if (lua_gettop (L) > 1) { if (lua_type (L, 2) == LUA_TSTRING) { const char *strtype = lua_tostring (L, 2); format = lua_ucl_str_to_emit_type (strtype); } } return lua_ucl_to_string (L, obj, format); } else { lua_pushnil (L); } return 1; } /*** * @method object:validate(schema[, path[, ext_refs]]) * Validates the given ucl object using schema object represented as another * opaque ucl object. You can also specify path in the form `#/path/def` to * specify the specific schema element to perform validation. * * @param {ucl.object} schema schema object * @param {string} path optional path for validation procedure * @return {result,err} two values: boolean result and the corresponding * error, if `ext_refs` are also specified, then they are returned as opaque * ucl object as {result,err,ext_refs} */ static int lua_ucl_object_validate (lua_State *L) { ucl_object_t *obj, *schema, *ext_refs = NULL; const ucl_object_t *schema_elt; bool res = false; struct ucl_schema_error err; const char *path = NULL; obj = lua_ucl_object_get (L, 1); schema = lua_ucl_object_get (L, 2); if (schema && obj && ucl_object_type (schema) == UCL_OBJECT) { if (lua_gettop (L) > 2) { if (lua_type (L, 3) == LUA_TSTRING) { path = lua_tostring (L, 3); if (path[0] == '#') { path++; } } else if (lua_type (L, 3) == LUA_TUSERDATA || lua_type (L, 3) == LUA_TTABLE) { /* External refs */ ext_refs = lua_ucl_object_get (L, 3); } if (lua_gettop (L) > 3) { if (lua_type (L, 4) == LUA_TUSERDATA || lua_type (L, 4) == LUA_TTABLE) { /* External refs */ ext_refs = lua_ucl_object_get (L, 4); } } } if (path) { schema_elt = ucl_object_lookup_path_char (schema, path, '/'); } else { /* Use the top object */ schema_elt = schema; } if (schema_elt) { res = ucl_object_validate_root_ext (schema_elt, obj, schema, ext_refs, &err); if (res) { lua_pushboolean (L, res); lua_pushnil (L); if (ext_refs) { lua_ucl_push_opaque (L, ext_refs); } } else { lua_pushboolean (L, res); lua_pushfstring (L, "validation error: %s", err.msg); if (ext_refs) { lua_ucl_push_opaque (L, ext_refs); } } } else { lua_pushboolean (L, res); lua_pushfstring (L, "cannot find the requested path: %s", path); if (ext_refs) { lua_ucl_push_opaque (L, ext_refs); } } } else { lua_pushboolean (L, res); lua_pushstring (L, "invalid object or schema"); } if (ext_refs) { return 3; } return 2; } static int lua_ucl_object_gc (lua_State *L) { ucl_object_t *obj; obj = lua_ucl_object_get (L, 1); ucl_object_unref (obj); return 0; } static void lua_ucl_parser_mt (lua_State *L) { luaL_newmetatable (L, PARSER_META); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); lua_pushcfunction (L, lua_ucl_parser_gc); lua_setfield (L, -2, "__gc"); lua_pushcfunction (L, lua_ucl_parser_parse_file); lua_setfield (L, -2, "parse_file"); lua_pushcfunction (L, lua_ucl_parser_parse_string); lua_setfield (L, -2, "parse_string"); lua_pushcfunction (L, lua_ucl_parser_parse_text); lua_setfield (L, -2, "parse_text"); lua_pushcfunction (L, lua_ucl_parser_register_variable); lua_setfield (L, -2, "register_variable"); lua_pushcfunction (L, lua_ucl_parser_register_variables); lua_setfield (L, -2, "register_variables"); lua_pushcfunction (L, lua_ucl_parser_get_object); lua_setfield (L, -2, "get_object"); lua_pushcfunction (L, lua_ucl_parser_get_object_wrapped); lua_setfield (L, -2, "get_object_wrapped"); lua_pushcfunction (L, lua_ucl_parser_validate); lua_setfield (L, -2, "validate"); lua_pop (L, 1); } static void lua_ucl_object_mt (lua_State *L) { luaL_newmetatable (L, OBJECT_META); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); lua_pushcfunction (L, lua_ucl_object_gc); lua_setfield (L, -2, "__gc"); lua_pushcfunction (L, lua_ucl_object_tostring); lua_setfield (L, -2, "__tostring"); lua_pushcfunction (L, lua_ucl_object_tostring); lua_setfield (L, -2, "tostring"); lua_pushcfunction (L, lua_ucl_object_unwrap); lua_setfield (L, -2, "unwrap"); lua_pushcfunction (L, lua_ucl_object_unwrap); lua_setfield (L, -2, "tolua"); lua_pushcfunction (L, lua_ucl_object_validate); lua_setfield (L, -2, "validate"); lua_pushstring (L, OBJECT_META); lua_setfield (L, -2, "class"); lua_pop (L, 1); } static void lua_ucl_types_mt (lua_State *L) { luaL_newmetatable (L, UCL_OBJECT_TYPE_META); lua_pushcfunction (L, lua_ucl_object_tostring); lua_setfield (L, -2, "__tostring"); lua_pushcfunction (L, lua_ucl_object_tostring); lua_setfield (L, -2, "tostring"); lua_pushstring (L, UCL_OBJECT_TYPE_META); lua_setfield (L, -2, "class"); lua_pop (L, 1); luaL_newmetatable (L, UCL_ARRAY_TYPE_META); lua_pushcfunction (L, lua_ucl_object_tostring); lua_setfield (L, -2, "__tostring"); lua_pushcfunction (L, lua_ucl_object_tostring); lua_setfield (L, -2, "tostring"); lua_pushstring (L, UCL_ARRAY_TYPE_META); lua_setfield (L, -2, "class"); lua_pop (L, 1); luaL_newmetatable (L, UCL_IMPL_ARRAY_TYPE_META); lua_pushcfunction (L, lua_ucl_object_tostring); lua_setfield (L, -2, "__tostring"); lua_pushcfunction (L, lua_ucl_object_tostring); lua_setfield (L, -2, "tostring"); lua_pushstring (L, UCL_IMPL_ARRAY_TYPE_META); lua_setfield (L, -2, "class"); lua_pop (L, 1); } static int lua_ucl_to_json (lua_State *L) { ucl_object_t *obj; int format = UCL_EMIT_JSON; if (lua_gettop (L) > 1) { if (lua_toboolean (L, 2)) { format = UCL_EMIT_JSON_COMPACT; } } obj = ucl_object_lua_import (L, 1); if (obj != NULL) { lua_ucl_to_string (L, obj, format); ucl_object_unref (obj); } else { lua_pushnil (L); } return 1; } static int lua_ucl_to_config (lua_State *L) { ucl_object_t *obj; obj = ucl_object_lua_import (L, 1); if (obj != NULL) { lua_ucl_to_string (L, obj, UCL_EMIT_CONFIG); ucl_object_unref (obj); } else { lua_pushnil (L); } return 1; } /*** * @function ucl.to_format(var, format) * Converts lua variable `var` to the specified `format`. Formats supported are: * * - `json` - fine printed json * - `json-compact` - compacted json * - `config` - fine printed configuration * - `ucl` - same as `config` * - `yaml` - embedded yaml * * If `var` contains function, they are called during output formatting and if * they return string value, then this value is used for output. * @param {variant} var any sort of lua variable (if userdata then metafield `__to_ucl` is searched for output) * @param {string} format any available format * @return {string} string representation of `var` in the specific `format`. * @example local table = { str = 'value', num = 100500, null = ucl.null, func = function () return 'huh' end } print(ucl.to_format(table, 'ucl')) -- Output: --[[ num = 100500; str = "value"; null = null; func = "huh"; --]] */ static int lua_ucl_to_format (lua_State *L) { ucl_object_t *obj; int format = UCL_EMIT_JSON; bool sort = false; if (lua_gettop (L) > 1) { if (lua_type (L, 2) == LUA_TNUMBER) { format = lua_tonumber (L, 2); if (format < 0 || format >= UCL_EMIT_YAML) { lua_pushnil (L); return 1; } } else if (lua_type (L, 2) == LUA_TSTRING) { const char *strtype = lua_tostring (L, 2); if (strcasecmp (strtype, "json") == 0) { format = UCL_EMIT_JSON; } else if (strcasecmp (strtype, "json-compact") == 0) { format = UCL_EMIT_JSON_COMPACT; } else if (strcasecmp (strtype, "yaml") == 0) { format = UCL_EMIT_YAML; } else if (strcasecmp (strtype, "config") == 0 || strcasecmp (strtype, "ucl") == 0) { format = UCL_EMIT_CONFIG; } else if (strcasecmp (strtype, "msgpack") == 0 || strcasecmp (strtype, "messagepack") == 0) { format = UCL_EMIT_MSGPACK; } } if (lua_isboolean (L, 3)) { sort = lua_toboolean (L, 3); } } obj = ucl_object_lua_import (L, 1); if (obj != NULL) { if (sort) { if (ucl_object_type (obj) == UCL_OBJECT) { ucl_object_sort_keys (obj, UCL_SORT_KEYS_RECURSIVE); } } lua_ucl_to_string (L, obj, format); ucl_object_unref (obj); } else { lua_pushnil (L); } return 1; } static int lua_ucl_null_tostring (lua_State* L) { lua_pushstring (L, "null"); return 1; } static void lua_ucl_null_mt (lua_State *L) { luaL_newmetatable (L, NULL_META); lua_pushcfunction (L, lua_ucl_null_tostring); lua_setfield (L, -2, "__tostring"); lua_pop (L, 1); } int luaopen_ucl (lua_State *L) { lua_ucl_parser_mt (L); lua_ucl_null_mt (L); lua_ucl_object_mt (L); lua_ucl_types_mt (L); /* Create the refs weak table: */ lua_createtable (L, 0, 2); lua_pushliteral (L, "v"); /* tbl, "v" */ lua_setfield (L, -2, "__mode"); lua_pushvalue (L, -1); /* tbl, tbl */ lua_setmetatable (L, -2); /* tbl */ lua_setfield (L, LUA_REGISTRYINDEX, "ucl.refs"); lua_newtable (L); lua_pushcfunction (L, lua_ucl_parser_init); lua_setfield (L, -2, "parser"); lua_pushcfunction (L, lua_ucl_to_json); lua_setfield (L, -2, "to_json"); lua_pushcfunction (L, lua_ucl_to_config); lua_setfield (L, -2, "to_config"); lua_pushcfunction (L, lua_ucl_to_format); lua_setfield (L, -2, "to_format"); ucl_null = lua_newuserdata (L, 0); luaL_getmetatable (L, NULL_META); lua_setmetatable (L, -2); lua_pushvalue (L, -1); lua_setfield (L, LUA_REGISTRYINDEX, "ucl.null"); lua_setfield (L, -2, "null"); return 1; } struct ucl_lua_funcdata* ucl_object_toclosure (const ucl_object_t *obj) { if (obj == NULL || obj->type != UCL_USERDATA) { return NULL; } return (struct ucl_lua_funcdata*)obj->value.ud; } FLUA_MODULE(ucl); diff --git a/contrib/libucl/src/mum.h b/contrib/libucl/src/mum.h index 318efea50268..aa1ed2d840a3 100644 --- a/contrib/libucl/src/mum.h +++ b/contrib/libucl/src/mum.h @@ -1,417 +1,440 @@ /* Copyright (c) 2016 Vladimir Makarov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* This file implements MUM (MUltiply and Mix) hashing. We randomize input data by 64x64-bit multiplication and mixing hi- and low-parts of the multiplication result by using an addition and then mix it into the current state. We use prime numbers randomly generated with the equal probability of their bit values for the multiplication. When all primes are used once, the state is randomized and the same prime numbers are used again for data randomization. The MUM hashing passes all SMHasher tests. Pseudo Random Number Generator based on MUM also passes NIST Statistical Test Suite for Random and Pseudorandom Number Generators for Cryptographic Applications (version 2.2.1) with 1000 bitstreams each containing 1M bits. MUM hashing is also faster Spooky64 and City64 on small strings (at least up to 512-bit) on Haswell and Power7. The MUM bulk speed (speed on very long data) is bigger than Spooky and City on Power7. On Haswell the bulk speed is bigger than Spooky one and close to City speed. */ #ifndef __MUM_HASH__ #define __MUM_HASH__ #include #include #include #include #ifdef _MSC_VER typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #else #include #endif /* Macro saying to use 128-bit integers implemented by GCC for some targets. */ #ifndef _MUM_USE_INT128 /* In GCC uint128_t is defined if HOST_BITS_PER_WIDE_INT >= 64. HOST_WIDE_INT is long if HOST_BITS_PER_LONG > HOST_BITS_PER_INT, otherwise int. */ #if defined(__GNUC__) && UINT_MAX != ULONG_MAX #define _MUM_USE_INT128 1 #else #define _MUM_USE_INT128 0 #endif #endif -#if defined(__GNUC__) && ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9) || (__GNUC__ > 4)) +#if defined(__GNUC__) && ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9) || (__GNUC__ > 4)) #define _MUM_FRESH_GCC #endif #if defined(__GNUC__) && !defined(__llvm__) && defined(_MUM_FRESH_GCC) -#define _MUM_ATTRIBUTE_UNUSED __attribute__((unused)) -#define _MUM_OPTIMIZE(opts) __attribute__((__optimize__ (opts))) -#define _MUM_TARGET(opts) __attribute__((__target__ (opts))) +#define _MUM_ATTRIBUTE_UNUSED __attribute__((unused)) +#define _MUM_OPTIMIZE(opts) __attribute__((__optimize__(opts))) +#define _MUM_TARGET(opts) __attribute__((__target__(opts))) #else #define _MUM_ATTRIBUTE_UNUSED #define _MUM_OPTIMIZE(opts) #define _MUM_TARGET(opts) #endif /* Here are different primes randomly generated with the equal probability of their bit values. They are used to randomize input values. */ static uint64_t _mum_hash_step_prime = 0x2e0bb864e9ea7df5ULL; static uint64_t _mum_key_step_prime = 0xcdb32970830fcaa1ULL; static uint64_t _mum_block_start_prime = 0xc42b5e2e6480b23bULL; static uint64_t _mum_unroll_prime = 0x7b51ec3d22f7096fULL; static uint64_t _mum_tail_prime = 0xaf47d47c99b1461bULL; static uint64_t _mum_finish_prime1 = 0xa9a7ae7ceff79f3fULL; static uint64_t _mum_finish_prime2 = 0xaf47d47c99b1461bULL; -static uint64_t _mum_primes [] = { - 0X9ebdcae10d981691, 0X32b9b9b97a27ac7d, 0X29b5584d83d35bbd, 0X4b04e0e61401255f, - 0X25e8f7b1f1c9d027, 0X80d4c8c000f3e881, 0Xbd1255431904b9dd, 0X8a3bd4485eee6d81, - 0X3bc721b2aad05197, 0X71b1a19b907d6e33, 0X525e6c1084a8534b, 0X9e4c2cd340c1299f, - 0Xde3add92e94caa37, 0X7e14eadb1f65311d, 0X3f5aa40f89812853, 0X33b15a3b587d15c9, +static uint64_t _mum_primes[] = { + 0X9ebdcae10d981691, + 0X32b9b9b97a27ac7d, + 0X29b5584d83d35bbd, + 0X4b04e0e61401255f, + 0X25e8f7b1f1c9d027, + 0X80d4c8c000f3e881, + 0Xbd1255431904b9dd, + 0X8a3bd4485eee6d81, + 0X3bc721b2aad05197, + 0X71b1a19b907d6e33, + 0X525e6c1084a8534b, + 0X9e4c2cd340c1299f, + 0Xde3add92e94caa37, + 0X7e14eadb1f65311d, + 0X3f5aa40f89812853, + 0X33b15a3b587d15c9, }; /* Multiply 64-bit V and P and return sum of high and low parts of the result. */ static inline uint64_t -_mum (uint64_t v, uint64_t p) { - uint64_t hi, lo; +_mum(uint64_t v, uint64_t p) +{ + uint64_t hi, lo; #if _MUM_USE_INT128 #if defined(__aarch64__) - /* AARCH64 needs 2 insns to calculate 128-bit result of the + /* AARCH64 needs 2 insns to calculate 128-bit result of the multiplication. If we use a generic code we actually call a function doing 128x128->128 bit multiplication. The function is very slow. */ - lo = v * p, hi; - asm ("umulh %0, %1, %2" : "=r" (hi) : "r" (v), "r" (p)); + lo = v * p, hi; + asm("umulh %0, %1, %2" : "=r"(hi) : "r"(v), "r"(p)); #else - __uint128_t r = (__uint128_t) v * (__uint128_t) p; - hi = (uint64_t) (r >> 64); - lo = (uint64_t) r; + __uint128_t r = (__uint128_t) v * (__uint128_t) p; + hi = (uint64_t) (r >> 64); + lo = (uint64_t) r; #endif #else - /* Implementation of 64x64->128-bit multiplication by four 32x32->64 + /* Implementation of 64x64->128-bit multiplication by four 32x32->64 bit multiplication. */ - uint64_t hv = v >> 32, hp = p >> 32; - uint64_t lv = (uint32_t) v, lp = (uint32_t) p; - uint64_t rh = hv * hp; - uint64_t rm_0 = hv * lp; - uint64_t rm_1 = hp * lv; - uint64_t rl = lv * lp; - uint64_t t, carry = 0; - - /* We could ignore a carry bit here if we did not care about the + uint64_t hv = v >> 32, hp = p >> 32; + uint64_t lv = (uint32_t) v, lp = (uint32_t) p; + uint64_t rh = hv * hp; + uint64_t rm_0 = hv * lp; + uint64_t rm_1 = hp * lv; + uint64_t rl = lv * lp; + uint64_t t, carry = 0; + + /* We could ignore a carry bit here if we did not care about the same hash for 32-bit and 64-bit targets. */ - t = rl + (rm_0 << 32); + t = rl + (rm_0 << 32); #ifdef MUM_TARGET_INDEPENDENT_HASH - carry = t < rl; + carry = t < rl; #endif - lo = t + (rm_1 << 32); + lo = t + (rm_1 << 32); #ifdef MUM_TARGET_INDEPENDENT_HASH - carry += lo < t; + carry += lo < t; #endif - hi = rh + (rm_0 >> 32) + (rm_1 >> 32) + carry; + hi = rh + (rm_0 >> 32) + (rm_1 >> 32) + carry; #endif - /* We could use XOR here too but, for some reasons, on Haswell and + /* We could use XOR here too but, for some reasons, on Haswell and Power7 using an addition improves hashing performance by 10% for small strings. */ - return hi + lo; + return hi + lo; } #if defined(_MSC_VER) -#define _mum_bswap_32(x) _byteswap_uint32_t (x) -#define _mum_bswap_64(x) _byteswap_uint64_t (x) +#define _mum_bswap_32(x) _byteswap_uint32_t(x) +#define _mum_bswap_64(x) _byteswap_uint64_t(x) #elif defined(__APPLE__) #include -#define _mum_bswap_32(x) OSSwapInt32 (x) -#define _mum_bswap_64(x) OSSwapInt64 (x) +#define _mum_bswap_32(x) OSSwapInt32(x) +#define _mum_bswap_64(x) OSSwapInt64(x) #elif defined(__GNUC__) -#define _mum_bswap32(x) __builtin_bswap32 (x) -#define _mum_bswap64(x) __builtin_bswap64 (x) +#define _mum_bswap32(x) __builtin_bswap32(x) +#define _mum_bswap64(x) __builtin_bswap64(x) #else #include -#define _mum_bswap32(x) bswap32 (x) -#define _mum_bswap64(x) bswap64 (x) +#define _mum_bswap32(x) bswap32(x) +#define _mum_bswap64(x) bswap64(x) #endif static inline uint64_t -_mum_le (uint64_t v) { +_mum_le(uint64_t v) +{ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || !defined(MUM_TARGET_INDEPENDENT_HASH) - return v; + return v; #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - return _mum_bswap64 (v); + return _mum_bswap64(v); #else #error "Unknown endianness" #endif } static inline uint32_t -_mum_le32 (uint32_t v) { +_mum_le32(uint32_t v) +{ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || !defined(MUM_TARGET_INDEPENDENT_HASH) - return v; + return v; #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - return _mum_bswap32 (v); + return _mum_bswap32(v); #else #error "Unknown endianness" #endif } /* Macro defining how many times the most nested loop in _mum_hash_aligned will be unrolled by the compiler (although it can make an own decision:). Use only a constant here to help a compiler to unroll a major loop. The macro value affects the result hash for strings > 128 bit. The unroll factor greatly affects the hashing speed. We prefer the speed. */ #ifndef _MUM_UNROLL_FACTOR_POWER #if defined(__PPC64__) && !defined(MUM_TARGET_INDEPENDENT_HASH) #define _MUM_UNROLL_FACTOR_POWER 3 #elif defined(__aarch64__) && !defined(MUM_TARGET_INDEPENDENT_HASH) #define _MUM_UNROLL_FACTOR_POWER 4 #else #define _MUM_UNROLL_FACTOR_POWER 2 #endif #endif #if _MUM_UNROLL_FACTOR_POWER < 1 #error "too small unroll factor" #elif _MUM_UNROLL_FACTOR_POWER > 4 #error "We have not enough primes for such unroll factor" #endif #define _MUM_UNROLL_FACTOR (1 << _MUM_UNROLL_FACTOR_POWER) static inline uint64_t _MUM_OPTIMIZE("unroll-loops") -_mum_hash_aligned (uint64_t start, const void *key, size_t len) { - uint64_t result = start; - const unsigned char *str = (const unsigned char *) key; - uint64_t u64; - int i; - size_t n; - - result = _mum (result, _mum_block_start_prime); - while (len > _MUM_UNROLL_FACTOR * sizeof (uint64_t)) { - /* This loop could be vectorized when we have vector insns for + _mum_hash_aligned(uint64_t start, const void *key, size_t len) +{ + uint64_t result = start; + const unsigned char *str = (const unsigned char *) key; + uint64_t u64; + int i; + size_t n; + + result = _mum(result, _mum_block_start_prime); + while (len > _MUM_UNROLL_FACTOR * sizeof(uint64_t)) { + /* This loop could be vectorized when we have vector insns for 64x64->128-bit multiplication. AVX2 currently only have a vector insn for 4 32x32->64-bit multiplication. */ - for (i = 0; i < _MUM_UNROLL_FACTOR; i++) - result ^= _mum (_mum_le (((uint64_t *) str)[i]), _mum_primes[i]); - len -= _MUM_UNROLL_FACTOR * sizeof (uint64_t); - str += _MUM_UNROLL_FACTOR * sizeof (uint64_t); - /* We will use the same prime numbers on the next iterations -- + for (i = 0; i < _MUM_UNROLL_FACTOR; i++) + result ^= _mum(_mum_le(((uint64_t *) str)[i]), _mum_primes[i]); + len -= _MUM_UNROLL_FACTOR * sizeof(uint64_t); + str += _MUM_UNROLL_FACTOR * sizeof(uint64_t); + /* We will use the same prime numbers on the next iterations -- randomize the state. */ - result = _mum (result, _mum_unroll_prime); - } - n = len / sizeof (uint64_t); - for (i = 0; i < (int)n; i++) - result ^= _mum (_mum_le (((uint64_t *) str)[i]), _mum_primes[i]); - len -= n * sizeof (uint64_t); str += n * sizeof (uint64_t); - switch (len) { - case 7: - u64 = _mum_le32 (*(uint32_t *) str); - u64 |= (uint64_t) str[4] << 32; - u64 |= (uint64_t) str[5] << 40; - u64 |= (uint64_t) str[6] << 48; - return result ^ _mum (u64, _mum_tail_prime); - case 6: - u64 = _mum_le32 (*(uint32_t *) str); - u64 |= (uint64_t) str[4] << 32; - u64 |= (uint64_t) str[5] << 40; - return result ^ _mum (u64, _mum_tail_prime); - case 5: - u64 = _mum_le32 (*(uint32_t *) str); - u64 |= (uint64_t) str[4] << 32; - return result ^ _mum (u64, _mum_tail_prime); - case 4: - u64 = _mum_le32 (*(uint32_t *) str); - return result ^ _mum (u64, _mum_tail_prime); - case 3: - u64 = str[0]; - u64 |= (uint64_t) str[1] << 8; - u64 |= (uint64_t) str[2] << 16; - return result ^ _mum (u64, _mum_tail_prime); - case 2: - u64 = str[0]; - u64 |= (uint64_t) str[1] << 8; - return result ^ _mum (u64, _mum_tail_prime); - case 1: - u64 = str[0]; - return result ^ _mum (u64, _mum_tail_prime); - } - return result; + result = _mum(result, _mum_unroll_prime); + } + n = len / sizeof(uint64_t); + for (i = 0; i < (int) n; i++) + result ^= _mum(_mum_le(((uint64_t *) str)[i]), _mum_primes[i]); + len -= n * sizeof(uint64_t); + str += n * sizeof(uint64_t); + switch (len) { + case 7: + u64 = _mum_le32(*(uint32_t *) str); + u64 |= (uint64_t) str[4] << 32; + u64 |= (uint64_t) str[5] << 40; + u64 |= (uint64_t) str[6] << 48; + return result ^ _mum(u64, _mum_tail_prime); + case 6: + u64 = _mum_le32(*(uint32_t *) str); + u64 |= (uint64_t) str[4] << 32; + u64 |= (uint64_t) str[5] << 40; + return result ^ _mum(u64, _mum_tail_prime); + case 5: + u64 = _mum_le32(*(uint32_t *) str); + u64 |= (uint64_t) str[4] << 32; + return result ^ _mum(u64, _mum_tail_prime); + case 4: + u64 = _mum_le32(*(uint32_t *) str); + return result ^ _mum(u64, _mum_tail_prime); + case 3: + u64 = str[0]; + u64 |= (uint64_t) str[1] << 8; + u64 |= (uint64_t) str[2] << 16; + return result ^ _mum(u64, _mum_tail_prime); + case 2: + u64 = str[0]; + u64 |= (uint64_t) str[1] << 8; + return result ^ _mum(u64, _mum_tail_prime); + case 1: + u64 = str[0]; + return result ^ _mum(u64, _mum_tail_prime); + } + return result; } /* Final randomization of H. */ static inline uint64_t -_mum_final (uint64_t h) { - h ^= _mum (h, _mum_finish_prime1); - h ^= _mum (h, _mum_finish_prime2); - return h; +_mum_final(uint64_t h) +{ + h ^= _mum(h, _mum_finish_prime1); + h ^= _mum(h, _mum_finish_prime2); + return h; } #if defined(__x86_64__) && defined(_MUM_FRESH_GCC) /* We want to use AVX2 insn MULX instead of generic x86-64 MULQ where it is possible. Although on modern Intel processors MULQ takes 3-cycles vs. 4 for MULX, MULX permits more freedom in insn scheduling as it uses less fixed registers. */ static inline uint64_t _MUM_TARGET("arch=haswell") -_mum_hash_avx2 (const void * key, size_t len, uint64_t seed) { - return _mum_final (_mum_hash_aligned (seed + len, key, len)); + _mum_hash_avx2(const void *key, size_t len, uint64_t seed) +{ + return _mum_final(_mum_hash_aligned(seed + len, key, len)); } #endif #ifndef _MUM_UNALIGNED_ACCESS -#if defined(__x86_64__) || defined(__i386__) || defined(__PPC64__) \ - || defined(__s390__) || defined(__m32c__) || defined(cris) \ - || defined(__CR16__) || defined(__vax__) || defined(__m68k__) \ - || defined(__aarch64__) +#if defined(__x86_64__) || defined(__i386__) || defined(__PPC64__) || defined(__s390__) || defined(__m32c__) || defined(cris) || defined(__CR16__) || defined(__vax__) || defined(__m68k__) || defined(__aarch64__) #define _MUM_UNALIGNED_ACCESS 1 #else #define _MUM_UNALIGNED_ACCESS 0 #endif #endif /* When we need an aligned access to data being hashed we move part of the unaligned data to an aligned block of given size and then process it, repeating processing the data by the block. */ #ifndef _MUM_BLOCK_LEN #define _MUM_BLOCK_LEN 1024 #endif #if _MUM_BLOCK_LEN < 8 #error "too small block length" #endif static inline uint64_t #if defined(__x86_64__) -_MUM_TARGET("inline-all-stringops") + _MUM_TARGET("inline-all-stringops") #endif -_mum_hash_default (const void *key, size_t len, uint64_t seed) { - uint64_t result; - const unsigned char *str = (const unsigned char *) key; - size_t block_len; - uint64_t buf[_MUM_BLOCK_LEN / sizeof (uint64_t)]; - - result = seed + len; - if (_MUM_UNALIGNED_ACCESS || ((size_t) str & 0x7) == 0) - result = _mum_hash_aligned (result, key, len); - else { - while (len != 0) { - block_len = len < _MUM_BLOCK_LEN ? len : _MUM_BLOCK_LEN; - memmove (buf, str, block_len); - result = _mum_hash_aligned (result, buf, block_len); - len -= block_len; - str += block_len; - } - } - return _mum_final (result); + _mum_hash_default(const void *key, size_t len, uint64_t seed) +{ + uint64_t result; + const unsigned char *str = (const unsigned char *) key; + size_t block_len; + uint64_t buf[_MUM_BLOCK_LEN / sizeof(uint64_t)]; + + result = seed + len; + if (_MUM_UNALIGNED_ACCESS || ((size_t) str & 0x7) == 0) + result = _mum_hash_aligned(result, key, len); + else { + while (len != 0) { + block_len = len < _MUM_BLOCK_LEN ? len : _MUM_BLOCK_LEN; + memmove(buf, str, block_len); + result = _mum_hash_aligned(result, buf, block_len); + len -= block_len; + str += block_len; + } + } + return _mum_final(result); } static inline uint64_t -_mum_next_factor (void) { - uint64_t start = 0; - int i; +_mum_next_factor(void) +{ + uint64_t start = 0; + int i; - for (i = 0; i < 8; i++) - start = (start << 8) | rand() % 256; - return start; + for (i = 0; i < 8; i++) + start = (start << 8) | rand() % 256; + return start; } /* ++++++++++++++++++++++++++ Interface functions: +++++++++++++++++++ */ /* Set random multiplicators depending on SEED. */ static inline void -mum_hash_randomize (uint64_t seed) { - int i; - - srand (seed); - _mum_hash_step_prime = _mum_next_factor (); - _mum_key_step_prime = _mum_next_factor (); - _mum_finish_prime1 = _mum_next_factor (); - _mum_finish_prime2 = _mum_next_factor (); - _mum_block_start_prime = _mum_next_factor (); - _mum_unroll_prime = _mum_next_factor (); - _mum_tail_prime = _mum_next_factor (); - for (i = 0; i < (int)(sizeof (_mum_primes) / sizeof (uint64_t)); i++) - _mum_primes[i] = _mum_next_factor (); +mum_hash_randomize(uint64_t seed) +{ + int i; + + srand(seed); + _mum_hash_step_prime = _mum_next_factor(); + _mum_key_step_prime = _mum_next_factor(); + _mum_finish_prime1 = _mum_next_factor(); + _mum_finish_prime2 = _mum_next_factor(); + _mum_block_start_prime = _mum_next_factor(); + _mum_unroll_prime = _mum_next_factor(); + _mum_tail_prime = _mum_next_factor(); + for (i = 0; i < (int) (sizeof(_mum_primes) / sizeof(uint64_t)); i++) + _mum_primes[i] = _mum_next_factor(); } /* Start hashing data with SEED. Return the state. */ static inline uint64_t -mum_hash_init (uint64_t seed) { - return seed; +mum_hash_init(uint64_t seed) +{ + return seed; } /* Process data KEY with the state H and return the updated state. */ static inline uint64_t -mum_hash_step (uint64_t h, uint64_t key) +mum_hash_step(uint64_t h, uint64_t key) { - return _mum (h, _mum_hash_step_prime) ^ _mum (key, _mum_key_step_prime); + return _mum(h, _mum_hash_step_prime) ^ _mum(key, _mum_key_step_prime); } /* Return the result of hashing using the current state H. */ static inline uint64_t -mum_hash_finish (uint64_t h) { - return _mum_final (h); +mum_hash_finish(uint64_t h) +{ + return _mum_final(h); } /* Fast hashing of KEY with SEED. The hash is always the same for the same key on any target. */ static inline size_t -mum_hash64 (uint64_t key, uint64_t seed) { - return mum_hash_finish (mum_hash_step (mum_hash_init (seed), key)); +mum_hash64(uint64_t key, uint64_t seed) +{ + return mum_hash_finish(mum_hash_step(mum_hash_init(seed), key)); } /* Hash data KEY of length LEN and SEED. The hash depends on the target endianness and the unroll factor. */ static inline uint64_t -mum_hash (const void *key, size_t len, uint64_t seed) { +mum_hash(const void *key, size_t len, uint64_t seed) +{ #if defined(__x86_64__) && defined(_MUM_FRESH_GCC) - static int avx2_support = 0; - - if (avx2_support > 0) - return _mum_hash_avx2 (key, len, seed); - else if (! avx2_support) { - __builtin_cpu_init (); - avx2_support = __builtin_cpu_supports ("avx2") ? 1 : -1; - if (avx2_support > 0) - return _mum_hash_avx2 (key, len, seed); - } + static int avx2_support = 0; + + if (avx2_support > 0) + return _mum_hash_avx2(key, len, seed); + else if (!avx2_support) { + __builtin_cpu_init(); + avx2_support = __builtin_cpu_supports("avx2") ? 1 : -1; + if (avx2_support > 0) + return _mum_hash_avx2(key, len, seed); + } #endif - return _mum_hash_default (key, len, seed); + return _mum_hash_default(key, len, seed); } #endif diff --git a/contrib/libucl/src/tree.h b/contrib/libucl/src/tree.h index 404b4a867be9..bb5fe46ff6a9 100644 --- a/contrib/libucl/src/tree.h +++ b/contrib/libucl/src/tree.h @@ -1,219 +1,209 @@ /* tree.h -- AVL trees (in the spirit of BSD's 'queue.h') -*- C -*- */ /* Copyright (c) 2005 Ian Piumarta * * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the 'Software'), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, and/or sell copies of the * Software, and to permit persons to whom the Software is furnished to do so, * provided that the above copyright notice(s) and this permission notice appear * in all copies of the Software and that both the above copyright notice(s) and * this permission notice appear in supporting documentation. * * THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK. */ /* This file defines an AVL balanced binary tree [Georgii M. Adelson-Velskii and * Evgenii M. Landis, 'An algorithm for the organization of information', * Doklady Akademii Nauk SSSR, 146:263-266, 1962 (Russian). Also in Myron * J. Ricci (trans.), Soviet Math, 3:1259-1263, 1962 (English)]. * * An AVL tree is headed by pointers to the root node and to a function defining * the ordering relation between nodes. Each node contains an arbitrary payload * plus three fields per tree entry: the depth of the subtree for which it forms * the root and two pointers to child nodes (singly-linked for minimum space, at * the expense of direct access to the parent node given a pointer to one of the * children). The tree is rebalanced after every insertion or removal. The * tree may be traversed in two directions: forward (in-order left-to-right) and * reverse (in-order, right-to-left). * * Because of the recursive nature of many of the operations on trees it is * necessary to define a number of helper functions for each type of tree node. * The macro TREE_DEFINE(node_tag, entry_name) defines these functions with * unique names according to the node_tag. This macro should be invoked, * thereby defining the necessary functions, once per node tag in the program. * * For details on the use of these macros, see the tree(3) manual page. */ #ifndef __tree_h #define __tree_h -#define TREE_DELTA_MAX 1 +#define TREE_DELTA_MAX 1 #ifndef _HU_FUNCTION -# if defined(__GNUC__) || defined(__clang__) -# define _HU_FUNCTION(x) __attribute__((__unused__)) x -# else -# define _HU_FUNCTION(x) x -# endif +#if defined(__GNUC__) || defined(__clang__) +#define _HU_FUNCTION(x) __attribute__((__unused__)) x +#else +#define _HU_FUNCTION(x) x +#endif #endif -#define TREE_ENTRY(type) \ - struct { \ - struct type *avl_left; \ - struct type *avl_right; \ - int avl_height; \ - } +#define TREE_ENTRY(type) \ + struct { \ + struct type *avl_left; \ + struct type *avl_right; \ + int avl_height; \ + } -#define TREE_HEAD(name, type) \ - struct name { \ - struct type *th_root; \ - int (*th_cmp)(struct type *lhs, struct type *rhs); \ - } +#define TREE_HEAD(name, type) \ + struct name { \ + struct type *th_root; \ + int (*th_cmp)(struct type * lhs, struct type *rhs); \ + } -#define TREE_INITIALIZER(cmp) { 0, cmp } +#define TREE_INITIALIZER(cmp) {0, cmp} -#define TREE_DELTA(self, field) \ - (( (((self)->field.avl_left) ? (self)->field.avl_left->field.avl_height : 0)) \ - - (((self)->field.avl_right) ? (self)->field.avl_right->field.avl_height : 0)) +#define TREE_DELTA(self, field) \ + (((((self)->field.avl_left) ? (self)->field.avl_left->field.avl_height : 0)) - (((self)->field.avl_right) ? (self)->field.avl_right->field.avl_height : 0)) /* Recursion prevents the following from being defined as macros. */ -#define TREE_DEFINE(node, field) \ - \ - static struct node *_HU_FUNCTION(TREE_BALANCE_##node##_##field)(struct node *); \ - \ - static struct node *_HU_FUNCTION(TREE_ROTL_##node##_##field)(struct node *self) \ - { \ - struct node *r= self->field.avl_right; \ - self->field.avl_right= r->field.avl_left; \ - r->field.avl_left= TREE_BALANCE_##node##_##field(self); \ - return TREE_BALANCE_##node##_##field(r); \ - } \ - \ - static struct node *_HU_FUNCTION(TREE_ROTR_##node##_##field)(struct node *self) \ - { \ - struct node *l= self->field.avl_left; \ - self->field.avl_left= l->field.avl_right; \ - l->field.avl_right= TREE_BALANCE_##node##_##field(self); \ - return TREE_BALANCE_##node##_##field(l); \ - } \ - \ - static struct node *_HU_FUNCTION(TREE_BALANCE_##node##_##field)(struct node *self) \ - { \ - int delta= TREE_DELTA(self, field); \ - \ - if (delta < -TREE_DELTA_MAX) \ - { \ - if (TREE_DELTA(self->field.avl_right, field) > 0) \ - self->field.avl_right= TREE_ROTR_##node##_##field(self->field.avl_right); \ - return TREE_ROTL_##node##_##field(self); \ - } \ - else if (delta > TREE_DELTA_MAX) \ - { \ - if (TREE_DELTA(self->field.avl_left, field) < 0) \ - self->field.avl_left= TREE_ROTL_##node##_##field(self->field.avl_left); \ - return TREE_ROTR_##node##_##field(self); \ - } \ - self->field.avl_height= 0; \ - if (self->field.avl_left && (self->field.avl_left->field.avl_height > self->field.avl_height)) \ - self->field.avl_height= self->field.avl_left->field.avl_height; \ - if (self->field.avl_right && (self->field.avl_right->field.avl_height > self->field.avl_height)) \ - self->field.avl_height= self->field.avl_right->field.avl_height; \ - self->field.avl_height += 1; \ - return self; \ - } \ - \ - static struct node *_HU_FUNCTION(TREE_INSERT_##node##_##field) \ - (struct node *self, struct node *elm, int (*compare)(struct node *lhs, struct node *rhs)) \ - { \ - if (!self) \ - return elm; \ - if (compare(elm, self) < 0) \ - self->field.avl_left= TREE_INSERT_##node##_##field(self->field.avl_left, elm, compare); \ - else \ - self->field.avl_right= TREE_INSERT_##node##_##field(self->field.avl_right, elm, compare); \ - return TREE_BALANCE_##node##_##field(self); \ - } \ - \ - static struct node *_HU_FUNCTION(TREE_FIND_##node##_##field) \ - (struct node *self, struct node *elm, int (*compare)(struct node *lhs, struct node *rhs)) \ - { \ - if (!self) \ - return 0; \ - if (compare(elm, self) == 0) \ - return self; \ - if (compare(elm, self) < 0) \ - return TREE_FIND_##node##_##field(self->field.avl_left, elm, compare); \ - else \ - return TREE_FIND_##node##_##field(self->field.avl_right, elm, compare); \ - } \ - \ - static struct node *_HU_FUNCTION(TREE_MOVE_RIGHT)(struct node *self, struct node *rhs) \ - { \ - if (!self) \ - return rhs; \ - self->field.avl_right= TREE_MOVE_RIGHT(self->field.avl_right, rhs); \ - return TREE_BALANCE_##node##_##field(self); \ - } \ - \ - static struct node *_HU_FUNCTION(TREE_REMOVE_##node##_##field) \ - (struct node *self, struct node *elm, int (*compare)(struct node *lhs, struct node *rhs)) \ - { \ - if (!self) return 0; \ - \ - if (compare(elm, self) == 0) \ - { \ - struct node *tmp= TREE_MOVE_RIGHT(self->field.avl_left, self->field.avl_right); \ - self->field.avl_left= 0; \ - self->field.avl_right= 0; \ - return tmp; \ - } \ - if (compare(elm, self) < 0) \ - self->field.avl_left= TREE_REMOVE_##node##_##field(self->field.avl_left, elm, compare); \ - else \ - self->field.avl_right= TREE_REMOVE_##node##_##field(self->field.avl_right, elm, compare); \ - return TREE_BALANCE_##node##_##field(self); \ - } \ - \ - static void _HU_FUNCTION(TREE_FORWARD_APPLY_ALL_##node##_##field) \ - (struct node *self, void (*function)(struct node *node, void *data), void *data) \ - { \ - if (self) \ - { \ - TREE_FORWARD_APPLY_ALL_##node##_##field(self->field.avl_left, function, data); \ - function(self, data); \ - TREE_FORWARD_APPLY_ALL_##node##_##field(self->field.avl_right, function, data); \ - } \ - } \ - \ - static void _HU_FUNCTION(TREE_REVERSE_APPLY_ALL_##node##_##field) \ - (struct node *self, void (*function)(struct node *node, void *data), void *data) \ - { \ - if (self) \ - { \ - TREE_REVERSE_APPLY_ALL_##node##_##field(self->field.avl_right, function, data); \ - function(self, data); \ - TREE_REVERSE_APPLY_ALL_##node##_##field(self->field.avl_left, function, data); \ - } \ - } - -#define TREE_INSERT(head, node, field, elm) \ - ((head)->th_root= TREE_INSERT_##node##_##field((head)->th_root, (elm), (head)->th_cmp)) - -#define TREE_FIND(head, node, field, elm) \ - (TREE_FIND_##node##_##field((head)->th_root, (elm), (head)->th_cmp)) - -#define TREE_REMOVE(head, node, field, elm) \ - ((head)->th_root= TREE_REMOVE_##node##_##field((head)->th_root, (elm), (head)->th_cmp)) - -#define TREE_DEPTH(head, field) \ - ((head)->th_root->field.avl_height) - -#define TREE_FORWARD_APPLY(head, node, field, function, data) \ - TREE_FORWARD_APPLY_ALL_##node##_##field((head)->th_root, function, data) - -#define TREE_REVERSE_APPLY(head, node, field, function, data) \ - TREE_REVERSE_APPLY_ALL_##node##_##field((head)->th_root, function, data) - -#define TREE_INIT(head, cmp) do { \ - (head)->th_root= 0; \ - (head)->th_cmp= (cmp); \ - } while (0) +#define TREE_DEFINE(node, field) \ + \ + static struct node *_HU_FUNCTION(TREE_BALANCE_##node##_##field)(struct node *); \ + \ + static struct node *_HU_FUNCTION(TREE_ROTL_##node##_##field)(struct node * self) \ + { \ + struct node *r = self->field.avl_right; \ + self->field.avl_right = r->field.avl_left; \ + r->field.avl_left = TREE_BALANCE_##node##_##field(self); \ + return TREE_BALANCE_##node##_##field(r); \ + } \ + \ + static struct node *_HU_FUNCTION(TREE_ROTR_##node##_##field)(struct node * self) \ + { \ + struct node *l = self->field.avl_left; \ + self->field.avl_left = l->field.avl_right; \ + l->field.avl_right = TREE_BALANCE_##node##_##field(self); \ + return TREE_BALANCE_##node##_##field(l); \ + } \ + \ + static struct node *_HU_FUNCTION(TREE_BALANCE_##node##_##field)(struct node * self) \ + { \ + int delta = TREE_DELTA(self, field); \ + \ + if (delta < -TREE_DELTA_MAX) { \ + if (TREE_DELTA(self->field.avl_right, field) > 0) \ + self->field.avl_right = TREE_ROTR_##node##_##field(self->field.avl_right); \ + return TREE_ROTL_##node##_##field(self); \ + } \ + else if (delta > TREE_DELTA_MAX) { \ + if (TREE_DELTA(self->field.avl_left, field) < 0) \ + self->field.avl_left = TREE_ROTL_##node##_##field(self->field.avl_left); \ + return TREE_ROTR_##node##_##field(self); \ + } \ + self->field.avl_height = 0; \ + if (self->field.avl_left && (self->field.avl_left->field.avl_height > self->field.avl_height)) \ + self->field.avl_height = self->field.avl_left->field.avl_height; \ + if (self->field.avl_right && (self->field.avl_right->field.avl_height > self->field.avl_height)) \ + self->field.avl_height = self->field.avl_right->field.avl_height; \ + self->field.avl_height += 1; \ + return self; \ + } \ + \ + static struct node *_HU_FUNCTION(TREE_INSERT_##node##_##field)(struct node * self, struct node * elm, int (*compare)(struct node * lhs, struct node * rhs)) \ + { \ + if (!self) \ + return elm; \ + if (compare(elm, self) < 0) \ + self->field.avl_left = TREE_INSERT_##node##_##field(self->field.avl_left, elm, compare); \ + else \ + self->field.avl_right = TREE_INSERT_##node##_##field(self->field.avl_right, elm, compare); \ + return TREE_BALANCE_##node##_##field(self); \ + } \ + \ + static struct node *_HU_FUNCTION(TREE_FIND_##node##_##field)(struct node * self, struct node * elm, int (*compare)(struct node * lhs, struct node * rhs)) \ + { \ + if (!self) \ + return 0; \ + if (compare(elm, self) == 0) \ + return self; \ + if (compare(elm, self) < 0) \ + return TREE_FIND_##node##_##field(self->field.avl_left, elm, compare); \ + else \ + return TREE_FIND_##node##_##field(self->field.avl_right, elm, compare); \ + } \ + \ + static struct node *_HU_FUNCTION(TREE_MOVE_RIGHT)(struct node * self, struct node * rhs) \ + { \ + if (!self) \ + return rhs; \ + self->field.avl_right = TREE_MOVE_RIGHT(self->field.avl_right, rhs); \ + return TREE_BALANCE_##node##_##field(self); \ + } \ + \ + static struct node *_HU_FUNCTION(TREE_REMOVE_##node##_##field)(struct node * self, struct node * elm, int (*compare)(struct node * lhs, struct node * rhs)) \ + { \ + if (!self) return 0; \ + \ + if (compare(elm, self) == 0) { \ + struct node *tmp = TREE_MOVE_RIGHT(self->field.avl_left, self->field.avl_right); \ + self->field.avl_left = 0; \ + self->field.avl_right = 0; \ + return tmp; \ + } \ + if (compare(elm, self) < 0) \ + self->field.avl_left = TREE_REMOVE_##node##_##field(self->field.avl_left, elm, compare); \ + else \ + self->field.avl_right = TREE_REMOVE_##node##_##field(self->field.avl_right, elm, compare); \ + return TREE_BALANCE_##node##_##field(self); \ + } \ + \ + static void _HU_FUNCTION(TREE_FORWARD_APPLY_ALL_##node##_##field)(struct node * self, void (*function)(struct node * node, void *data), void *data) \ + { \ + if (self) { \ + TREE_FORWARD_APPLY_ALL_##node##_##field(self->field.avl_left, function, data); \ + function(self, data); \ + TREE_FORWARD_APPLY_ALL_##node##_##field(self->field.avl_right, function, data); \ + } \ + } \ + \ + static void _HU_FUNCTION(TREE_REVERSE_APPLY_ALL_##node##_##field)(struct node * self, void (*function)(struct node * node, void *data), void *data) \ + { \ + if (self) { \ + TREE_REVERSE_APPLY_ALL_##node##_##field(self->field.avl_right, function, data); \ + function(self, data); \ + TREE_REVERSE_APPLY_ALL_##node##_##field(self->field.avl_left, function, data); \ + } \ + } + +#define TREE_INSERT(head, node, field, elm) \ + ((head)->th_root = TREE_INSERT_##node##_##field((head)->th_root, (elm), (head)->th_cmp)) + +#define TREE_FIND(head, node, field, elm) \ + (TREE_FIND_##node##_##field((head)->th_root, (elm), (head)->th_cmp)) + +#define TREE_REMOVE(head, node, field, elm) \ + ((head)->th_root = TREE_REMOVE_##node##_##field((head)->th_root, (elm), (head)->th_cmp)) + +#define TREE_DEPTH(head, field) \ + ((head)->th_root->field.avl_height) + +#define TREE_FORWARD_APPLY(head, node, field, function, data) \ + TREE_FORWARD_APPLY_ALL_##node##_##field((head)->th_root, function, data) + +#define TREE_REVERSE_APPLY(head, node, field, function, data) \ + TREE_REVERSE_APPLY_ALL_##node##_##field((head)->th_root, function, data) + +#define TREE_INIT(head, cmp) \ + do { \ + (head)->th_root = 0; \ + (head)->th_cmp = (cmp); \ + } while (0) #endif /* __tree_h */ diff --git a/contrib/libucl/src/ucl_chartable.h b/contrib/libucl/src/ucl_chartable.h index 7571a1d91549..aa896ea5f0a3 100644 --- a/contrib/libucl/src/ucl_chartable.h +++ b/contrib/libucl/src/ucl_chartable.h @@ -1,268 +1,267 @@ /* Copyright (c) 2013, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UCL_CHARTABLE_H_ #define UCL_CHARTABLE_H_ #include "ucl_internal.h" static const unsigned int ucl_chartable[256] = { -UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_VALUE_END|UCL_CHARACTER_UCL_UNSAFE, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, -UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, -UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, -UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_UCL_UNSAFE, -UCL_CHARACTER_WHITESPACE|UCL_CHARACTER_WHITESPACE_UNSAFE|UCL_CHARACTER_KEY_SEP|UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_UCL_UNSAFE, -UCL_CHARACTER_WHITESPACE_UNSAFE|UCL_CHARACTER_VALUE_END|UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_UCL_UNSAFE, -UCL_CHARACTER_WHITESPACE_UNSAFE, -UCL_CHARACTER_WHITESPACE_UNSAFE|UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_UCL_UNSAFE, -UCL_CHARACTER_WHITESPACE_UNSAFE|UCL_CHARACTER_VALUE_END|UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_UCL_UNSAFE, -UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, -UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, -UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, -UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, -UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, -UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, -UCL_CHARACTER_WHITESPACE|UCL_CHARACTER_WHITESPACE_UNSAFE|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_KEY_SEP|UCL_CHARACTER_UCL_UNSAFE /* */, -UCL_CHARACTER_VALUE_STR /* ! */, -UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_ESCAPE|UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_UCL_UNSAFE /* " */, -UCL_CHARACTER_VALUE_END /* # */, UCL_CHARACTER_VALUE_STR /* $ */, -UCL_CHARACTER_VALUE_STR /* % */, UCL_CHARACTER_VALUE_STR /* & */, -UCL_CHARACTER_VALUE_STR /* ' */, UCL_CHARACTER_VALUE_STR /* ( */, -UCL_CHARACTER_VALUE_STR /* ) */, UCL_CHARACTER_VALUE_STR /* * */, -UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT|UCL_CHARACTER_UCL_UNSAFE /* + */, -UCL_CHARACTER_VALUE_END /* , */, -UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* - */, -UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* . */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_ESCAPE /* / */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 0 */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 1 */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 2 */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 3 */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 4 */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 5 */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 6 */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 7 */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 8 */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT_START|UCL_CHARACTER_VALUE_DIGIT /* 9 */, -UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_KEY_SEP|UCL_CHARACTER_UCL_UNSAFE /* : */, -UCL_CHARACTER_VALUE_END /* ; */, UCL_CHARACTER_VALUE_STR /* < */, -UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_KEY_SEP|UCL_CHARACTER_UCL_UNSAFE /* = */, -UCL_CHARACTER_VALUE_STR /* > */, UCL_CHARACTER_VALUE_STR /* ? */, -UCL_CHARACTER_VALUE_STR /* @ */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* A */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* B */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* C */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* D */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* E */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* F */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* G */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* H */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* I */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* J */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* K */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* L */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* M */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* N */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* O */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* P */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* Q */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* R */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* S */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* T */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* U */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* V */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* W */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* X */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* Y */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* Z */, -UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_UCL_UNSAFE /* [ */, -UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_ESCAPE|UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_UCL_UNSAFE /* \ */, -UCL_CHARACTER_VALUE_END /* ] */, UCL_CHARACTER_VALUE_STR /* ^ */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR /* _ */, -UCL_CHARACTER_VALUE_STR /* ` */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* a */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT|UCL_CHARACTER_ESCAPE /* b */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* c */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* d */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* e */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT|UCL_CHARACTER_ESCAPE /* f */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* g */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* h */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* i */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* j */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* k */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* l */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* m */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT|UCL_CHARACTER_ESCAPE /* n */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* o */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* p */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* q */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT|UCL_CHARACTER_ESCAPE /* r */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* s */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT|UCL_CHARACTER_ESCAPE /* t */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT|UCL_CHARACTER_ESCAPE /* u */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* v */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* w */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* x */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* y */, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_VALUE_DIGIT /* z */, -UCL_CHARACTER_VALUE_STR|UCL_CHARACTER_UCL_UNSAFE /* { */, -UCL_CHARACTER_VALUE_STR /* | */, UCL_CHARACTER_VALUE_END /* } */, -UCL_CHARACTER_VALUE_STR /* ~ */, UCL_CHARACTER_DENIED, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR, -UCL_CHARACTER_KEY_START|UCL_CHARACTER_KEY|UCL_CHARACTER_VALUE_STR -}; + UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_VALUE_END | UCL_CHARACTER_UCL_UNSAFE, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, + UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, + UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, + UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_UCL_UNSAFE, + UCL_CHARACTER_WHITESPACE | UCL_CHARACTER_WHITESPACE_UNSAFE | UCL_CHARACTER_KEY_SEP | UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_UCL_UNSAFE, + UCL_CHARACTER_WHITESPACE_UNSAFE | UCL_CHARACTER_VALUE_END | UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_UCL_UNSAFE, + UCL_CHARACTER_WHITESPACE_UNSAFE, + UCL_CHARACTER_WHITESPACE_UNSAFE | UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_UCL_UNSAFE, + UCL_CHARACTER_WHITESPACE_UNSAFE | UCL_CHARACTER_VALUE_END | UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_UCL_UNSAFE, + UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, + UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, + UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, + UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, + UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, + UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, UCL_CHARACTER_DENIED, + UCL_CHARACTER_WHITESPACE | UCL_CHARACTER_WHITESPACE_UNSAFE | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_KEY_SEP | UCL_CHARACTER_UCL_UNSAFE /* */, + UCL_CHARACTER_VALUE_STR /* ! */, + UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_ESCAPE | UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_UCL_UNSAFE /* " */, + UCL_CHARACTER_VALUE_END /* # */, UCL_CHARACTER_VALUE_STR /* $ */, + UCL_CHARACTER_VALUE_STR /* % */, UCL_CHARACTER_VALUE_STR /* & */, + UCL_CHARACTER_VALUE_STR /* ' */, UCL_CHARACTER_VALUE_STR /* ( */, + UCL_CHARACTER_VALUE_STR /* ) */, UCL_CHARACTER_VALUE_STR /* * */, + UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT | UCL_CHARACTER_UCL_UNSAFE /* + */, + UCL_CHARACTER_VALUE_END /* , */, + UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* - */, + UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* . */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_ESCAPE /* / */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 0 */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 1 */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 2 */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 3 */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 4 */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 5 */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 6 */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 7 */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 8 */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT_START | UCL_CHARACTER_VALUE_DIGIT /* 9 */, + UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_KEY_SEP | UCL_CHARACTER_UCL_UNSAFE /* : */, + UCL_CHARACTER_VALUE_END /* ; */, UCL_CHARACTER_VALUE_STR /* < */, + UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_KEY_SEP | UCL_CHARACTER_UCL_UNSAFE /* = */, + UCL_CHARACTER_VALUE_STR /* > */, UCL_CHARACTER_VALUE_STR /* ? */, + UCL_CHARACTER_VALUE_STR /* @ */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* A */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* B */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* C */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* D */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* E */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* F */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* G */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* H */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* I */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* J */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* K */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* L */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* M */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* N */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* O */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* P */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* Q */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* R */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* S */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* T */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* U */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* V */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* W */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* X */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* Y */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* Z */, + UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_UCL_UNSAFE /* [ */, + UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_ESCAPE | UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_UCL_UNSAFE /* \ */, + UCL_CHARACTER_VALUE_END /* ] */, UCL_CHARACTER_VALUE_STR /* ^ */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR /* _ */, + UCL_CHARACTER_VALUE_STR /* ` */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* a */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT | UCL_CHARACTER_ESCAPE /* b */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* c */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* d */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* e */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT | UCL_CHARACTER_ESCAPE /* f */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* g */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* h */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* i */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* j */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* k */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* l */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* m */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT | UCL_CHARACTER_ESCAPE /* n */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* o */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* p */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* q */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT | UCL_CHARACTER_ESCAPE /* r */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* s */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT | UCL_CHARACTER_ESCAPE /* t */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT | UCL_CHARACTER_ESCAPE /* u */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* v */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* w */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* x */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* y */, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_VALUE_DIGIT /* z */, + UCL_CHARACTER_VALUE_STR | UCL_CHARACTER_UCL_UNSAFE /* { */, + UCL_CHARACTER_VALUE_STR /* | */, UCL_CHARACTER_VALUE_END /* } */, + UCL_CHARACTER_VALUE_STR /* ~ */, UCL_CHARACTER_DENIED, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR, + UCL_CHARACTER_KEY_START | UCL_CHARACTER_KEY | UCL_CHARACTER_VALUE_STR}; static inline bool -ucl_test_character (unsigned char c, int type_flags) +ucl_test_character(unsigned char c, int type_flags) { return (ucl_chartable[c] & type_flags) != 0; } #endif /* UCL_CHARTABLE_H_ */ diff --git a/contrib/libucl/src/ucl_emitter.c b/contrib/libucl/src/ucl_emitter.c index 97d8f618021f..84c1b13e1865 100644 --- a/contrib/libucl/src/ucl_emitter.c +++ b/contrib/libucl/src/ucl_emitter.c @@ -1,714 +1,715 @@ /* Copyright (c) 2013, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ucl.h" #include "ucl_internal.h" #include "ucl_chartable.h" #ifdef HAVE_FLOAT_H #include #endif #ifdef HAVE_MATH_H #include #endif /** * @file ucl_emitter.c * Serialise UCL object to various of output formats */ -static void ucl_emitter_common_elt (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool first, bool print_key, bool compact); - -#define UCL_EMIT_TYPE_OPS(type) \ - static void ucl_emit_ ## type ## _elt (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj, bool first, bool print_key); \ - static void ucl_emit_ ## type ## _start_obj (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj, bool first, bool print_key); \ - static void ucl_emit_ ## type## _start_array (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj, bool first, bool print_key); \ - static void ucl_emit_ ##type## _end_object (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj); \ - static void ucl_emit_ ##type## _end_array (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj) +static void ucl_emitter_common_elt(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool first, bool print_key, bool compact); + +#define UCL_EMIT_TYPE_OPS(type) \ + static void ucl_emit_##type##_elt(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj, bool first, bool print_key); \ + static void ucl_emit_##type##_start_obj(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj, bool first, bool print_key); \ + static void ucl_emit_##type##_start_array(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj, bool first, bool print_key); \ + static void ucl_emit_##type##_end_object(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj); \ + static void ucl_emit_##type##_end_array(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj) /* * JSON format operations */ UCL_EMIT_TYPE_OPS(json); UCL_EMIT_TYPE_OPS(json_compact); UCL_EMIT_TYPE_OPS(config); UCL_EMIT_TYPE_OPS(yaml); UCL_EMIT_TYPE_OPS(msgpack); -#define UCL_EMIT_TYPE_CONTENT(type) { \ - .ucl_emitter_write_elt = ucl_emit_ ## type ## _elt, \ - .ucl_emitter_start_object = ucl_emit_ ## type ##_start_obj, \ - .ucl_emitter_start_array = ucl_emit_ ## type ##_start_array, \ - .ucl_emitter_end_object = ucl_emit_ ## type ##_end_object, \ - .ucl_emitter_end_array = ucl_emit_ ## type ##_end_array \ -} +#define UCL_EMIT_TYPE_CONTENT(type) { \ + .ucl_emitter_write_elt = ucl_emit_##type##_elt, \ + .ucl_emitter_start_object = ucl_emit_##type##_start_obj, \ + .ucl_emitter_start_array = ucl_emit_##type##_start_array, \ + .ucl_emitter_end_object = ucl_emit_##type##_end_object, \ + .ucl_emitter_end_array = ucl_emit_##type##_end_array} const struct ucl_emitter_operations ucl_standartd_emitter_ops[] = { [UCL_EMIT_JSON] = UCL_EMIT_TYPE_CONTENT(json), [UCL_EMIT_JSON_COMPACT] = UCL_EMIT_TYPE_CONTENT(json_compact), [UCL_EMIT_CONFIG] = UCL_EMIT_TYPE_CONTENT(config), [UCL_EMIT_YAML] = UCL_EMIT_TYPE_CONTENT(yaml), - [UCL_EMIT_MSGPACK] = UCL_EMIT_TYPE_CONTENT(msgpack) -}; + [UCL_EMIT_MSGPACK] = UCL_EMIT_TYPE_CONTENT(msgpack)}; /* * Utility to check whether we need a top object */ #define UCL_EMIT_IDENT_TOP_OBJ(ctx, obj) ((ctx)->top != (obj) || \ - ((ctx)->id == UCL_EMIT_JSON_COMPACT || (ctx)->id == UCL_EMIT_JSON)) + ((ctx)->id == UCL_EMIT_JSON_COMPACT || (ctx)->id == UCL_EMIT_JSON)) /** * Add tabulation to the output buffer * @param buf target buffer * @param tabs number of tabs to add */ static inline void -ucl_add_tabs (const struct ucl_emitter_functions *func, unsigned int tabs, - bool compact) +ucl_add_tabs(const struct ucl_emitter_functions *func, unsigned int tabs, + bool compact) { if (!compact && tabs > 0) { - func->ucl_emitter_append_character (' ', tabs * 4, func->ud); + func->ucl_emitter_append_character(' ', tabs * 4, func->ud); } } /** * Print key for the element * @param ctx * @param obj */ static void -ucl_emitter_print_key (bool print_key, struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool compact) +ucl_emitter_print_key(bool print_key, struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool compact) { const struct ucl_emitter_functions *func = ctx->func; if (!print_key) { return; } if (ctx->id == UCL_EMIT_CONFIG) { if (obj->flags & UCL_OBJECT_NEED_KEY_ESCAPE) { - ucl_elt_string_write_json (obj->key, obj->keylen, ctx); + ucl_elt_string_write_json(obj->key, obj->keylen, ctx); } else { - func->ucl_emitter_append_len (obj->key, obj->keylen, func->ud); + func->ucl_emitter_append_len(obj->key, obj->keylen, func->ud); } if (obj->type != UCL_OBJECT && obj->type != UCL_ARRAY) { - func->ucl_emitter_append_len (" = ", 3, func->ud); + func->ucl_emitter_append_len(" = ", 3, func->ud); } else { - func->ucl_emitter_append_character (' ', 1, func->ud); + func->ucl_emitter_append_character(' ', 1, func->ud); } } else if (ctx->id == UCL_EMIT_YAML) { if (obj->keylen > 0 && (obj->flags & UCL_OBJECT_NEED_KEY_ESCAPE)) { - ucl_elt_string_write_json (obj->key, obj->keylen, ctx); + ucl_elt_string_write_json(obj->key, obj->keylen, ctx); } else if (obj->keylen > 0) { - func->ucl_emitter_append_len (obj->key, obj->keylen, func->ud); + func->ucl_emitter_append_len(obj->key, obj->keylen, func->ud); } else { - func->ucl_emitter_append_len ("null", 4, func->ud); + func->ucl_emitter_append_len("null", 4, func->ud); } - func->ucl_emitter_append_len (": ", 2, func->ud); + func->ucl_emitter_append_len(": ", 2, func->ud); } else { if (obj->keylen > 0) { - ucl_elt_string_write_json (obj->key, obj->keylen, ctx); + ucl_elt_string_write_json(obj->key, obj->keylen, ctx); } else { - func->ucl_emitter_append_len ("null", 4, func->ud); + func->ucl_emitter_append_len("null", 4, func->ud); } if (compact) { - func->ucl_emitter_append_character (':', 1, func->ud); + func->ucl_emitter_append_character(':', 1, func->ud); } else { - func->ucl_emitter_append_len (": ", 2, func->ud); + func->ucl_emitter_append_len(": ", 2, func->ud); } } } static void -ucl_emitter_finish_object (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool compact, bool is_array) +ucl_emitter_finish_object(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool compact, bool is_array) { const struct ucl_emitter_functions *func = ctx->func; if (ctx->id == UCL_EMIT_CONFIG && obj != ctx->top) { if (obj->type != UCL_OBJECT && obj->type != UCL_ARRAY) { if (!is_array) { /* Objects are split by ';' */ - func->ucl_emitter_append_len (";\n", 2, func->ud); + func->ucl_emitter_append_len(";\n", 2, func->ud); } else { /* Use commas for arrays */ - func->ucl_emitter_append_len (",\n", 2, func->ud); + func->ucl_emitter_append_len(",\n", 2, func->ud); } } else { - func->ucl_emitter_append_character ('\n', 1, func->ud); + func->ucl_emitter_append_character('\n', 1, func->ud); } } } /** * End standard ucl object * @param ctx emitter context * @param compact compact flag */ static void -ucl_emitter_common_end_object (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool compact) +ucl_emitter_common_end_object(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool compact) { const struct ucl_emitter_functions *func = ctx->func; if (UCL_EMIT_IDENT_TOP_OBJ(ctx, obj)) { - ctx->indent --; + ctx->indent--; if (compact) { - func->ucl_emitter_append_character ('}', 1, func->ud); + func->ucl_emitter_append_character('}', 1, func->ud); } else { if (ctx->id != UCL_EMIT_CONFIG) { /* newline is already added for this format */ - func->ucl_emitter_append_character ('\n', 1, func->ud); + func->ucl_emitter_append_character('\n', 1, func->ud); } - ucl_add_tabs (func, ctx->indent, compact); - func->ucl_emitter_append_character ('}', 1, func->ud); + ucl_add_tabs(func, ctx->indent, compact); + func->ucl_emitter_append_character('}', 1, func->ud); } } - ucl_emitter_finish_object (ctx, obj, compact, false); + ucl_emitter_finish_object(ctx, obj, compact, false); } /** * End standard ucl array * @param ctx emitter context * @param compact compact flag */ static void -ucl_emitter_common_end_array (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool compact) +ucl_emitter_common_end_array(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool compact) { const struct ucl_emitter_functions *func = ctx->func; - ctx->indent --; + ctx->indent--; if (compact) { - func->ucl_emitter_append_character (']', 1, func->ud); + func->ucl_emitter_append_character(']', 1, func->ud); } else { if (ctx->id != UCL_EMIT_CONFIG) { /* newline is already added for this format */ - func->ucl_emitter_append_character ('\n', 1, func->ud); + func->ucl_emitter_append_character('\n', 1, func->ud); } - ucl_add_tabs (func, ctx->indent, compact); - func->ucl_emitter_append_character (']', 1, func->ud); + ucl_add_tabs(func, ctx->indent, compact); + func->ucl_emitter_append_character(']', 1, func->ud); } - ucl_emitter_finish_object (ctx, obj, compact, true); + ucl_emitter_finish_object(ctx, obj, compact, true); } /** * Start emit standard UCL array * @param ctx emitter context * @param obj object to write * @param compact compact flag */ static void -ucl_emitter_common_start_array (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool first, bool print_key, bool compact) +ucl_emitter_common_start_array(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool first, bool print_key, bool compact) { const ucl_object_t *cur; ucl_object_iter_t iter = NULL; const struct ucl_emitter_functions *func = ctx->func; bool first_key = true; if (ctx->id != UCL_EMIT_CONFIG && !first) { if (compact) { - func->ucl_emitter_append_character (',', 1, func->ud); + func->ucl_emitter_append_character(',', 1, func->ud); } else { if (ctx->id == UCL_EMIT_YAML && ctx->indent == 0) { - func->ucl_emitter_append_len ("\n", 1, func->ud); - } else { - func->ucl_emitter_append_len (",\n", 2, func->ud); + func->ucl_emitter_append_len("\n", 1, func->ud); + } + else { + func->ucl_emitter_append_len(",\n", 2, func->ud); } } - ucl_add_tabs (func, ctx->indent, compact); + ucl_add_tabs(func, ctx->indent, compact); } - ucl_emitter_print_key (print_key, ctx, obj, compact); + ucl_emitter_print_key(print_key, ctx, obj, compact); if (compact) { - func->ucl_emitter_append_character ('[', 1, func->ud); + func->ucl_emitter_append_character('[', 1, func->ud); } else { - func->ucl_emitter_append_len ("[\n", 2, func->ud); + func->ucl_emitter_append_len("[\n", 2, func->ud); } - ctx->indent ++; + ctx->indent++; if (obj->type == UCL_ARRAY) { /* explicit array */ - while ((cur = ucl_object_iterate (obj, &iter, true)) != NULL) { - ucl_emitter_common_elt (ctx, cur, first_key, false, compact); + while ((cur = ucl_object_iterate(obj, &iter, true)) != NULL) { + ucl_emitter_common_elt(ctx, cur, first_key, false, compact); first_key = false; } } else { /* implicit array */ cur = obj; while (cur) { - ucl_emitter_common_elt (ctx, cur, first_key, false, compact); + ucl_emitter_common_elt(ctx, cur, first_key, false, compact); first_key = false; cur = cur->next; } } - - } /** * Start emit standard UCL object * @param ctx emitter context * @param obj object to write * @param compact compact flag */ static void -ucl_emitter_common_start_object (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool first, bool print_key, bool compact) +ucl_emitter_common_start_object(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool first, bool print_key, bool compact) { ucl_hash_iter_t it = NULL; const ucl_object_t *cur, *elt; const struct ucl_emitter_functions *func = ctx->func; bool first_key = true; if (ctx->id != UCL_EMIT_CONFIG && !first) { if (compact) { - func->ucl_emitter_append_character (',', 1, func->ud); + func->ucl_emitter_append_character(',', 1, func->ud); } else { if (ctx->id == UCL_EMIT_YAML && ctx->indent == 0) { - func->ucl_emitter_append_len ("\n", 1, func->ud); - } else { - func->ucl_emitter_append_len (",\n", 2, func->ud); + func->ucl_emitter_append_len("\n", 1, func->ud); + } + else { + func->ucl_emitter_append_len(",\n", 2, func->ud); } } - ucl_add_tabs (func, ctx->indent, compact); + ucl_add_tabs(func, ctx->indent, compact); } - ucl_emitter_print_key (print_key, ctx, obj, compact); + ucl_emitter_print_key(print_key, ctx, obj, compact); /* * Print { * */ if (UCL_EMIT_IDENT_TOP_OBJ(ctx, obj)) { if (compact) { - func->ucl_emitter_append_character ('{', 1, func->ud); + func->ucl_emitter_append_character('{', 1, func->ud); } else { - func->ucl_emitter_append_len ("{\n", 2, func->ud); + func->ucl_emitter_append_len("{\n", 2, func->ud); } - ctx->indent ++; + ctx->indent++; } - while ((cur = ucl_hash_iterate (obj->value.ov, &it))) { + while ((cur = ucl_hash_iterate(obj->value.ov, &it))) { if (ctx->id == UCL_EMIT_CONFIG) { - LL_FOREACH (cur, elt) { - ucl_emitter_common_elt (ctx, elt, first_key, true, compact); + LL_FOREACH(cur, elt) + { + ucl_emitter_common_elt(ctx, elt, first_key, true, compact); } } else { /* Expand implicit arrays */ if (cur->next != NULL) { - if (!first_key) { - if (compact) { - func->ucl_emitter_append_character (',', 1, func->ud); - } - else { - func->ucl_emitter_append_len (",\n", 2, func->ud); - } + if (first_key) { + ucl_add_tabs(func, ctx->indent, compact); } - ucl_add_tabs (func, ctx->indent, compact); - ucl_emitter_common_start_array (ctx, cur, first_key, true, compact); - ucl_emitter_common_end_array (ctx, cur, compact); + ucl_emitter_common_start_array(ctx, cur, first_key, true, compact); + ucl_emitter_common_end_array(ctx, cur, compact); } else { - ucl_emitter_common_elt (ctx, cur, first_key, true, compact); + ucl_emitter_common_elt(ctx, cur, first_key, true, compact); } } first_key = false; } } /** * Common choice of object emitting * @param ctx emitter context * @param obj object to print * @param first flag to mark the first element * @param print_key print key of an object * @param compact compact output */ static void -ucl_emitter_common_elt (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool first, bool print_key, bool compact) +ucl_emitter_common_elt(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool first, bool print_key, bool compact) { const struct ucl_emitter_functions *func = ctx->func; bool flag; struct ucl_object_userdata *ud; const ucl_object_t *comment = NULL, *cur_comment; const char *ud_out = ""; if (ctx->id != UCL_EMIT_CONFIG && !first) { if (compact) { - func->ucl_emitter_append_character (',', 1, func->ud); + func->ucl_emitter_append_character(',', 1, func->ud); } else { if (ctx->id == UCL_EMIT_YAML && ctx->indent == 0) { - func->ucl_emitter_append_len ("\n", 1, func->ud); - } else { - func->ucl_emitter_append_len (",\n", 2, func->ud); + func->ucl_emitter_append_len("\n", 1, func->ud); + } + else { + func->ucl_emitter_append_len(",\n", 2, func->ud); } } } - ucl_add_tabs (func, ctx->indent, compact); + ucl_add_tabs(func, ctx->indent, compact); if (ctx->comments && ctx->id == UCL_EMIT_CONFIG) { - comment = ucl_object_lookup_len (ctx->comments, (const char *)&obj, - sizeof (void *)); + comment = ucl_object_lookup_len(ctx->comments, (const char *) &obj, + sizeof(void *)); if (comment) { if (!(comment->flags & UCL_OBJECT_INHERITED)) { - DL_FOREACH (comment, cur_comment) { - func->ucl_emitter_append_len (cur_comment->value.sv, - cur_comment->len, - func->ud); - func->ucl_emitter_append_character ('\n', 1, func->ud); - ucl_add_tabs (func, ctx->indent, compact); + DL_FOREACH(comment, cur_comment) + { + func->ucl_emitter_append_len(cur_comment->value.sv, + cur_comment->len, + func->ud); + func->ucl_emitter_append_character('\n', 1, func->ud); + ucl_add_tabs(func, ctx->indent, compact); } comment = NULL; } } } switch (obj->type) { case UCL_INT: - ucl_emitter_print_key (print_key, ctx, obj, compact); - func->ucl_emitter_append_int (ucl_object_toint (obj), func->ud); - ucl_emitter_finish_object (ctx, obj, compact, !print_key); + ucl_emitter_print_key(print_key, ctx, obj, compact); + func->ucl_emitter_append_int(ucl_object_toint(obj), func->ud); + ucl_emitter_finish_object(ctx, obj, compact, !print_key); break; case UCL_FLOAT: case UCL_TIME: - ucl_emitter_print_key (print_key, ctx, obj, compact); - func->ucl_emitter_append_double (ucl_object_todouble (obj), func->ud); - ucl_emitter_finish_object (ctx, obj, compact, !print_key); + ucl_emitter_print_key(print_key, ctx, obj, compact); + func->ucl_emitter_append_double(ucl_object_todouble(obj), func->ud); + ucl_emitter_finish_object(ctx, obj, compact, !print_key); break; case UCL_BOOLEAN: - ucl_emitter_print_key (print_key, ctx, obj, compact); - flag = ucl_object_toboolean (obj); + ucl_emitter_print_key(print_key, ctx, obj, compact); + flag = ucl_object_toboolean(obj); if (flag) { - func->ucl_emitter_append_len ("true", 4, func->ud); + func->ucl_emitter_append_len("true", 4, func->ud); } else { - func->ucl_emitter_append_len ("false", 5, func->ud); + func->ucl_emitter_append_len("false", 5, func->ud); } - ucl_emitter_finish_object (ctx, obj, compact, !print_key); + ucl_emitter_finish_object(ctx, obj, compact, !print_key); break; case UCL_STRING: - ucl_emitter_print_key (print_key, ctx, obj, compact); + ucl_emitter_print_key(print_key, ctx, obj, compact); if (ctx->id == UCL_EMIT_CONFIG) { - if (ucl_maybe_long_string (obj)) { - ucl_elt_string_write_multiline (obj->value.sv, obj->len, ctx); - } else { + if (ucl_maybe_long_string(obj)) { + ucl_elt_string_write_multiline(obj->value.sv, obj->len, ctx); + } + else { if (obj->flags & UCL_OBJECT_SQUOTED) { - ucl_elt_string_write_squoted (obj->value.sv, obj->len, ctx); - } else { - ucl_elt_string_write_json (obj->value.sv, obj->len, ctx); + ucl_elt_string_write_squoted(obj->value.sv, obj->len, ctx); + } + else { + ucl_elt_string_write_json(obj->value.sv, obj->len, ctx); } } } else { - ucl_elt_string_write_json (obj->value.sv, obj->len, ctx); + ucl_elt_string_write_json(obj->value.sv, obj->len, ctx); } - ucl_emitter_finish_object (ctx, obj, compact, !print_key); + ucl_emitter_finish_object(ctx, obj, compact, !print_key); break; case UCL_NULL: - ucl_emitter_print_key (print_key, ctx, obj, compact); - func->ucl_emitter_append_len ("null", 4, func->ud); - ucl_emitter_finish_object (ctx, obj, compact, !print_key); + ucl_emitter_print_key(print_key, ctx, obj, compact); + func->ucl_emitter_append_len("null", 4, func->ud); + ucl_emitter_finish_object(ctx, obj, compact, !print_key); break; case UCL_OBJECT: - ucl_emitter_common_start_object (ctx, obj, true, print_key, compact); - ucl_emitter_common_end_object (ctx, obj, compact); + ucl_emitter_common_start_object(ctx, obj, true, print_key, compact); + ucl_emitter_common_end_object(ctx, obj, compact); break; case UCL_ARRAY: - ucl_emitter_common_start_array (ctx, obj, true, print_key, compact); - ucl_emitter_common_end_array (ctx, obj, compact); + ucl_emitter_common_start_array(ctx, obj, true, print_key, compact); + ucl_emitter_common_end_array(ctx, obj, compact); break; case UCL_USERDATA: - ud = (struct ucl_object_userdata *)obj; - ucl_emitter_print_key (print_key, ctx, obj, compact); + ud = (struct ucl_object_userdata *) obj; + ucl_emitter_print_key(print_key, ctx, obj, compact); if (ud->emitter) { - ud_out = ud->emitter (obj->value.ud); + ud_out = ud->emitter(obj->value.ud); if (ud_out == NULL) { ud_out = "null"; } } - ucl_elt_string_write_json (ud_out, strlen (ud_out), ctx); - ucl_emitter_finish_object (ctx, obj, compact, !print_key); + ucl_elt_string_write_json(ud_out, strlen(ud_out), ctx); + ucl_emitter_finish_object(ctx, obj, compact, !print_key); break; } if (comment) { - DL_FOREACH (comment, cur_comment) { - func->ucl_emitter_append_len (cur_comment->value.sv, - cur_comment->len, - func->ud); - func->ucl_emitter_append_character ('\n', 1, func->ud); + DL_FOREACH(comment, cur_comment) + { + func->ucl_emitter_append_len(cur_comment->value.sv, + cur_comment->len, + func->ud); + func->ucl_emitter_append_character('\n', 1, func->ud); if (cur_comment->next) { - ucl_add_tabs (func, ctx->indent, compact); + ucl_add_tabs(func, ctx->indent, compact); } } } } /* * Specific standard implementations of the emitter functions */ -#define UCL_EMIT_TYPE_IMPL(type, compact) \ - static void ucl_emit_ ## type ## _elt (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj, bool first, bool print_key) { \ - ucl_emitter_common_elt (ctx, obj, first, print_key, (compact)); \ - } \ - static void ucl_emit_ ## type ## _start_obj (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj, bool first, bool print_key) { \ - ucl_emitter_common_start_object (ctx, obj, first, print_key, (compact)); \ - } \ - static void ucl_emit_ ## type## _start_array (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj, bool first, bool print_key) { \ - ucl_emitter_common_start_array (ctx, obj, first, print_key, (compact)); \ - } \ - static void ucl_emit_ ##type## _end_object (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj) { \ - ucl_emitter_common_end_object (ctx, obj, (compact)); \ - } \ - static void ucl_emit_ ##type## _end_array (struct ucl_emitter_context *ctx, \ - const ucl_object_t *obj) { \ - ucl_emitter_common_end_array (ctx, obj, (compact)); \ +#define UCL_EMIT_TYPE_IMPL(type, compact) \ + static void ucl_emit_##type##_elt(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj, bool first, bool print_key) \ + { \ + ucl_emitter_common_elt(ctx, obj, first, print_key, (compact)); \ + } \ + static void ucl_emit_##type##_start_obj(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj, bool first, bool print_key) \ + { \ + ucl_emitter_common_start_object(ctx, obj, first, print_key, (compact)); \ + } \ + static void ucl_emit_##type##_start_array(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj, bool first, bool print_key) \ + { \ + ucl_emitter_common_start_array(ctx, obj, first, print_key, (compact)); \ + } \ + static void ucl_emit_##type##_end_object(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj) \ + { \ + ucl_emitter_common_end_object(ctx, obj, (compact)); \ + } \ + static void ucl_emit_##type##_end_array(struct ucl_emitter_context *ctx, \ + const ucl_object_t *obj) \ + { \ + ucl_emitter_common_end_array(ctx, obj, (compact)); \ } UCL_EMIT_TYPE_IMPL(json, false) UCL_EMIT_TYPE_IMPL(json_compact, true) UCL_EMIT_TYPE_IMPL(config, false) UCL_EMIT_TYPE_IMPL(yaml, false) static void -ucl_emit_msgpack_elt (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool _first, bool print_key) +ucl_emit_msgpack_elt(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool _first, bool print_key) { ucl_object_iter_t it; struct ucl_object_userdata *ud; const char *ud_out; const ucl_object_t *cur, *celt; switch (obj->type) { case UCL_INT: - ucl_emitter_print_key_msgpack (print_key, ctx, obj); - ucl_emitter_print_int_msgpack (ctx, ucl_object_toint (obj)); + ucl_emitter_print_key_msgpack(print_key, ctx, obj); + ucl_emitter_print_int_msgpack(ctx, ucl_object_toint(obj)); break; case UCL_FLOAT: case UCL_TIME: - ucl_emitter_print_key_msgpack (print_key, ctx, obj); - ucl_emitter_print_double_msgpack (ctx, ucl_object_todouble (obj)); + ucl_emitter_print_key_msgpack(print_key, ctx, obj); + ucl_emitter_print_double_msgpack(ctx, ucl_object_todouble(obj)); break; case UCL_BOOLEAN: - ucl_emitter_print_key_msgpack (print_key, ctx, obj); - ucl_emitter_print_bool_msgpack (ctx, ucl_object_toboolean (obj)); + ucl_emitter_print_key_msgpack(print_key, ctx, obj); + ucl_emitter_print_bool_msgpack(ctx, ucl_object_toboolean(obj)); break; case UCL_STRING: - ucl_emitter_print_key_msgpack (print_key, ctx, obj); + ucl_emitter_print_key_msgpack(print_key, ctx, obj); if (obj->flags & UCL_OBJECT_BINARY) { - ucl_emitter_print_binary_string_msgpack (ctx, obj->value.sv, - obj->len); + ucl_emitter_print_binary_string_msgpack(ctx, obj->value.sv, + obj->len); } else { - ucl_emitter_print_string_msgpack (ctx, obj->value.sv, obj->len); + ucl_emitter_print_string_msgpack(ctx, obj->value.sv, obj->len); } break; case UCL_NULL: - ucl_emitter_print_key_msgpack (print_key, ctx, obj); - ucl_emitter_print_null_msgpack (ctx); + ucl_emitter_print_key_msgpack(print_key, ctx, obj); + ucl_emitter_print_null_msgpack(ctx); break; case UCL_OBJECT: - ucl_emitter_print_key_msgpack (print_key, ctx, obj); - ucl_emit_msgpack_start_obj (ctx, obj, false, print_key); + ucl_emitter_print_key_msgpack(print_key, ctx, obj); + ucl_emit_msgpack_start_obj(ctx, obj, false, print_key); it = NULL; - while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) { - LL_FOREACH (cur, celt) { - ucl_emit_msgpack_elt (ctx, celt, false, true); + while ((cur = ucl_object_iterate(obj, &it, true)) != NULL) { + LL_FOREACH(cur, celt) + { + ucl_emit_msgpack_elt(ctx, celt, false, true); /* XXX: * in msgpack the length of objects is encoded within a single elt * so in case of multi-value keys we are using merely the first * element ignoring others */ break; } } break; case UCL_ARRAY: - ucl_emitter_print_key_msgpack (print_key, ctx, obj); - ucl_emit_msgpack_start_array (ctx, obj, false, print_key); + ucl_emitter_print_key_msgpack(print_key, ctx, obj); + ucl_emit_msgpack_start_array(ctx, obj, false, print_key); it = NULL; - while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) { - ucl_emit_msgpack_elt (ctx, cur, false, false); + while ((cur = ucl_object_iterate(obj, &it, true)) != NULL) { + ucl_emit_msgpack_elt(ctx, cur, false, false); } break; case UCL_USERDATA: - ud = (struct ucl_object_userdata *)obj; - ucl_emitter_print_key_msgpack (print_key, ctx, obj); + ud = (struct ucl_object_userdata *) obj; + ucl_emitter_print_key_msgpack(print_key, ctx, obj); if (ud->emitter) { - ud_out = ud->emitter (obj->value.ud); + ud_out = ud->emitter(obj->value.ud); if (ud_out == NULL) { ud_out = "null"; } } - ucl_emitter_print_string_msgpack (ctx, obj->value.sv, obj->len); + ucl_emitter_print_string_msgpack(ctx, obj->value.sv, obj->len); break; } } static void -ucl_emit_msgpack_start_obj (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool _first, bool _print_key) +ucl_emit_msgpack_start_obj(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool _first, bool _print_key) { - ucl_emitter_print_object_msgpack (ctx, obj->len); + ucl_emitter_print_object_msgpack(ctx, obj->len); } static void -ucl_emit_msgpack_start_array (struct ucl_emitter_context *ctx, - const ucl_object_t *obj, bool _first, bool _print_key) +ucl_emit_msgpack_start_array(struct ucl_emitter_context *ctx, + const ucl_object_t *obj, bool _first, bool _print_key) { - ucl_emitter_print_array_msgpack (ctx, obj->len); + ucl_emitter_print_array_msgpack(ctx, obj->len); } static void -ucl_emit_msgpack_end_object (struct ucl_emitter_context *ctx, - const ucl_object_t *obj) +ucl_emit_msgpack_end_object(struct ucl_emitter_context *ctx, + const ucl_object_t *obj) { - } static void -ucl_emit_msgpack_end_array (struct ucl_emitter_context *ctx, - const ucl_object_t *obj) +ucl_emit_msgpack_end_array(struct ucl_emitter_context *ctx, + const ucl_object_t *obj) { - } unsigned char * -ucl_object_emit (const ucl_object_t *obj, enum ucl_emitter emit_type) +ucl_object_emit(const ucl_object_t *obj, enum ucl_emitter emit_type) { - return ucl_object_emit_len (obj, emit_type, NULL); + return ucl_object_emit_len(obj, emit_type, NULL); } unsigned char * -ucl_object_emit_len (const ucl_object_t *obj, enum ucl_emitter emit_type, - size_t *outlen) +ucl_object_emit_len(const ucl_object_t *obj, enum ucl_emitter emit_type, + size_t *outlen) { unsigned char *res = NULL; struct ucl_emitter_functions *func; UT_string *s; if (obj == NULL) { return NULL; } - func = ucl_object_emit_memory_funcs ((void **)&res); + func = ucl_object_emit_memory_funcs((void **) &res); if (func != NULL) { s = func->ud; - ucl_object_emit_full (obj, emit_type, func, NULL); + ucl_object_emit_full(obj, emit_type, func, NULL); if (outlen != NULL) { *outlen = s->i; } - ucl_object_emit_funcs_free (func); + ucl_object_emit_funcs_free(func); } return res; } -bool -ucl_object_emit_full (const ucl_object_t *obj, enum ucl_emitter emit_type, - struct ucl_emitter_functions *emitter, - const ucl_object_t *comments) +bool ucl_object_emit_full(const ucl_object_t *obj, enum ucl_emitter emit_type, + struct ucl_emitter_functions *emitter, + const ucl_object_t *comments) { const struct ucl_emitter_context *ctx; struct ucl_emitter_context my_ctx; bool res = false; - ctx = ucl_emit_get_standard_context (emit_type); + ctx = ucl_emit_get_standard_context(emit_type); if (ctx != NULL) { - memcpy (&my_ctx, ctx, sizeof (my_ctx)); + memcpy(&my_ctx, ctx, sizeof(my_ctx)); my_ctx.func = emitter; my_ctx.indent = 0; my_ctx.top = obj; my_ctx.comments = comments; - my_ctx.ops->ucl_emitter_write_elt (&my_ctx, obj, true, false); + my_ctx.ops->ucl_emitter_write_elt(&my_ctx, obj, true, false); res = true; } return res; } diff --git a/contrib/libucl/src/ucl_emitter_streamline.c b/contrib/libucl/src/ucl_emitter_streamline.c index 8ca86fa081c9..1da1b7c5b14c 100644 --- a/contrib/libucl/src/ucl_emitter_streamline.c +++ b/contrib/libucl/src/ucl_emitter_streamline.c @@ -1,174 +1,178 @@ /* Copyright (c) 2014, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ucl.h" #include "ucl_internal.h" #include "ucl_chartable.h" struct ucl_emitter_streamline_stack { bool is_array; bool empty; const ucl_object_t *obj; struct ucl_emitter_streamline_stack *next; }; struct ucl_emitter_context_streamline { /* Inherited from the main context */ /** Name of emitter (e.g. json, compact_json) */ const char *name; /** Unique id (e.g. UCL_EMIT_JSON for standard emitters */ int id; /** A set of output functions */ const struct ucl_emitter_functions *func; /** A set of output operations */ const struct ucl_emitter_operations *ops; /** Current amount of indent tabs */ unsigned int indent; /** Top level object */ const ucl_object_t *top; /** Optional comments */ const ucl_object_t *comments; /* Streamline specific fields */ struct ucl_emitter_streamline_stack *containers; }; -#define TO_STREAMLINE(ctx) (struct ucl_emitter_context_streamline *)(ctx) +#define TO_STREAMLINE(ctx) (struct ucl_emitter_context_streamline *) (ctx) -struct ucl_emitter_context* -ucl_object_emit_streamline_new (const ucl_object_t *obj, - enum ucl_emitter emit_type, - struct ucl_emitter_functions *emitter) +struct ucl_emitter_context * +ucl_object_emit_streamline_new(const ucl_object_t *obj, + enum ucl_emitter emit_type, + struct ucl_emitter_functions *emitter) { const struct ucl_emitter_context *ctx; struct ucl_emitter_context_streamline *sctx; - ctx = ucl_emit_get_standard_context (emit_type); + ctx = ucl_emit_get_standard_context(emit_type); if (ctx == NULL) { return NULL; } - sctx = calloc (1, sizeof (*sctx)); + sctx = calloc(1, sizeof(*sctx)); if (sctx == NULL) { return NULL; } - memcpy (sctx, ctx, sizeof (*ctx)); + memcpy(sctx, ctx, sizeof(*ctx)); sctx->func = emitter; sctx->top = obj; - ucl_object_emit_streamline_start_container ((struct ucl_emitter_context *)sctx, - obj); + ucl_object_emit_streamline_start_container((struct ucl_emitter_context *) sctx, + obj); - return (struct ucl_emitter_context *)sctx; + return (struct ucl_emitter_context *) sctx; } -void -ucl_object_emit_streamline_start_container (struct ucl_emitter_context *ctx, - const ucl_object_t *obj) +bool ucl_object_emit_streamline_start_container(struct ucl_emitter_context *ctx, + const ucl_object_t *obj) { struct ucl_emitter_context_streamline *sctx = TO_STREAMLINE(ctx); struct ucl_emitter_streamline_stack *st, *top; bool print_key = false; /* Check top object presence */ if (sctx->top == NULL) { sctx->top = obj; } top = sctx->containers; - st = malloc (sizeof (*st)); + st = malloc(sizeof(*st)); if (st != NULL) { st->empty = true; if (top && !top->is_array) { print_key = true; } st->obj = obj; if (obj != NULL && obj->type == UCL_ARRAY) { st->is_array = true; - sctx->ops->ucl_emitter_start_array (ctx, obj, top == NULL, print_key); + sctx->ops->ucl_emitter_start_array(ctx, obj, top == NULL, print_key); } - else { + else if (obj != NULL && obj->type == UCL_OBJECT) { st->is_array = false; - sctx->ops->ucl_emitter_start_object (ctx, obj, top == NULL, print_key); + sctx->ops->ucl_emitter_start_object(ctx, obj, top == NULL, print_key); } - LL_PREPEND (sctx->containers, st); + else { + /* API MISUSE */ + free(st); + + return false; + } + LL_PREPEND(sctx->containers, st); } + + return true; } -void -ucl_object_emit_streamline_add_object ( - struct ucl_emitter_context *ctx, const ucl_object_t *obj) +void ucl_object_emit_streamline_add_object( + struct ucl_emitter_context *ctx, const ucl_object_t *obj) { struct ucl_emitter_context_streamline *sctx = TO_STREAMLINE(ctx); bool is_array = false, is_first = false; if (sctx->containers != NULL) { if (sctx->containers->is_array) { is_array = true; } if (sctx->containers->empty) { is_first = true; sctx->containers->empty = false; } } - sctx->ops->ucl_emitter_write_elt (ctx, obj, is_first, !is_array); + sctx->ops->ucl_emitter_write_elt(ctx, obj, is_first, !is_array); } -void -ucl_object_emit_streamline_end_container (struct ucl_emitter_context *ctx) +void ucl_object_emit_streamline_end_container(struct ucl_emitter_context *ctx) { struct ucl_emitter_context_streamline *sctx = TO_STREAMLINE(ctx); struct ucl_emitter_streamline_stack *st; if (sctx->containers != NULL) { st = sctx->containers; if (st->is_array) { - sctx->ops->ucl_emitter_end_array (ctx, st->obj); + sctx->ops->ucl_emitter_end_array(ctx, st->obj); } else { - sctx->ops->ucl_emitter_end_object (ctx, st->obj); + sctx->ops->ucl_emitter_end_object(ctx, st->obj); } sctx->containers = st->next; - free (st); + free(st); } } -void -ucl_object_emit_streamline_finish (struct ucl_emitter_context *ctx) +void ucl_object_emit_streamline_finish(struct ucl_emitter_context *ctx) { struct ucl_emitter_context_streamline *sctx = TO_STREAMLINE(ctx); while (sctx->containers != NULL) { - ucl_object_emit_streamline_end_container (ctx); + ucl_object_emit_streamline_end_container(ctx); } - free (sctx); + free(sctx); } diff --git a/contrib/libucl/src/ucl_emitter_utils.c b/contrib/libucl/src/ucl_emitter_utils.c index b9f7de8f0224..7f966228bba2 100644 --- a/contrib/libucl/src/ucl_emitter_utils.c +++ b/contrib/libucl/src/ucl_emitter_utils.c @@ -1,548 +1,521 @@ /* Copyright (c) 2014, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ucl.h" #include "ucl_internal.h" #include "ucl_chartable.h" #ifdef HAVE_FLOAT_H #include #endif #ifdef HAVE_MATH_H #include #endif extern const struct ucl_emitter_operations ucl_standartd_emitter_ops[]; static const struct ucl_emitter_context ucl_standard_emitters[] = { [UCL_EMIT_JSON] = { .name = "json", .id = UCL_EMIT_JSON, .func = NULL, - .ops = &ucl_standartd_emitter_ops[UCL_EMIT_JSON] - }, - [UCL_EMIT_JSON_COMPACT] = { - .name = "json_compact", - .id = UCL_EMIT_JSON_COMPACT, - .func = NULL, - .ops = &ucl_standartd_emitter_ops[UCL_EMIT_JSON_COMPACT] - }, - [UCL_EMIT_CONFIG] = { - .name = "config", - .id = UCL_EMIT_CONFIG, - .func = NULL, - .ops = &ucl_standartd_emitter_ops[UCL_EMIT_CONFIG] - }, - [UCL_EMIT_YAML] = { - .name = "yaml", - .id = UCL_EMIT_YAML, - .func = NULL, - .ops = &ucl_standartd_emitter_ops[UCL_EMIT_YAML] - }, - [UCL_EMIT_MSGPACK] = { - .name = "msgpack", - .id = UCL_EMIT_MSGPACK, - .func = NULL, - .ops = &ucl_standartd_emitter_ops[UCL_EMIT_MSGPACK] - } -}; + .ops = &ucl_standartd_emitter_ops[UCL_EMIT_JSON]}, + [UCL_EMIT_JSON_COMPACT] = {.name = "json_compact", .id = UCL_EMIT_JSON_COMPACT, .func = NULL, .ops = &ucl_standartd_emitter_ops[UCL_EMIT_JSON_COMPACT]}, + [UCL_EMIT_CONFIG] = {.name = "config", .id = UCL_EMIT_CONFIG, .func = NULL, .ops = &ucl_standartd_emitter_ops[UCL_EMIT_CONFIG]}, + [UCL_EMIT_YAML] = {.name = "yaml", .id = UCL_EMIT_YAML, .func = NULL, .ops = &ucl_standartd_emitter_ops[UCL_EMIT_YAML]}, + [UCL_EMIT_MSGPACK] = {.name = "msgpack", .id = UCL_EMIT_MSGPACK, .func = NULL, .ops = &ucl_standartd_emitter_ops[UCL_EMIT_MSGPACK]}}; static inline void _ucl_emitter_free(void *p) { - free(p); + free(p); } /** * Get standard emitter context for a specified emit_type * @param emit_type type of emitter * @return context or NULL if input is invalid */ const struct ucl_emitter_context * -ucl_emit_get_standard_context (enum ucl_emitter emit_type) +ucl_emit_get_standard_context(enum ucl_emitter emit_type) { if (emit_type >= UCL_EMIT_JSON && emit_type < UCL_EMIT_MAX) { return &ucl_standard_emitters[emit_type]; } return NULL; } /** * Serialise string * @param str string to emit * @param buf target buffer */ -void -ucl_elt_string_write_json (const char *str, size_t size, - struct ucl_emitter_context *ctx) +void ucl_elt_string_write_json(const char *str, size_t size, + struct ucl_emitter_context *ctx) { const char *p = str, *c = str; size_t len = 0; const struct ucl_emitter_functions *func = ctx->func; - func->ucl_emitter_append_character ('"', 1, func->ud); + func->ucl_emitter_append_character('"', 1, func->ud); while (size) { - if (ucl_test_character (*p, (UCL_CHARACTER_JSON_UNSAFE| - UCL_CHARACTER_DENIED| - UCL_CHARACTER_WHITESPACE_UNSAFE))) { + if (ucl_test_character(*p, (UCL_CHARACTER_JSON_UNSAFE | + UCL_CHARACTER_DENIED | + UCL_CHARACTER_WHITESPACE_UNSAFE))) { if (len > 0) { - func->ucl_emitter_append_len (c, len, func->ud); + func->ucl_emitter_append_len(c, len, func->ud); } switch (*p) { case '\n': - func->ucl_emitter_append_len ("\\n", 2, func->ud); + func->ucl_emitter_append_len("\\n", 2, func->ud); break; case '\r': - func->ucl_emitter_append_len ("\\r", 2, func->ud); + func->ucl_emitter_append_len("\\r", 2, func->ud); break; case '\b': - func->ucl_emitter_append_len ("\\b", 2, func->ud); + func->ucl_emitter_append_len("\\b", 2, func->ud); break; case '\t': - func->ucl_emitter_append_len ("\\t", 2, func->ud); + func->ucl_emitter_append_len("\\t", 2, func->ud); break; case '\f': - func->ucl_emitter_append_len ("\\f", 2, func->ud); + func->ucl_emitter_append_len("\\f", 2, func->ud); break; case '\v': - func->ucl_emitter_append_len ("\\u000B", 6, func->ud); + func->ucl_emitter_append_len("\\u000B", 6, func->ud); break; case '\\': - func->ucl_emitter_append_len ("\\\\", 2, func->ud); + func->ucl_emitter_append_len("\\\\", 2, func->ud); break; case ' ': - func->ucl_emitter_append_character (' ', 1, func->ud); + func->ucl_emitter_append_character(' ', 1, func->ud); break; case '"': - func->ucl_emitter_append_len ("\\\"", 2, func->ud); + func->ucl_emitter_append_len("\\\"", 2, func->ud); break; default: /* Emit unicode unknown character */ - func->ucl_emitter_append_len ("\\uFFFD", 6, func->ud); + func->ucl_emitter_append_len("\\uFFFD", 6, func->ud); break; } len = 0; c = ++p; } else { - p ++; - len ++; + p++; + len++; } - size --; + size--; } if (len > 0) { - func->ucl_emitter_append_len (c, len, func->ud); + func->ucl_emitter_append_len(c, len, func->ud); } - func->ucl_emitter_append_character ('"', 1, func->ud); + func->ucl_emitter_append_character('"', 1, func->ud); } -void -ucl_elt_string_write_squoted (const char *str, size_t size, - struct ucl_emitter_context *ctx) +void ucl_elt_string_write_squoted(const char *str, size_t size, + struct ucl_emitter_context *ctx) { const char *p = str, *c = str; size_t len = 0; const struct ucl_emitter_functions *func = ctx->func; - func->ucl_emitter_append_character ('\'', 1, func->ud); + func->ucl_emitter_append_character('\'', 1, func->ud); while (size) { if (*p == '\'') { if (len > 0) { - func->ucl_emitter_append_len (c, len, func->ud); + func->ucl_emitter_append_len(c, len, func->ud); } len = 0; c = ++p; - func->ucl_emitter_append_len ("\\\'", 2, func->ud); + func->ucl_emitter_append_len("\\\'", 2, func->ud); } else { - p ++; - len ++; + p++; + len++; } - size --; + size--; } if (len > 0) { - func->ucl_emitter_append_len (c, len, func->ud); + func->ucl_emitter_append_len(c, len, func->ud); } - func->ucl_emitter_append_character ('\'', 1, func->ud); + func->ucl_emitter_append_character('\'', 1, func->ud); } -void -ucl_elt_string_write_multiline (const char *str, size_t size, - struct ucl_emitter_context *ctx) +void ucl_elt_string_write_multiline(const char *str, size_t size, + struct ucl_emitter_context *ctx) { const struct ucl_emitter_functions *func = ctx->func; - func->ucl_emitter_append_len ("<ud); - func->ucl_emitter_append_len (str, size, func->ud); - func->ucl_emitter_append_len ("\nEOD", sizeof ("\nEOD") - 1, func->ud); + func->ucl_emitter_append_len("<ud); + func->ucl_emitter_append_len(str, size, func->ud); + func->ucl_emitter_append_len("\nEOD", sizeof("\nEOD") - 1, func->ud); } /* * Generic utstring output */ static int -ucl_utstring_append_character (unsigned char c, size_t len, void *ud) +ucl_utstring_append_character(unsigned char c, size_t len, void *ud) { UT_string *buf = ud; if (len == 1) { - utstring_append_c (buf, c); + utstring_append_c(buf, c); } else { - utstring_reserve (buf, len + 1); - memset (&buf->d[buf->i], c, len); + utstring_reserve(buf, len + 1); + memset(&buf->d[buf->i], c, len); buf->i += len; buf->d[buf->i] = '\0'; } return 0; } static int -ucl_utstring_append_len (const unsigned char *str, size_t len, void *ud) +ucl_utstring_append_len(const unsigned char *str, size_t len, void *ud) { UT_string *buf = ud; - utstring_append_len (buf, str, len); + utstring_append_len(buf, str, len); return 0; } static int -ucl_utstring_append_int (int64_t val, void *ud) +ucl_utstring_append_int(int64_t val, void *ud) { UT_string *buf = ud; - utstring_printf (buf, "%jd", (intmax_t)val); + utstring_printf(buf, "%jd", (intmax_t) val); return 0; } static int -ucl_utstring_append_double (double val, void *ud) +ucl_utstring_append_double(double val, void *ud) { UT_string *buf = ud; const double delta = 0.0000001; - if (val == (double)(int)val) { - utstring_printf (buf, "%.1lf", val); + if (val == (double) (int) val) { + utstring_printf(buf, "%.1lf", val); } - else if (fabs (val - (double)(int)val) < delta) { + else if (fabs(val - (double) (int) val) < delta) { /* Write at maximum precision */ - utstring_printf (buf, "%.*lg", DBL_DIG, val); + utstring_printf(buf, "%.*lg", DBL_DIG, val); } else { - utstring_printf (buf, "%lf", val); + utstring_printf(buf, "%lf", val); } return 0; } /* * Generic file output */ static int -ucl_file_append_character (unsigned char c, size_t len, void *ud) +ucl_file_append_character(unsigned char c, size_t len, void *ud) { FILE *fp = ud; - while (len --) { - fputc (c, fp); + while (len--) { + fputc(c, fp); } return 0; } static int -ucl_file_append_len (const unsigned char *str, size_t len, void *ud) +ucl_file_append_len(const unsigned char *str, size_t len, void *ud) { FILE *fp = ud; - fwrite (str, len, 1, fp); + fwrite(str, len, 1, fp); return 0; } static int -ucl_file_append_int (int64_t val, void *ud) +ucl_file_append_int(int64_t val, void *ud) { FILE *fp = ud; - fprintf (fp, "%jd", (intmax_t)val); + fprintf(fp, "%jd", (intmax_t) val); return 0; } static int -ucl_file_append_double (double val, void *ud) +ucl_file_append_double(double val, void *ud) { FILE *fp = ud; const double delta = 0.0000001; - if (val == (double)(int)val) { - fprintf (fp, "%.1lf", val); + if (val == (double) (int) val) { + fprintf(fp, "%.1lf", val); } - else if (fabs (val - (double)(int)val) < delta) { + else if (fabs(val - (double) (int) val) < delta) { /* Write at maximum precision */ - fprintf (fp, "%.*lg", DBL_DIG, val); + fprintf(fp, "%.*lg", DBL_DIG, val); } else { - fprintf (fp, "%lf", val); + fprintf(fp, "%lf", val); } return 0; } /* * Generic file descriptor writing functions */ static int -ucl_fd_append_character (unsigned char c, size_t len, void *ud) +ucl_fd_append_character(unsigned char c, size_t len, void *ud) { - int fd = *(int *)ud; + int fd = *(int *) ud; unsigned char *buf; if (len == 1) { - return write (fd, &c, 1); + return write(fd, &c, 1); } else { - buf = malloc (len); + buf = malloc(len); if (buf == NULL) { /* Fallback */ - while (len --) { - if (write (fd, &c, 1) == -1) { + while (len--) { + if (write(fd, &c, 1) == -1) { return -1; } } } else { - memset (buf, c, len); - if (write (fd, buf, len) == -1) { + memset(buf, c, len); + if (write(fd, buf, len) == -1) { free(buf); return -1; } - free (buf); + free(buf); } } return 0; } static int -ucl_fd_append_len (const unsigned char *str, size_t len, void *ud) +ucl_fd_append_len(const unsigned char *str, size_t len, void *ud) { - int fd = *(int *)ud; + int fd = *(int *) ud; - return write (fd, str, len); + return write(fd, str, len); } static int -ucl_fd_append_int (int64_t val, void *ud) +ucl_fd_append_int(int64_t val, void *ud) { - int fd = *(int *)ud; + int fd = *(int *) ud; char intbuf[64]; - snprintf (intbuf, sizeof (intbuf), "%jd", (intmax_t)val); - return write (fd, intbuf, strlen (intbuf)); + snprintf(intbuf, sizeof(intbuf), "%jd", (intmax_t) val); + return write(fd, intbuf, strlen(intbuf)); } static int -ucl_fd_append_double (double val, void *ud) +ucl_fd_append_double(double val, void *ud) { - int fd = *(int *)ud; + int fd = *(int *) ud; const double delta = 0.0000001; char nbuf[64]; - if (val == (double)(int)val) { - snprintf (nbuf, sizeof (nbuf), "%.1lf", val); + if (val == (double) (int) val) { + snprintf(nbuf, sizeof(nbuf), "%.1lf", val); } - else if (fabs (val - (double)(int)val) < delta) { + else if (fabs(val - (double) (int) val) < delta) { /* Write at maximum precision */ - snprintf (nbuf, sizeof (nbuf), "%.*lg", DBL_DIG, val); + snprintf(nbuf, sizeof(nbuf), "%.*lg", DBL_DIG, val); } else { - snprintf (nbuf, sizeof (nbuf), "%lf", val); + snprintf(nbuf, sizeof(nbuf), "%lf", val); } - return write (fd, nbuf, strlen (nbuf)); + return write(fd, nbuf, strlen(nbuf)); } -struct ucl_emitter_functions* -ucl_object_emit_memory_funcs (void **pmem) +struct ucl_emitter_functions * +ucl_object_emit_memory_funcs(void **pmem) { struct ucl_emitter_functions *f; UT_string *s; - f = calloc (1, sizeof (*f)); + f = calloc(1, sizeof(*f)); if (f != NULL) { f->ucl_emitter_append_character = ucl_utstring_append_character; f->ucl_emitter_append_double = ucl_utstring_append_double; f->ucl_emitter_append_int = ucl_utstring_append_int; f->ucl_emitter_append_len = ucl_utstring_append_len; f->ucl_emitter_free_func = _ucl_emitter_free; - utstring_new (s); + utstring_new(s); f->ud = s; *pmem = s->d; s->pd = pmem; } return f; } -struct ucl_emitter_functions* -ucl_object_emit_file_funcs (FILE *fp) +struct ucl_emitter_functions * +ucl_object_emit_file_funcs(FILE *fp) { struct ucl_emitter_functions *f; - f = calloc (1, sizeof (*f)); + f = calloc(1, sizeof(*f)); if (f != NULL) { f->ucl_emitter_append_character = ucl_file_append_character; f->ucl_emitter_append_double = ucl_file_append_double; f->ucl_emitter_append_int = ucl_file_append_int; f->ucl_emitter_append_len = ucl_file_append_len; f->ucl_emitter_free_func = NULL; f->ud = fp; } return f; } -struct ucl_emitter_functions* -ucl_object_emit_fd_funcs (int fd) +struct ucl_emitter_functions * +ucl_object_emit_fd_funcs(int fd) { struct ucl_emitter_functions *f; int *ip; - f = calloc (1, sizeof (*f)); + f = calloc(1, sizeof(*f)); if (f != NULL) { - ip = malloc (sizeof (fd)); + ip = malloc(sizeof(fd)); if (ip == NULL) { - free (f); + free(f); return NULL; } - memcpy (ip, &fd, sizeof (fd)); + memcpy(ip, &fd, sizeof(fd)); f->ucl_emitter_append_character = ucl_fd_append_character; f->ucl_emitter_append_double = ucl_fd_append_double; f->ucl_emitter_append_int = ucl_fd_append_int; f->ucl_emitter_append_len = ucl_fd_append_len; f->ucl_emitter_free_func = _ucl_emitter_free; f->ud = ip; } return f; } -void -ucl_object_emit_funcs_free (struct ucl_emitter_functions *f) +void ucl_object_emit_funcs_free(struct ucl_emitter_functions *f) { if (f != NULL) { if (f->ucl_emitter_free_func != NULL) { - f->ucl_emitter_free_func (f->ud); + f->ucl_emitter_free_func(f->ud); } - free (f); + free(f); } } unsigned char * -ucl_object_emit_single_json (const ucl_object_t *obj) +ucl_object_emit_single_json(const ucl_object_t *obj) { UT_string *buf = NULL; unsigned char *res = NULL; if (obj == NULL) { return NULL; } - utstring_new (buf); + utstring_new(buf); if (buf != NULL) { switch (obj->type) { case UCL_OBJECT: - ucl_utstring_append_len ("object", 6, buf); + ucl_utstring_append_len("object", 6, buf); break; case UCL_ARRAY: - ucl_utstring_append_len ("array", 5, buf); + ucl_utstring_append_len("array", 5, buf); break; case UCL_INT: - ucl_utstring_append_int (obj->value.iv, buf); + ucl_utstring_append_int(obj->value.iv, buf); break; case UCL_FLOAT: case UCL_TIME: - ucl_utstring_append_double (obj->value.dv, buf); + ucl_utstring_append_double(obj->value.dv, buf); break; case UCL_NULL: - ucl_utstring_append_len ("null", 4, buf); + ucl_utstring_append_len("null", 4, buf); break; case UCL_BOOLEAN: if (obj->value.iv) { - ucl_utstring_append_len ("true", 4, buf); + ucl_utstring_append_len("true", 4, buf); } else { - ucl_utstring_append_len ("false", 5, buf); + ucl_utstring_append_len("false", 5, buf); } break; case UCL_STRING: - ucl_utstring_append_len (obj->value.sv, obj->len, buf); + ucl_utstring_append_len(obj->value.sv, obj->len, buf); break; case UCL_USERDATA: - ucl_utstring_append_len ("userdata", 8, buf); + ucl_utstring_append_len("userdata", 8, buf); break; } - res = utstring_body (buf); - free (buf); + res = utstring_body(buf); + free(buf); } return res; } #define LONG_STRING_LIMIT 80 -bool -ucl_maybe_long_string (const ucl_object_t *obj) +bool ucl_maybe_long_string(const ucl_object_t *obj) { if (obj->len > LONG_STRING_LIMIT || (obj->flags & UCL_OBJECT_MULTILINE)) { /* String is long enough, so search for newline characters in it */ - if (memchr (obj->value.sv, '\n', obj->len) != NULL) { + if (memchr(obj->value.sv, '\n', obj->len) != NULL) { return true; } } return false; } diff --git a/contrib/libucl/src/ucl_hash.c b/contrib/libucl/src/ucl_hash.c index 0208cfd29c9a..d648f405951b 100644 --- a/contrib/libucl/src/ucl_hash.c +++ b/contrib/libucl/src/ucl_hash.c @@ -1,629 +1,631 @@ /* Copyright (c) 2013, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ucl_internal.h" #include "ucl_hash.h" #include "khash.h" #include "kvec.h" #include "mum.h" #include #include struct ucl_hash_elt { const ucl_object_t *obj; struct ucl_hash_elt *prev, *next; }; struct ucl_hash_struct { void *hash; struct ucl_hash_elt *head; bool caseless; }; static uint64_t -ucl_hash_seed (void) +ucl_hash_seed(void) { static uint64_t seed; if (seed == 0) { #ifdef UCL_RANDOM_FUNCTION seed = UCL_RANDOM_FUNCTION; #else /* Not very random but can be useful for our purposes */ - seed = time (NULL); + seed = time(NULL); #endif } return seed; } static const unsigned char lc_map[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -#if (defined(WORD_BIT) && WORD_BIT == 64) || \ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff}; + +#if (defined(WORD_BIT) && WORD_BIT == 64) || \ (defined(__WORDSIZE) && __WORDSIZE == 64) || \ - defined(__x86_64__) || \ + defined(__x86_64__) || \ defined(__amd64__) #define UCL64_BIT_HASH 1 #endif static inline uint32_t -ucl_hash_func (const ucl_object_t *o) +ucl_hash_func(const ucl_object_t *o) { - return mum_hash (o->key, o->keylen, ucl_hash_seed ()); + return mum_hash(o->key, o->keylen, ucl_hash_seed()); } static inline int -ucl_hash_equal (const ucl_object_t *k1, const ucl_object_t *k2) +ucl_hash_equal(const ucl_object_t *k1, const ucl_object_t *k2) { if (k1->keylen == k2->keylen) { - return memcmp (k1->key, k2->key, k1->keylen) == 0; + return memcmp(k1->key, k2->key, k1->keylen) == 0; } return 0; } -KHASH_INIT (ucl_hash_node, const ucl_object_t *, struct ucl_hash_elt *, 1, - ucl_hash_func, ucl_hash_equal) +KHASH_INIT(ucl_hash_node, const ucl_object_t *, struct ucl_hash_elt *, 1, + ucl_hash_func, ucl_hash_equal) static inline uint32_t -ucl_hash_caseless_func (const ucl_object_t *o) +ucl_hash_caseless_func(const ucl_object_t *o) { unsigned len = o->keylen; unsigned leftover = o->keylen % 8; unsigned fp, i; - const uint8_t* s = (const uint8_t*)o->key; + const uint8_t *s = (const uint8_t *) o->key; union { struct { unsigned char c1, c2, c3, c4, c5, c6, c7, c8; } c; uint64_t pp; } u; uint64_t r; fp = len - leftover; - r = ucl_hash_seed (); + r = ucl_hash_seed(); for (i = 0; i != fp; i += 8) { u.c.c1 = s[i], u.c.c2 = s[i + 1], u.c.c3 = s[i + 2], u.c.c4 = s[i + 3]; u.c.c5 = s[i + 4], u.c.c6 = s[i + 5], u.c.c7 = s[i + 6], u.c.c8 = s[i + 7]; u.c.c1 = lc_map[u.c.c1]; u.c.c2 = lc_map[u.c.c2]; u.c.c3 = lc_map[u.c.c3]; u.c.c4 = lc_map[u.c.c4]; u.c.c5 = lc_map[u.c.c5]; u.c.c6 = lc_map[u.c.c6]; u.c.c7 = lc_map[u.c.c7]; u.c.c8 = lc_map[u.c.c8]; - r = mum_hash_step (r, u.pp); + r = mum_hash_step(r, u.pp); } u.pp = 0; switch (leftover) { case 7: - u.c.c7 = lc_map[(unsigned char)s[i++]]; + u.c.c7 = lc_map[(unsigned char) s[i++]]; /* FALLTHRU */ case 6: - u.c.c6 = lc_map[(unsigned char)s[i++]]; + u.c.c6 = lc_map[(unsigned char) s[i++]]; /* FALLTHRU */ case 5: - u.c.c5 = lc_map[(unsigned char)s[i++]]; + u.c.c5 = lc_map[(unsigned char) s[i++]]; /* FALLTHRU */ case 4: - u.c.c4 = lc_map[(unsigned char)s[i++]]; + u.c.c4 = lc_map[(unsigned char) s[i++]]; /* FALLTHRU */ case 3: - u.c.c3 = lc_map[(unsigned char)s[i++]]; + u.c.c3 = lc_map[(unsigned char) s[i++]]; /* FALLTHRU */ case 2: - u.c.c2 = lc_map[(unsigned char)s[i++]]; + u.c.c2 = lc_map[(unsigned char) s[i++]]; /* FALLTHRU */ case 1: - u.c.c1 = lc_map[(unsigned char)s[i]]; - r = mum_hash_step (r, u.pp); + u.c.c1 = lc_map[(unsigned char) s[i]]; + r = mum_hash_step(r, u.pp); break; } - return mum_hash_finish (r); + return mum_hash_finish(r); } static inline int -ucl_hash_caseless_equal (const ucl_object_t *k1, const ucl_object_t *k2) +ucl_hash_caseless_equal(const ucl_object_t *k1, const ucl_object_t *k2) { if (k1->keylen == k2->keylen) { unsigned fp, i; const char *s = k1->key, *d = k2->key; unsigned char c1, c2, c3, c4; union { unsigned char c[4]; uint32_t n; } cmp1, cmp2; size_t leftover = k1->keylen % 4; fp = k1->keylen - leftover; for (i = 0; i != fp; i += 4) { c1 = s[i], c2 = s[i + 1], c3 = s[i + 2], c4 = s[i + 3]; cmp1.c[0] = lc_map[c1]; cmp1.c[1] = lc_map[c2]; cmp1.c[2] = lc_map[c3]; cmp1.c[3] = lc_map[c4]; c1 = d[i], c2 = d[i + 1], c3 = d[i + 2], c4 = d[i + 3]; cmp2.c[0] = lc_map[c1]; cmp2.c[1] = lc_map[c2]; cmp2.c[2] = lc_map[c3]; cmp2.c[3] = lc_map[c4]; if (cmp1.n != cmp2.n) { return 0; } } while (leftover > 0) { - if (lc_map[(unsigned char)s[i]] != lc_map[(unsigned char)d[i]]) { + if (lc_map[(unsigned char) s[i]] != lc_map[(unsigned char) d[i]]) { return 0; } leftover--; i++; } return 1; } return 0; } -KHASH_INIT (ucl_hash_caseless_node, const ucl_object_t *, struct ucl_hash_elt *, 1, - ucl_hash_caseless_func, ucl_hash_caseless_equal) +KHASH_INIT(ucl_hash_caseless_node, const ucl_object_t *, struct ucl_hash_elt *, 1, + ucl_hash_caseless_func, ucl_hash_caseless_equal) -ucl_hash_t* -ucl_hash_create (bool ignore_case) +ucl_hash_t * +ucl_hash_create(bool ignore_case) { ucl_hash_t *new; - new = UCL_ALLOC (sizeof (ucl_hash_t)); + new = UCL_ALLOC(sizeof(ucl_hash_t)); if (new != NULL) { void *h; new->head = NULL; new->caseless = ignore_case; if (ignore_case) { - h = (void *)kh_init (ucl_hash_caseless_node); + h = (void *) kh_init(ucl_hash_caseless_node); } else { - h = (void *)kh_init (ucl_hash_node); + h = (void *) kh_init(ucl_hash_node); } if (h == NULL) { - UCL_FREE (sizeof (ucl_hash_t), new); + UCL_FREE(sizeof(ucl_hash_t), new); return NULL; } new->hash = h; } return new; } -void ucl_hash_destroy (ucl_hash_t* hashlin, ucl_hash_free_func func) +void ucl_hash_destroy(ucl_hash_t *hashlin, ucl_hash_free_func func) { if (hashlin == NULL) { return; } if (func != NULL) { /* Iterate over the hash first */ khash_t(ucl_hash_node) *h = (khash_t(ucl_hash_node) *) - hashlin->hash; + hashlin->hash; khiter_t k; const ucl_object_t *cur, *tmp; - for (k = kh_begin (h); k != kh_end (h); ++k) { - if (kh_exist (h, k)) { - cur = (kh_value (h, k))->obj; + for (k = kh_begin(h); k != kh_end(h); ++k) { + if (kh_exist(h, k)) { + cur = (kh_value(h, k))->obj; while (cur != NULL) { tmp = cur->next; - func (__DECONST (ucl_object_t *, cur)); + func(__DECONST(ucl_object_t *, cur)); cur = tmp; } } } } if (hashlin->caseless) { khash_t(ucl_hash_caseless_node) *h = (khash_t(ucl_hash_caseless_node) *) - hashlin->hash; - kh_destroy (ucl_hash_caseless_node, h); + hashlin->hash; + kh_destroy(ucl_hash_caseless_node, h); } else { khash_t(ucl_hash_node) *h = (khash_t(ucl_hash_node) *) - hashlin->hash; - kh_destroy (ucl_hash_node, h); + hashlin->hash; + kh_destroy(ucl_hash_node, h); } struct ucl_hash_elt *cur, *tmp; - DL_FOREACH_SAFE(hashlin->head, cur, tmp) { + DL_FOREACH_SAFE(hashlin->head, cur, tmp) + { UCL_FREE(sizeof(*cur), cur); } - UCL_FREE (sizeof (*hashlin), hashlin); + UCL_FREE(sizeof(*hashlin), hashlin); } -bool -ucl_hash_insert (ucl_hash_t* hashlin, const ucl_object_t *obj, - const char *key, unsigned keylen) +bool ucl_hash_insert(ucl_hash_t *hashlin, const ucl_object_t *obj, + const char *key, unsigned keylen) { khiter_t k; int ret; struct ucl_hash_elt **pelt, *elt; if (hashlin == NULL) { return false; } if (hashlin->caseless) { khash_t(ucl_hash_caseless_node) *h = (khash_t(ucl_hash_caseless_node) *) - hashlin->hash; - k = kh_put (ucl_hash_caseless_node, h, obj, &ret); + hashlin->hash; + k = kh_put(ucl_hash_caseless_node, h, obj, &ret); if (ret > 0) { elt = UCL_ALLOC(sizeof(*elt)); - pelt = &kh_value (h, k); + pelt = &kh_value(h, k); *pelt = elt; DL_APPEND(hashlin->head, elt); elt->obj = obj; } else if (ret < 0) { goto e0; } } else { khash_t(ucl_hash_node) *h = (khash_t(ucl_hash_node) *) - hashlin->hash; - k = kh_put (ucl_hash_node, h, obj, &ret); + hashlin->hash; + k = kh_put(ucl_hash_node, h, obj, &ret); if (ret > 0) { elt = UCL_ALLOC(sizeof(*elt)); - pelt = &kh_value (h, k); + pelt = &kh_value(h, k); *pelt = elt; DL_APPEND(hashlin->head, elt); elt->obj = obj; - } else if (ret < 0) { + } + else if (ret < 0) { goto e0; } } return true; e0: return false; } -void ucl_hash_replace (ucl_hash_t* hashlin, const ucl_object_t *old, - const ucl_object_t *new) +void ucl_hash_replace(ucl_hash_t *hashlin, const ucl_object_t *old, + const ucl_object_t *new) { khiter_t k; int ret; struct ucl_hash_elt *elt, *nelt; if (hashlin == NULL) { return; } if (hashlin->caseless) { khash_t(ucl_hash_caseless_node) *h = (khash_t(ucl_hash_caseless_node) *) - hashlin->hash; - k = kh_put (ucl_hash_caseless_node, h, old, &ret); + hashlin->hash; + k = kh_put(ucl_hash_caseless_node, h, old, &ret); if (ret == 0) { elt = kh_value(h, k); - kh_del (ucl_hash_caseless_node, h, k); - k = kh_put (ucl_hash_caseless_node, h, new, &ret); + kh_del(ucl_hash_caseless_node, h, k); + k = kh_put(ucl_hash_caseless_node, h, new, &ret); nelt = UCL_ALLOC(sizeof(*nelt)); nelt->obj = new; kh_value(h, k) = nelt; DL_REPLACE_ELEM(hashlin->head, elt, nelt); UCL_FREE(sizeof(*elt), elt); } } else { khash_t(ucl_hash_node) *h = (khash_t(ucl_hash_node) *) - hashlin->hash; - k = kh_put (ucl_hash_node, h, old, &ret); + hashlin->hash; + k = kh_put(ucl_hash_node, h, old, &ret); if (ret == 0) { - elt = kh_value (h, k); - kh_del (ucl_hash_node, h, k); - k = kh_put (ucl_hash_node, h, new, &ret); + elt = kh_value(h, k); + kh_del(ucl_hash_node, h, k); + k = kh_put(ucl_hash_node, h, new, &ret); nelt = UCL_ALLOC(sizeof(*nelt)); nelt->obj = new; kh_value(h, k) = nelt; DL_REPLACE_ELEM(hashlin->head, elt, nelt); UCL_FREE(sizeof(*elt), elt); } } } struct ucl_hash_real_iter { const struct ucl_hash_elt *cur; }; -#define UHI_SETERR(ep, ern) {if (ep != NULL) *ep = (ern);} +#define UHI_SETERR(ep, ern) \ + { \ + if (ep != NULL) *ep = (ern); \ + } -const void* -ucl_hash_iterate2 (ucl_hash_t *hashlin, ucl_hash_iter_t *iter, int *ep) +const void * +ucl_hash_iterate2(ucl_hash_t *hashlin, ucl_hash_iter_t *iter, int *ep) { - struct ucl_hash_real_iter *it = (struct ucl_hash_real_iter *)(*iter); + struct ucl_hash_real_iter *it = (struct ucl_hash_real_iter *) (*iter); const ucl_object_t *ret = NULL; if (hashlin == NULL) { UHI_SETERR(ep, EINVAL); return NULL; } if (it == NULL) { - it = UCL_ALLOC (sizeof (*it)); + it = UCL_ALLOC(sizeof(*it)); if (it == NULL) { UHI_SETERR(ep, ENOMEM); return NULL; } it->cur = hashlin->head; } UHI_SETERR(ep, 0); if (it->cur) { ret = it->cur->obj; it->cur = it->cur->next; } else { - UCL_FREE (sizeof (*it), it); + UCL_FREE(sizeof(*it), it); *iter = NULL; return NULL; } *iter = it; return ret; } -bool -ucl_hash_iter_has_next (ucl_hash_t *hashlin, ucl_hash_iter_t iter) +bool ucl_hash_iter_has_next(ucl_hash_t *hashlin, ucl_hash_iter_t iter) { - struct ucl_hash_real_iter *it = (struct ucl_hash_real_iter *)(iter); + struct ucl_hash_real_iter *it = (struct ucl_hash_real_iter *) (iter); return it->cur != NULL; } -const ucl_object_t* -ucl_hash_search (ucl_hash_t* hashlin, const char *key, unsigned keylen) +const ucl_object_t * +ucl_hash_search(ucl_hash_t *hashlin, const char *key, unsigned keylen) { khiter_t k; const ucl_object_t *ret = NULL; ucl_object_t search; struct ucl_hash_elt *elt; search.key = key; search.keylen = keylen; if (hashlin == NULL) { return NULL; } if (hashlin->caseless) { khash_t(ucl_hash_caseless_node) *h = (khash_t(ucl_hash_caseless_node) *) - hashlin->hash; + hashlin->hash; - k = kh_get (ucl_hash_caseless_node, h, &search); - if (k != kh_end (h)) { - elt = kh_value (h, k); + k = kh_get(ucl_hash_caseless_node, h, &search); + if (k != kh_end(h)) { + elt = kh_value(h, k); ret = elt->obj; } } else { khash_t(ucl_hash_node) *h = (khash_t(ucl_hash_node) *) - hashlin->hash; - k = kh_get (ucl_hash_node, h, &search); - if (k != kh_end (h)) { - elt = kh_value (h, k); + hashlin->hash; + k = kh_get(ucl_hash_node, h, &search); + if (k != kh_end(h)) { + elt = kh_value(h, k); ret = elt->obj; } } return ret; } -void -ucl_hash_delete (ucl_hash_t* hashlin, const ucl_object_t *obj) +void ucl_hash_delete(ucl_hash_t *hashlin, const ucl_object_t *obj) { khiter_t k; struct ucl_hash_elt *elt; if (hashlin == NULL) { return; } if (hashlin->caseless) { khash_t(ucl_hash_caseless_node) *h = (khash_t(ucl_hash_caseless_node) *) - hashlin->hash; + hashlin->hash; - k = kh_get (ucl_hash_caseless_node, h, obj); - if (k != kh_end (h)) { - elt = kh_value (h, k); + k = kh_get(ucl_hash_caseless_node, h, obj); + if (k != kh_end(h)) { + elt = kh_value(h, k); DL_DELETE(hashlin->head, elt); - kh_del (ucl_hash_caseless_node, h, k); + kh_del(ucl_hash_caseless_node, h, k); UCL_FREE(sizeof(*elt), elt); } } else { khash_t(ucl_hash_node) *h = (khash_t(ucl_hash_node) *) - hashlin->hash; - k = kh_get (ucl_hash_node, h, obj); - if (k != kh_end (h)) { - elt = kh_value (h, k); + hashlin->hash; + k = kh_get(ucl_hash_node, h, obj); + if (k != kh_end(h)) { + elt = kh_value(h, k); DL_DELETE(hashlin->head, elt); - kh_del (ucl_hash_node, h, k); + kh_del(ucl_hash_node, h, k); UCL_FREE(sizeof(*elt), elt); } } } -bool ucl_hash_reserve (ucl_hash_t *hashlin, size_t sz) +bool ucl_hash_reserve(ucl_hash_t *hashlin, size_t sz) { if (hashlin == NULL) { return false; } - if (sz > kh_size((khash_t(ucl_hash_node) *)hashlin->hash)) { + if (sz > kh_size((khash_t(ucl_hash_node) *) hashlin->hash)) { if (hashlin->caseless) { khash_t(ucl_hash_caseless_node) *h = (khash_t( - ucl_hash_caseless_node) *) - hashlin->hash; - kh_resize (ucl_hash_caseless_node, h, sz * 2); - } else { + ucl_hash_caseless_node) *) + hashlin->hash; + kh_resize(ucl_hash_caseless_node, h, sz * 2); + } + else { khash_t(ucl_hash_node) *h = (khash_t(ucl_hash_node) *) - hashlin->hash; - kh_resize (ucl_hash_node, h, sz * 2); + hashlin->hash; + kh_resize(ucl_hash_node, h, sz * 2); } } return true; } static int -ucl_lc_cmp (const char *s, const char *d, size_t l) +ucl_lc_cmp(const char *s, const char *d, size_t l) { unsigned int fp, i; unsigned char c1, c2, c3, c4; union { unsigned char c[4]; uint32_t n; } cmp1, cmp2; size_t leftover = l % 4; int ret = 0; fp = l - leftover; for (i = 0; i != fp; i += 4) { c1 = s[i], c2 = s[i + 1], c3 = s[i + 2], c4 = s[i + 3]; cmp1.c[0] = lc_map[c1]; cmp1.c[1] = lc_map[c2]; cmp1.c[2] = lc_map[c3]; cmp1.c[3] = lc_map[c4]; c1 = d[i], c2 = d[i + 1], c3 = d[i + 2], c4 = d[i + 3]; cmp2.c[0] = lc_map[c1]; cmp2.c[1] = lc_map[c2]; cmp2.c[2] = lc_map[c3]; cmp2.c[3] = lc_map[c4]; if (cmp1.n != cmp2.n) { return cmp1.n - cmp2.n; } } while (leftover > 0) { - if (lc_map[(unsigned char)s[i]] != lc_map[(unsigned char)d[i]]) { + if (lc_map[(unsigned char) s[i]] != lc_map[(unsigned char) d[i]]) { return s[i] - d[i]; } leftover--; i++; } return ret; } static int -ucl_hash_cmp_icase (const void *a, const void *b) +ucl_hash_cmp_icase(const void *a, const void *b) { - const struct ucl_hash_elt *oa = (const struct ucl_hash_elt *)a, - *ob = (const struct ucl_hash_elt *)b; + const struct ucl_hash_elt *oa = (const struct ucl_hash_elt *) a, + *ob = (const struct ucl_hash_elt *) b; if (oa->obj->keylen == ob->obj->keylen) { - return ucl_lc_cmp (oa->obj->key, ob->obj->key, oa->obj->keylen); + return ucl_lc_cmp(oa->obj->key, ob->obj->key, oa->obj->keylen); } - return ((int)(oa->obj->keylen)) - ob->obj->keylen; + return ((int) (oa->obj->keylen)) - ob->obj->keylen; } static int -ucl_hash_cmp_case_sens (const void *a, const void *b) +ucl_hash_cmp_case_sens(const void *a, const void *b) { - const struct ucl_hash_elt *oa = (const struct ucl_hash_elt *)a, - *ob = (const struct ucl_hash_elt *)b; + const struct ucl_hash_elt *oa = (const struct ucl_hash_elt *) a, + *ob = (const struct ucl_hash_elt *) b; if (oa->obj->keylen == ob->obj->keylen) { - return memcmp (oa->obj->key, ob->obj->key, oa->obj->keylen); + return memcmp(oa->obj->key, ob->obj->key, oa->obj->keylen); } - return ((int)(oa->obj->keylen)) - ob->obj->keylen; + return ((int) (oa->obj->keylen)) - ob->obj->keylen; } -void -ucl_hash_sort (ucl_hash_t *hashlin, enum ucl_object_keys_sort_flags fl) +void ucl_hash_sort(ucl_hash_t *hashlin, enum ucl_object_keys_sort_flags fl) { if (fl & UCL_SORT_KEYS_ICASE) { DL_SORT(hashlin->head, ucl_hash_cmp_icase); } else { DL_SORT(hashlin->head, ucl_hash_cmp_case_sens); } if (fl & UCL_SORT_KEYS_RECURSIVE) { struct ucl_hash_elt *elt; - DL_FOREACH(hashlin->head, elt) { - if (ucl_object_type (elt->obj) == UCL_OBJECT) { - ucl_hash_sort (elt->obj->value.ov, fl); + DL_FOREACH(hashlin->head, elt) + { + if (ucl_object_type(elt->obj) == UCL_OBJECT) { + ucl_hash_sort(elt->obj->value.ov, fl); } } } } diff --git a/contrib/libucl/src/ucl_hash.h b/contrib/libucl/src/ucl_hash.h index 8f6d69e21a25..95fe206b677e 100644 --- a/contrib/libucl/src/ucl_hash.h +++ b/contrib/libucl/src/ucl_hash.h @@ -1,109 +1,109 @@ /* Copyright (c) 2013, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __UCL_HASH_H #define __UCL_HASH_H #include "ucl.h" /******************************************************************************/ struct ucl_hash_node_s; typedef struct ucl_hash_node_s ucl_hash_node_t; -typedef int (*ucl_hash_cmp_func) (const void* void_a, const void* void_b); -typedef void (*ucl_hash_free_func) (void *ptr); -typedef void* ucl_hash_iter_t; +typedef int (*ucl_hash_cmp_func)(const void *void_a, const void *void_b); +typedef void (*ucl_hash_free_func)(void *ptr); +typedef void *ucl_hash_iter_t; /** * Linear chained hashtable. */ struct ucl_hash_struct; typedef struct ucl_hash_struct ucl_hash_t; /** * Initializes the hashtable. */ -ucl_hash_t* ucl_hash_create (bool ignore_case); +ucl_hash_t *ucl_hash_create(bool ignore_case); /** * Deinitializes the hashtable. */ -void ucl_hash_destroy (ucl_hash_t* hashlin, ucl_hash_free_func func); +void ucl_hash_destroy(ucl_hash_t *hashlin, ucl_hash_free_func func); /** * Inserts an element in the the hashtable. * @return true on success, false on failure (i.e. ENOMEM) */ -bool ucl_hash_insert (ucl_hash_t* hashlin, const ucl_object_t *obj, const char *key, - unsigned keylen); +bool ucl_hash_insert(ucl_hash_t *hashlin, const ucl_object_t *obj, const char *key, + unsigned keylen); /** * Replace element in the hash */ -void ucl_hash_replace (ucl_hash_t* hashlin, const ucl_object_t *old, - const ucl_object_t *new); +void ucl_hash_replace(ucl_hash_t *hashlin, const ucl_object_t *old, + const ucl_object_t *new); /** * Delete an element from the the hashtable. */ -void ucl_hash_delete (ucl_hash_t* hashlin, const ucl_object_t *obj); +void ucl_hash_delete(ucl_hash_t *hashlin, const ucl_object_t *obj); /** * Searches an element in the hashtable. */ -const ucl_object_t* ucl_hash_search (ucl_hash_t* hashlin, const char *key, - unsigned keylen); +const ucl_object_t *ucl_hash_search(ucl_hash_t *hashlin, const char *key, + unsigned keylen); /** * Iterate over hash table * @param hashlin hash * @param iter iterator (must be NULL on first iteration) * @param ep pointer record exception (such as ENOMEM), could be NULL * @return the next object */ -const void* ucl_hash_iterate2 (ucl_hash_t *hashlin, ucl_hash_iter_t *iter, int *ep); +const void *ucl_hash_iterate2(ucl_hash_t *hashlin, ucl_hash_iter_t *iter, int *ep); /** * Helper macro to support older code */ #define ucl_hash_iterate(hl, ip) ucl_hash_iterate2((hl), (ip), NULL) /** * Check whether an iterator has next element */ -bool ucl_hash_iter_has_next (ucl_hash_t *hashlin, ucl_hash_iter_t iter); +bool ucl_hash_iter_has_next(ucl_hash_t *hashlin, ucl_hash_iter_t iter); /** * Reserves space in hash * @return true on sucess, false on failure (e.g. ENOMEM) * @param hashlin */ -bool ucl_hash_reserve (ucl_hash_t *hashlin, size_t sz); +bool ucl_hash_reserve(ucl_hash_t *hashlin, size_t sz); -void ucl_hash_sort (ucl_hash_t *hashlin, enum ucl_object_keys_sort_flags fl); +void ucl_hash_sort(ucl_hash_t *hashlin, enum ucl_object_keys_sort_flags fl); #endif diff --git a/contrib/libucl/src/ucl_internal.h b/contrib/libucl/src/ucl_internal.h index 2c5fdf84fee7..5d58ddc486f5 100644 --- a/contrib/libucl/src/ucl_internal.h +++ b/contrib/libucl/src/ucl_internal.h @@ -1,667 +1,668 @@ /* Copyright (c) 2013, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UCL_INTERNAL_H_ #define UCL_INTERNAL_H_ #ifdef HAVE_CONFIG_H #include "config.h" #else /* Help embedded builds */ #define HAVE_SYS_TYPES_H #define HAVE_SYS_MMAN_H #define HAVE_SYS_STAT_H #define HAVE_SYS_PARAM_H #define HAVE_LIMITS_H #define HAVE_FCNTL_H #define HAVE_ERRNO_H #define HAVE_UNISTD_H #define HAVE_CTYPE_H #define HAVE_STDIO_H #define HAVE_STRING_H #define HAVE_FLOAT_H #define HAVE_LIBGEN_H #define HAVE_MATH_H #define HAVE_STDBOOL_H #define HAVE_STDINT_H #define HAVE_STDARG_H #ifndef _WIN32 -# define HAVE_REGEX_H +#define HAVE_REGEX_H #endif #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_MMAN_H -# ifndef _WIN32 -# include -# endif +#ifndef _WIN32 +#include +#endif #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_SYS_PARAM_H -# ifndef _WIN32 -# include -# endif +#ifndef _WIN32 +#include +#endif #endif #ifdef HAVE_LIMITS_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_UNISTD_H -# ifndef _WIN32 -# include -# endif +#ifndef _WIN32 +#include +#endif #endif #ifdef HAVE_CTYPE_H #include #endif #ifdef HAVE_STDIO_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #if defined(_MSC_VER) /* Windows hacks */ #include #include typedef SSIZE_T ssize_t; #define strdup _strdup #define snprintf _snprintf #define vsnprintf _vsnprintf #define strcasecmp _stricmp #define strncasecmp _strnicmp #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #if _MSC_VER >= 1900 #include <../ucrt/stdlib.h> #else #include <../include/stdlib.h> #endif #ifndef PATH_MAX #define PATH_MAX _MAX_PATH #endif /* Dirname, basename implementations */ #endif #include "utlist.h" #include "utstring.h" #include "uthash.h" #include "ucl.h" #include "ucl_hash.h" #ifdef HAVE_OPENSSL #include #endif #ifndef __DECONST -#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) +#define __DECONST(type, var) ((type) (uintptr_t) (const void *) (var)) #endif /** * @file rcl_internal.h * Internal structures and functions of UCL library */ #define UCL_MAX_RECURSION 16 #define UCL_TRASH_KEY 0 #define UCL_TRASH_VALUE 1 enum ucl_parser_state { UCL_STATE_INIT = 0, UCL_STATE_OBJECT, UCL_STATE_ARRAY, UCL_STATE_KEY, UCL_STATE_KEY_OBRACE, UCL_STATE_VALUE, UCL_STATE_AFTER_VALUE, UCL_STATE_ARRAY_VALUE, UCL_STATE_SCOMMENT, UCL_STATE_MCOMMENT, UCL_STATE_MACRO_NAME, UCL_STATE_MACRO, UCL_STATE_ERROR }; enum ucl_character_type { UCL_CHARACTER_DENIED = (1 << 0), UCL_CHARACTER_KEY = (1 << 1), UCL_CHARACTER_KEY_START = (1 << 2), UCL_CHARACTER_WHITESPACE = (1 << 3), UCL_CHARACTER_WHITESPACE_UNSAFE = (1 << 4), UCL_CHARACTER_VALUE_END = (1 << 5), UCL_CHARACTER_VALUE_STR = (1 << 6), UCL_CHARACTER_VALUE_DIGIT = (1 << 7), UCL_CHARACTER_VALUE_DIGIT_START = (1 << 8), UCL_CHARACTER_ESCAPE = (1 << 9), UCL_CHARACTER_KEY_SEP = (1 << 10), UCL_CHARACTER_JSON_UNSAFE = (1 << 11), UCL_CHARACTER_UCL_UNSAFE = (1 << 12) }; struct ucl_macro { char *name; union _ucl_macro { ucl_macro_handler handler; ucl_context_macro_handler context_handler; } h; - void* ud; + void *ud; bool is_context; UT_hash_handle hh; }; enum ucl_stack_flags { UCL_STACK_HAS_OBRACE = (1u << 0), - UCL_STACK_MAX = (1u << 1), + UCL_STACK_AUTOMATIC = (1u << 1), + UCL_STACK_MAX = (1u << 2), }; struct ucl_stack { ucl_object_t *obj; struct ucl_stack *next; union { struct { uint16_t level; uint16_t flags; uint32_t line; } params; uint64_t len; } e; struct ucl_chunk *chunk; }; struct ucl_parser_special_handler_chain { unsigned char *begin; size_t len; struct ucl_parser_special_handler *special_handler; struct ucl_parser_special_handler_chain *next; }; struct ucl_chunk { const unsigned char *begin; const unsigned char *end; const unsigned char *pos; char *fname; size_t remain; unsigned int line; unsigned int column; unsigned priority; enum ucl_duplicate_strategy strategy; enum ucl_parse_type parse_type; struct ucl_parser_special_handler_chain *special_handlers; struct ucl_chunk *next; }; #ifdef HAVE_OPENSSL struct ucl_pubkey { EVP_PKEY *key; struct ucl_pubkey *next; }; #else struct ucl_pubkey { struct ucl_pubkey *next; }; #endif struct ucl_variable { char *var; char *value; size_t var_len; size_t value_len; struct ucl_variable *prev, *next; }; struct ucl_parser { enum ucl_parser_state state; enum ucl_parser_state prev_state; unsigned int recursion; int flags; unsigned default_priority; int err_code; ucl_object_t *top_obj; ucl_object_t *cur_obj; ucl_object_t *trash_objs; ucl_object_t *includepaths; char *cur_file; struct ucl_macro *macroes; struct ucl_stack *stack; struct ucl_chunk *chunks; struct ucl_pubkey *keys; struct ucl_parser_special_handler *special_handlers; ucl_include_trace_func_t *include_trace_func; void *include_trace_ud; struct ucl_variable *variables; ucl_variable_handler var_handler; void *var_data; ucl_object_t *comments; ucl_object_t *last_comment; UT_string *err; }; struct ucl_object_userdata { ucl_object_t obj; ucl_userdata_dtor dtor; ucl_userdata_emitter emitter; }; /** * Unescape json string inplace * @param str */ -size_t ucl_unescape_json_string (char *str, size_t len); +size_t ucl_unescape_json_string(char *str, size_t len); /** * Unescape single quoted string inplace * @param str */ -size_t ucl_unescape_squoted_string (char *str, size_t len); +size_t ucl_unescape_squoted_string(char *str, size_t len); /** * Handle include macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool ucl_include_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud); +bool ucl_include_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud); /** * Handle tryinclude macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool ucl_try_include_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud); +bool ucl_try_include_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud); /** * Handle includes macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool ucl_includes_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud); +bool ucl_includes_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud); /** * Handle priority macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool ucl_priority_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud); +bool ucl_priority_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud); /** * Handle load macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool ucl_load_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud); +bool ucl_load_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud); /** * Handle inherit macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ctx the current context object * @param ud user data * @return */ -bool ucl_inherit_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, const ucl_object_t *ctx, void* ud); +bool ucl_inherit_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, const ucl_object_t *ctx, void *ud); -size_t ucl_strlcpy (char *dst, const char *src, size_t siz); -size_t ucl_strlcpy_unsafe (char *dst, const char *src, size_t siz); -size_t ucl_strlcpy_tolower (char *dst, const char *src, size_t siz); +size_t ucl_strlcpy(char *dst, const char *src, size_t siz); +size_t ucl_strlcpy_unsafe(char *dst, const char *src, size_t siz); +size_t ucl_strlcpy_tolower(char *dst, const char *src, size_t siz); -char *ucl_strnstr (const char *s, const char *find, int len); -char *ucl_strncasestr (const char *s, const char *find, int len); +char *ucl_strnstr(const char *s, const char *find, int len); +char *ucl_strncasestr(const char *s, const char *find, int len); #ifdef __GNUC__ static inline void -ucl_create_err (UT_string **err, const char *fmt, ...) -__attribute__ (( format( printf, 2, 3) )); +ucl_create_err(UT_string **err, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); #endif #undef UCL_FATAL_ERRORS static inline void -ucl_create_err (UT_string **err, const char *fmt, ...) +ucl_create_err(UT_string **err, const char *fmt, ...) { if (*err == NULL) { - utstring_new (*err); + utstring_new(*err); va_list ap; - va_start (ap, fmt); - utstring_printf_va (*err, fmt, ap); - va_end (ap); + va_start(ap, fmt); + utstring_printf_va(*err, fmt, ap); + va_end(ap); } #ifdef UCL_FATAL_ERRORS - assert (0); + assert(0); #endif } /** * Check whether a given string contains a boolean value * @param obj object to set * @param start start of a string * @param len length of a string * @return true if a string is a boolean value */ static inline bool -ucl_maybe_parse_boolean (ucl_object_t *obj, const unsigned char *start, size_t len) +ucl_maybe_parse_boolean(ucl_object_t *obj, const unsigned char *start, size_t len) { - const char *p = (const char *)start; + const char *p = (const char *) start; bool ret = false, val = false; if (len == 5) { - if ((p[0] == 'f' || p[0] == 'F') && strncasecmp (p, "false", 5) == 0) { + if ((p[0] == 'f' || p[0] == 'F') && strncasecmp(p, "false", 5) == 0) { ret = true; val = false; } } else if (len == 4) { - if ((p[0] == 't' || p[0] == 'T') && strncasecmp (p, "true", 4) == 0) { + if ((p[0] == 't' || p[0] == 'T') && strncasecmp(p, "true", 4) == 0) { ret = true; val = true; } } else if (len == 3) { - if ((p[0] == 'y' || p[0] == 'Y') && strncasecmp (p, "yes", 3) == 0) { + if ((p[0] == 'y' || p[0] == 'Y') && strncasecmp(p, "yes", 3) == 0) { ret = true; val = true; } - else if ((p[0] == 'o' || p[0] == 'O') && strncasecmp (p, "off", 3) == 0) { + else if ((p[0] == 'o' || p[0] == 'O') && strncasecmp(p, "off", 3) == 0) { ret = true; val = false; } } else if (len == 2) { - if ((p[0] == 'n' || p[0] == 'N') && strncasecmp (p, "no", 2) == 0) { + if ((p[0] == 'n' || p[0] == 'N') && strncasecmp(p, "no", 2) == 0) { ret = true; val = false; } - else if ((p[0] == 'o' || p[0] == 'O') && strncasecmp (p, "on", 2) == 0) { + else if ((p[0] == 'o' || p[0] == 'O') && strncasecmp(p, "on", 2) == 0) { ret = true; val = true; } } if (ret && obj != NULL) { obj->type = UCL_BOOLEAN; obj->value.iv = val; } return ret; } /** * Check numeric string * @param obj object to set if a string is numeric * @param start start of string * @param end end of string * @param pos position where parsing has stopped * @param allow_double allow parsing of floating point values * @return 0 if string is numeric and error code (EINVAL or ERANGE) in case of conversion error */ -int ucl_maybe_parse_number (ucl_object_t *obj, - const char *start, const char *end, const char **pos, - bool allow_double, bool number_bytes, bool allow_time); +int ucl_maybe_parse_number(ucl_object_t *obj, + const char *start, const char *end, const char **pos, + bool allow_double, bool number_bytes, bool allow_time); static inline const ucl_object_t * -ucl_hash_search_obj (ucl_hash_t* hashlin, ucl_object_t *obj) +ucl_hash_search_obj(ucl_hash_t *hashlin, ucl_object_t *obj) { - return (const ucl_object_t *)ucl_hash_search (hashlin, obj->key, obj->keylen); + return (const ucl_object_t *) ucl_hash_search(hashlin, obj->key, obj->keylen); } -static inline ucl_hash_t * ucl_hash_insert_object (ucl_hash_t *hashlin, - const ucl_object_t *obj, - bool ignore_case) UCL_WARN_UNUSED_RESULT; +static inline ucl_hash_t *ucl_hash_insert_object(ucl_hash_t *hashlin, + const ucl_object_t *obj, + bool ignore_case) UCL_WARN_UNUSED_RESULT; static inline ucl_hash_t * -ucl_hash_insert_object (ucl_hash_t *hashlin, - const ucl_object_t *obj, - bool ignore_case) +ucl_hash_insert_object(ucl_hash_t *hashlin, + const ucl_object_t *obj, + bool ignore_case) { ucl_hash_t *nhp; if (hashlin == NULL) { - nhp = ucl_hash_create (ignore_case); + nhp = ucl_hash_create(ignore_case); if (nhp == NULL) { return NULL; } - } else { + } + else { nhp = hashlin; } - if (!ucl_hash_insert (nhp, obj, obj->key, obj->keylen)) { + if (!ucl_hash_insert(nhp, obj, obj->key, obj->keylen)) { if (nhp != hashlin) { ucl_hash_destroy(nhp, NULL); } return NULL; } return nhp; } /** * Get standard emitter context for a specified emit_type * @param emit_type type of emitter * @return context or NULL if input is invalid */ const struct ucl_emitter_context * -ucl_emit_get_standard_context (enum ucl_emitter emit_type); +ucl_emit_get_standard_context(enum ucl_emitter emit_type); /** * Serialize string as JSON string * @param str string to emit * @param buf target buffer */ -void ucl_elt_string_write_json (const char *str, size_t size, - struct ucl_emitter_context *ctx); +void ucl_elt_string_write_json(const char *str, size_t size, + struct ucl_emitter_context *ctx); /** * Serialize string as single quoted string * @param str string to emit * @param buf target buffer */ -void -ucl_elt_string_write_squoted (const char *str, size_t size, - struct ucl_emitter_context *ctx); +void ucl_elt_string_write_squoted(const char *str, size_t size, + struct ucl_emitter_context *ctx); /** * Write multiline string using `EOD` as string terminator * @param str * @param size * @param ctx */ -void ucl_elt_string_write_multiline (const char *str, size_t size, - struct ucl_emitter_context *ctx); +void ucl_elt_string_write_multiline(const char *str, size_t size, + struct ucl_emitter_context *ctx); /** * Emit a single object to string * @param obj * @return */ -unsigned char * ucl_object_emit_single_json (const ucl_object_t *obj); +unsigned char *ucl_object_emit_single_json(const ucl_object_t *obj); /** * Check whether a specified string is long and should be likely printed in * multiline mode * @param obj * @return */ -bool ucl_maybe_long_string (const ucl_object_t *obj); +bool ucl_maybe_long_string(const ucl_object_t *obj); /** * Print integer to the msgpack output * @param ctx * @param val */ -void ucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, - int64_t val); +void ucl_emitter_print_int_msgpack(struct ucl_emitter_context *ctx, + int64_t val); /** * Print integer to the msgpack output * @param ctx * @param val */ -void ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, - double val); +void ucl_emitter_print_double_msgpack(struct ucl_emitter_context *ctx, + double val); /** * Print double to the msgpack output * @param ctx * @param val */ -void ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, - bool val); +void ucl_emitter_print_bool_msgpack(struct ucl_emitter_context *ctx, + bool val); /** * Print string to the msgpack output * @param ctx * @param s * @param len */ -void ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx, - const char *s, size_t len); +void ucl_emitter_print_string_msgpack(struct ucl_emitter_context *ctx, + const char *s, size_t len); /** * Print binary string to the msgpack output * @param ctx * @param s * @param len */ -void ucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx, - const char *s, size_t len); +void ucl_emitter_print_binary_string_msgpack(struct ucl_emitter_context *ctx, + const char *s, size_t len); /** * Print array preamble for msgpack * @param ctx * @param len */ -void ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, - size_t len); +void ucl_emitter_print_array_msgpack(struct ucl_emitter_context *ctx, + size_t len); /** * Print object preamble for msgpack * @param ctx * @param len */ -void ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, - size_t len); +void ucl_emitter_print_object_msgpack(struct ucl_emitter_context *ctx, + size_t len); /** * Print NULL to the msgpack output * @param ctx */ -void ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx); +void ucl_emitter_print_null_msgpack(struct ucl_emitter_context *ctx); /** * Print object's key if needed to the msgpack output * @param print_key * @param ctx * @param obj */ -void ucl_emitter_print_key_msgpack (bool print_key, - struct ucl_emitter_context *ctx, - const ucl_object_t *obj); +void ucl_emitter_print_key_msgpack(bool print_key, + struct ucl_emitter_context *ctx, + const ucl_object_t *obj); /** * Fetch URL into a buffer * @param url url to fetch * @param buf pointer to buffer (must be freed by callee) * @param buflen pointer to buffer length * @param err pointer to error argument * @param must_exist fail if cannot find a url */ -bool ucl_fetch_url (const unsigned char *url, - unsigned char **buf, - size_t *buflen, - UT_string **err, - bool must_exist); +bool ucl_fetch_url(const unsigned char *url, + unsigned char **buf, + size_t *buflen, + UT_string **err, + bool must_exist); /** * Fetch a file and save results to the memory buffer * @param filename filename to fetch * @param len length of filename * @param buf target buffer * @param buflen target length * @return */ -bool ucl_fetch_file (const unsigned char *filename, - unsigned char **buf, - size_t *buflen, - UT_string **err, - bool must_exist); +bool ucl_fetch_file(const unsigned char *filename, + unsigned char **buf, + size_t *buflen, + UT_string **err, + bool must_exist); /** * Add new element to an object using the current merge strategy and priority * @param parser * @param nobj * @return */ -bool ucl_parser_process_object_element (struct ucl_parser *parser, - ucl_object_t *nobj); +bool ucl_parser_process_object_element(struct ucl_parser *parser, + ucl_object_t *nobj); /** * Parse msgpack chunk * @param parser * @return */ -bool ucl_parse_msgpack (struct ucl_parser *parser); +bool ucl_parse_msgpack(struct ucl_parser *parser); -bool ucl_parse_csexp (struct ucl_parser *parser); +bool ucl_parse_csexp(struct ucl_parser *parser); /** * Free ucl chunk * @param chunk */ -void ucl_chunk_free (struct ucl_chunk *chunk); +void ucl_chunk_free(struct ucl_chunk *chunk); #endif /* UCL_INTERNAL_H_ */ diff --git a/contrib/libucl/src/ucl_msgpack.c b/contrib/libucl/src/ucl_msgpack.c index 628ed2be993d..6cc0c0747671 100644 --- a/contrib/libucl/src/ucl_msgpack.c +++ b/contrib/libucl/src/ucl_msgpack.c @@ -1,1638 +1,1574 @@ /* * Copyright (c) 2015, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ucl.h" #include "ucl_internal.h" #ifdef HAVE_ENDIAN_H #include #elif defined(HAVE_SYS_ENDIAN_H) #include #elif defined(HAVE_MACHINE_ENDIAN_H) #include #endif #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) - #if __BYTE_ORDER == __LITTLE_ENDIAN - #define __LITTLE_ENDIAN__ - #elif __BYTE_ORDER == __BIG_ENDIAN - #define __BIG_ENDIAN__ - #elif _WIN32 - #define __LITTLE_ENDIAN__ - #endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __LITTLE_ENDIAN__ +#elif __BYTE_ORDER == __BIG_ENDIAN +#define __BIG_ENDIAN__ +#elif _WIN32 +#define __LITTLE_ENDIAN__ +#endif #endif -#define SWAP_LE_BE16(val) ((uint16_t) ( \ - (uint16_t) ((uint16_t) (val) >> 8) | \ - (uint16_t) ((uint16_t) (val) << 8))) +#define SWAP_LE_BE16(val) ((uint16_t) ((uint16_t) ((uint16_t) (val) >> 8) | \ + (uint16_t) ((uint16_t) (val) << 8))) -#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3) -# define SWAP_LE_BE32(val) ((uint32_t)__builtin_bswap32 ((uint32_t)(val))) -# define SWAP_LE_BE64(val) ((uint64_t)__builtin_bswap64 ((uint64_t)(val))) +#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 3) +#define SWAP_LE_BE32(val) ((uint32_t) __builtin_bswap32((uint32_t) (val))) +#define SWAP_LE_BE64(val) ((uint64_t) __builtin_bswap64((uint64_t) (val))) #else - #define SWAP_LE_BE32(val) ((uint32_t)( \ - (((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \ - (((uint32_t)(val) & (uint32_t)0x0000ff00U) << 8) | \ - (((uint32_t)(val) & (uint32_t)0x00ff0000U) >> 8) | \ - (((uint32_t)(val) & (uint32_t)0xff000000U) >> 24))) - - #define SWAP_LE_BE64(val) ((uint64_t)( \ - (((uint64_t)(val) & \ - (uint64_t)(0x00000000000000ffULL)) << 56) | \ - (((uint64_t)(val) & \ - (uint64_t)(0x000000000000ff00ULL)) << 40) | \ - (((uint64_t)(val) & \ - (uint64_t)(0x0000000000ff0000ULL)) << 24) | \ - (((uint64_t)(val) & \ - (uint64_t) (0x00000000ff000000ULL)) << 8) | \ - (((uint64_t)(val) & \ - (uint64_t)(0x000000ff00000000ULL)) >> 8) | \ - (((uint64_t)(val) & \ - (uint64_t)(0x0000ff0000000000ULL)) >> 24) | \ - (((uint64_t)(val) & \ - (uint64_t)(0x00ff000000000000ULL)) >> 40) | \ - (((uint64_t)(val) & \ - (uint64_t)(0xff00000000000000ULL)) >> 56))) +#define SWAP_LE_BE32(val) ((uint32_t) ((((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \ + (((uint32_t) (val) & (uint32_t) 0x0000ff00U) << 8) | \ + (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >> 8) | \ + (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24))) + +#define SWAP_LE_BE64(val) ((uint64_t) ((((uint64_t) (val) & \ + (uint64_t) (0x00000000000000ffULL)) \ + << 56) | \ + (((uint64_t) (val) & \ + (uint64_t) (0x000000000000ff00ULL)) \ + << 40) | \ + (((uint64_t) (val) & \ + (uint64_t) (0x0000000000ff0000ULL)) \ + << 24) | \ + (((uint64_t) (val) & \ + (uint64_t) (0x00000000ff000000ULL)) \ + << 8) | \ + (((uint64_t) (val) & \ + (uint64_t) (0x000000ff00000000ULL)) >> \ + 8) | \ + (((uint64_t) (val) & \ + (uint64_t) (0x0000ff0000000000ULL)) >> \ + 24) | \ + (((uint64_t) (val) & \ + (uint64_t) (0x00ff000000000000ULL)) >> \ + 40) | \ + (((uint64_t) (val) & \ + (uint64_t) (0xff00000000000000ULL)) >> \ + 56))) #endif #ifdef __LITTLE_ENDIAN__ #define TO_BE16 SWAP_LE_BE16 #define TO_BE32 SWAP_LE_BE32 #define TO_BE64 SWAP_LE_BE64 #define FROM_BE16 SWAP_LE_BE16 #define FROM_BE32 SWAP_LE_BE32 #define FROM_BE64 SWAP_LE_BE64 #else -#define TO_BE16(val) (uint16_t)(val) -#define TO_BE32(val) (uint32_t)(val) -#define TO_BE64(val) (uint64_t)(val) -#define FROM_BE16(val) (uint16_t)(val) -#define FROM_BE32(val) (uint32_t)(val) -#define FROM_BE64(val) (uint64_t)(val) +#define TO_BE16(val) (uint16_t) (val) +#define TO_BE32(val) (uint32_t) (val) +#define TO_BE64(val) (uint64_t) (val) +#define FROM_BE16(val) (uint16_t) (val) +#define FROM_BE32(val) (uint32_t) (val) +#define FROM_BE64(val) (uint64_t) (val) #endif -void -ucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, int64_t val) +void ucl_emitter_print_int_msgpack(struct ucl_emitter_context *ctx, int64_t val) { const struct ucl_emitter_functions *func = ctx->func; unsigned char buf[sizeof(uint64_t) + 1]; const unsigned char mask_positive = 0x7f, mask_negative = 0xe0, - uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf, - int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3; + uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf, + int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3; unsigned len; if (val >= 0) { if (val <= 0x7f) { /* Fixed num 7 bits */ len = 1; buf[0] = mask_positive & val; } else if (val <= UINT8_MAX) { len = 2; buf[0] = uint8_ch; buf[1] = val & 0xff; } else if (val <= UINT16_MAX) { - uint16_t v = TO_BE16 (val); + uint16_t v = TO_BE16(val); len = 3; buf[0] = uint16_ch; - memcpy (&buf[1], &v, sizeof (v)); + memcpy(&buf[1], &v, sizeof(v)); } else if (val <= UINT32_MAX) { - uint32_t v = TO_BE32 (val); + uint32_t v = TO_BE32(val); len = 5; buf[0] = uint32_ch; - memcpy (&buf[1], &v, sizeof (v)); + memcpy(&buf[1], &v, sizeof(v)); } else { - uint64_t v = TO_BE64 (val); + uint64_t v = TO_BE64(val); len = 9; buf[0] = uint64_ch; - memcpy (&buf[1], &v, sizeof (v)); + memcpy(&buf[1], &v, sizeof(v)); } } else { uint64_t uval; /* Bithack abs */ uval = ((val ^ (val >> 63)) - (val >> 63)); if (val > -(1 << 5)) { len = 1; buf[0] = (mask_negative | uval) & 0xff; } else if (uval <= INT8_MAX) { - uint8_t v = (uint8_t)val; + uint8_t v = (uint8_t) val; len = 2; buf[0] = int8_ch; buf[1] = v; } else if (uval <= INT16_MAX) { - uint16_t v = TO_BE16 (val); + uint16_t v = TO_BE16(val); len = 3; buf[0] = int16_ch; - memcpy (&buf[1], &v, sizeof (v)); + memcpy(&buf[1], &v, sizeof(v)); } else if (uval <= INT32_MAX) { - uint32_t v = TO_BE32 (val); + uint32_t v = TO_BE32(val); len = 5; buf[0] = int32_ch; - memcpy (&buf[1], &v, sizeof (v)); + memcpy(&buf[1], &v, sizeof(v)); } else { - uint64_t v = TO_BE64 (val); + uint64_t v = TO_BE64(val); len = 9; buf[0] = int64_ch; - memcpy (&buf[1], &v, sizeof (v)); + memcpy(&buf[1], &v, sizeof(v)); } } - func->ucl_emitter_append_len (buf, len, func->ud); + func->ucl_emitter_append_len(buf, len, func->ud); } -void -ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val) +void ucl_emitter_print_double_msgpack(struct ucl_emitter_context *ctx, double val) { const struct ucl_emitter_functions *func = ctx->func; union { double d; uint64_t i; } u; const unsigned char dbl_ch = 0xcb; unsigned char buf[sizeof(double) + 1]; /* Convert to big endian */ u.d = val; - u.i = TO_BE64 (u.i); + u.i = TO_BE64(u.i); buf[0] = dbl_ch; - memcpy (&buf[1], &u.d, sizeof (double)); - func->ucl_emitter_append_len (buf, sizeof (buf), func->ud); + memcpy(&buf[1], &u.d, sizeof(double)); + func->ucl_emitter_append_len(buf, sizeof(buf), func->ud); } -void -ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val) +void ucl_emitter_print_bool_msgpack(struct ucl_emitter_context *ctx, bool val) { const struct ucl_emitter_functions *func = ctx->func; const unsigned char true_ch = 0xc3, false_ch = 0xc2; - func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud); + func->ucl_emitter_append_character(val ? true_ch : false_ch, 1, func->ud); } -void -ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx, - const char *s, size_t len) +void ucl_emitter_print_string_msgpack(struct ucl_emitter_context *ctx, + const char *s, size_t len) { const struct ucl_emitter_functions *func = ctx->func; const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb; unsigned char buf[5]; unsigned blen; if (len <= 0x1F) { blen = 1; buf[0] = (len | fix_mask) & 0xff; } else if (len <= 0xff) { blen = 2; buf[0] = l8_ch; buf[1] = len & 0xff; } else if (len <= 0xffff) { - uint16_t bl = TO_BE16 (len); + uint16_t bl = TO_BE16(len); blen = 3; buf[0] = l16_ch; - memcpy (&buf[1], &bl, sizeof (bl)); + memcpy(&buf[1], &bl, sizeof(bl)); } else { - uint32_t bl = TO_BE32 (len); + uint32_t bl = TO_BE32(len); blen = 5; buf[0] = l32_ch; - memcpy (&buf[1], &bl, sizeof (bl)); + memcpy(&buf[1], &bl, sizeof(bl)); } - func->ucl_emitter_append_len (buf, blen, func->ud); - func->ucl_emitter_append_len (s, len, func->ud); + func->ucl_emitter_append_len(buf, blen, func->ud); + func->ucl_emitter_append_len(s, len, func->ud); } -void -ucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx, - const char *s, size_t len) +void ucl_emitter_print_binary_string_msgpack(struct ucl_emitter_context *ctx, + const char *s, size_t len) { const struct ucl_emitter_functions *func = ctx->func; const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6; unsigned char buf[5]; unsigned blen; if (len <= 0xff) { blen = 2; buf[0] = l8_ch; buf[1] = len & 0xff; } else if (len <= 0xffff) { - uint16_t bl = TO_BE16 (len); + uint16_t bl = TO_BE16(len); blen = 3; buf[0] = l16_ch; - memcpy (&buf[1], &bl, sizeof (bl)); + memcpy(&buf[1], &bl, sizeof(bl)); } else { - uint32_t bl = TO_BE32 (len); + uint32_t bl = TO_BE32(len); blen = 5; buf[0] = l32_ch; - memcpy (&buf[1], &bl, sizeof (bl)); + memcpy(&buf[1], &bl, sizeof(bl)); } - func->ucl_emitter_append_len (buf, blen, func->ud); - func->ucl_emitter_append_len (s, len, func->ud); + func->ucl_emitter_append_len(buf, blen, func->ud); + func->ucl_emitter_append_len(s, len, func->ud); } -void -ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx) +void ucl_emitter_print_null_msgpack(struct ucl_emitter_context *ctx) { const struct ucl_emitter_functions *func = ctx->func; const unsigned char nil = 0xc0; - func->ucl_emitter_append_character (nil, 1, func->ud); + func->ucl_emitter_append_character(nil, 1, func->ud); } -void -ucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx, - const ucl_object_t *obj) +void ucl_emitter_print_key_msgpack(bool print_key, struct ucl_emitter_context *ctx, + const ucl_object_t *obj) { if (print_key) { - ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen); + ucl_emitter_print_string_msgpack(ctx, obj->key, obj->keylen); } } -void -ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len) +void ucl_emitter_print_array_msgpack(struct ucl_emitter_context *ctx, size_t len) { const struct ucl_emitter_functions *func = ctx->func; const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd; unsigned char buf[5]; unsigned blen; if (len <= 0xF) { blen = 1; buf[0] = (len | fix_mask) & 0xff; } else if (len <= 0xffff) { - uint16_t bl = TO_BE16 (len); + uint16_t bl = TO_BE16(len); blen = 3; buf[0] = l16_ch; - memcpy (&buf[1], &bl, sizeof (bl)); + memcpy(&buf[1], &bl, sizeof(bl)); } else { - uint32_t bl = TO_BE32 (len); + uint32_t bl = TO_BE32(len); blen = 5; buf[0] = l32_ch; - memcpy (&buf[1], &bl, sizeof (bl)); + memcpy(&buf[1], &bl, sizeof(bl)); } - func->ucl_emitter_append_len (buf, blen, func->ud); + func->ucl_emitter_append_len(buf, blen, func->ud); } -void -ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len) +void ucl_emitter_print_object_msgpack(struct ucl_emitter_context *ctx, size_t len) { const struct ucl_emitter_functions *func = ctx->func; const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf; unsigned char buf[5]; unsigned blen; if (len <= 0xF) { blen = 1; buf[0] = (len | fix_mask) & 0xff; } else if (len <= 0xffff) { - uint16_t bl = TO_BE16 (len); + uint16_t bl = TO_BE16(len); blen = 3; buf[0] = l16_ch; - memcpy (&buf[1], &bl, sizeof (bl)); + memcpy(&buf[1], &bl, sizeof(bl)); } else { - uint32_t bl = TO_BE32 (len); + uint32_t bl = TO_BE32(len); blen = 5; buf[0] = l32_ch; - memcpy (&buf[1], &bl, sizeof (bl)); + memcpy(&buf[1], &bl, sizeof(bl)); } - func->ucl_emitter_append_len (buf, blen, func->ud); + func->ucl_emitter_append_len(buf, blen, func->ud); } enum ucl_msgpack_format { msgpack_positive_fixint = 0, msgpack_fixmap, msgpack_fixarray, msgpack_fixstr, msgpack_nil, msgpack_false, msgpack_true, msgpack_bin8, msgpack_bin16, msgpack_bin32, msgpack_ext8, msgpack_ext16, msgpack_ext32, msgpack_float32, msgpack_float64, msgpack_uint8, msgpack_uint16, msgpack_uint32, msgpack_uint64, msgpack_int8, msgpack_int16, msgpack_int32, msgpack_int64, msgpack_fixext1, msgpack_fixext2, msgpack_fixext4, msgpack_fixext8, msgpack_fixext16, msgpack_str8, msgpack_str16, msgpack_str32, msgpack_array16, msgpack_array32, msgpack_map16, msgpack_map32, msgpack_negative_fixint, msgpack_invalid }; typedef ssize_t (*ucl_msgpack_parse_function)(struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain); - -static ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain); -static ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain); -static ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain); -static ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain); -static ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain); -static ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain); -static ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain); -static ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain); + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain); + +static ssize_t ucl_msgpack_parse_map(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain); +static ssize_t ucl_msgpack_parse_array(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain); +static ssize_t ucl_msgpack_parse_string(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain); +static ssize_t ucl_msgpack_parse_int(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain); +static ssize_t ucl_msgpack_parse_float(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain); +static ssize_t ucl_msgpack_parse_bool(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain); +static ssize_t ucl_msgpack_parse_null(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain); +static ssize_t ucl_msgpack_parse_ignore(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain); #define MSGPACK_FLAG_FIXED (1 << 0) #define MSGPACK_FLAG_CONTAINER (1 << 1) #define MSGPACK_FLAG_TYPEVALUE (1 << 2) #define MSGPACK_FLAG_EXT (1 << 3) #define MSGPACK_FLAG_ASSOC (1 << 4) #define MSGPACK_FLAG_KEY (1 << 5) /* * Search tree packed in array */ struct ucl_msgpack_parser { - uint8_t prefix; /* Prefix byte */ - uint8_t prefixlen; /* Length of prefix in bits */ - uint8_t fmt; /* The desired format */ - uint8_t len; /* Length of the object + uint8_t prefix; /* Prefix byte */ + uint8_t prefixlen; /* Length of prefix in bits */ + uint8_t fmt; /* The desired format */ + uint8_t len; /* Length of the object (either length bytes or length of value in case of fixed objects */ - uint8_t flags; /* Flags of the specified type */ - ucl_msgpack_parse_function func; /* Parser function */ + uint8_t flags; /* Flags of the specified type */ + ucl_msgpack_parse_function func; /* Parser function */ } parsers[] = { - { - 0xa0, - 3, - msgpack_fixstr, - 0, - MSGPACK_FLAG_FIXED|MSGPACK_FLAG_KEY, - ucl_msgpack_parse_string - }, - { - 0x0, - 1, - msgpack_positive_fixint, - 0, - MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE, - ucl_msgpack_parse_int - }, - { - 0xe0, - 3, - msgpack_negative_fixint, - 0, - MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE, - ucl_msgpack_parse_int - }, - { - 0x80, - 4, - msgpack_fixmap, - 0, - MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC, - ucl_msgpack_parse_map - }, - { - 0x90, - 4, - msgpack_fixarray, - 0, - MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER, - ucl_msgpack_parse_array - }, - { - 0xd9, - 8, - msgpack_str8, - 1, - MSGPACK_FLAG_KEY, - ucl_msgpack_parse_string - }, - { - 0xc4, - 8, - msgpack_bin8, - 1, - MSGPACK_FLAG_KEY, - ucl_msgpack_parse_string - }, - { - 0xcf, - 8, - msgpack_uint64, - 8, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_int - }, - { - 0xd3, - 8, - msgpack_int64, - 8, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_int - }, - { - 0xce, - 8, - msgpack_uint32, - 4, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_int - }, - { - 0xd2, - 8, - msgpack_int32, - 4, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_int - }, - { - 0xcb, - 8, - msgpack_float64, - 8, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_float - }, - { - 0xca, - 8, - msgpack_float32, - 4, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_float - }, - { - 0xc2, - 8, - msgpack_false, - 1, - MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, - ucl_msgpack_parse_bool - }, - { - 0xc3, - 8, - msgpack_true, - 1, - MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, - ucl_msgpack_parse_bool - }, - { - 0xcc, - 8, - msgpack_uint8, - 1, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_int - }, - { - 0xcd, - 8, - msgpack_uint16, - 2, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_int - }, - { - 0xd0, - 8, - msgpack_int8, - 1, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_int - }, - { - 0xd1, - 8, - msgpack_int16, - 2, - MSGPACK_FLAG_FIXED, - ucl_msgpack_parse_int - }, - { - 0xc0, - 8, - msgpack_nil, - 0, - MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, - ucl_msgpack_parse_null - }, - { - 0xda, - 8, - msgpack_str16, - 2, - MSGPACK_FLAG_KEY, - ucl_msgpack_parse_string - }, - { - 0xdb, - 8, - msgpack_str32, - 4, - MSGPACK_FLAG_KEY, - ucl_msgpack_parse_string - }, - { - 0xc5, - 8, - msgpack_bin16, - 2, - MSGPACK_FLAG_KEY, - ucl_msgpack_parse_string - }, - { - 0xc6, - 8, - msgpack_bin32, - 4, - MSGPACK_FLAG_KEY, - ucl_msgpack_parse_string - }, - { - 0xdc, - 8, - msgpack_array16, - 2, - MSGPACK_FLAG_CONTAINER, - ucl_msgpack_parse_array - }, - { - 0xdd, - 8, - msgpack_array32, - 4, - MSGPACK_FLAG_CONTAINER, - ucl_msgpack_parse_array - }, - { - 0xde, - 8, - msgpack_map16, - 2, - MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC, - ucl_msgpack_parse_map - }, - { - 0xdf, - 8, - msgpack_map32, - 4, - MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC, - ucl_msgpack_parse_map - }, - { - 0xc7, - 8, - msgpack_ext8, - 1, - MSGPACK_FLAG_EXT, - ucl_msgpack_parse_ignore - }, - { - 0xc8, - 8, - msgpack_ext16, - 2, - MSGPACK_FLAG_EXT, - ucl_msgpack_parse_ignore - }, - { - 0xc9, - 8, - msgpack_ext32, - 4, - MSGPACK_FLAG_EXT, - ucl_msgpack_parse_ignore - }, - { - 0xd4, - 8, - msgpack_fixext1, - 1, - MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, - ucl_msgpack_parse_ignore - }, - { - 0xd5, - 8, - msgpack_fixext2, - 2, - MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, - ucl_msgpack_parse_ignore - }, - { - 0xd6, - 8, - msgpack_fixext4, - 4, - MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, - ucl_msgpack_parse_ignore - }, - { - 0xd7, - 8, - msgpack_fixext8, - 8, - MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, - ucl_msgpack_parse_ignore - }, - { - 0xd8, - 8, - msgpack_fixext16, - 16, - MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, - ucl_msgpack_parse_ignore - } -}; + {0xa0, + 3, + msgpack_fixstr, + 0, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_KEY, + ucl_msgpack_parse_string}, + {0x0, + 1, + msgpack_positive_fixint, + 0, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, + ucl_msgpack_parse_int}, + {0xe0, + 3, + msgpack_negative_fixint, + 0, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, + ucl_msgpack_parse_int}, + {0x80, + 4, + msgpack_fixmap, + 0, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_CONTAINER | MSGPACK_FLAG_ASSOC, + ucl_msgpack_parse_map}, + {0x90, + 4, + msgpack_fixarray, + 0, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_CONTAINER, + ucl_msgpack_parse_array}, + {0xd9, + 8, + msgpack_str8, + 1, + MSGPACK_FLAG_KEY, + ucl_msgpack_parse_string}, + {0xc4, + 8, + msgpack_bin8, + 1, + MSGPACK_FLAG_KEY, + ucl_msgpack_parse_string}, + {0xcf, + 8, + msgpack_uint64, + 8, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_int}, + {0xd3, + 8, + msgpack_int64, + 8, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_int}, + {0xce, + 8, + msgpack_uint32, + 4, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_int}, + {0xd2, + 8, + msgpack_int32, + 4, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_int}, + {0xcb, + 8, + msgpack_float64, + 8, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_float}, + {0xca, + 8, + msgpack_float32, + 4, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_float}, + {0xc2, + 8, + msgpack_false, + 1, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, + ucl_msgpack_parse_bool}, + {0xc3, + 8, + msgpack_true, + 1, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, + ucl_msgpack_parse_bool}, + {0xcc, + 8, + msgpack_uint8, + 1, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_int}, + {0xcd, + 8, + msgpack_uint16, + 2, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_int}, + {0xd0, + 8, + msgpack_int8, + 1, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_int}, + {0xd1, + 8, + msgpack_int16, + 2, + MSGPACK_FLAG_FIXED, + ucl_msgpack_parse_int}, + {0xc0, + 8, + msgpack_nil, + 0, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, + ucl_msgpack_parse_null}, + {0xda, + 8, + msgpack_str16, + 2, + MSGPACK_FLAG_KEY, + ucl_msgpack_parse_string}, + {0xdb, + 8, + msgpack_str32, + 4, + MSGPACK_FLAG_KEY, + ucl_msgpack_parse_string}, + {0xc5, + 8, + msgpack_bin16, + 2, + MSGPACK_FLAG_KEY, + ucl_msgpack_parse_string}, + {0xc6, + 8, + msgpack_bin32, + 4, + MSGPACK_FLAG_KEY, + ucl_msgpack_parse_string}, + {0xdc, + 8, + msgpack_array16, + 2, + MSGPACK_FLAG_CONTAINER, + ucl_msgpack_parse_array}, + {0xdd, + 8, + msgpack_array32, + 4, + MSGPACK_FLAG_CONTAINER, + ucl_msgpack_parse_array}, + {0xde, + 8, + msgpack_map16, + 2, + MSGPACK_FLAG_CONTAINER | MSGPACK_FLAG_ASSOC, + ucl_msgpack_parse_map}, + {0xdf, + 8, + msgpack_map32, + 4, + MSGPACK_FLAG_CONTAINER | MSGPACK_FLAG_ASSOC, + ucl_msgpack_parse_map}, + {0xc7, + 8, + msgpack_ext8, + 1, + MSGPACK_FLAG_EXT, + ucl_msgpack_parse_ignore}, + {0xc8, + 8, + msgpack_ext16, + 2, + MSGPACK_FLAG_EXT, + ucl_msgpack_parse_ignore}, + {0xc9, + 8, + msgpack_ext32, + 4, + MSGPACK_FLAG_EXT, + ucl_msgpack_parse_ignore}, + {0xd4, + 8, + msgpack_fixext1, + 1, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, + ucl_msgpack_parse_ignore}, + {0xd5, + 8, + msgpack_fixext2, + 2, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, + ucl_msgpack_parse_ignore}, + {0xd6, + 8, + msgpack_fixext4, + 4, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, + ucl_msgpack_parse_ignore}, + {0xd7, + 8, + msgpack_fixext8, + 8, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, + ucl_msgpack_parse_ignore}, + {0xd8, + 8, + msgpack_fixext16, + 16, + MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, + ucl_msgpack_parse_ignore}}; #undef MSGPACK_DEBUG_PARSER static inline struct ucl_msgpack_parser * -ucl_msgpack_get_parser_from_type (unsigned char t) +ucl_msgpack_get_parser_from_type(unsigned char t) { unsigned int i, shift, mask; - for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) { + for (i = 0; i < sizeof(parsers) / sizeof(parsers[0]); i++) { shift = CHAR_BIT - parsers[i].prefixlen; mask = parsers[i].prefix >> shift; - if (mask == (((unsigned int)t) >> shift)) { + if (mask == (((unsigned int) t) >> shift)) { return &parsers[i]; } } return NULL; } static inline struct ucl_stack * -ucl_msgpack_get_container (struct ucl_parser *parser, - struct ucl_msgpack_parser *obj_parser, uint64_t len) +ucl_msgpack_get_container(struct ucl_parser *parser, + struct ucl_msgpack_parser *obj_parser, uint64_t len) { struct ucl_stack *stack; - assert (obj_parser != NULL); + assert(obj_parser != NULL); if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) { /* * Insert new container to the stack */ if (parser->stack == NULL) { - parser->stack = calloc (1, sizeof (struct ucl_stack)); + parser->stack = calloc(1, sizeof(struct ucl_stack)); if (parser->stack == NULL) { - ucl_create_err (&parser->err, "no memory"); + ucl_create_err(&parser->err, "no memory"); return NULL; } parser->stack->chunk = parser->chunks; } else { - stack = calloc (1, sizeof (struct ucl_stack)); + stack = calloc(1, sizeof(struct ucl_stack)); if (stack == NULL) { - ucl_create_err (&parser->err, "no memory"); + ucl_create_err(&parser->err, "no memory"); return NULL; } stack->chunk = parser->chunks; stack->next = parser->stack; parser->stack = stack; } parser->stack->e.len = len; #ifdef MSGPACK_DEBUG_PARSER stack = parser->stack; while (stack) { fprintf(stderr, "+"); stack = stack->next; } - fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len); + fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int) len); #endif } else { /* * Get the current stack top */ if (parser->stack) { return parser->stack; } else { - ucl_create_err (&parser->err, "bad top level object for msgpack"); + ucl_create_err(&parser->err, "bad top level object for msgpack"); return NULL; } } return parser->stack; } static bool -ucl_msgpack_is_container_finished (struct ucl_stack *container) +ucl_msgpack_is_container_finished(struct ucl_stack *container) { - assert (container != NULL); + assert(container != NULL); if (container->e.len == 0) { return true; } return false; } static bool -ucl_msgpack_insert_object (struct ucl_parser *parser, - const unsigned char *key, - size_t keylen, ucl_object_t *obj) +ucl_msgpack_insert_object(struct ucl_parser *parser, + const unsigned char *key, + size_t keylen, ucl_object_t *obj) { struct ucl_stack *container; container = parser->stack; - assert (container != NULL); - assert (container->e.len > 0); - assert (obj != NULL); - assert (container->obj != NULL); + assert(container != NULL); + assert(container->e.len > 0); + assert(obj != NULL); + assert(container->obj != NULL); if (container->obj->type == UCL_ARRAY) { - ucl_array_append (container->obj, obj); + ucl_array_append(container->obj, obj); } else if (container->obj->type == UCL_OBJECT) { if (key == NULL || keylen == 0) { - ucl_create_err (&parser->err, "cannot insert object with no key"); + ucl_create_err(&parser->err, "cannot insert object with no key"); return false; } obj->key = key; obj->keylen = keylen; if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { - ucl_copy_key_trash (obj); + ucl_copy_key_trash(obj); } - ucl_parser_process_object_element (parser, obj); + ucl_parser_process_object_element(parser, obj); } else { - ucl_create_err (&parser->err, "bad container type"); + ucl_create_err(&parser->err, "bad container type"); return false; } container->e.len--; return true; } static struct ucl_stack * -ucl_msgpack_get_next_container (struct ucl_parser *parser) +ucl_msgpack_get_next_container(struct ucl_parser *parser) { struct ucl_stack *cur = NULL; uint64_t len; cur = parser->stack; if (cur == NULL) { return NULL; } len = cur->e.len; if (len == 0) { /* We need to switch to the previous container */ parser->stack = cur->next; parser->cur_obj = cur->obj; - free (cur); + free(cur); #ifdef MSGPACK_DEBUG_PARSER cur = parser->stack; - while (cur) { - fprintf(stderr, "-"); - cur = cur->next; - } - fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len); + while (cur) { + fprintf(stderr, "-"); + cur = cur->next; + } + fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int) parser->cur_obj->len); #endif - return ucl_msgpack_get_next_container (parser); + return ucl_msgpack_get_next_container(parser); } /* * For UCL containers we don't know length, so we just insert the whole * message pack blob into the top level container */ - assert (cur->obj != NULL); + assert(cur->obj != NULL); return cur; } -#define CONSUME_RET do { \ - if (ret != -1) { \ - p += ret; \ - remain -= ret; \ - obj_parser = NULL; \ - assert (remain >= 0); \ - } \ - else { \ - ucl_create_err (&parser->err, \ - "cannot parse type %d of len %u", \ - (int)obj_parser->fmt, \ - (unsigned)len); \ - return false; \ - } \ -} while(0) - -#define GET_NEXT_STATE do { \ - container = ucl_msgpack_get_next_container (parser); \ - if (container == NULL) { \ - ucl_create_err (&parser->err, \ - "empty container"); \ - return false; \ - } \ - next_state = container->obj->type == UCL_OBJECT ? \ - read_assoc_key : read_array_value; \ -} while(0) +#define CONSUME_RET \ + do { \ + if (ret != -1) { \ + p += ret; \ + remain -= ret; \ + obj_parser = NULL; \ + assert(remain >= 0); \ + } \ + else { \ + ucl_create_err(&parser->err, \ + "cannot parse type %d of len %u", \ + (int) obj_parser->fmt, \ + (unsigned) len); \ + return false; \ + } \ + } while (0) + +#define GET_NEXT_STATE \ + do { \ + container = ucl_msgpack_get_next_container(parser); \ + if (container == NULL) { \ + ucl_create_err(&parser->err, \ + "empty container"); \ + return false; \ + } \ + next_state = container->obj->type == UCL_OBJECT ? read_assoc_key : read_array_value; \ + } while (0) static bool -ucl_msgpack_consume (struct ucl_parser *parser) +ucl_msgpack_consume(struct ucl_parser *parser) { const unsigned char *p, *end, *key = NULL; struct ucl_stack *container; enum e_msgpack_parser_state { read_type, start_assoc, start_array, read_assoc_key, read_assoc_value, finish_assoc_value, read_array_value, finish_array_value, error_state - } state = read_type, next_state = error_state; + } state = read_type, + next_state = error_state; struct ucl_msgpack_parser *obj_parser = NULL; uint64_t len = 0; ssize_t ret, remain, keylen = 0; #ifdef MSGPACK_DEBUG_PARSER uint64_t i; enum e_msgpack_parser_state hist[256]; #endif p = parser->chunks->begin; remain = parser->chunks->remain; end = p + remain; while (p < end) { #ifdef MSGPACK_DEBUG_PARSER hist[i++ % 256] = state; #endif switch (state) { case read_type: - obj_parser = ucl_msgpack_get_parser_from_type (*p); + obj_parser = ucl_msgpack_get_parser_from_type(*p); if (obj_parser == NULL) { - ucl_create_err (&parser->err, "unknown msgpack format: %x", - (unsigned int)*p); + ucl_create_err(&parser->err, "unknown msgpack format: %x", + (unsigned int) *p); return false; } /* Now check length sanity */ if (obj_parser->flags & MSGPACK_FLAG_FIXED) { if (obj_parser->len == 0) { /* We have an embedded size */ len = *p & ~obj_parser->prefix; } else { if (remain < obj_parser->len) { - ucl_create_err (&parser->err, "not enough data remain to " - "read object's length: %u remain, %u needed", - (unsigned)remain, obj_parser->len); + ucl_create_err(&parser->err, "not enough data remain to " + "read object's length: %u remain, %u needed", + (unsigned) remain, obj_parser->len); return false; } len = obj_parser->len; } if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) { /* We must pass value as the second byte */ if (remain > 0) { - p ++; - remain --; + p++; + remain--; } } else { /* Len is irrelevant now */ len = 0; } } else { /* Length is not embedded */ - remain --; + remain--; if (remain < obj_parser->len) { - ucl_create_err (&parser->err, "not enough data remain to " - "read object's length: %u remain, %u needed", - (unsigned)remain, obj_parser->len); + ucl_create_err(&parser->err, "not enough data remain to " + "read object's length: %u remain, %u needed", + (unsigned) remain, obj_parser->len); return false; } - p ++; + p++; switch (obj_parser->len) { case 1: len = *p; break; case 2: - len = FROM_BE16 (*(uint16_t *)p); + len = FROM_BE16(*(uint16_t *) p); break; case 4: - len = FROM_BE32 (*(uint32_t *)p); + len = FROM_BE32(*(uint32_t *) p); break; case 8: - len = FROM_BE64 (*(uint64_t *)p); + len = FROM_BE64(*(uint64_t *) p); break; default: - ucl_create_err (&parser->err, "invalid length of the length field: %u", - (unsigned)obj_parser->len); + ucl_create_err(&parser->err, "invalid length of the length field: %u", + (unsigned) obj_parser->len); return false; } p += obj_parser->len; remain -= obj_parser->len; } if (obj_parser->flags & MSGPACK_FLAG_ASSOC) { /* We have just read the new associative map */ state = start_assoc; } - else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){ + else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) { state = start_array; } else { state = next_state; } break; case start_assoc: - parser->cur_obj = ucl_object_new_full (UCL_OBJECT, - parser->chunks->priority); + parser->cur_obj = ucl_object_new_full(UCL_OBJECT, + parser->chunks->priority); /* Insert to the previous level container */ - if (parser->stack && !ucl_msgpack_insert_object (parser, - key, keylen, parser->cur_obj)) { + if (parser->stack && !ucl_msgpack_insert_object(parser, + key, keylen, parser->cur_obj)) { return false; } /* Get new container */ - container = ucl_msgpack_get_container (parser, obj_parser, len); + container = ucl_msgpack_get_container(parser, obj_parser, len); if (container == NULL) { return false; } - ret = obj_parser->func (parser, container, len, obj_parser->fmt, - p, remain); + ret = obj_parser->func(parser, container, len, obj_parser->fmt, + p, remain); CONSUME_RET; key = NULL; keylen = 0; if (len > 0) { state = read_type; next_state = read_assoc_key; } else { /* Empty object */ state = finish_assoc_value; } break; case start_array: - parser->cur_obj = ucl_object_new_full (UCL_ARRAY, - parser->chunks->priority); + parser->cur_obj = ucl_object_new_full(UCL_ARRAY, + parser->chunks->priority); /* Insert to the previous level container */ - if (parser->stack && !ucl_msgpack_insert_object (parser, - key, keylen, parser->cur_obj)) { + if (parser->stack && !ucl_msgpack_insert_object(parser, + key, keylen, parser->cur_obj)) { return false; } /* Get new container */ - container = ucl_msgpack_get_container (parser, obj_parser, len); + container = ucl_msgpack_get_container(parser, obj_parser, len); if (container == NULL) { return false; } - ret = obj_parser->func (parser, container, len, obj_parser->fmt, - p, remain); + ret = obj_parser->func(parser, container, len, obj_parser->fmt, + p, remain); CONSUME_RET; if (len > 0) { state = read_type; next_state = read_array_value; } else { /* Empty array */ state = finish_array_value; } break; case read_array_value: /* * p is now at the value start, len now contains length read and * obj_parser contains the corresponding specific parser */ container = parser->stack; if (parser->stack == NULL) { - ucl_create_err (&parser->err, - "read assoc value when no container represented"); + ucl_create_err(&parser->err, + "read assoc value when no container represented"); return false; } - ret = obj_parser->func (parser, container, len, obj_parser->fmt, - p, remain); + ret = obj_parser->func(parser, container, len, obj_parser->fmt, + p, remain); CONSUME_RET; /* Insert value to the container and check if we have finished array */ - if (!ucl_msgpack_insert_object (parser, NULL, 0, - parser->cur_obj)) { - return false; + if (parser->cur_obj) { + if (!ucl_msgpack_insert_object(parser, NULL, 0, + parser->cur_obj)) { + return false; + } + } + else { + /* We have parsed ext, ignore it */ } - if (ucl_msgpack_is_container_finished (container)) { + if (ucl_msgpack_is_container_finished(container)) { state = finish_array_value; } else { /* Read more elements */ state = read_type; next_state = read_array_value; } break; case read_assoc_key: /* * Keys must have string type for ucl msgpack */ if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) { - ucl_create_err (&parser->err, "bad type for key: %u, expected " - "string", (unsigned)obj_parser->fmt); + ucl_create_err(&parser->err, "bad type for key: %u, expected " + "string", + (unsigned) obj_parser->fmt); return false; } key = p; keylen = len; if (keylen > remain || keylen == 0) { - ucl_create_err (&parser->err, "too long or empty key"); + ucl_create_err(&parser->err, "too long or empty key"); return false; } p += len; remain -= len; state = read_type; next_state = read_assoc_value; break; case read_assoc_value: /* * p is now at the value start, len now contains length read and * obj_parser contains the corresponding specific parser */ container = parser->stack; if (container == NULL) { - ucl_create_err (&parser->err, - "read assoc value when no container represented"); + ucl_create_err(&parser->err, + "read assoc value when no container represented"); return false; } - ret = obj_parser->func (parser, container, len, obj_parser->fmt, - p, remain); + ret = obj_parser->func(parser, container, len, obj_parser->fmt, + p, remain); CONSUME_RET; - assert (key != NULL && keylen > 0); + assert(key != NULL && keylen > 0); - if (!ucl_msgpack_insert_object (parser, key, keylen, - parser->cur_obj)) { + if (parser->cur_obj) { + if (!ucl_msgpack_insert_object(parser, key, keylen, + parser->cur_obj)) { - return false; + return false; + } } key = NULL; keylen = 0; - if (ucl_msgpack_is_container_finished (container)) { + if (ucl_msgpack_is_container_finished(container)) { state = finish_assoc_value; } else { /* Read more elements */ state = read_type; next_state = read_assoc_key; } break; case finish_array_value: case finish_assoc_value: GET_NEXT_STATE; state = read_type; break; case error_state: - ucl_create_err (&parser->err, "invalid state machine state"); + ucl_create_err(&parser->err, "invalid state machine state"); return false; } } /* Check the finishing state */ switch (state) { case start_array: case start_assoc: /* Empty container at the end */ if (len != 0) { ucl_create_err (&parser->err, "invalid non-empty container at the end; len=%ju", (uintmax_t)len); return false; } - parser->cur_obj = ucl_object_new_full ( - state == start_array ? UCL_ARRAY : UCL_OBJECT, - parser->chunks->priority); + parser->cur_obj = ucl_object_new_full( + state == start_array ? UCL_ARRAY : UCL_OBJECT, + parser->chunks->priority); if (parser->stack == NULL) { - ucl_create_err (&parser->err, - "read assoc value when no container represented"); + ucl_create_err(&parser->err, + "read assoc value when no container represented"); return false; } /* Insert to the previous level container */ - if (!ucl_msgpack_insert_object (parser, - key, keylen, parser->cur_obj)) { + if (!ucl_msgpack_insert_object(parser, + key, keylen, parser->cur_obj)) { return false; } /* Get new container */ - container = ucl_msgpack_get_container (parser, obj_parser, len); + container = ucl_msgpack_get_container(parser, obj_parser, len); if (container == NULL) { return false; } - ret = obj_parser->func (parser, container, len, obj_parser->fmt, - p, remain); + ret = obj_parser->func(parser, container, len, obj_parser->fmt, + p, remain); break; case read_array_value: case read_assoc_value: if (len != 0) { - ucl_create_err (&parser->err, "unfinished value at the end"); + ucl_create_err(&parser->err, "unfinished value at the end"); return false; } container = parser->stack; if (parser->stack == NULL) { - ucl_create_err (&parser->err, - "read assoc value when no container represented"); + ucl_create_err(&parser->err, + "read assoc value when no container represented"); return false; } - ret = obj_parser->func (parser, container, len, obj_parser->fmt, - p, remain); + ret = obj_parser->func(parser, container, len, obj_parser->fmt, + p, remain); CONSUME_RET; /* Insert value to the container and check if we have finished array */ - if (!ucl_msgpack_insert_object (parser, NULL, 0, - parser->cur_obj)) { - return false; + if (parser->cur_obj) { + if (!ucl_msgpack_insert_object(parser, NULL, 0, + parser->cur_obj)) { + return false; + } } break; case finish_array_value: case finish_assoc_value: case read_type: /* Valid finishing state */ break; default: /* Invalid finishing state */ - ucl_create_err (&parser->err, "invalid state machine finishing state: %d", - state); + ucl_create_err(&parser->err, "invalid state machine finishing state: %d", + state); return false; } /* Rewind to the top level container */ - ucl_msgpack_get_next_container (parser); + ucl_msgpack_get_next_container(parser); if (parser->stack != NULL) { - ucl_create_err (&parser->err, "incomplete container"); + ucl_create_err(&parser->err, "incomplete container"); return false; } return true; } -bool -ucl_parse_msgpack (struct ucl_parser *parser) +bool ucl_parse_msgpack(struct ucl_parser *parser) { ucl_object_t *container = NULL; const unsigned char *p; bool ret; - assert (parser != NULL); - assert (parser->chunks != NULL); - assert (parser->chunks->begin != NULL); - assert (parser->chunks->remain != 0); + assert(parser != NULL); + assert(parser->chunks != NULL); + assert(parser->chunks->begin != NULL); + assert(parser->chunks->remain != 0); p = parser->chunks->begin; if (parser->stack) { container = parser->stack->obj; } /* * When we start parsing message pack chunk, we must ensure that we * have either a valid container or the top object inside message pack is * of container type */ if (container == NULL) { if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) { - ucl_create_err (&parser->err, "bad top level object for msgpack"); + ucl_create_err(&parser->err, "bad top level object for msgpack"); return false; } } - ret = ucl_msgpack_consume (parser); + ret = ucl_msgpack_consume(parser); if (ret && parser->top_obj == NULL) { parser->top_obj = parser->cur_obj; } return ret; } static ssize_t -ucl_msgpack_parse_map (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain) +ucl_msgpack_parse_map(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain) { container->obj = parser->cur_obj; return 0; } static ssize_t -ucl_msgpack_parse_array (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain) +ucl_msgpack_parse_array(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain) { container->obj = parser->cur_obj; return 0; } static ssize_t -ucl_msgpack_parse_string (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain) +ucl_msgpack_parse_string(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain) { ucl_object_t *obj; if (len > remain) { return -1; } - obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority); + obj = ucl_object_new_full(UCL_STRING, parser->chunks->priority); obj->value.sv = pos; obj->len = len; if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) { obj->flags |= UCL_OBJECT_BINARY; } if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { if (obj->flags & UCL_OBJECT_BINARY) { - obj->trash_stack[UCL_TRASH_VALUE] = malloc (len); + obj->trash_stack[UCL_TRASH_VALUE] = malloc(len); if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) { - memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len); + memcpy(obj->trash_stack[UCL_TRASH_VALUE], pos, len); } } else { - ucl_copy_value_trash (obj); + ucl_copy_value_trash(obj); } } parser->cur_obj = obj; return len; } static ssize_t -ucl_msgpack_parse_int (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain) +ucl_msgpack_parse_int(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain) { ucl_object_t *obj; int8_t iv8; int16_t iv16; int32_t iv32; int64_t iv64; uint16_t uiv16; uint32_t uiv32; uint64_t uiv64; if (len > remain) { return -1; } - obj = ucl_object_new_full (UCL_INT, parser->chunks->priority); + obj = ucl_object_new_full(UCL_INT, parser->chunks->priority); switch (fmt) { case msgpack_positive_fixint: obj->value.iv = (*pos & 0x7f); len = 1; break; case msgpack_negative_fixint: - obj->value.iv = - (*pos & 0x1f); + obj->value.iv = -(*pos & 0x1f); len = 1; break; case msgpack_uint8: - obj->value.iv = (unsigned char)*pos; + obj->value.iv = (unsigned char) *pos; len = 1; break; case msgpack_int8: - memcpy (&iv8, pos, sizeof (iv8)); + memcpy(&iv8, pos, sizeof(iv8)); obj->value.iv = iv8; len = 1; break; case msgpack_int16: - memcpy (&iv16, pos, sizeof (iv16)); - iv16 = FROM_BE16 (iv16); + memcpy(&iv16, pos, sizeof(iv16)); + iv16 = FROM_BE16(iv16); obj->value.iv = iv16; len = 2; break; case msgpack_uint16: - memcpy (&uiv16, pos, sizeof (uiv16)); - uiv16 = FROM_BE16 (uiv16); + memcpy(&uiv16, pos, sizeof(uiv16)); + uiv16 = FROM_BE16(uiv16); obj->value.iv = uiv16; len = 2; break; case msgpack_int32: - memcpy (&iv32, pos, sizeof (iv32)); - iv32 = FROM_BE32 (iv32); + memcpy(&iv32, pos, sizeof(iv32)); + iv32 = FROM_BE32(iv32); obj->value.iv = iv32; len = 4; break; case msgpack_uint32: memcpy(&uiv32, pos, sizeof(uiv32)); uiv32 = FROM_BE32(uiv32); obj->value.iv = uiv32; len = 4; break; case msgpack_int64: - memcpy (&iv64, pos, sizeof (iv64)); - iv64 = FROM_BE64 (iv64); + memcpy(&iv64, pos, sizeof(iv64)); + iv64 = FROM_BE64(iv64); obj->value.iv = iv64; len = 8; break; case msgpack_uint64: memcpy(&uiv64, pos, sizeof(uiv64)); uiv64 = FROM_BE64(uiv64); obj->value.iv = uiv64; len = 8; break; default: - assert (0); + assert(0); break; } parser->cur_obj = obj; return len; } static ssize_t -ucl_msgpack_parse_float (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain) +ucl_msgpack_parse_float(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain) { ucl_object_t *obj; union { uint32_t i; float f; } d; uint64_t uiv64; if (len > remain) { return -1; } - obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority); + obj = ucl_object_new_full(UCL_FLOAT, parser->chunks->priority); switch (fmt) { case msgpack_float32: memcpy(&d.i, pos, sizeof(d.i)); d.i = FROM_BE32(d.i); /* XXX: can be slow */ obj->value.dv = d.f; len = 4; break; case msgpack_float64: memcpy(&uiv64, pos, sizeof(uiv64)); uiv64 = FROM_BE64(uiv64); obj->value.iv = uiv64; len = 8; break; default: - assert (0); + assert(0); break; } parser->cur_obj = obj; return len; } static ssize_t -ucl_msgpack_parse_bool (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain) +ucl_msgpack_parse_bool(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain) { ucl_object_t *obj; if (len > remain) { return -1; } - obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority); + obj = ucl_object_new_full(UCL_BOOLEAN, parser->chunks->priority); switch (fmt) { case msgpack_true: obj->value.iv = true; break; case msgpack_false: obj->value.iv = false; break; default: - assert (0); + assert(0); break; } parser->cur_obj = obj; return 1; } static ssize_t -ucl_msgpack_parse_null (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain) +ucl_msgpack_parse_null(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain) { ucl_object_t *obj; if (len > remain) { return -1; } - obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority); + obj = ucl_object_new_full(UCL_NULL, parser->chunks->priority); parser->cur_obj = obj; return 1; } static ssize_t -ucl_msgpack_parse_ignore (struct ucl_parser *parser, - struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, - const unsigned char *pos, size_t remain) +ucl_msgpack_parse_ignore(struct ucl_parser *parser, + struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, + const unsigned char *pos, size_t remain) { if (len > remain) { return -1; } switch (fmt) { case msgpack_fixext1: len = 2; break; case msgpack_fixext2: len = 3; break; case msgpack_fixext4: len = 5; break; case msgpack_fixext8: len = 9; break; case msgpack_fixext16: len = 17; break; case msgpack_ext8: case msgpack_ext16: case msgpack_ext32: len = len + 1; break; default: - ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt); + ucl_create_err(&parser->err, "bad type: %x", (unsigned) fmt); return -1; } + parser->cur_obj = NULL; + return len; } diff --git a/contrib/libucl/src/ucl_parser.c b/contrib/libucl/src/ucl_parser.c index 728cd6381056..69b8143181be 100644 --- a/contrib/libucl/src/ucl_parser.c +++ b/contrib/libucl/src/ucl_parser.c @@ -1,3236 +1,3247 @@ /* Copyright (c) 2013, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "ucl.h" #include "ucl_internal.h" #include "ucl_chartable.h" /** * @file ucl_parser.c * The implementation of ucl parser */ struct ucl_parser_saved_state { unsigned int line; unsigned int column; size_t remain; const unsigned char *pos; }; /** * Move up to len characters * @param parser * @param begin * @param len * @return new position in chunk */ -#define ucl_chunk_skipc(chunk, p) \ -do { \ - if (p == chunk->end) { \ - break; \ - } \ - if (*(p) == '\n') { \ - (chunk)->line ++; \ - (chunk)->column = 0; \ - } \ - else (chunk)->column ++; \ - (p++); \ - (chunk)->pos ++; \ - (chunk)->remain --; \ -} while (0) +#define ucl_chunk_skipc(chunk, p) \ + do { \ + if (p == chunk->end) { \ + break; \ + } \ + if (*(p) == '\n') { \ + (chunk)->line++; \ + (chunk)->column = 0; \ + } \ + else \ + (chunk)->column++; \ + (p++); \ + (chunk)->pos++; \ + (chunk)->remain--; \ + } while (0) static inline void -ucl_set_err (struct ucl_parser *parser, int code, const char *str, UT_string **err) +ucl_set_err(struct ucl_parser *parser, int code, const char *str, UT_string **err) { const char *fmt_string, *filename; struct ucl_chunk *chunk = parser->chunks; if (parser->cur_file) { filename = parser->cur_file; } else { filename = ""; } if (chunk->pos < chunk->end) { - if (isgraph (*chunk->pos)) { + if (isgraph(*chunk->pos)) { fmt_string = "error while parsing %s: " - "line: %d, column: %d - '%s', character: '%c'"; + "line: %d, column: %d - '%s', character: '%c'"; } else { fmt_string = "error while parsing %s: " - "line: %d, column: %d - '%s', character: '0x%02x'"; + "line: %d, column: %d - '%s', character: '0x%02x'"; } - ucl_create_err (err, fmt_string, - filename, chunk->line, chunk->column, - str, *chunk->pos); + ucl_create_err(err, fmt_string, + filename, chunk->line, chunk->column, + str, *chunk->pos); } else { - ucl_create_err (err, "error while parsing %s: at the end of chunk: %s", - filename, str); + ucl_create_err(err, "error while parsing %s: at the end of chunk: %s", + filename, str); } parser->err_code = code; parser->state = UCL_STATE_ERROR; } static void -ucl_save_comment (struct ucl_parser *parser, const char *begin, size_t len) +ucl_save_comment(struct ucl_parser *parser, const char *begin, size_t len) { ucl_object_t *nobj; if (len > 0 && begin != NULL) { - nobj = ucl_object_fromstring_common (begin, len, 0); + nobj = ucl_object_fromstring_common(begin, len, 0); if (parser->last_comment) { /* We need to append data to an existing object */ - DL_APPEND (parser->last_comment, nobj); + DL_APPEND(parser->last_comment, nobj); } else { parser->last_comment = nobj; } } } static void -ucl_attach_comment (struct ucl_parser *parser, ucl_object_t *obj, bool before) +ucl_attach_comment(struct ucl_parser *parser, ucl_object_t *obj, bool before) { if (parser->last_comment) { - ucl_object_insert_key (parser->comments, parser->last_comment, - (const char *)&obj, sizeof (void *), true); + ucl_object_insert_key(parser->comments, parser->last_comment, + (const char *) &obj, sizeof(void *), true); if (before) { parser->last_comment->flags |= UCL_OBJECT_INHERITED; } parser->last_comment = NULL; } } /** * Skip all comments from the current pos resolving nested and multiline comments * @param parser * @return */ static bool -ucl_skip_comments (struct ucl_parser *parser) +ucl_skip_comments(struct ucl_parser *parser) { struct ucl_chunk *chunk = parser->chunks; const unsigned char *p, *beg = NULL; int comments_nested = 0; bool quoted = false; p = chunk->pos; start: if (chunk->remain > 0 && *p == '#') { if (parser->state != UCL_STATE_SCOMMENT && - parser->state != UCL_STATE_MCOMMENT) { + parser->state != UCL_STATE_MCOMMENT) { beg = p; while (p < chunk->end) { if (*p == '\n') { if (parser->flags & UCL_PARSER_SAVE_COMMENTS) { - ucl_save_comment (parser, beg, p - beg); + ucl_save_comment(parser, beg, p - beg); beg = NULL; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); goto start; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } } } else if (chunk->remain >= 2 && *p == '/' && p[1] == '*') { beg = p; comments_nested ++; ucl_chunk_skipc (chunk, p); ucl_chunk_skipc (chunk, p); while (p < chunk->end) { if (*p == '"' && *(p - 1) != '\\') { /* begin or end double-quoted string */ quoted = !quoted; ucl_chunk_skipc (chunk, p); } else if (quoted) { /* quoted character */ ucl_chunk_skipc (chunk, p); } else if (chunk->remain >= 2 && *p == '*' && p[1] == '/') { /* end of comment */ ucl_chunk_skipc (chunk, p); ucl_chunk_skipc (chunk, p); comments_nested --; if (comments_nested == 0) { if (parser->flags & UCL_PARSER_SAVE_COMMENTS) { ucl_save_comment (parser, beg, p - beg + 1); beg = NULL; } goto start; } } else if (chunk->remain >= 2 && *p == '/' && p[1] == '*') { /* start of nested comment */ comments_nested ++; ucl_chunk_skipc (chunk, p); ucl_chunk_skipc (chunk, p); } else { /* anything else */ ucl_chunk_skipc (chunk, p); } } if (comments_nested != 0) { - ucl_set_err (parser, UCL_ENESTED, - "unfinished multiline comment", &parser->err); + ucl_set_err(parser, UCL_ENESTED, + "unfinished multiline comment", &parser->err); return false; } } if (beg && p > beg && (parser->flags & UCL_PARSER_SAVE_COMMENTS)) { - ucl_save_comment (parser, beg, p - beg); + ucl_save_comment(parser, beg, p - beg); } return true; } /** * Return multiplier for a character * @param c multiplier character * @param is_bytes if true use 1024 multiplier * @return multiplier */ static inline unsigned long -ucl_lex_num_multiplier (const unsigned char c, bool is_bytes) { +ucl_lex_num_multiplier(const unsigned char c, bool is_bytes) +{ const struct { char c; long mult_normal; long mult_bytes; } multipliers[] = { - {'m', 1000 * 1000, 1024 * 1024}, - {'k', 1000, 1024}, - {'g', 1000 * 1000 * 1000, 1024 * 1024 * 1024} - }; + {'m', 1000 * 1000, 1024 * 1024}, + {'k', 1000, 1024}, + {'g', 1000 * 1000 * 1000, 1024 * 1024 * 1024}}; int i; - for (i = 0; i < 3; i ++) { - if (tolower (c) == multipliers[i].c) { + for (i = 0; i < 3; i++) { + if (tolower(c) == multipliers[i].c) { if (is_bytes) { return multipliers[i].mult_bytes; } return multipliers[i].mult_normal; } } return 1; } /** * Return multiplier for time scaling * @param c * @return */ static inline double -ucl_lex_time_multiplier (const unsigned char c) { +ucl_lex_time_multiplier(const unsigned char c) +{ const struct { char c; double mult; } multipliers[] = { - {'m', 60}, - {'h', 60 * 60}, - {'d', 60 * 60 * 24}, - {'w', 60 * 60 * 24 * 7}, - {'y', 60 * 60 * 24 * 365} - }; + {'m', 60}, + {'h', 60 * 60}, + {'d', 60 * 60 * 24}, + {'w', 60 * 60 * 24 * 7}, + {'y', 60 * 60 * 24 * 365}}; int i; - for (i = 0; i < 5; i ++) { - if (tolower (c) == multipliers[i].c) { + for (i = 0; i < 5; i++) { + if (tolower(c) == multipliers[i].c) { return multipliers[i].mult; } } return 1; } /** * Return true if a character is a end of an atom * @param c * @return */ static inline bool -ucl_lex_is_atom_end (const unsigned char c) +ucl_lex_is_atom_end(const unsigned char c) { - return ucl_test_character (c, UCL_CHARACTER_VALUE_END); + return ucl_test_character(c, UCL_CHARACTER_VALUE_END); } static inline bool -ucl_lex_is_comment (const unsigned char c1, const unsigned char c2) +ucl_lex_is_comment(const unsigned char c1, const unsigned char c2) { if (c1 == '/') { if (c2 == '*') { return true; } } else if (c1 == '#') { return true; } return false; } /** * Check variable found * @param parser * @param ptr * @param remain * @param out_len * @param strict * @param found * @return */ static inline const char * -ucl_check_variable_safe (struct ucl_parser *parser, const char *ptr, size_t remain, - size_t *out_len, bool strict, bool *found) +ucl_check_variable_safe(struct ucl_parser *parser, const char *ptr, size_t remain, + size_t *out_len, bool strict, bool *found) { struct ucl_variable *var; unsigned char *dst; size_t dstlen; bool need_free = false; - LL_FOREACH (parser->variables, var) { + LL_FOREACH(parser->variables, var) + { if (strict) { if (remain == var->var_len) { - if (memcmp (ptr, var->var, var->var_len) == 0) { + if (memcmp(ptr, var->var, var->var_len) == 0) { *out_len += var->value_len; *found = true; return (ptr + var->var_len); } } } else { if (remain >= var->var_len) { - if (memcmp (ptr, var->var, var->var_len) == 0) { + if (memcmp(ptr, var->var, var->var_len) == 0) { *out_len += var->value_len; *found = true; return (ptr + var->var_len); } } } } /* XXX: can only handle ${VAR} */ if (!(*found) && parser->var_handler != NULL && strict) { /* Call generic handler */ - if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free, - parser->var_data)) { + if (parser->var_handler(ptr, remain, &dst, &dstlen, &need_free, + parser->var_data)) { *found = true; *out_len = dstlen; if (need_free) { - free (dst); + free(dst); } return (ptr + remain); } } return ptr; } /** * Check for a variable in a given string * @param parser * @param ptr * @param remain * @param out_len * @param vars_found * @return */ static const char * -ucl_check_variable (struct ucl_parser *parser, const char *ptr, - size_t remain, size_t *out_len, bool *vars_found) +ucl_check_variable(struct ucl_parser *parser, const char *ptr, + size_t remain, size_t *out_len, bool *vars_found) { const char *p, *end, *ret = ptr; bool found = false; if (*ptr == '{') { /* We need to match the variable enclosed in braces */ p = ptr + 1; end = ptr + remain; while (p < end) { if (*p == '}') { - ret = ucl_check_variable_safe (parser, ptr + 1, p - ptr - 1, - out_len, true, &found); + ret = ucl_check_variable_safe(parser, ptr + 1, p - ptr - 1, + out_len, true, &found); if (found) { /* {} must be excluded actually */ - ret ++; + ret++; if (!*vars_found) { *vars_found = true; } } else { *out_len += 2; } break; } - p ++; + p++; } - if(p == end) { - (*out_len) ++; + if (p == end) { + (*out_len)++; } } else if (*ptr != '$') { /* Not count escaped dollar sign */ - ret = ucl_check_variable_safe (parser, ptr, remain, out_len, false, &found); + ret = ucl_check_variable_safe(parser, ptr, remain, out_len, false, &found); if (found && !*vars_found) { *vars_found = true; } if (!found) { - (*out_len) ++; + (*out_len)++; } } else { - ret ++; - (*out_len) ++; + ret++; + (*out_len)++; } return ret; } /** * Expand a single variable * @param parser * @param ptr * @param in_len * @param dest * @param out_len * @return */ static const char * -ucl_expand_single_variable (struct ucl_parser *parser, const char *ptr, - size_t in_len, unsigned char **dest, size_t out_len) +ucl_expand_single_variable(struct ucl_parser *parser, const char *ptr, + size_t in_len, unsigned char **dest, size_t out_len) { unsigned char *d = *dest, *dst; const char *p = ptr + 1, *ret; struct ucl_variable *var; size_t dstlen; bool need_free = false; bool found = false; bool strict = false; ret = ptr + 1; /* For the $ sign */ - in_len --; + in_len--; if (*p == '$') { *d++ = *p++; *dest = d; return p; } else if (*p == '{') { - p ++; - in_len --; + p++; + in_len--; strict = true; ret += 2; } - LL_FOREACH (parser->variables, var) { + LL_FOREACH(parser->variables, var) + { if (out_len >= var->value_len && in_len >= (var->var_len + (strict ? 1 : 0))) { - if (memcmp (p, var->var, var->var_len) == 0) { + if (memcmp(p, var->var, var->var_len) == 0) { if (!strict || p[var->var_len] == '}') { - memcpy (d, var->value, var->value_len); + memcpy(d, var->value, var->value_len); ret += var->var_len; d += var->value_len; found = true; break; } } } } if (!found) { if (strict && parser->var_handler != NULL) { dstlen = out_len; - if (parser->var_handler (p, in_len, &dst, &dstlen, &need_free, - parser->var_data)) { + if (parser->var_handler(p, in_len, &dst, &dstlen, &need_free, + parser->var_data)) { if (dstlen > out_len) { /* We do not have enough space! */ if (need_free) { - free (dst); + free(dst); } } else { memcpy(d, dst, dstlen); ret += in_len; d += dstlen; found = true; if (need_free) { free(dst); } } } } /* Leave variable as is, in this case we use dest */ if (!found) { if (strict && out_len >= 2) { /* Copy '${' */ - memcpy (d, ptr, 2); + memcpy(d, ptr, 2); d += 2; - ret --; + ret--; } else { - memcpy (d, ptr, 1); - d ++; + memcpy(d, ptr, 1); + d++; } } } *dest = d; return ret; } /** * Expand variables in string * @param parser * @param dst * @param src * @param in_len * @return */ static ssize_t -ucl_expand_variable (struct ucl_parser *parser, unsigned char **dst, - const char *src, size_t in_len) +ucl_expand_variable(struct ucl_parser *parser, unsigned char **dst, + const char *src, size_t in_len) { const char *p, *end = src + in_len; unsigned char *d, *d_end; size_t out_len = 0; bool vars_found = false; if (parser->flags & UCL_PARSER_DISABLE_MACRO) { *dst = NULL; return in_len; } p = src; while (p != end) { if (*p == '$' && p + 1 != end) { - p = ucl_check_variable (parser, p + 1, end - p - 1, &out_len, &vars_found); + p = ucl_check_variable(parser, p + 1, end - p - 1, &out_len, &vars_found); } else { - p ++; - out_len ++; + p++; + out_len++; } } if (!vars_found) { /* Trivial case */ *dst = NULL; return in_len; } - *dst = UCL_ALLOC (out_len + 1); + *dst = UCL_ALLOC(out_len + 1); if (*dst == NULL) { return in_len; } d = *dst; d_end = d + out_len; p = src; while (p != end && d != d_end) { if (*p == '$' && p + 1 != end) { - p = ucl_expand_single_variable (parser, p, end - p, &d, d_end - d); + p = ucl_expand_single_variable(parser, p, end - p, &d, d_end - d); } else { *d++ = *p++; } } *d = '\0'; return out_len; } /** * Store or copy pointer to the trash stack * @param parser parser object * @param src src string * @param dst destination buffer (trash stack pointer) * @param dst_const const destination pointer (e.g. value of object) * @param in_len input length * @param need_unescape need to unescape source (and copy it) * @param need_lowercase need to lowercase value (and copy) * @param need_expand need to expand variables (and copy as well) * @param unescape_squote unescape single quoted string * @return output length (excluding \0 symbol) */ static inline ssize_t -ucl_copy_or_store_ptr (struct ucl_parser *parser, - const unsigned char *src, unsigned char **dst, - const char **dst_const, size_t in_len, - bool need_unescape, bool need_lowercase, bool need_expand, - bool unescape_squote) +ucl_copy_or_store_ptr(struct ucl_parser *parser, + const unsigned char *src, unsigned char **dst, + const char **dst_const, size_t in_len, + bool need_unescape, bool need_lowercase, bool need_expand, + bool unescape_squote) { ssize_t ret = -1, tret; unsigned char *tmp; if (need_unescape || need_lowercase || - (need_expand && parser->variables != NULL) || - !(parser->flags & UCL_PARSER_ZEROCOPY)) { + (need_expand && parser->variables != NULL) || + !(parser->flags & UCL_PARSER_ZEROCOPY)) { /* Copy string */ - *dst = UCL_ALLOC (in_len + 1); + *dst = UCL_ALLOC(in_len + 1); if (*dst == NULL) { - ucl_set_err (parser, UCL_EINTERNAL, "cannot allocate memory for a string", - &parser->err); + ucl_set_err(parser, UCL_EINTERNAL, "cannot allocate memory for a string", + &parser->err); return false; } if (need_lowercase) { - ret = ucl_strlcpy_tolower (*dst, src, in_len + 1); + ret = ucl_strlcpy_tolower(*dst, src, in_len + 1); } else { - ret = ucl_strlcpy_unsafe (*dst, src, in_len + 1); + ret = ucl_strlcpy_unsafe(*dst, src, in_len + 1); } if (need_unescape) { if (!unescape_squote) { - ret = ucl_unescape_json_string (*dst, ret); + ret = ucl_unescape_json_string(*dst, ret); } else { - ret = ucl_unescape_squoted_string (*dst, ret); + ret = ucl_unescape_squoted_string(*dst, ret); } } if (need_expand) { tmp = *dst; tret = ret; - ret = ucl_expand_variable (parser, dst, tmp, ret); + ret = ucl_expand_variable(parser, dst, tmp, ret); if (*dst == NULL) { /* Nothing to expand */ *dst = tmp; ret = tret; } else { /* Free unexpanded value */ - UCL_FREE (in_len + 1, tmp); + UCL_FREE(in_len + 1, tmp); } } *dst_const = *dst; } else { *dst_const = src; ret = in_len; } return ret; } /** * Create and append an object at the specified level * @param parser * @param is_array * @param level * @return */ static inline ucl_object_t * -ucl_parser_add_container (ucl_object_t *obj, struct ucl_parser *parser, - bool is_array, uint32_t level, bool has_obrace) +ucl_parser_add_container(ucl_object_t *obj, struct ucl_parser *parser, + bool is_array, uint32_t level, bool has_obrace) { struct ucl_stack *st; ucl_object_t *nobj; if (obj == NULL) { - nobj = ucl_object_new_full (is_array ? UCL_ARRAY : UCL_OBJECT, parser->chunks->priority); + nobj = ucl_object_new_full(is_array ? UCL_ARRAY : UCL_OBJECT, parser->chunks->priority); if (nobj == NULL) { goto enomem0; } - } else { + } + else { if (obj->type == (is_array ? UCL_OBJECT : UCL_ARRAY)) { /* Bad combination for merge: array and object */ - ucl_set_err (parser, UCL_EMERGE, - "cannot merge an object with an array", - &parser->err); + ucl_set_err(parser, UCL_EMERGE, + "cannot merge an object with an array", + &parser->err); return NULL; } nobj = obj; nobj->type = is_array ? UCL_ARRAY : UCL_OBJECT; } if (!is_array) { if (nobj->value.ov == NULL) { - nobj->value.ov = ucl_hash_create (parser->flags & UCL_PARSER_KEY_LOWERCASE); + nobj->value.ov = ucl_hash_create(parser->flags & UCL_PARSER_KEY_LOWERCASE); if (nobj->value.ov == NULL) { goto enomem1; } } parser->state = UCL_STATE_KEY; - } else { + } + else { parser->state = UCL_STATE_VALUE; } - st = UCL_ALLOC (sizeof (struct ucl_stack)); + st = UCL_ALLOC(sizeof(struct ucl_stack)); if (st == NULL) { goto enomem1; } st->obj = nobj; if (level >= UINT16_MAX) { - ucl_set_err (parser, UCL_ENESTED, - "objects are nesting too deep (over 65535 limit)", - &parser->err); + ucl_set_err(parser, UCL_ENESTED, + "objects are nesting too deep (over 65535 limit)", + &parser->err); if (nobj != obj) { - ucl_object_unref (obj); + ucl_object_unref(obj); } - UCL_FREE(sizeof (struct ucl_stack), st); + UCL_FREE(sizeof(struct ucl_stack), st); return NULL; } st->e.params.level = level; st->e.params.line = parser->chunks->line; st->chunk = parser->chunks; if (has_obrace) { st->e.params.flags = UCL_STACK_HAS_OBRACE; } else { st->e.params.flags = 0; } - LL_PREPEND (parser->stack, st); + LL_PREPEND(parser->stack, st); parser->cur_obj = nobj; return nobj; enomem1: if (nobj != obj) - ucl_object_unref (nobj); + ucl_object_unref(nobj); enomem0: - ucl_set_err (parser, UCL_EINTERNAL, "cannot allocate memory for an object", - &parser->err); + ucl_set_err(parser, UCL_EINTERNAL, "cannot allocate memory for an object", + &parser->err); return NULL; } -int -ucl_maybe_parse_number (ucl_object_t *obj, - const char *start, const char *end, const char **pos, - bool allow_double, bool number_bytes, bool allow_time) +int ucl_maybe_parse_number(ucl_object_t *obj, + const char *start, const char *end, const char **pos, + bool allow_double, bool number_bytes, bool allow_time) { const char *p = start, *c = start; char *endptr; bool got_dot = false, got_exp = false, need_double = false, - is_time = false, valid_start = false, is_hex = false; + is_time = false, valid_start = false, is_hex = false; int is_neg = 0; double dv = 0; int64_t lv = 0; if (*p == '-') { is_neg = 1; - c ++; - p ++; + c++; + p++; } while (p < end) { - if (is_hex && isxdigit (*p)) { - p ++; + if (is_hex && isxdigit(*p)) { + p++; } - else if (isdigit (*p)) { + else if (isdigit(*p)) { valid_start = true; - p ++; + p++; } else if (!is_hex && (*p == 'x' || *p == 'X')) { is_hex = true; allow_double = false; c = p + 1; - p ++; + p++; } else if (allow_double) { if (p == c) { /* Empty digits sequence, not a number */ *pos = start; return EINVAL; } else if (*p == '.') { if (got_dot) { /* Double dots, not a number */ *pos = start; return EINVAL; } else { got_dot = true; need_double = true; - p ++; + p++; } } else if (*p == 'e' || *p == 'E') { if (got_exp) { /* Double exp, not a number */ *pos = start; return EINVAL; } else { got_exp = true; need_double = true; - p ++; + p++; if (p >= end) { *pos = start; return EINVAL; } - if (!isdigit (*p) && *p != '+' && *p != '-') { + if (!isdigit(*p) && *p != '+' && *p != '-') { /* Wrong exponent sign */ *pos = start; return EINVAL; } else { - p ++; + p++; } } } else { /* Got the end of the number, need to check */ break; } } else if (!allow_double && *p == '.') { /* Unexpected dot */ *pos = start; return EINVAL; } else { break; } } if (!valid_start || p == c) { *pos = start; return EINVAL; } char numbuf[128]; - if ((size_t)(p - c + 1) >= sizeof(numbuf)) { + if ((size_t) (p - c + 1) >= sizeof(numbuf)) { *pos = start; return EINVAL; } if (is_neg) { numbuf[0] = '-'; - ucl_strlcpy (&numbuf[1], c, p - c + 1); + ucl_strlcpy(&numbuf[1], c, p - c + 1); } else { - ucl_strlcpy (numbuf, c, p - c + 1); + ucl_strlcpy(numbuf, c, p - c + 1); } errno = 0; if (need_double) { - dv = strtod (numbuf, &endptr); + dv = strtod(numbuf, &endptr); } else { if (is_hex) { - lv = strtoimax (numbuf, &endptr, 16); + lv = strtoimax(numbuf, &endptr, 16); } else { - lv = strtoimax (numbuf, &endptr, 10); + lv = strtoimax(numbuf, &endptr, 10); } } if (errno == ERANGE) { *pos = start; return ERANGE; } /* Now check endptr and move it from numbuf to the real ending */ if (endptr != NULL) { long shift = endptr - numbuf - is_neg; - endptr = (char *)c + shift; + endptr = (char *) c + shift; } if (endptr >= end) { p = end; goto set_obj; } - if (endptr == NULL || ucl_lex_is_atom_end (*endptr) || *endptr == '\0') { + if (endptr == NULL || ucl_lex_is_atom_end(*endptr) || *endptr == '\0') { p = endptr; goto set_obj; } if (endptr < end && endptr != start) { p = endptr; switch (*p) { case 'm': case 'M': case 'g': case 'G': case 'k': case 'K': if (end - p >= 2) { if (p[1] == 's' || p[1] == 'S') { /* Milliseconds */ if (!need_double) { need_double = true; dv = lv; } is_time = true; if (p[0] == 'm' || p[0] == 'M') { dv /= 1000.; } else { - dv *= ucl_lex_num_multiplier (*p, false); + dv *= ucl_lex_num_multiplier(*p, false); } p += 2; - if (end - p > 0 && !ucl_lex_is_atom_end (*p)) { + if (end - p > 0 && !ucl_lex_is_atom_end(*p)) { *pos = start; return EINVAL; } goto set_obj; } else if (number_bytes || (p[1] == 'b' || p[1] == 'B')) { /* Bytes */ if (need_double) { need_double = false; lv = dv; } - lv *= ucl_lex_num_multiplier (*p, true); + lv *= ucl_lex_num_multiplier(*p, true); p += 2; - if (end - p > 0 && !ucl_lex_is_atom_end (*p)) { + if (end - p > 0 && !ucl_lex_is_atom_end(*p)) { *pos = start; return EINVAL; } goto set_obj; } - else if (ucl_lex_is_atom_end (p[1])) { + else if (ucl_lex_is_atom_end(p[1])) { if (need_double) { - dv *= ucl_lex_num_multiplier (*p, false); + dv *= ucl_lex_num_multiplier(*p, false); } else { - lv *= ucl_lex_num_multiplier (*p, number_bytes); + lv *= ucl_lex_num_multiplier(*p, number_bytes); } - p ++; + p++; goto set_obj; } else if (allow_time && end - p >= 3) { - if (tolower (p[0]) == 'm' && - tolower (p[1]) == 'i' && - tolower (p[2]) == 'n') { + if (tolower(p[0]) == 'm' && + tolower(p[1]) == 'i' && + tolower(p[2]) == 'n') { /* Minutes */ if (!need_double) { need_double = true; dv = lv; } is_time = true; dv *= 60.; p += 3; - if (end - p > 0 && !ucl_lex_is_atom_end (*p)) { + if (end - p > 0 && !ucl_lex_is_atom_end(*p)) { *pos = start; return EINVAL; } goto set_obj; } } } else { if (need_double) { - dv *= ucl_lex_num_multiplier (*p, false); + dv *= ucl_lex_num_multiplier(*p, false); } else { - lv *= ucl_lex_num_multiplier (*p, number_bytes); + lv *= ucl_lex_num_multiplier(*p, number_bytes); } - p ++; - if (end - p > 0 && !ucl_lex_is_atom_end (*p)) { + p++; + if (end - p > 0 && !ucl_lex_is_atom_end(*p)) { *pos = start; return EINVAL; } goto set_obj; } break; case 'S': case 's': if (allow_time && - (p == end - 1 || ucl_lex_is_atom_end (p[1]))) { + (p == end - 1 || ucl_lex_is_atom_end(p[1]))) { if (!need_double) { need_double = true; dv = lv; } - p ++; + p++; is_time = true; goto set_obj; } break; case 'h': case 'H': case 'd': case 'D': case 'w': case 'W': case 'Y': case 'y': if (allow_time && - (p == end - 1 || ucl_lex_is_atom_end (p[1]))) { + (p == end - 1 || ucl_lex_is_atom_end(p[1]))) { if (!need_double) { need_double = true; dv = lv; } is_time = true; - dv *= ucl_lex_time_multiplier (*p); - p ++; + dv *= ucl_lex_time_multiplier(*p); + p++; goto set_obj; } break; case '\t': case ' ': while (p < end && ucl_test_character(*p, UCL_CHARACTER_WHITESPACE)) { p++; } - if (ucl_lex_is_atom_end(*p)) + if (p == end || ucl_lex_is_atom_end(*p)) goto set_obj; break; } } else if (endptr == end) { /* Just a number at the end of chunk */ p = end; goto set_obj; } *pos = c; return EINVAL; set_obj: if (obj != NULL) { if (allow_double && (need_double || is_time)) { if (!is_time) { obj->type = UCL_FLOAT; } else { obj->type = UCL_TIME; } obj->value.dv = dv; } else { obj->type = UCL_INT; obj->value.iv = lv; } } *pos = p; return 0; } /** * Parse possible number * @param parser * @param chunk * @param obj * @return true if a number has been parsed */ static bool -ucl_lex_number (struct ucl_parser *parser, - struct ucl_chunk *chunk, ucl_object_t *obj) +ucl_lex_number(struct ucl_parser *parser, + struct ucl_chunk *chunk, ucl_object_t *obj) { const unsigned char *pos; int ret; - ret = ucl_maybe_parse_number (obj, chunk->pos, chunk->end, (const char **)&pos, - true, false, ((parser->flags & UCL_PARSER_NO_TIME) == 0)); + ret = ucl_maybe_parse_number(obj, chunk->pos, chunk->end, (const char **) &pos, + true, false, ((parser->flags & UCL_PARSER_NO_TIME) == 0)); if (ret == 0) { chunk->remain -= pos - chunk->pos; chunk->column += pos - chunk->pos; chunk->pos = pos; return true; } else if (ret == ERANGE) { - ucl_set_err (parser, UCL_ESYNTAX, "numeric value out of range", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "numeric value out of range", + &parser->err); } return false; } /** * Parse quoted string with possible escapes * @param parser * @param chunk * @param need_unescape * @param ucl_escape * @param var_expand * @return true if a string has been parsed */ static bool -ucl_lex_json_string (struct ucl_parser *parser, - struct ucl_chunk *chunk, - bool *need_unescape, - bool *ucl_escape, - bool *var_expand) +ucl_lex_json_string(struct ucl_parser *parser, + struct ucl_chunk *chunk, + bool *need_unescape, + bool *ucl_escape, + bool *var_expand) { const unsigned char *p = chunk->pos; unsigned char c; int i; while (p < chunk->end) { c = *p; if (c < 0x1F) { /* Unmasked control character */ if (c == '\n') { - ucl_set_err (parser, UCL_ESYNTAX, "unexpected newline", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "unexpected newline", + &parser->err); } else { - ucl_set_err (parser, UCL_ESYNTAX, "unexpected control character", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "unexpected control character", + &parser->err); } return false; } else if (c == '\\') { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); if (p >= chunk->end) { - ucl_set_err (parser, UCL_ESYNTAX, "unfinished escape character", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "unfinished escape character", + &parser->err); return false; } c = *p; - if (ucl_test_character (c, UCL_CHARACTER_ESCAPE)) { + if (ucl_test_character(c, UCL_CHARACTER_ESCAPE)) { if (c == 'u') { - ucl_chunk_skipc (chunk, p); - for (i = 0; i < 4 && p < chunk->end; i ++) { - if (!isxdigit (*p)) { - ucl_set_err (parser, UCL_ESYNTAX, "invalid utf escape", - &parser->err); + ucl_chunk_skipc(chunk, p); + for (i = 0; i < 4 && p < chunk->end; i++) { + if (!isxdigit(*p)) { + ucl_set_err(parser, UCL_ESYNTAX, "invalid utf escape", + &parser->err); return false; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } if (p >= chunk->end) { - ucl_set_err (parser, UCL_ESYNTAX, - "unfinished escape character", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, + "unfinished escape character", + &parser->err); return false; } } else { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } } *need_unescape = true; *ucl_escape = true; continue; } else if (c == '"') { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); return true; } - else if (ucl_test_character (c, UCL_CHARACTER_UCL_UNSAFE)) { + else if (ucl_test_character(c, UCL_CHARACTER_UCL_UNSAFE)) { *ucl_escape = true; } else if (c == '$') { *var_expand = true; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } - ucl_set_err (parser, UCL_ESYNTAX, - "no quote at the end of json string", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, + "no quote at the end of json string", + &parser->err); return false; } /** * Process single quoted string * @param parser * @param chunk * @param need_unescape * @return */ static bool -ucl_lex_squoted_string (struct ucl_parser *parser, - struct ucl_chunk *chunk, bool *need_unescape) +ucl_lex_squoted_string(struct ucl_parser *parser, + struct ucl_chunk *chunk, bool *need_unescape) { const unsigned char *p = chunk->pos; unsigned char c; while (p < chunk->end) { c = *p; if (c == '\\') { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); if (p >= chunk->end) { - ucl_set_err (parser, UCL_ESYNTAX, - "unfinished escape character", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, + "unfinished escape character", + &parser->err); return false; } else { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } *need_unescape = true; continue; } else if (c == '\'') { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); return true; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } - ucl_set_err (parser, UCL_ESYNTAX, - "no quote at the end of single quoted string", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, + "no quote at the end of single quoted string", + &parser->err); return false; } static void -ucl_parser_append_elt (struct ucl_parser *parser, ucl_hash_t *cont, - ucl_object_t *top, - ucl_object_t *elt) +ucl_parser_append_elt(struct ucl_parser *parser, ucl_hash_t *cont, + ucl_object_t *top, + ucl_object_t *elt) { ucl_object_t *nobj; if ((parser->flags & UCL_PARSER_NO_IMPLICIT_ARRAYS) == 0) { /* Implicit array */ top->flags |= UCL_OBJECT_MULTIVALUE; - DL_APPEND (top, elt); - parser->stack->obj->len ++; + DL_APPEND(top, elt); + parser->stack->obj->len++; } else { if ((top->flags & UCL_OBJECT_MULTIVALUE) != 0) { /* Just add to the explicit array */ - ucl_array_append (top, elt); + ucl_array_append(top, elt); } else { /* Convert to an array */ - nobj = ucl_object_typed_new (UCL_ARRAY); + nobj = ucl_object_typed_new(UCL_ARRAY); nobj->key = top->key; nobj->keylen = top->keylen; nobj->flags |= UCL_OBJECT_MULTIVALUE; - ucl_array_append (nobj, top); - ucl_array_append (nobj, elt); - ucl_hash_replace (cont, top, nobj); + ucl_array_append(nobj, top); + ucl_array_append(nobj, elt); + ucl_hash_replace(cont, top, nobj); } } } -bool -ucl_parser_process_object_element (struct ucl_parser *parser, ucl_object_t *nobj) +bool ucl_parser_process_object_element(struct ucl_parser *parser, ucl_object_t *nobj) { ucl_hash_t *container; ucl_object_t *tobj = NULL, *cur; char errmsg[256]; container = parser->stack->obj->value.ov; - DL_FOREACH (parser->stack->obj, cur) { - tobj = __DECONST (ucl_object_t *, ucl_hash_search_obj (cur->value.ov, nobj)); + DL_FOREACH(parser->stack->obj, cur) + { + if (cur->type == UCL_OBJECT) { + tobj = __DECONST(ucl_object_t *, ucl_hash_search_obj(cur->value.ov, nobj)); - if (tobj != NULL) { - break; + if (tobj != NULL) { + /* + * Check if we have found an object in the same container. + * If not, we should probably ignore it as we cannot replace it + * effectively and we definitely should not unref it. + */ + if (cur->value.ov != container) { + tobj = NULL; + continue; + } + break; + } } } if (tobj == NULL) { - container = ucl_hash_insert_object (container, nobj, - parser->flags & UCL_PARSER_KEY_LOWERCASE); + container = ucl_hash_insert_object(container, nobj, + parser->flags & UCL_PARSER_KEY_LOWERCASE); if (container == NULL) { return false; } nobj->prev = nobj; nobj->next = NULL; - parser->stack->obj->len ++; + parser->stack->obj->len++; } else { - unsigned priold = ucl_object_get_priority (tobj), - prinew = ucl_object_get_priority (nobj); + unsigned priold = ucl_object_get_priority(tobj), + prinew = ucl_object_get_priority(nobj); switch (parser->chunks->strategy) { case UCL_DUPLICATE_APPEND: /* * The logic here is the following: * * - if we have two objects with the same priority, then we form an * implicit or explicit array * - if a new object has bigger priority, then we overwrite an old one * - if a new object has lower priority, then we ignore it */ /* Special case for inherited objects */ if (tobj->flags & UCL_OBJECT_INHERITED) { prinew = priold + 1; } if (priold == prinew) { - ucl_parser_append_elt (parser, container, tobj, nobj); + ucl_parser_append_elt(parser, container, tobj, nobj); } else if (priold > prinew) { /* * We add this new object to a list of trash objects just to ensure * that it won't come to any real object * XXX: rather inefficient approach */ - DL_APPEND (parser->trash_objs, nobj); + DL_APPEND(parser->trash_objs, nobj); } else { - ucl_hash_replace (container, tobj, nobj); - ucl_object_unref (tobj); + ucl_hash_replace(container, tobj, nobj); + ucl_object_unref(tobj); } break; case UCL_DUPLICATE_REWRITE: /* We just rewrite old values regardless of priority */ - ucl_hash_replace (container, tobj, nobj); - ucl_object_unref (tobj); + ucl_hash_replace(container, tobj, nobj); + ucl_object_unref(tobj); break; case UCL_DUPLICATE_ERROR: snprintf(errmsg, sizeof(errmsg), - "duplicate element for key '%s' found", - nobj->key); - ucl_set_err (parser, UCL_EMERGE, errmsg, &parser->err); + "duplicate element for key '%s' found", + nobj->key); + ucl_set_err(parser, UCL_EMERGE, errmsg, &parser->err); return false; case UCL_DUPLICATE_MERGE: /* * Here we do have some old object so we just push it on top of objects stack * Check priority and then perform the merge on the remaining objects */ if (tobj->type == UCL_OBJECT || tobj->type == UCL_ARRAY) { - ucl_object_unref (nobj); + ucl_object_unref(nobj); nobj = tobj; } else if (priold == prinew) { - ucl_parser_append_elt (parser, container, tobj, nobj); + ucl_parser_append_elt(parser, container, tobj, nobj); } else if (priold > prinew) { /* * We add this new object to a list of trash objects just to ensure * that it won't come to any real object * XXX: rather inefficient approach */ - DL_APPEND (parser->trash_objs, nobj); + DL_APPEND(parser->trash_objs, nobj); } else { - ucl_hash_replace (container, tobj, nobj); - ucl_object_unref (tobj); + ucl_hash_replace(container, tobj, nobj); + ucl_object_unref(tobj); } break; } } parser->stack->obj->value.ov = container; parser->cur_obj = nobj; - ucl_attach_comment (parser, nobj, false); + ucl_attach_comment(parser, nobj, false); return true; } /** * Parse a key in an object * @param parser * @param chunk * @param next_key * @param end_of_object * @return true if a key has been parsed */ static bool -ucl_parse_key (struct ucl_parser *parser, struct ucl_chunk *chunk, - bool *next_key, bool *end_of_object, bool *got_content) +ucl_parse_key(struct ucl_parser *parser, struct ucl_chunk *chunk, + bool *next_key, bool *end_of_object, bool *got_content) { const unsigned char *p, *c = NULL, *end, *t; const char *key = NULL; bool got_quote = false, got_eq = false, got_semicolon = false, - need_unescape = false, ucl_escape = false, var_expand = false, - got_sep = false; + need_unescape = false, ucl_escape = false, var_expand = false, + got_sep = false; ucl_object_t *nobj; ssize_t keylen; p = chunk->pos; if (*p == '.' && !(parser->flags & UCL_PARSER_DISABLE_MACRO)) { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); parser->prev_state = parser->state; parser->state = UCL_STATE_MACRO_NAME; *end_of_object = false; return true; } while (p < chunk->end) { /* * A key must start with alpha, number, '/' or '_' and end with space character */ if (c == NULL) { - if (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1])) { - if (!ucl_skip_comments (parser)) { + if (chunk->remain >= 2 && ucl_lex_is_comment(p[0], p[1])) { + if (!ucl_skip_comments(parser)) { return false; } p = chunk->pos; } - else if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { - ucl_chunk_skipc (chunk, p); + else if (ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { + ucl_chunk_skipc(chunk, p); } - else if (ucl_test_character (*p, UCL_CHARACTER_KEY_START)) { + else if (ucl_test_character(*p, UCL_CHARACTER_KEY_START)) { /* The first symbol */ c = p; - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); *got_content = true; } else if (*p == '"') { /* JSON style key */ c = p + 1; got_quote = true; *got_content = true; - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } else if (*p == '}') { /* We have actually end of an object */ *end_of_object = true; return true; } else if (*p == '.' && !(parser->flags & UCL_PARSER_DISABLE_MACRO)) { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); parser->prev_state = parser->state; parser->state = UCL_STATE_MACRO_NAME; return true; } else { /* Invalid identifier */ - ucl_set_err (parser, UCL_ESYNTAX, "key must begin with a letter", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "key must begin with a letter", + &parser->err); return false; } } else { /* Parse the body of a key */ if (!got_quote) { - if (ucl_test_character (*p, UCL_CHARACTER_KEY)) { + if (ucl_test_character(*p, UCL_CHARACTER_KEY)) { *got_content = true; - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } - else if (ucl_test_character (*p, UCL_CHARACTER_KEY_SEP)) { + else if (ucl_test_character(*p, UCL_CHARACTER_KEY_SEP)) { end = p; break; } else { - ucl_set_err (parser, UCL_ESYNTAX, "invalid character in a key", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "invalid character in a key", + &parser->err); return false; } } else { /* We need to parse json like quoted string */ - if (!ucl_lex_json_string (parser, chunk, &need_unescape, &ucl_escape, &var_expand)) { + if (!ucl_lex_json_string(parser, chunk, &need_unescape, &ucl_escape, &var_expand)) { return false; } /* Always escape keys obtained via json */ end = chunk->pos - 1; p = chunk->pos; break; } } } if (p >= chunk->end && *got_content) { - ucl_set_err (parser, UCL_ESYNTAX, "unfinished key", &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "unfinished key", &parser->err); return false; } else if (!*got_content) { return true; } *end_of_object = false; /* We are now at the end of the key, need to parse the rest */ while (p < chunk->end) { - if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE)) { - ucl_chunk_skipc (chunk, p); + if (ucl_test_character(*p, UCL_CHARACTER_WHITESPACE)) { + ucl_chunk_skipc(chunk, p); } else if (*p == '=') { if (!got_eq && !got_semicolon) { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); got_eq = true; } else { - ucl_set_err (parser, UCL_ESYNTAX, "unexpected '=' character", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "unexpected '=' character", + &parser->err); return false; } } else if (*p == ':') { if (!got_eq && !got_semicolon) { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); got_semicolon = true; } else { - ucl_set_err (parser, UCL_ESYNTAX, "unexpected ':' character", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "unexpected ':' character", + &parser->err); return false; } } - else if (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1])) { + else if (chunk->remain >= 2 && ucl_lex_is_comment(p[0], p[1])) { /* Check for comment */ - if (!ucl_skip_comments (parser)) { + if (!ucl_skip_comments(parser)) { return false; } p = chunk->pos; } else { /* Start value */ break; } } if (p >= chunk->end && got_content) { - ucl_set_err (parser, UCL_ESYNTAX, "unfinished key", &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "unfinished key", &parser->err); return false; } got_sep = got_semicolon || got_eq; if (!got_sep) { /* * Maybe we have more keys nested, so search for termination character. * Possible choices: * 1) key1 key2 ... keyN [:=] value <- we treat that as error * 2) key1 ... keyN {} or [] <- we treat that as nested objects * 3) key1 value[;,\n] <- we treat that as linear object */ t = p; *next_key = false; - while (ucl_test_character (*t, UCL_CHARACTER_WHITESPACE)) { - t ++; + while (ucl_test_character(*t, UCL_CHARACTER_WHITESPACE)) { + t++; } /* Check first non-space character after a key */ if (*t != '{' && *t != '[') { while (t < chunk->end) { if (*t == ',' || *t == ';' || *t == '\n' || *t == '\r') { break; } else if (*t == '{' || *t == '[') { *next_key = true; break; } - t ++; + t++; } } } /* Create a new object */ - nobj = ucl_object_new_full (UCL_NULL, parser->chunks->priority); + nobj = ucl_object_new_full(UCL_NULL, parser->chunks->priority); if (nobj == NULL) { return false; } - keylen = ucl_copy_or_store_ptr (parser, c, &nobj->trash_stack[UCL_TRASH_KEY], - &key, end - c, need_unescape, parser->flags & UCL_PARSER_KEY_LOWERCASE, - false, false); + keylen = ucl_copy_or_store_ptr(parser, c, &nobj->trash_stack[UCL_TRASH_KEY], + &key, end - c, need_unescape, parser->flags & UCL_PARSER_KEY_LOWERCASE, + false, false); if (keylen == -1) { - ucl_object_unref (nobj); + ucl_object_unref(nobj); return false; } else if (keylen == 0) { - ucl_set_err (parser, UCL_ESYNTAX, "empty keys are not allowed", &parser->err); - ucl_object_unref (nobj); + ucl_set_err(parser, UCL_ESYNTAX, "empty keys are not allowed", &parser->err); + ucl_object_unref(nobj); return false; } nobj->key = key; nobj->keylen = keylen; - if (!ucl_parser_process_object_element (parser, nobj)) { + if (!ucl_parser_process_object_element(parser, nobj)) { return false; } if (ucl_escape) { nobj->flags |= UCL_OBJECT_NEED_KEY_ESCAPE; } return true; } /** * Parse a cl string * @param parser * @param chunk * @param var_expand * @param need_unescape * @return true if a key has been parsed */ static bool -ucl_parse_string_value (struct ucl_parser *parser, - struct ucl_chunk *chunk, bool *var_expand, bool *need_unescape) +ucl_parse_string_value(struct ucl_parser *parser, + struct ucl_chunk *chunk, bool *var_expand, bool *need_unescape) { const unsigned char *p; enum { UCL_BRACE_ROUND = 0, UCL_BRACE_SQUARE, UCL_BRACE_FIGURE }; int braces[3][2] = {{0, 0}, {0, 0}, {0, 0}}; p = chunk->pos; while (p < chunk->end) { /* Skip pairs of figure braces */ if (*p == '{') { - braces[UCL_BRACE_FIGURE][0] ++; + braces[UCL_BRACE_FIGURE][0]++; } else if (*p == '}') { - braces[UCL_BRACE_FIGURE][1] ++; + braces[UCL_BRACE_FIGURE][1]++; if (braces[UCL_BRACE_FIGURE][1] <= braces[UCL_BRACE_FIGURE][0]) { /* This is not a termination symbol, continue */ - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); continue; } } /* Skip pairs of square braces */ else if (*p == '[') { - braces[UCL_BRACE_SQUARE][0] ++; + braces[UCL_BRACE_SQUARE][0]++; } else if (*p == ']') { - braces[UCL_BRACE_SQUARE][1] ++; + braces[UCL_BRACE_SQUARE][1]++; if (braces[UCL_BRACE_SQUARE][1] <= braces[UCL_BRACE_SQUARE][0]) { /* This is not a termination symbol, continue */ - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); continue; } } else if (*p == '$') { *var_expand = true; } else if (*p == '\\') { *need_unescape = true; - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); if (p < chunk->end) { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } continue; } - if (ucl_lex_is_atom_end (*p) || (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1]))) { + if (ucl_lex_is_atom_end(*p) || (chunk->remain >= 2 && ucl_lex_is_comment(p[0], p[1]))) { break; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } return true; } /** * Parse multiline string ending with \n{term}\n * @param parser * @param chunk * @param term * @param term_len * @param beg * @param var_expand * @return size of multiline string or 0 in case of error */ static int -ucl_parse_multiline_string (struct ucl_parser *parser, - struct ucl_chunk *chunk, const unsigned char *term, - int term_len, unsigned char const **beg, - bool *var_expand) +ucl_parse_multiline_string(struct ucl_parser *parser, + struct ucl_chunk *chunk, const unsigned char *term, + int term_len, unsigned char const **beg, + bool *var_expand) { const unsigned char *p, *c, *tend; bool newline = false; int len = 0; p = chunk->pos; c = p; while (p < chunk->end) { if (newline) { if (chunk->end - p < term_len) { return 0; } - else if (memcmp (p, term, term_len) == 0) { + else if (memcmp(p, term, term_len) == 0) { tend = p + term_len; - if (*tend != '\n' && *tend != ';' && *tend != ',') { + if (tend < chunk->end && *tend != '\n' && *tend != ';' && *tend != ',') { /* Incomplete terminator */ - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); continue; } len = p - c; chunk->remain -= term_len; chunk->pos = p + term_len; chunk->column = term_len; *beg = c; break; } } if (*p == '\n') { newline = true; } else { if (*p == '$') { *var_expand = true; } newline = false; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } return len; } -static inline ucl_object_t* -ucl_parser_get_container (struct ucl_parser *parser) +static inline ucl_object_t * +ucl_parser_get_container(struct ucl_parser *parser) { ucl_object_t *t, *obj = NULL; if (parser == NULL || parser->stack == NULL || parser->stack->obj == NULL) { return NULL; } if (parser->stack->obj->type == UCL_ARRAY) { /* Object must be allocated */ - obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority); + obj = ucl_object_new_full(UCL_NULL, parser->chunks->priority); t = parser->stack->obj; - if (!ucl_array_append (t, obj)) { - ucl_object_unref (obj); + if (!ucl_array_append(t, obj)) { + ucl_object_unref(obj); return NULL; } parser->cur_obj = obj; - ucl_attach_comment (parser, obj, false); + ucl_attach_comment(parser, obj, false); } else { /* Object has been already allocated */ obj = parser->cur_obj; } return obj; } /** * Handle value data * @param parser * @param chunk * @return */ static bool -ucl_parse_value (struct ucl_parser *parser, struct ucl_chunk *chunk) +ucl_parse_value(struct ucl_parser *parser, struct ucl_chunk *chunk) { const unsigned char *p, *c; ucl_object_t *obj = NULL; unsigned int stripped_spaces; ssize_t str_len; bool need_unescape = false, ucl_escape = false, var_expand = false; p = chunk->pos; /* Skip any spaces and comments */ - if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE) || - (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1]))) { - while (p < chunk->end && ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { - ucl_chunk_skipc (chunk, p); + if (ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE) || + (chunk->remain >= 2 && ucl_lex_is_comment(p[0], p[1]))) { + while (p < chunk->end && ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { + ucl_chunk_skipc(chunk, p); } - if (!ucl_skip_comments (parser)) { + if (!ucl_skip_comments(parser)) { return false; } p = chunk->pos; } while (p < chunk->end) { c = p; switch (*p) { case '"': - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); - if (!ucl_lex_json_string (parser, chunk, &need_unescape, &ucl_escape, - &var_expand)) { + if (!ucl_lex_json_string(parser, chunk, &need_unescape, &ucl_escape, + &var_expand)) { return false; } - obj = ucl_parser_get_container (parser); + obj = ucl_parser_get_container(parser); if (!obj) { return false; } str_len = chunk->pos - c - 2; obj->type = UCL_STRING; - if ((str_len = ucl_copy_or_store_ptr (parser, c + 1, - &obj->trash_stack[UCL_TRASH_VALUE], - &obj->value.sv, str_len, need_unescape, false, - var_expand, false)) == -1) { + if ((str_len = ucl_copy_or_store_ptr(parser, c + 1, + &obj->trash_stack[UCL_TRASH_VALUE], + &obj->value.sv, str_len, need_unescape, false, + var_expand, false)) == -1) { return false; } obj->len = str_len; parser->state = UCL_STATE_AFTER_VALUE; return true; break; case '\'': - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); - if (!ucl_lex_squoted_string (parser, chunk, &need_unescape)) { + if (!ucl_lex_squoted_string(parser, chunk, &need_unescape)) { return false; } - obj = ucl_parser_get_container (parser); + obj = ucl_parser_get_container(parser); if (!obj) { return false; } str_len = chunk->pos - c - 2; obj->type = UCL_STRING; obj->flags |= UCL_OBJECT_SQUOTED; - if ((str_len = ucl_copy_or_store_ptr (parser, c + 1, - &obj->trash_stack[UCL_TRASH_VALUE], - &obj->value.sv, str_len, need_unescape, false, - var_expand, true)) == -1) { + if ((str_len = ucl_copy_or_store_ptr(parser, c + 1, + &obj->trash_stack[UCL_TRASH_VALUE], + &obj->value.sv, str_len, need_unescape, false, + var_expand, true)) == -1) { return false; } obj->len = str_len; parser->state = UCL_STATE_AFTER_VALUE; return true; break; case '{': - obj = ucl_parser_get_container (parser); + obj = ucl_parser_get_container(parser); if (obj == NULL) { parser->state = UCL_STATE_ERROR; ucl_set_err(parser, UCL_ESYNTAX, "object value must be a part of an object", - &parser->err); + &parser->err); return false; } /* We have a new object */ if (parser->stack) { - obj = ucl_parser_add_container (obj, parser, false, - parser->stack->e.params.level, true); + obj = ucl_parser_add_container(obj, parser, false, + parser->stack->e.params.level, true); } else { return false; } if (obj == NULL) { return false; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); return true; break; case '[': - obj = ucl_parser_get_container (parser); + obj = ucl_parser_get_container(parser); if (obj == NULL) { parser->state = UCL_STATE_ERROR; ucl_set_err(parser, UCL_ESYNTAX, "array value must be a part of an object", - &parser->err); + &parser->err); return false; } /* We have a new array */ if (parser->stack) { - obj = ucl_parser_add_container (obj, parser, true, - parser->stack->e.params.level, true); + obj = ucl_parser_add_container(obj, parser, true, + parser->stack->e.params.level, true); } else { return false; } if (obj == NULL) { return false; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); return true; break; case ']': /* We have the array ending */ if (parser->stack && parser->stack->obj->type == UCL_ARRAY) { parser->state = UCL_STATE_AFTER_VALUE; return true; } else { goto parse_string; } break; case '<': - obj = ucl_parser_get_container (parser); + obj = ucl_parser_get_container(parser); if (obj == NULL) { parser->state = UCL_STATE_ERROR; ucl_set_err(parser, UCL_ESYNTAX, "multiline value must be a part of an object", - &parser->err); + &parser->err); return false; } /* We have something like multiline value, which must be <<[A-Z]+\n */ if (chunk->end - p > 3) { - if (memcmp (p, "<<", 2) == 0) { + if (memcmp(p, "<<", 2) == 0) { p += 2; /* We allow only uppercase characters in multiline definitions */ while (p < chunk->end && *p >= 'A' && *p <= 'Z') { - p ++; + p++; } - if(p == chunk->end) { - ucl_set_err (parser, UCL_ESYNTAX, - "unterminated multiline value", &parser->err); + if (p == chunk->end) { + ucl_set_err(parser, UCL_ESYNTAX, + "unterminated multiline value", &parser->err); return false; } - if (*p =='\n') { + if (*p == '\n') { /* Set chunk positions and start multiline parsing */ chunk->remain -= p - c + 1; c += 2; chunk->pos = p + 1; chunk->column = 0; - chunk->line ++; - if ((str_len = ucl_parse_multiline_string (parser, chunk, c, - p - c, &c, &var_expand)) == 0) { - ucl_set_err (parser, UCL_ESYNTAX, - "unterminated multiline value", &parser->err); + chunk->line++; + if ((str_len = ucl_parse_multiline_string(parser, chunk, c, + p - c, &c, &var_expand)) == 0) { + ucl_set_err(parser, UCL_ESYNTAX, + "unterminated multiline value", &parser->err); return false; } obj->type = UCL_STRING; obj->flags |= UCL_OBJECT_MULTILINE; - if ((str_len = ucl_copy_or_store_ptr (parser, c, - &obj->trash_stack[UCL_TRASH_VALUE], - &obj->value.sv, str_len - 1, false, - false, var_expand, false)) == -1) { + if ((str_len = ucl_copy_or_store_ptr(parser, c, + &obj->trash_stack[UCL_TRASH_VALUE], + &obj->value.sv, str_len - 1, false, + false, var_expand, false)) == -1) { return false; } obj->len = str_len; parser->state = UCL_STATE_AFTER_VALUE; return true; } } } /* Fallback to ordinary strings */ /* FALLTHRU */ default: -parse_string: + parse_string: if (obj == NULL) { - obj = ucl_parser_get_container (parser); + obj = ucl_parser_get_container(parser); } if (obj == NULL) { parser->state = UCL_STATE_ERROR; ucl_set_err(parser, UCL_ESYNTAX, "value must be a part of an object", - &parser->err); + &parser->err); return false; } /* Parse atom */ - if (ucl_test_character (*p, UCL_CHARACTER_VALUE_DIGIT_START)) { - if (!ucl_lex_number (parser, chunk, obj)) { + if (ucl_test_character(*p, UCL_CHARACTER_VALUE_DIGIT_START)) { + if (!ucl_lex_number(parser, chunk, obj)) { if (parser->state == UCL_STATE_ERROR) { return false; } } else { parser->state = UCL_STATE_AFTER_VALUE; return true; } /* Fallback to normal string */ } - if (!ucl_parse_string_value (parser, chunk, &var_expand, - &need_unescape)) { + if (!ucl_parse_string_value(parser, chunk, &var_expand, + &need_unescape)) { return false; } /* Cut trailing spaces */ stripped_spaces = 0; - while (ucl_test_character (*(chunk->pos - 1 - stripped_spaces), - UCL_CHARACTER_WHITESPACE)) { - stripped_spaces ++; + while (ucl_test_character(*(chunk->pos - 1 - stripped_spaces), + UCL_CHARACTER_WHITESPACE)) { + stripped_spaces++; } str_len = chunk->pos - c - stripped_spaces; if (str_len <= 0) { - ucl_set_err (parser, UCL_ESYNTAX, "string value must not be empty", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "string value must not be empty", + &parser->err); return false; } - else if (str_len == 4 && memcmp (c, "null", 4) == 0) { + else if (str_len == 4 && memcmp(c, "null", 4) == 0) { obj->len = 0; obj->type = UCL_NULL; } - else if (str_len == 3 && memcmp (c, "nan", 3) == 0) { + else if (str_len == 3 && memcmp(c, "nan", 3) == 0) { obj->len = 0; obj->type = UCL_FLOAT; obj->value.dv = NAN; } - else if (str_len == 3 && memcmp (c, "inf", 3) == 0) { + else if (str_len == 3 && memcmp(c, "inf", 3) == 0) { obj->len = 0; obj->type = UCL_FLOAT; obj->value.dv = INFINITY; } - else if (!ucl_maybe_parse_boolean (obj, c, str_len)) { + else if (!ucl_maybe_parse_boolean(obj, c, str_len)) { obj->type = UCL_STRING; - if ((str_len = ucl_copy_or_store_ptr (parser, c, - &obj->trash_stack[UCL_TRASH_VALUE], - &obj->value.sv, str_len, need_unescape, - false, var_expand, false)) == -1) { + if ((str_len = ucl_copy_or_store_ptr(parser, c, + &obj->trash_stack[UCL_TRASH_VALUE], + &obj->value.sv, str_len, need_unescape, + false, var_expand, false)) == -1) { return false; } obj->len = str_len; } parser->state = UCL_STATE_AFTER_VALUE; return true; break; } } return true; } /** * Handle after value data * @param parser * @param chunk * @return */ static bool -ucl_parse_after_value (struct ucl_parser *parser, struct ucl_chunk *chunk) +ucl_parse_after_value(struct ucl_parser *parser, struct ucl_chunk *chunk) { const unsigned char *p; bool got_sep = false; struct ucl_stack *st; p = chunk->pos; while (p < chunk->end) { - if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE)) { + if (ucl_test_character(*p, UCL_CHARACTER_WHITESPACE)) { /* Skip whitespaces */ - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } - else if (chunk->remain >= 2 && ucl_lex_is_comment (p[0], p[1])) { + else if (chunk->remain >= 2 && ucl_lex_is_comment(p[0], p[1])) { /* Skip comment */ - if (!ucl_skip_comments (parser)) { + if (!ucl_skip_comments(parser)) { return false; } /* Treat comment as a separator */ got_sep = true; p = chunk->pos; } - else if (ucl_test_character (*p, UCL_CHARACTER_VALUE_END)) { + else if (ucl_test_character(*p, UCL_CHARACTER_VALUE_END)) { if (*p == '}' || *p == ']') { if (parser->stack == NULL) { - ucl_set_err (parser, UCL_ESYNTAX, - "end of array or object detected without corresponding start", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, + "end of array or object detected without corresponding start", + &parser->err); return false; } if ((*p == '}' && parser->stack->obj->type == UCL_OBJECT) || - (*p == ']' && parser->stack->obj->type == UCL_ARRAY)) { + (*p == ']' && parser->stack->obj->type == UCL_ARRAY)) { /* Pop all nested objects from a stack */ st = parser->stack; if (!(st->e.params.flags & UCL_STACK_HAS_OBRACE)) { parser->err_code = UCL_EUNPAIRED; - ucl_create_err (&parser->err, - "%s:%d object closed with } is not opened with { at line %d", - chunk->fname ? chunk->fname : "memory", - parser->chunks->line, st->e.params.line); + ucl_create_err(&parser->err, + "%s:%d object closed with } is not opened with { at line %d", + chunk->fname ? chunk->fname : "memory", + parser->chunks->line, st->e.params.line); return false; } - parser->stack = st->next; - UCL_FREE (sizeof (struct ucl_stack), st); + if ((st->e.params.flags & UCL_STACK_AUTOMATIC)) { + st->e.params.flags = 0; + } + else { + parser->stack = st->next; + UCL_FREE(sizeof(struct ucl_stack), st); + } if (parser->cur_obj) { - ucl_attach_comment (parser, parser->cur_obj, true); + ucl_attach_comment(parser, parser->cur_obj, true); } while (parser->stack != NULL) { st = parser->stack; if (st->next == NULL) { break; } else if (st->next->e.params.level == st->e.params.level) { break; } parser->stack = st->next; parser->cur_obj = st->obj; - UCL_FREE (sizeof (struct ucl_stack), st); + UCL_FREE(sizeof(struct ucl_stack), st); } } else { - ucl_set_err (parser, UCL_ESYNTAX, - "unexpected terminating symbol detected", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, + "unexpected terminating symbol detected", + &parser->err); return false; } if (parser->stack == NULL) { /* Ignore everything after a top object */ return true; } else { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } got_sep = true; } else { /* Got a separator */ got_sep = true; - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } } else { /* Anything else */ if (!got_sep) { - ucl_set_err (parser, UCL_ESYNTAX, "delimiter is missing", - &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "delimiter is missing", + &parser->err); return false; } return true; } } return true; } static bool -ucl_skip_macro_as_comment (struct ucl_parser *parser, - struct ucl_chunk *chunk) +ucl_skip_macro_as_comment(struct ucl_parser *parser, + struct ucl_chunk *chunk) { const unsigned char *p, *c; enum { macro_skip_start = 0, macro_has_symbols, macro_has_obrace, macro_has_quote, macro_has_backslash, macro_has_sqbrace, macro_save - } state = macro_skip_start, prev_state = macro_skip_start; + } state = macro_skip_start, + prev_state = macro_skip_start; p = chunk->pos; c = chunk->pos; while (p < chunk->end) { switch (state) { case macro_skip_start: - if (!ucl_test_character (*p, UCL_CHARACTER_WHITESPACE)) { + if (!ucl_test_character(*p, UCL_CHARACTER_WHITESPACE)) { state = macro_has_symbols; } - else if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { + else if (ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { state = macro_save; continue; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); break; case macro_has_symbols: if (*p == '{') { state = macro_has_sqbrace; } else if (*p == '(') { state = macro_has_obrace; } else if (*p == '"') { state = macro_has_quote; } else if (*p == '\n') { state = macro_save; continue; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); break; case macro_has_obrace: if (*p == '\\') { prev_state = state; state = macro_has_backslash; } else if (*p == ')') { state = macro_has_symbols; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); break; case macro_has_sqbrace: if (*p == '\\') { prev_state = state; state = macro_has_backslash; } else if (*p == '}') { state = macro_save; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); break; case macro_has_quote: if (*p == '\\') { prev_state = state; state = macro_has_backslash; } else if (*p == '"') { state = macro_save; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); break; case macro_has_backslash: state = prev_state; - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); break; case macro_save: if (parser->flags & UCL_PARSER_SAVE_COMMENTS) { - ucl_save_comment (parser, c, p - c); + ucl_save_comment(parser, c, p - c); } return true; } } return false; } /** * Handle macro data * @param parser * @param chunk * @param marco * @param macro_start * @param macro_len * @return */ static bool -ucl_parse_macro_value (struct ucl_parser *parser, - struct ucl_chunk *chunk, struct ucl_macro *macro, - unsigned char const **macro_start, size_t *macro_len) +ucl_parse_macro_value(struct ucl_parser *parser, + struct ucl_chunk *chunk, struct ucl_macro *macro, + unsigned char const **macro_start, size_t *macro_len) { const unsigned char *p, *c; bool need_unescape = false, ucl_escape = false, var_expand = false; p = chunk->pos; switch (*p) { case '"': /* We have macro value encoded in quotes */ c = p; - ucl_chunk_skipc (chunk, p); - if (!ucl_lex_json_string (parser, chunk, &need_unescape, &ucl_escape, &var_expand)) { + ucl_chunk_skipc(chunk, p); + if (!ucl_lex_json_string(parser, chunk, &need_unescape, &ucl_escape, &var_expand)) { return false; } *macro_start = c + 1; *macro_len = chunk->pos - c - 2; p = chunk->pos; break; case '{': /* We got a multiline macro body */ - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); /* Skip spaces at the beginning */ while (p < chunk->end) { - if (ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { - ucl_chunk_skipc (chunk, p); + if (ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { + ucl_chunk_skipc(chunk, p); } else { break; } } c = p; while (p < chunk->end) { if (*p == '}') { break; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } *macro_start = c; *macro_len = p - c; - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); break; default: /* Macro is not enclosed in quotes or braces */ c = p; while (p < chunk->end) { - if (ucl_lex_is_atom_end (*p)) { + if (ucl_lex_is_atom_end(*p)) { break; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } *macro_start = c; *macro_len = p - c; break; } /* We are at the end of a macro */ /* Skip ';' and space characters and return to previous state */ while (p < chunk->end) { - if (!ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE) && *p != ';') { + if (!ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE) && *p != ';') { break; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); } return true; } /** * Parse macro arguments as UCL object * @param parser parser structure * @param chunk the current data chunk * @return */ static ucl_object_t * -ucl_parse_macro_arguments (struct ucl_parser *parser, - struct ucl_chunk *chunk) +ucl_parse_macro_arguments(struct ucl_parser *parser, + struct ucl_chunk *chunk) { ucl_object_t *res = NULL; struct ucl_parser *params_parser; int obraces = 1, ebraces = 0, state = 0; const unsigned char *p, *c; size_t args_len = 0; struct ucl_parser_saved_state saved; saved.column = chunk->column; saved.line = chunk->line; saved.pos = chunk->pos; saved.remain = chunk->remain; p = chunk->pos; if (*p != '(' || chunk->remain < 2) { return NULL; } /* Set begin and start */ - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); c = p; while ((p) < (chunk)->end) { switch (state) { case 0: /* Parse symbols and check for '(', ')' and '"' */ if (*p == '(') { - obraces ++; + obraces++; } else if (*p == ')') { - ebraces ++; + ebraces++; } else if (*p == '"') { state = 1; } /* Check pairing */ if (obraces == ebraces) { state = 99; } else { - args_len ++; + args_len++; } /* Check overflow */ if (chunk->remain == 0) { goto restore_chunk; } - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); break; case 1: /* We have quote character, so skip all but quotes */ if (*p == '"' && *(p - 1) != '\\') { state = 0; } if (chunk->remain == 0) { goto restore_chunk; } - args_len ++; - ucl_chunk_skipc (chunk, p); + args_len++; + ucl_chunk_skipc(chunk, p); break; case 99: /* * We have read the full body of arguments, so we need to parse and set * object from that */ - params_parser = ucl_parser_new (parser->flags); - if (!ucl_parser_add_chunk (params_parser, c, args_len)) { - ucl_set_err (parser, UCL_ESYNTAX, "macro arguments parsing error", - &parser->err); + params_parser = ucl_parser_new(parser->flags); + if (!ucl_parser_add_chunk(params_parser, c, args_len)) { + ucl_set_err(parser, UCL_ESYNTAX, "macro arguments parsing error", + &parser->err); } else { - res = ucl_parser_get_object (params_parser); + res = ucl_parser_get_object(params_parser); } - ucl_parser_free (params_parser); + ucl_parser_free(params_parser); return res; break; } } return res; restore_chunk: chunk->column = saved.column; chunk->line = saved.line; chunk->pos = saved.pos; chunk->remain = saved.remain; return NULL; } -#define SKIP_SPACES_COMMENTS(parser, chunk, p) do { \ - while ((p) < (chunk)->end) { \ - if (!ucl_test_character (*(p), UCL_CHARACTER_WHITESPACE_UNSAFE)) { \ - if ((chunk)->remain >= 2 && ucl_lex_is_comment ((p)[0], (p)[1])) { \ - if (!ucl_skip_comments (parser)) { \ - return false; \ - } \ - p = (chunk)->pos; \ - } \ - break; \ - } \ - ucl_chunk_skipc (chunk, p); \ - } \ -} while(0) +#define SKIP_SPACES_COMMENTS(parser, chunk, p) \ + do { \ + while ((p) < (chunk)->end) { \ + if (!ucl_test_character(*(p), UCL_CHARACTER_WHITESPACE_UNSAFE)) { \ + if ((chunk)->remain >= 2 && ucl_lex_is_comment((p)[0], (p)[1])) { \ + if (!ucl_skip_comments(parser)) { \ + return false; \ + } \ + p = (chunk)->pos; \ + } \ + break; \ + } \ + ucl_chunk_skipc(chunk, p); \ + } \ + } while (0) /** * Handle the main states of rcl parser * @param parser parser structure * @return true if chunk has been parsed and false in case of error */ static bool -ucl_state_machine (struct ucl_parser *parser) +ucl_state_machine(struct ucl_parser *parser) { ucl_object_t *obj, *macro_args; struct ucl_chunk *chunk = parser->chunks; const unsigned char *p, *c = NULL, *macro_start = NULL; unsigned char *macro_escaped; size_t macro_len = 0; struct ucl_macro *macro = NULL; bool next_key = false, end_of_object = false, got_content = false, ret; if (parser->top_obj == NULL) { parser->state = UCL_STATE_INIT; } p = chunk->pos; while (chunk->pos < chunk->end) { switch (parser->state) { case UCL_STATE_INIT: /* * At the init state we can either go to the parse array or object * if we got [ or { correspondingly or can just treat new data as * a key of newly created object */ - if (!ucl_skip_comments (parser)) { + if (!ucl_skip_comments(parser)) { parser->prev_state = parser->state; parser->state = UCL_STATE_ERROR; return false; } else { bool seen_obrace = false; /* Skip any spaces */ - while (p < chunk->end && ucl_test_character (*p, - UCL_CHARACTER_WHITESPACE_UNSAFE)) { - ucl_chunk_skipc (chunk, p); + while (p < chunk->end && ucl_test_character(*p, + UCL_CHARACTER_WHITESPACE_UNSAFE)) { + ucl_chunk_skipc(chunk, p); } p = chunk->pos; if (p < chunk->end) { if (*p == '[') { parser->state = UCL_STATE_VALUE; - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); seen_obrace = true; } else { if (*p == '{') { - ucl_chunk_skipc (chunk, p); + ucl_chunk_skipc(chunk, p); parser->state = UCL_STATE_KEY_OBRACE; seen_obrace = true; } else { parser->state = UCL_STATE_KEY; } } } if (parser->top_obj == NULL) { if (parser->state == UCL_STATE_VALUE) { - obj = ucl_parser_add_container (NULL, parser, true, 0, - seen_obrace); + obj = ucl_parser_add_container(NULL, parser, true, 0, + seen_obrace); } else { - obj = ucl_parser_add_container (NULL, parser, false, 0, - seen_obrace); + obj = ucl_parser_add_container(NULL, parser, false, 0, + seen_obrace); } if (obj == NULL) { return false; } parser->top_obj = obj; parser->cur_obj = obj; } - } break; - case UCL_STATE_KEY: case UCL_STATE_KEY_OBRACE: + parser->stack->e.params.flags |= UCL_STACK_HAS_OBRACE | UCL_STACK_AUTOMATIC; + /* FALLTHROUGHT */ + case UCL_STATE_KEY: /* Skip any spaces */ - while (p < chunk->end && ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { - ucl_chunk_skipc (chunk, p); + while (p < chunk->end && ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) { + ucl_chunk_skipc(chunk, p); } if (p == chunk->end || *p == '}') { /* We have the end of an object */ parser->state = UCL_STATE_AFTER_VALUE; continue; } if (parser->stack == NULL) { /* No objects are on stack, but we want to parse a key */ - ucl_set_err (parser, UCL_ESYNTAX, "top object is finished but the parser " - "expects a key", &parser->err); + ucl_set_err(parser, UCL_ESYNTAX, "top object is finished but the parser " + "expects a key", + &parser->err); parser->prev_state = parser->state; parser->state = UCL_STATE_ERROR; return false; } got_content = false; - if (!ucl_parse_key (parser, chunk, &next_key, &end_of_object, &got_content)) { + if (!ucl_parse_key(parser, chunk, &next_key, &end_of_object, &got_content)) { parser->prev_state = parser->state; parser->state = UCL_STATE_ERROR; return false; } if (end_of_object) { p = chunk->pos; parser->state = UCL_STATE_AFTER_VALUE; continue; } else if (parser->state != UCL_STATE_MACRO_NAME) { if (next_key && parser->stack->obj->type == UCL_OBJECT) { /* Parse more keys and nest objects accordingly */ - obj = ucl_parser_add_container (parser->cur_obj, - parser, - false, - parser->stack->e.params.level + 1, - parser->state == UCL_STATE_KEY_OBRACE); + obj = ucl_parser_add_container(parser->cur_obj, + parser, + false, + parser->stack->e.params.level + 1, + parser->state == UCL_STATE_KEY_OBRACE); if (obj == NULL) { return false; } } else if (got_content) { /* Do not switch state if we have not read any content */ parser->state = UCL_STATE_VALUE; } } else { c = chunk->pos; } p = chunk->pos; break; case UCL_STATE_VALUE: /* We need to check what we do have */ - if (!parser->cur_obj || !ucl_parse_value (parser, chunk)) { + if (!parser->cur_obj || !ucl_parse_value(parser, chunk)) { parser->prev_state = parser->state; parser->state = UCL_STATE_ERROR; return false; } /* State is set in ucl_parse_value call */ p = chunk->pos; break; case UCL_STATE_AFTER_VALUE: - if (!ucl_parse_after_value (parser, chunk)) { + if (!ucl_parse_after_value(parser, chunk)) { parser->prev_state = parser->state; parser->state = UCL_STATE_ERROR; return false; } if (parser->stack != NULL) { if (parser->stack->obj->type == UCL_OBJECT) { parser->state = UCL_STATE_KEY; } else { /* Array */ parser->state = UCL_STATE_VALUE; } } else { /* Skip everything at the end */ return true; } p = chunk->pos; break; case UCL_STATE_MACRO_NAME: if (parser->flags & UCL_PARSER_DISABLE_MACRO) { - if (!ucl_skip_macro_as_comment (parser, chunk)) { + if (!ucl_skip_macro_as_comment(parser, chunk)) { /* We have invalid macro */ - ucl_create_err (&parser->err, - "error at %s:%d at column %d: invalid macro", - chunk->fname ? chunk->fname : "memory", - chunk->line, - chunk->column); + ucl_create_err(&parser->err, + "error at %s:%d at column %d: invalid macro", + chunk->fname ? chunk->fname : "memory", + chunk->line, + chunk->column); parser->state = UCL_STATE_ERROR; return false; } else { p = chunk->pos; parser->state = parser->prev_state; } } else { - if (!ucl_test_character (*p, UCL_CHARACTER_WHITESPACE_UNSAFE) && - *p != '(') { - ucl_chunk_skipc (chunk, p); + if (!ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE) && + *p != '(') { + ucl_chunk_skipc(chunk, p); } else { if (c != NULL && p - c > 0) { /* We got macro name */ macro_len = (size_t) (p - c); - HASH_FIND (hh, parser->macroes, c, macro_len, macro); + HASH_FIND(hh, parser->macroes, c, macro_len, macro); if (macro == NULL) { - ucl_create_err (&parser->err, - "error at %s:%d at column %d: " - "unknown macro: '%.*s', character: '%c'", - chunk->fname ? chunk->fname : "memory", - chunk->line, - chunk->column, - (int) (p - c), - c, - *chunk->pos); + ucl_create_err(&parser->err, + "error at %s:%d at column %d: " + "unknown macro: '%.*s', character: '%c'", + chunk->fname ? chunk->fname : "memory", + chunk->line, + chunk->column, + (int) (p - c), + c, + *chunk->pos); parser->state = UCL_STATE_ERROR; return false; } /* Now we need to skip all spaces */ SKIP_SPACES_COMMENTS(parser, chunk, p); parser->state = UCL_STATE_MACRO; } else { /* We have invalid macro name */ - ucl_create_err (&parser->err, - "error at %s:%d at column %d: invalid macro name", - chunk->fname ? chunk->fname : "memory", - chunk->line, - chunk->column); + ucl_create_err(&parser->err, + "error at %s:%d at column %d: invalid macro name", + chunk->fname ? chunk->fname : "memory", + chunk->line, + chunk->column); parser->state = UCL_STATE_ERROR; return false; } } } break; case UCL_STATE_MACRO: if (*chunk->pos == '(') { - macro_args = ucl_parse_macro_arguments (parser, chunk); + macro_args = ucl_parse_macro_arguments(parser, chunk); p = chunk->pos; if (macro_args) { SKIP_SPACES_COMMENTS(parser, chunk, p); } } else { macro_args = NULL; } - if (!ucl_parse_macro_value (parser, chunk, macro, - ¯o_start, ¯o_len)) { + if (!ucl_parse_macro_value(parser, chunk, macro, + ¯o_start, ¯o_len)) { parser->prev_state = parser->state; parser->state = UCL_STATE_ERROR; return false; } - macro_len = ucl_expand_variable (parser, ¯o_escaped, - macro_start, macro_len); + macro_len = ucl_expand_variable(parser, ¯o_escaped, + macro_start, macro_len); parser->state = parser->prev_state; if (macro_escaped == NULL && macro != NULL) { if (macro->is_context) { - ret = macro->h.context_handler (macro_start, macro_len, - macro_args, - parser->top_obj, - macro->ud); + ret = macro->h.context_handler(macro_start, macro_len, + macro_args, + parser->top_obj, + macro->ud); } else { - ret = macro->h.handler (macro_start, macro_len, macro_args, - macro->ud); + ret = macro->h.handler(macro_start, macro_len, macro_args, + macro->ud); } } else if (macro != NULL) { if (macro->is_context) { - ret = macro->h.context_handler (macro_escaped, macro_len, - macro_args, - parser->top_obj, - macro->ud); + ret = macro->h.context_handler(macro_escaped, macro_len, + macro_args, + parser->top_obj, + macro->ud); } else { - ret = macro->h.handler (macro_escaped, macro_len, macro_args, - macro->ud); + ret = macro->h.handler(macro_escaped, macro_len, macro_args, + macro->ud); } - UCL_FREE (macro_len + 1, macro_escaped); + UCL_FREE(macro_len + 1, macro_escaped); } else { ret = false; - ucl_set_err (parser, UCL_EINTERNAL, - "internal error: parser has macro undefined", &parser->err); + ucl_set_err(parser, UCL_EINTERNAL, + "internal error: parser has macro undefined", &parser->err); } /* * Chunk can be modified within macro handler */ chunk = parser->chunks; p = chunk->pos; if (macro_args) { - ucl_object_unref (macro_args); + ucl_object_unref(macro_args); } if (!ret) { return false; } break; case UCL_STATE_ERROR: /* Already in the error state */ return false; default: - ucl_set_err (parser, UCL_EINTERNAL, - "internal error: parser is in an unknown state", &parser->err); + ucl_set_err(parser, UCL_EINTERNAL, + "internal error: parser is in an unknown state", &parser->err); parser->state = UCL_STATE_ERROR; return false; } } if (parser->last_comment) { if (parser->cur_obj) { - ucl_attach_comment (parser, parser->cur_obj, true); + ucl_attach_comment(parser, parser->cur_obj, true); } else if (parser->stack && parser->stack->obj) { - ucl_attach_comment (parser, parser->stack->obj, true); + ucl_attach_comment(parser, parser->stack->obj, true); } else if (parser->top_obj) { - ucl_attach_comment (parser, parser->top_obj, true); + ucl_attach_comment(parser, parser->top_obj, true); } else { - ucl_object_unref (parser->last_comment); + ucl_object_unref(parser->last_comment); } } if (parser->stack != NULL && parser->state != UCL_STATE_ERROR) { struct ucl_stack *st; bool has_error = false; - LL_FOREACH (parser->stack, st) { + LL_FOREACH(parser->stack, st) + { if (st->chunk != parser->chunks) { break; /* Not our chunk, give up */ } if (st->e.params.flags & UCL_STACK_HAS_OBRACE) { if (parser->err == NULL) { - utstring_new (parser->err); + utstring_new(parser->err); } - utstring_printf (parser->err, "%s:%d unmatched open brace at %d; ", - chunk->fname ? chunk->fname : "memory", - parser->chunks->line, - st->e.params.line); + utstring_printf(parser->err, "%s:%d unmatched open brace at %d; ", + chunk->fname ? chunk->fname : "memory", + parser->chunks->line, + st->e.params.line); has_error = true; } } if (has_error) { parser->err_code = UCL_EUNPAIRED; return false; } } return true; } -#define UPRM_SAFE(fn, a, b, c, el) do { \ - if (!fn(a, b, c, a)) \ - goto el; \ +#define UPRM_SAFE(fn, a, b, c, el) \ + do { \ + if (!fn(a, b, c, a)) \ + goto el; \ } while (0) -struct ucl_parser* -ucl_parser_new (int flags) +struct ucl_parser * +ucl_parser_new(int flags) { struct ucl_parser *parser; - parser = UCL_ALLOC (sizeof (struct ucl_parser)); + parser = UCL_ALLOC(sizeof(struct ucl_parser)); if (parser == NULL) { return NULL; } - memset (parser, 0, sizeof (struct ucl_parser)); + memset(parser, 0, sizeof(struct ucl_parser)); UPRM_SAFE(ucl_parser_register_macro, parser, "include", ucl_include_handler, e0); UPRM_SAFE(ucl_parser_register_macro, parser, "try_include", ucl_try_include_handler, e0); UPRM_SAFE(ucl_parser_register_macro, parser, "includes", ucl_includes_handler, e0); UPRM_SAFE(ucl_parser_register_macro, parser, "priority", ucl_priority_handler, e0); UPRM_SAFE(ucl_parser_register_macro, parser, "load", ucl_load_handler, e0); UPRM_SAFE(ucl_parser_register_context_macro, parser, "inherit", ucl_inherit_handler, e0); parser->flags = flags; parser->includepaths = NULL; if (flags & UCL_PARSER_SAVE_COMMENTS) { - parser->comments = ucl_object_typed_new (UCL_OBJECT); + parser->comments = ucl_object_typed_new(UCL_OBJECT); } if (!(flags & UCL_PARSER_NO_FILEVARS)) { /* Initial assumption about filevars */ - ucl_parser_set_filevars (parser, NULL, false); + ucl_parser_set_filevars(parser, NULL, false); } return parser; e0: ucl_parser_free(parser); return NULL; } -bool -ucl_parser_set_default_priority (struct ucl_parser *parser, unsigned prio) +bool ucl_parser_set_default_priority(struct ucl_parser *parser, unsigned prio) { if (parser == NULL) { return false; } parser->default_priority = prio; return true; } -int -ucl_parser_get_default_priority (struct ucl_parser *parser) +int ucl_parser_get_default_priority(struct ucl_parser *parser) { if (parser == NULL) { return -1; } return parser->default_priority; } -bool -ucl_parser_register_macro (struct ucl_parser *parser, const char *macro, - ucl_macro_handler handler, void* ud) +bool ucl_parser_register_macro(struct ucl_parser *parser, const char *macro, + ucl_macro_handler handler, void *ud) { struct ucl_macro *new; if (macro == NULL || handler == NULL) { return false; } - new = UCL_ALLOC (sizeof (struct ucl_macro)); + new = UCL_ALLOC(sizeof(struct ucl_macro)); if (new == NULL) { return false; } - memset (new, 0, sizeof (struct ucl_macro)); + memset(new, 0, sizeof(struct ucl_macro)); new->h.handler = handler; - new->name = strdup (macro); + new->name = UCL_STRDUP(macro); if (new->name == NULL) { - UCL_FREE (sizeof (struct ucl_macro), new); + UCL_FREE(sizeof(struct ucl_macro), new); return false; } new->ud = ud; - HASH_ADD_KEYPTR (hh, parser->macroes, new->name, strlen (new->name), new); + HASH_ADD_KEYPTR(hh, parser->macroes, new->name, strlen(new->name), new); return true; } -bool -ucl_parser_register_context_macro (struct ucl_parser *parser, const char *macro, - ucl_context_macro_handler handler, void* ud) +bool ucl_parser_register_context_macro(struct ucl_parser *parser, const char *macro, + ucl_context_macro_handler handler, void *ud) { struct ucl_macro *new; if (macro == NULL || handler == NULL) { return false; } - new = UCL_ALLOC (sizeof (struct ucl_macro)); + new = UCL_ALLOC(sizeof(struct ucl_macro)); if (new == NULL) { return false; } - memset (new, 0, sizeof (struct ucl_macro)); + memset(new, 0, sizeof(struct ucl_macro)); new->h.context_handler = handler; - new->name = strdup (macro); + new->name = UCL_STRDUP(macro); if (new->name == NULL) { - UCL_FREE (sizeof (struct ucl_macro), new); + UCL_FREE(sizeof(struct ucl_macro), new); return false; } new->ud = ud; new->is_context = true; - HASH_ADD_KEYPTR (hh, parser->macroes, new->name, strlen (new->name), new); + HASH_ADD_KEYPTR(hh, parser->macroes, new->name, strlen(new->name), new); return true; } -void -ucl_parser_register_variable (struct ucl_parser *parser, const char *var, - const char *value) +void ucl_parser_register_variable(struct ucl_parser *parser, const char *var, + const char *value) { struct ucl_variable *new = NULL, *cur; if (var == NULL) { return; } /* Find whether a variable already exists */ - LL_FOREACH (parser->variables, cur) { - if (strcmp (cur->var, var) == 0) { + LL_FOREACH(parser->variables, cur) + { + if (strcmp(cur->var, var) == 0) { new = cur; break; } } if (value == NULL) { if (new != NULL) { /* Remove variable */ - DL_DELETE (parser->variables, new); - free (new->var); - free (new->value); - UCL_FREE (sizeof (struct ucl_variable), new); + DL_DELETE(parser->variables, new); + UCL_FREE(new->var_len + 1, new->var); + UCL_FREE(new->value_len + 1, new->value); + UCL_FREE(sizeof(struct ucl_variable), new); } else { /* Do nothing */ return; } } else { if (new == NULL) { - new = UCL_ALLOC (sizeof (struct ucl_variable)); + new = UCL_ALLOC(sizeof(struct ucl_variable)); if (new == NULL) { return; } - memset (new, 0, sizeof (struct ucl_variable)); - new->var = strdup (var); - new->var_len = strlen (var); - new->value = strdup (value); - new->value_len = strlen (value); + memset(new, 0, sizeof(struct ucl_variable)); + new->var = UCL_STRDUP(var); + new->var_len = strlen(var); + new->value = UCL_STRDUP(value); + new->value_len = strlen(value); - DL_APPEND (parser->variables, new); + DL_APPEND(parser->variables, new); } else { - free (new->value); - new->value = strdup (value); - new->value_len = strlen (value); + UCL_FREE(new->value_len + 1, new->value); + new->value = UCL_STRDUP(value); + new->value_len = strlen(value); } } } -void -ucl_parser_set_variables_handler (struct ucl_parser *parser, - ucl_variable_handler handler, void *ud) +void ucl_parser_set_variables_handler(struct ucl_parser *parser, + ucl_variable_handler handler, void *ud) { parser->var_handler = handler; parser->var_data = ud; } -bool -ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data, - size_t len, unsigned priority, enum ucl_duplicate_strategy strat, - enum ucl_parse_type parse_type) +bool ucl_parser_add_chunk_full(struct ucl_parser *parser, const unsigned char *data, + size_t len, unsigned priority, enum ucl_duplicate_strategy strat, + enum ucl_parse_type parse_type) { struct ucl_chunk *chunk; struct ucl_parser_special_handler *special_handler; if (parser == NULL) { return false; } if (data == NULL && len != 0) { - ucl_create_err (&parser->err, "invalid chunk added"); + ucl_create_err(&parser->err, "invalid chunk added"); return false; } if (parser->state != UCL_STATE_ERROR) { - chunk = UCL_ALLOC (sizeof (struct ucl_chunk)); + chunk = UCL_ALLOC(sizeof(struct ucl_chunk)); if (chunk == NULL) { - ucl_create_err (&parser->err, "cannot allocate chunk structure"); + ucl_create_err(&parser->err, "cannot allocate chunk structure"); return false; } - memset (chunk, 0, sizeof (*chunk)); + memset(chunk, 0, sizeof(*chunk)); /* Apply all matching handlers from the first to the last */ - LL_FOREACH (parser->special_handlers, special_handler) { + LL_FOREACH(parser->special_handlers, special_handler) + { if ((special_handler->flags & UCL_SPECIAL_HANDLER_PREPROCESS_ALL) || - (len >= special_handler->magic_len && - memcmp (data, special_handler->magic, special_handler->magic_len) == 0)) { + (len >= special_handler->magic_len && + memcmp(data, special_handler->magic, special_handler->magic_len) == 0)) { unsigned char *ndata = NULL; size_t nlen = 0; - if (!special_handler->handler (parser, data, len, &ndata, &nlen, - special_handler->user_data)) { - UCL_FREE(sizeof (struct ucl_chunk), chunk); - ucl_create_err (&parser->err, "call for external handler failed"); + if (!special_handler->handler(parser, data, len, &ndata, &nlen, + special_handler->user_data)) { + UCL_FREE(sizeof(struct ucl_chunk), chunk); + ucl_create_err(&parser->err, "call for external handler failed"); return false; } struct ucl_parser_special_handler_chain *nchain; - nchain = UCL_ALLOC (sizeof (*nchain)); + nchain = UCL_ALLOC(sizeof(*nchain)); nchain->begin = ndata; nchain->len = nlen; nchain->special_handler = special_handler; /* Free order is reversed */ - LL_PREPEND (chunk->special_handlers, nchain); + LL_PREPEND(chunk->special_handlers, nchain); data = ndata; len = nlen; } } if (parse_type == UCL_PARSE_AUTO && len > 0) { /* We need to detect parse type by the first symbol */ if ((*data & 0x80) == 0x80) { parse_type = UCL_PARSE_MSGPACK; } else if (*data == '(') { parse_type = UCL_PARSE_CSEXP; } else { parse_type = UCL_PARSE_UCL; } } chunk->begin = data; chunk->remain = len; chunk->pos = chunk->begin; chunk->end = chunk->begin + len; chunk->line = 1; chunk->column = 0; chunk->priority = priority; chunk->strategy = strat; chunk->parse_type = parse_type; if (parser->cur_file) { - chunk->fname = strdup (parser->cur_file); + chunk->fname = strdup(parser->cur_file); } - LL_PREPEND (parser->chunks, chunk); - parser->recursion ++; + LL_PREPEND(parser->chunks, chunk); + parser->recursion++; if (parser->recursion > UCL_MAX_RECURSION) { - ucl_create_err (&parser->err, "maximum include nesting limit is reached: %d", - parser->recursion); + ucl_create_err(&parser->err, "maximum include nesting limit is reached: %d", + parser->recursion); return false; } if (len > 0) { /* Need to parse something */ switch (parse_type) { default: case UCL_PARSE_UCL: - return ucl_state_machine (parser); + return ucl_state_machine(parser); case UCL_PARSE_MSGPACK: - return ucl_parse_msgpack (parser); + return ucl_parse_msgpack(parser); case UCL_PARSE_CSEXP: - return ucl_parse_csexp (parser); + return ucl_parse_csexp(parser); } } else { /* Just add empty chunk and go forward */ if (parser->top_obj == NULL) { /* * In case of empty object, create one to indicate that we've * read something */ - parser->top_obj = ucl_object_new_full (UCL_OBJECT, priority); + parser->top_obj = ucl_object_new_full(UCL_OBJECT, priority); } return true; } } - ucl_create_err (&parser->err, "a parser is in an invalid state"); + ucl_create_err(&parser->err, "a parser is in an invalid state"); return false; } -bool -ucl_parser_add_chunk_priority (struct ucl_parser *parser, - const unsigned char *data, size_t len, unsigned priority) +bool ucl_parser_add_chunk_priority(struct ucl_parser *parser, + const unsigned char *data, size_t len, unsigned priority) { /* We dereference parser, so this check is essential */ if (parser == NULL) { return false; } - return ucl_parser_add_chunk_full (parser, data, len, - priority, UCL_DUPLICATE_APPEND, UCL_PARSE_UCL); + return ucl_parser_add_chunk_full(parser, data, len, + priority, UCL_DUPLICATE_APPEND, UCL_PARSE_UCL); } -bool -ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data, - size_t len) +bool ucl_parser_add_chunk(struct ucl_parser *parser, const unsigned char *data, + size_t len) { if (parser == NULL) { return false; } - return ucl_parser_add_chunk_full (parser, data, len, - parser->default_priority, UCL_DUPLICATE_APPEND, UCL_PARSE_UCL); + return ucl_parser_add_chunk_full(parser, data, len, + parser->default_priority, UCL_DUPLICATE_APPEND, UCL_PARSE_UCL); } -bool -ucl_parser_insert_chunk (struct ucl_parser *parser, const unsigned char *data, - size_t len) +bool ucl_parser_insert_chunk(struct ucl_parser *parser, const unsigned char *data, + size_t len) { if (parser == NULL || parser->top_obj == NULL) { return false; } bool res; struct ucl_chunk *chunk; int state = parser->state; parser->state = UCL_STATE_INIT; /* Prevent inserted chunks from unintentionally closing the current object */ if (parser->stack != NULL && parser->stack->next != NULL) { parser->stack->e.params.level = parser->stack->next->e.params.level; } - res = ucl_parser_add_chunk_full (parser, data, len, parser->chunks->priority, - parser->chunks->strategy, parser->chunks->parse_type); + res = ucl_parser_add_chunk_full(parser, data, len, parser->chunks->priority, + parser->chunks->strategy, parser->chunks->parse_type); /* Remove chunk from the stack */ chunk = parser->chunks; if (chunk != NULL) { parser->chunks = chunk->next; - ucl_chunk_free (chunk); - parser->recursion --; + ucl_chunk_free(chunk); + parser->recursion--; } parser->state = state; return res; } -bool -ucl_parser_add_string_priority (struct ucl_parser *parser, const char *data, - size_t len, unsigned priority) +bool ucl_parser_add_string_priority(struct ucl_parser *parser, const char *data, + size_t len, unsigned priority) { if (data == NULL) { - ucl_create_err (&parser->err, "invalid string added"); + ucl_create_err(&parser->err, "invalid string added"); return false; } if (len == 0) { - len = strlen (data); + len = strlen(data); } - return ucl_parser_add_chunk_priority (parser, - (const unsigned char *)data, len, priority); + return ucl_parser_add_chunk_priority(parser, + (const unsigned char *) data, len, priority); } -bool -ucl_parser_add_string (struct ucl_parser *parser, const char *data, - size_t len) +bool ucl_parser_add_string(struct ucl_parser *parser, const char *data, + size_t len) { if (parser == NULL) { return false; } - return ucl_parser_add_string_priority (parser, - (const unsigned char *)data, len, parser->default_priority); + return ucl_parser_add_string_priority(parser, + (const unsigned char *) data, len, parser->default_priority); } -bool -ucl_set_include_path (struct ucl_parser *parser, ucl_object_t *paths) +bool ucl_set_include_path(struct ucl_parser *parser, ucl_object_t *paths) { - if (parser == NULL || paths == NULL) { + if (parser == NULL || paths == NULL || paths->type != UCL_ARRAY) { return false; } if (parser->includepaths == NULL) { - parser->includepaths = ucl_object_copy (paths); + parser->includepaths = ucl_object_copy(paths); } else { - ucl_object_unref (parser->includepaths); - parser->includepaths = ucl_object_copy (paths); + ucl_object_unref(parser->includepaths); + parser->includepaths = ucl_object_copy(paths); } if (parser->includepaths == NULL) { return false; } return true; } -unsigned char ucl_parser_chunk_peek (struct ucl_parser *parser) +unsigned char ucl_parser_chunk_peek(struct ucl_parser *parser) { if (parser == NULL || parser->chunks == NULL || parser->chunks->pos == NULL || parser->chunks->end == NULL || parser->chunks->pos == parser->chunks->end) { return 0; } - return( *parser->chunks->pos ); + return (*parser->chunks->pos); } -bool ucl_parser_chunk_skip (struct ucl_parser *parser) +bool ucl_parser_chunk_skip(struct ucl_parser *parser) { if (parser == NULL || parser->chunks == NULL || parser->chunks->pos == NULL || parser->chunks->end == NULL || parser->chunks->pos == parser->chunks->end) { return false; } const unsigned char *p = parser->chunks->pos; - ucl_chunk_skipc( parser->chunks, p ); - if( parser->chunks->pos != NULL ) return true; + ucl_chunk_skipc(parser->chunks, p); + if (parser->chunks->pos != NULL) return true; return false; } -ucl_object_t* -ucl_parser_get_current_stack_object (struct ucl_parser *parser, unsigned int depth) +ucl_object_t * +ucl_parser_get_current_stack_object(struct ucl_parser *parser, unsigned int depth) { ucl_object_t *obj; if (parser == NULL || parser->stack == NULL) { return NULL; } struct ucl_stack *stack = parser->stack; - if(stack == NULL || stack->obj == NULL || ucl_object_type (stack->obj) != UCL_OBJECT) - { + if (stack == NULL || stack->obj == NULL || ucl_object_type(stack->obj) != UCL_OBJECT) { return NULL; } - for( unsigned int i = 0; i < depth; ++i ) - { + for (unsigned int i = 0; i < depth; ++i) { stack = stack->next; - if(stack == NULL || stack->obj == NULL || ucl_object_type (stack->obj) != UCL_OBJECT) - { + if (stack == NULL || stack->obj == NULL || ucl_object_type(stack->obj) != UCL_OBJECT) { return NULL; } } - obj = ucl_object_ref (stack->obj); + obj = ucl_object_ref(stack->obj); return obj; } - diff --git a/contrib/libucl/src/ucl_schema.c b/contrib/libucl/src/ucl_schema.c index f4ec0ed3284a..02362d16b838 100644 --- a/contrib/libucl/src/ucl_schema.c +++ b/contrib/libucl/src/ucl_schema.c @@ -1,1105 +1,1102 @@ /* * Copyright (c) 2014, Vsevolod Stakhov * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ucl.h" #include "ucl_internal.h" #include "tree.h" #include "utlist.h" #ifdef HAVE_STDARG_H #include #endif #ifdef HAVE_STDIO_H #include #endif #ifdef HAVE_REGEX_H #include #endif #ifdef HAVE_MATH_H #include #endif #include -static bool ucl_schema_validate (const ucl_object_t *schema, - const ucl_object_t *obj, bool try_array, - struct ucl_schema_error *err, - const ucl_object_t *root, - ucl_object_t *ext_ref); +static bool ucl_schema_validate(const ucl_object_t *schema, + const ucl_object_t *obj, bool try_array, + struct ucl_schema_error *err, + const ucl_object_t *root, + ucl_object_t *ext_ref); /* * Create validation error */ #ifdef __GNUC__ static inline void -ucl_schema_create_error (struct ucl_schema_error *err, - enum ucl_schema_error_code code, const ucl_object_t *obj, - const char *fmt, ...) -__attribute__ (( format( printf, 4, 5) )); +ucl_schema_create_error(struct ucl_schema_error *err, + enum ucl_schema_error_code code, const ucl_object_t *obj, + const char *fmt, ...) + __attribute__((format(printf, 4, 5))); #endif static inline void -ucl_schema_create_error (struct ucl_schema_error *err, - enum ucl_schema_error_code code, const ucl_object_t *obj, - const char *fmt, ...) +ucl_schema_create_error(struct ucl_schema_error *err, + enum ucl_schema_error_code code, const ucl_object_t *obj, + const char *fmt, ...) { va_list va; if (err != NULL) { err->code = code; err->obj = obj; - va_start (va, fmt); - vsnprintf (err->msg, sizeof (err->msg), fmt, va); - va_end (va); + va_start(va, fmt); + vsnprintf(err->msg, sizeof(err->msg), fmt, va); + va_end(va); } } /* * Check whether we have a pattern specified */ static const ucl_object_t * -ucl_schema_test_pattern (const ucl_object_t *obj, const char *pattern, bool recursive) +ucl_schema_test_pattern(const ucl_object_t *obj, const char *pattern, bool recursive) { const ucl_object_t *res = NULL; #ifdef HAVE_REGEX_H regex_t reg; const ucl_object_t *elt; ucl_object_iter_t iter = NULL; - if (regcomp (®, pattern, REG_EXTENDED | REG_NOSUB) == 0) { + if (regcomp(®, pattern, REG_EXTENDED | REG_NOSUB) == 0) { if (recursive) { - while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) { - if (regexec (®, ucl_object_key (elt), 0, NULL, 0) == 0) { + while ((elt = ucl_object_iterate(obj, &iter, true)) != NULL) { + if (regexec(®, ucl_object_key(elt), 0, NULL, 0) == 0) { res = elt; break; } } - } else { - if (regexec (®, ucl_object_key (obj), 0, NULL, 0) == 0) + } + else { + if (regexec(®, ucl_object_key(obj), 0, NULL, 0) == 0) res = obj; } - regfree (®); + regfree(®); } #endif return res; } /* * Check dependencies for an object */ static bool -ucl_schema_validate_dependencies (const ucl_object_t *deps, - const ucl_object_t *obj, struct ucl_schema_error *err, - const ucl_object_t *root, - ucl_object_t *ext_ref) +ucl_schema_validate_dependencies(const ucl_object_t *deps, + const ucl_object_t *obj, struct ucl_schema_error *err, + const ucl_object_t *root, + ucl_object_t *ext_ref) { const ucl_object_t *elt, *cur, *cur_dep; ucl_object_iter_t iter = NULL, piter; bool ret = true; - while (ret && (cur = ucl_object_iterate (deps, &iter, true)) != NULL) { - elt = ucl_object_lookup (obj, ucl_object_key (cur)); + while (ret && (cur = ucl_object_iterate(deps, &iter, true)) != NULL) { + elt = ucl_object_lookup(obj, ucl_object_key(cur)); if (elt != NULL) { /* Need to check dependencies */ if (cur->type == UCL_ARRAY) { piter = NULL; - while (ret && (cur_dep = ucl_object_iterate (cur, &piter, true)) != NULL) { - if (ucl_object_lookup (obj, ucl_object_tostring (cur_dep)) == NULL) { - ucl_schema_create_error (err, UCL_SCHEMA_MISSING_DEPENDENCY, elt, - "dependency %s is missing for key %s", - ucl_object_tostring (cur_dep), ucl_object_key (cur)); + while (ret && (cur_dep = ucl_object_iterate(cur, &piter, true)) != NULL) { + if (ucl_object_lookup(obj, ucl_object_tostring(cur_dep)) == NULL) { + ucl_schema_create_error(err, UCL_SCHEMA_MISSING_DEPENDENCY, elt, + "dependency %s is missing for key %s", + ucl_object_tostring(cur_dep), ucl_object_key(cur)); ret = false; break; } } } else if (cur->type == UCL_OBJECT) { - ret = ucl_schema_validate (cur, obj, true, err, root, ext_ref); + ret = ucl_schema_validate(cur, obj, true, err, root, ext_ref); } } } return ret; } /* * Validate object */ static bool -ucl_schema_validate_object (const ucl_object_t *schema, - const ucl_object_t *obj, struct ucl_schema_error *err, - const ucl_object_t *root, - ucl_object_t *ext_ref) +ucl_schema_validate_object(const ucl_object_t *schema, + const ucl_object_t *obj, struct ucl_schema_error *err, + const ucl_object_t *root, + ucl_object_t *ext_ref) { const ucl_object_t *elt, *prop, *found, *additional_schema = NULL, - *required = NULL, *pat, *pelt; + *required = NULL, *pat, *pelt; ucl_object_iter_t iter = NULL, piter = NULL; bool ret = true, allow_additional = true; int64_t minmax; - while (ret && (elt = ucl_object_iterate (schema, &iter, true)) != NULL) { + while (ret && (elt = ucl_object_iterate(schema, &iter, true)) != NULL) { if (elt->type == UCL_OBJECT && - strcmp (ucl_object_key (elt), "properties") == 0) { + strcmp(ucl_object_key(elt), "properties") == 0) { piter = NULL; - while (ret && (prop = ucl_object_iterate (elt, &piter, true)) != NULL) { - found = ucl_object_lookup (obj, ucl_object_key (prop)); + while (ret && (prop = ucl_object_iterate(elt, &piter, true)) != NULL) { + found = ucl_object_lookup(obj, ucl_object_key(prop)); if (found) { - ret = ucl_schema_validate (prop, found, true, err, root, - ext_ref); + ret = ucl_schema_validate(prop, found, true, err, root, + ext_ref); } } } - else if (strcmp (ucl_object_key (elt), "additionalProperties") == 0) { + else if (strcmp(ucl_object_key(elt), "additionalProperties") == 0) { if (elt->type == UCL_BOOLEAN) { - if (!ucl_object_toboolean (elt)) { + if (!ucl_object_toboolean(elt)) { /* Deny additional fields completely */ allow_additional = false; } } else if (elt->type == UCL_OBJECT) { /* Define validator for additional fields */ additional_schema = elt; } else { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, elt, - "additionalProperties attribute is invalid in schema"); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, elt, + "additionalProperties attribute is invalid in schema"); ret = false; break; } } - else if (strcmp (ucl_object_key (elt), "required") == 0) { + else if (strcmp(ucl_object_key(elt), "required") == 0) { if (elt->type == UCL_ARRAY) { required = elt; } else { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, elt, - "required attribute is invalid in schema"); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, elt, + "required attribute is invalid in schema"); ret = false; break; } } - else if (strcmp (ucl_object_key (elt), "minProperties") == 0 - && ucl_object_toint_safe (elt, &minmax)) { + else if (strcmp(ucl_object_key(elt), "minProperties") == 0 && ucl_object_toint_safe(elt, &minmax)) { if (obj->len < minmax) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "object has not enough properties: %u, minimum is: %u", - obj->len, (unsigned)minmax); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "object has not enough properties: %u, minimum is: %u", + obj->len, (unsigned) minmax); ret = false; break; } } - else if (strcmp (ucl_object_key (elt), "maxProperties") == 0 - && ucl_object_toint_safe (elt, &minmax)) { + else if (strcmp(ucl_object_key(elt), "maxProperties") == 0 && ucl_object_toint_safe(elt, &minmax)) { if (obj->len > minmax) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "object has too many properties: %u, maximum is: %u", - obj->len, (unsigned)minmax); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "object has too many properties: %u, maximum is: %u", + obj->len, (unsigned) minmax); ret = false; break; } } - else if (strcmp (ucl_object_key (elt), "patternProperties") == 0) { + else if (strcmp(ucl_object_key(elt), "patternProperties") == 0) { const ucl_object_t *vobj; ucl_object_iter_t viter; piter = NULL; - while (ret && (prop = ucl_object_iterate (elt, &piter, true)) != NULL) { + while (ret && (prop = ucl_object_iterate(elt, &piter, true)) != NULL) { viter = NULL; - while (ret && (vobj = ucl_object_iterate (obj, &viter, true)) != NULL) { - found = ucl_schema_test_pattern (vobj, ucl_object_key (prop), false); + while (ret && (vobj = ucl_object_iterate(obj, &viter, true)) != NULL) { + found = ucl_schema_test_pattern(vobj, ucl_object_key(prop), false); if (found) { - ret = ucl_schema_validate (prop, found, true, err, root, - ext_ref); + ret = ucl_schema_validate(prop, found, true, err, root, + ext_ref); } } } } else if (elt->type == UCL_OBJECT && - strcmp (ucl_object_key (elt), "dependencies") == 0) { - ret = ucl_schema_validate_dependencies (elt, obj, err, root, - ext_ref); + strcmp(ucl_object_key(elt), "dependencies") == 0) { + ret = ucl_schema_validate_dependencies(elt, obj, err, root, + ext_ref); } } if (ret) { /* Additional properties */ if (!allow_additional || additional_schema != NULL) { /* Check if we have exactly the same properties in schema and object */ - iter = ucl_object_iterate_new (obj); - prop = ucl_object_lookup (schema, "properties"); - while ((elt = ucl_object_iterate_safe (iter, true)) != NULL) { - found = ucl_object_lookup (prop, ucl_object_key (elt)); + iter = ucl_object_iterate_new(obj); + prop = ucl_object_lookup(schema, "properties"); + while ((elt = ucl_object_iterate_safe(iter, true)) != NULL) { + found = ucl_object_lookup(prop, ucl_object_key(elt)); if (found == NULL) { /* Try patternProperties */ - pat = ucl_object_lookup (schema, "patternProperties"); - piter = ucl_object_iterate_new (pat); - while ((pelt = ucl_object_iterate_safe (piter, true)) != NULL) { - found = ucl_schema_test_pattern (obj, ucl_object_key (pelt), true); + pat = ucl_object_lookup(schema, "patternProperties"); + piter = ucl_object_iterate_new(pat); + while ((pelt = ucl_object_iterate_safe(piter, true)) != NULL) { + found = ucl_schema_test_pattern(obj, ucl_object_key(pelt), true); if (found != NULL) { break; } } - ucl_object_iterate_free (piter); + ucl_object_iterate_free(piter); piter = NULL; } if (found == NULL) { if (!allow_additional) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "object has non-allowed property %s", - ucl_object_key (elt)); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "object has non-allowed property %s", + ucl_object_key(elt)); ret = false; break; } else if (additional_schema != NULL) { - if (!ucl_schema_validate (additional_schema, elt, - true, err, root, ext_ref)) { + if (!ucl_schema_validate(additional_schema, elt, + true, err, root, ext_ref)) { ret = false; break; } } } } - ucl_object_iterate_free (iter); + ucl_object_iterate_free(iter); iter = NULL; } /* Required properties */ if (required != NULL) { iter = NULL; - while ((elt = ucl_object_iterate (required, &iter, true)) != NULL) { - if (ucl_object_lookup (obj, ucl_object_tostring (elt)) == NULL) { - ucl_schema_create_error (err, UCL_SCHEMA_MISSING_PROPERTY, obj, - "object has missing property %s", - ucl_object_tostring (elt)); + while ((elt = ucl_object_iterate(required, &iter, true)) != NULL) { + if (ucl_object_lookup(obj, ucl_object_tostring(elt)) == NULL) { + ucl_schema_create_error(err, UCL_SCHEMA_MISSING_PROPERTY, obj, + "object has missing property %s", + ucl_object_tostring(elt)); ret = false; break; } } } } return ret; } static bool -ucl_schema_validate_number (const ucl_object_t *schema, - const ucl_object_t *obj, struct ucl_schema_error *err) +ucl_schema_validate_number(const ucl_object_t *schema, + const ucl_object_t *obj, struct ucl_schema_error *err) { const ucl_object_t *elt, *test; ucl_object_iter_t iter = NULL; bool ret = true, exclusive = false; double constraint, val; const double alpha = 1e-16; - while (ret && (elt = ucl_object_iterate (schema, &iter, true)) != NULL) { + while (ret && (elt = ucl_object_iterate(schema, &iter, true)) != NULL) { if ((elt->type == UCL_FLOAT || elt->type == UCL_INT) && - strcmp (ucl_object_key (elt), "multipleOf") == 0) { - constraint = ucl_object_todouble (elt); + strcmp(ucl_object_key(elt), "multipleOf") == 0) { + constraint = ucl_object_todouble(elt); if (constraint <= 0) { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, elt, - "multipleOf must be greater than zero"); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, elt, + "multipleOf must be greater than zero"); ret = false; break; } - val = ucl_object_todouble (obj); - if (fabs (remainder (val, constraint)) > alpha) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "number %.4f is not multiple of %.4f, remainder is %.7f", - val, constraint, remainder (val, constraint)); + val = ucl_object_todouble(obj); + if (fabs(remainder(val, constraint)) > alpha) { + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "number %.4f is not multiple of %.4f, remainder is %.7f", + val, constraint, remainder(val, constraint)); ret = false; break; } } else if ((elt->type == UCL_FLOAT || elt->type == UCL_INT) && - strcmp (ucl_object_key (elt), "maximum") == 0) { - constraint = ucl_object_todouble (elt); - test = ucl_object_lookup (schema, "exclusiveMaximum"); + strcmp(ucl_object_key(elt), "maximum") == 0) { + constraint = ucl_object_todouble(elt); + test = ucl_object_lookup(schema, "exclusiveMaximum"); if (test && test->type == UCL_BOOLEAN) { - exclusive = ucl_object_toboolean (test); + exclusive = ucl_object_toboolean(test); } - val = ucl_object_todouble (obj); + val = ucl_object_todouble(obj); if (val > constraint || (exclusive && val >= constraint)) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "number is too big: %.3f, maximum is: %.3f", - val, constraint); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "number is too big: %.3f, maximum is: %.3f", + val, constraint); ret = false; break; } } else if ((elt->type == UCL_FLOAT || elt->type == UCL_INT) && - strcmp (ucl_object_key (elt), "minimum") == 0) { - constraint = ucl_object_todouble (elt); - test = ucl_object_lookup (schema, "exclusiveMinimum"); + strcmp(ucl_object_key(elt), "minimum") == 0) { + constraint = ucl_object_todouble(elt); + test = ucl_object_lookup(schema, "exclusiveMinimum"); if (test && test->type == UCL_BOOLEAN) { - exclusive = ucl_object_toboolean (test); + exclusive = ucl_object_toboolean(test); } - val = ucl_object_todouble (obj); + val = ucl_object_todouble(obj); if (val < constraint || (exclusive && val <= constraint)) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "number is too small: %.3f, minimum is: %.3f", - val, constraint); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "number is too small: %.3f, minimum is: %.3f", + val, constraint); ret = false; break; } } } return ret; } static bool -ucl_schema_validate_string (const ucl_object_t *schema, - const ucl_object_t *obj, struct ucl_schema_error *err) +ucl_schema_validate_string(const ucl_object_t *schema, + const ucl_object_t *obj, struct ucl_schema_error *err) { const ucl_object_t *elt; ucl_object_iter_t iter = NULL; bool ret = true; int64_t constraint; #ifdef HAVE_REGEX_H regex_t re; #endif - while (ret && (elt = ucl_object_iterate (schema, &iter, true)) != NULL) { + while (ret && (elt = ucl_object_iterate(schema, &iter, true)) != NULL) { if (elt->type == UCL_INT && - strcmp (ucl_object_key (elt), "maxLength") == 0) { - constraint = ucl_object_toint (elt); + strcmp(ucl_object_key(elt), "maxLength") == 0) { + constraint = ucl_object_toint(elt); if (obj->len > constraint) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "string is too big: %u, maximum is: %" PRId64, - obj->len, constraint); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "string is too big: %u, maximum is: %" PRId64, + obj->len, constraint); ret = false; break; } } else if (elt->type == UCL_INT && - strcmp (ucl_object_key (elt), "minLength") == 0) { - constraint = ucl_object_toint (elt); + strcmp(ucl_object_key(elt), "minLength") == 0) { + constraint = ucl_object_toint(elt); if (obj->len < constraint) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "string is too short: %u, minimum is: %" PRId64, - obj->len, constraint); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "string is too short: %u, minimum is: %" PRId64, + obj->len, constraint); ret = false; break; } } #ifdef HAVE_REGEX_H else if (elt->type == UCL_STRING && - strcmp (ucl_object_key (elt), "pattern") == 0) { - if (regcomp (&re, ucl_object_tostring (elt), - REG_EXTENDED | REG_NOSUB) != 0) { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, elt, - "cannot compile pattern %s", ucl_object_tostring (elt)); + strcmp(ucl_object_key(elt), "pattern") == 0) { + if (regcomp(&re, ucl_object_tostring(elt), + REG_EXTENDED | REG_NOSUB) != 0) { + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, elt, + "cannot compile pattern %s", ucl_object_tostring(elt)); ret = false; break; } - if (regexec (&re, ucl_object_tostring (obj), 0, NULL, 0) != 0) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "string doesn't match regexp %s", - ucl_object_tostring (elt)); + if (regexec(&re, ucl_object_tostring(obj), 0, NULL, 0) != 0) { + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "string doesn't match regexp %s", + ucl_object_tostring(elt)); ret = false; } - regfree (&re); + regfree(&re); } #endif } return ret; } struct ucl_compare_node { const ucl_object_t *obj; - TREE_ENTRY(ucl_compare_node) link; + TREE_ENTRY(ucl_compare_node) + link; struct ucl_compare_node *next; }; typedef TREE_HEAD(_tree, ucl_compare_node) ucl_compare_tree_t; TREE_DEFINE(ucl_compare_node, link) static int -ucl_schema_elt_compare (struct ucl_compare_node *n1, struct ucl_compare_node *n2) +ucl_schema_elt_compare(struct ucl_compare_node *n1, struct ucl_compare_node *n2) { const ucl_object_t *o1 = n1->obj, *o2 = n2->obj; - return ucl_object_compare (o1, o2); + return ucl_object_compare(o1, o2); } static bool -ucl_schema_array_is_unique (const ucl_object_t *obj, struct ucl_schema_error *err) +ucl_schema_array_is_unique(const ucl_object_t *obj, struct ucl_schema_error *err) { - ucl_compare_tree_t tree = TREE_INITIALIZER (ucl_schema_elt_compare); + ucl_compare_tree_t tree = TREE_INITIALIZER(ucl_schema_elt_compare); ucl_object_iter_t iter = NULL; const ucl_object_t *elt; struct ucl_compare_node *node, test, *nodes = NULL, *tmp; bool ret = true; - while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) { + while ((elt = ucl_object_iterate(obj, &iter, true)) != NULL) { test.obj = elt; - node = TREE_FIND (&tree, ucl_compare_node, link, &test); + node = TREE_FIND(&tree, ucl_compare_node, link, &test); if (node != NULL) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, elt, - "duplicate values detected while uniqueItems is true"); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, elt, + "duplicate values detected while uniqueItems is true"); ret = false; break; } - node = calloc (1, sizeof (*node)); + node = calloc(1, sizeof(*node)); if (node == NULL) { - ucl_schema_create_error (err, UCL_SCHEMA_UNKNOWN, elt, - "cannot allocate tree node"); + ucl_schema_create_error(err, UCL_SCHEMA_UNKNOWN, elt, + "cannot allocate tree node"); ret = false; break; } node->obj = elt; - TREE_INSERT (&tree, ucl_compare_node, link, node); - LL_PREPEND (nodes, node); + TREE_INSERT(&tree, ucl_compare_node, link, node); + LL_PREPEND(nodes, node); } - LL_FOREACH_SAFE (nodes, node, tmp) { - free (node); + LL_FOREACH_SAFE(nodes, node, tmp) + { + free(node); } return ret; } static bool -ucl_schema_validate_array (const ucl_object_t *schema, - const ucl_object_t *obj, struct ucl_schema_error *err, - const ucl_object_t *root, - ucl_object_t *ext_ref) +ucl_schema_validate_array(const ucl_object_t *schema, + const ucl_object_t *obj, struct ucl_schema_error *err, + const ucl_object_t *root, + ucl_object_t *ext_ref) { const ucl_object_t *elt, *it, *found, *additional_schema = NULL, - *first_unvalidated = NULL; + *first_unvalidated = NULL; ucl_object_iter_t iter = NULL, piter = NULL; bool ret = true, allow_additional = true, need_unique = false; int64_t minmax; unsigned int idx = 0; - while (ret && (elt = ucl_object_iterate (schema, &iter, true)) != NULL) { - if (strcmp (ucl_object_key (elt), "items") == 0) { + while (ret && (elt = ucl_object_iterate(schema, &iter, true)) != NULL) { + if (strcmp(ucl_object_key(elt), "items") == 0) { if (elt->type == UCL_ARRAY) { - found = ucl_array_head (obj); - while (ret && (it = ucl_object_iterate (elt, &piter, true)) != NULL) { + found = ucl_array_head(obj); + while (ret && (it = ucl_object_iterate(elt, &piter, true)) != NULL) { if (found) { - ret = ucl_schema_validate (it, found, false, err, - root, ext_ref); - found = ucl_array_find_index (obj, ++idx); + ret = ucl_schema_validate(it, found, false, err, + root, ext_ref); + found = ucl_array_find_index(obj, ++idx); } } if (found != NULL) { /* The first element that is not validated */ first_unvalidated = found; } } else if (elt->type == UCL_OBJECT) { /* Validate all items using the specified schema */ - while (ret && (it = ucl_object_iterate (obj, &piter, true)) != NULL) { - ret = ucl_schema_validate (elt, it, false, err, root, - ext_ref); + while (ret && (it = ucl_object_iterate(obj, &piter, true)) != NULL) { + ret = ucl_schema_validate(elt, it, false, err, root, + ext_ref); } } else { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, elt, - "items attribute is invalid in schema"); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, elt, + "items attribute is invalid in schema"); ret = false; break; } } - else if (strcmp (ucl_object_key (elt), "additionalItems") == 0) { + else if (strcmp(ucl_object_key(elt), "additionalItems") == 0) { if (elt->type == UCL_BOOLEAN) { - if (!ucl_object_toboolean (elt)) { + if (!ucl_object_toboolean(elt)) { /* Deny additional fields completely */ allow_additional = false; } } else if (elt->type == UCL_OBJECT) { /* Define validator for additional fields */ additional_schema = elt; } else { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, elt, - "additionalItems attribute is invalid in schema"); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, elt, + "additionalItems attribute is invalid in schema"); ret = false; break; } } else if (elt->type == UCL_BOOLEAN && - strcmp (ucl_object_key (elt), "uniqueItems") == 0) { - need_unique = ucl_object_toboolean (elt); + strcmp(ucl_object_key(elt), "uniqueItems") == 0) { + need_unique = ucl_object_toboolean(elt); } - else if (strcmp (ucl_object_key (elt), "minItems") == 0 - && ucl_object_toint_safe (elt, &minmax)) { + else if (strcmp(ucl_object_key(elt), "minItems") == 0 && ucl_object_toint_safe(elt, &minmax)) { if (obj->len < minmax) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "array has not enough items: %u, minimum is: %u", - obj->len, (unsigned)minmax); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "array has not enough items: %u, minimum is: %u", + obj->len, (unsigned) minmax); ret = false; break; } } - else if (strcmp (ucl_object_key (elt), "maxItems") == 0 - && ucl_object_toint_safe (elt, &minmax)) { + else if (strcmp(ucl_object_key(elt), "maxItems") == 0 && ucl_object_toint_safe(elt, &minmax)) { if (obj->len > minmax) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "array has too many items: %u, maximum is: %u", - obj->len, (unsigned)minmax); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "array has too many items: %u, maximum is: %u", + obj->len, (unsigned) minmax); ret = false; break; } } } if (ret) { /* Additional properties */ if (!allow_additional || additional_schema != NULL) { if (first_unvalidated != NULL) { if (!allow_additional) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "array has undefined item"); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "array has undefined item"); ret = false; } else if (additional_schema != NULL) { - elt = ucl_array_find_index (obj, idx); + elt = ucl_array_find_index(obj, idx); while (elt) { - if (!ucl_schema_validate (additional_schema, elt, false, - err, root, ext_ref)) { + if (!ucl_schema_validate(additional_schema, elt, false, + err, root, ext_ref)) { ret = false; break; } - elt = ucl_array_find_index (obj, idx ++); + elt = ucl_array_find_index(obj, idx++); } } } } /* Required properties */ if (ret && need_unique) { - ret = ucl_schema_array_is_unique (obj, err); + ret = ucl_schema_array_is_unique(obj, err); } } return ret; } /* * Returns whether this object is allowed for this type */ static bool -ucl_schema_type_is_allowed (const ucl_object_t *type, const ucl_object_t *obj, - struct ucl_schema_error *err) +ucl_schema_type_is_allowed(const ucl_object_t *type, const ucl_object_t *obj, + struct ucl_schema_error *err) { ucl_object_iter_t iter = NULL; const ucl_object_t *elt; const char *type_str; ucl_type_t t; if (type == NULL) { /* Any type is allowed */ return true; } if (type->type == UCL_ARRAY) { /* One of allowed types */ - while ((elt = ucl_object_iterate (type, &iter, true)) != NULL) { - if (ucl_schema_type_is_allowed (elt, obj, err)) { + while ((elt = ucl_object_iterate(type, &iter, true)) != NULL) { + if (ucl_schema_type_is_allowed(elt, obj, err)) { return true; } } } else if (type->type == UCL_STRING) { - type_str = ucl_object_tostring (type); - if (!ucl_object_string_to_type (type_str, &t)) { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, type, - "Type attribute is invalid in schema"); + type_str = ucl_object_tostring(type); + if (!ucl_object_string_to_type(type_str, &t)) { + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, type, + "Type attribute is invalid in schema"); return false; } if (obj->type != t) { /* Some types are actually compatible */ if (obj->type == UCL_TIME && t == UCL_FLOAT) { return true; } else if (obj->type == UCL_INT && t == UCL_FLOAT) { return true; } else { - ucl_schema_create_error (err, UCL_SCHEMA_TYPE_MISMATCH, obj, - "Invalid type of %s, expected %s", - ucl_object_type_to_string (obj->type), - ucl_object_type_to_string (t)); + ucl_schema_create_error(err, UCL_SCHEMA_TYPE_MISMATCH, obj, + "Invalid type of %s, expected %s", + ucl_object_type_to_string(obj->type), + ucl_object_type_to_string(t)); } } else { /* Types are equal */ return true; } } return false; } /* * Check if object is equal to one of elements of enum */ static bool -ucl_schema_validate_enum (const ucl_object_t *en, const ucl_object_t *obj, - struct ucl_schema_error *err) +ucl_schema_validate_enum(const ucl_object_t *en, const ucl_object_t *obj, + struct ucl_schema_error *err) { ucl_object_iter_t iter = NULL; const ucl_object_t *elt; bool ret = false; - while ((elt = ucl_object_iterate (en, &iter, true)) != NULL) { - if (ucl_object_compare (elt, obj) == 0) { + while ((elt = ucl_object_iterate(en, &iter, true)) != NULL) { + if (ucl_object_compare(elt, obj) == 0) { ret = true; break; } } if (!ret) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "object is not one of enumerated patterns"); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "object is not one of enumerated patterns"); } return ret; } /* * Check a single ref component */ static const ucl_object_t * -ucl_schema_resolve_ref_component (const ucl_object_t *cur, - const char *refc, int len, - struct ucl_schema_error *err) +ucl_schema_resolve_ref_component(const ucl_object_t *cur, + const char *refc, int len, + struct ucl_schema_error *err) { const ucl_object_t *res = NULL; char *err_str; int num, i; if (cur->type == UCL_OBJECT) { /* Find a key inside an object */ - res = ucl_object_lookup_len (cur, refc, len); + res = ucl_object_lookup_len(cur, refc, len); if (res == NULL) { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, cur, - "reference %s is invalid, missing path component", refc); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, cur, + "reference %s is invalid, missing path component", refc); return NULL; } } else if (cur->type == UCL_ARRAY) { /* We must figure out a number inside array */ - num = strtoul (refc, &err_str, 10); + num = strtoul(refc, &err_str, 10); if (err_str != NULL && *err_str != '/' && *err_str != '\0') { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, cur, - "reference %s is invalid, invalid item number", refc); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, cur, + "reference %s is invalid, invalid item number", refc); return NULL; } - res = ucl_array_head (cur); + res = ucl_array_head(cur); i = 0; while (res != NULL) { if (i == num) { break; } res = res->next; } if (res == NULL) { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, cur, - "reference %s is invalid, item number %d does not exist", - refc, num); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, cur, + "reference %s is invalid, item number %d does not exist", + refc, num); return NULL; } } else { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, res, - "reference %s is invalid, contains primitive object in the path", - refc); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, res, + "reference %s is invalid, contains primitive object in the path", + refc); return NULL; } return res; } /* * Find reference schema */ static const ucl_object_t * -ucl_schema_resolve_ref (const ucl_object_t *root, const char *ref, - struct ucl_schema_error *err, ucl_object_t *ext_ref, - ucl_object_t const ** nroot) +ucl_schema_resolve_ref(const ucl_object_t *root, const char *ref, + struct ucl_schema_error *err, ucl_object_t *ext_ref, + ucl_object_t const **nroot) { UT_string *url_err = NULL; struct ucl_parser *parser; const ucl_object_t *res = NULL, *ext_obj = NULL; ucl_object_t *url_obj; const char *p, *c, *hash_ptr = NULL; char *url_copy = NULL; unsigned char *url_buf; size_t url_buflen; if (ref[0] != '#') { - hash_ptr = strrchr (ref, '#'); + hash_ptr = strrchr(ref, '#'); if (hash_ptr) { - url_copy = malloc (hash_ptr - ref + 1); + url_copy = malloc(hash_ptr - ref + 1); if (url_copy == NULL) { - ucl_schema_create_error (err, UCL_SCHEMA_INTERNAL_ERROR, root, - "cannot allocate memory"); + ucl_schema_create_error(err, UCL_SCHEMA_INTERNAL_ERROR, root, + "cannot allocate memory"); return NULL; } - ucl_strlcpy (url_copy, ref, hash_ptr - ref + 1); + ucl_strlcpy(url_copy, ref, hash_ptr - ref + 1); p = url_copy; } else { /* Full URL */ p = ref; } - ext_obj = ucl_object_lookup (ext_ref, p); + ext_obj = ucl_object_lookup(ext_ref, p); if (ext_obj == NULL) { - if (ucl_strnstr (p, "://", strlen (p)) != NULL) { - if (!ucl_fetch_url (p, &url_buf, &url_buflen, &url_err, true)) { - - ucl_schema_create_error (err, - UCL_SCHEMA_INVALID_SCHEMA, - root, - "cannot fetch reference %s: %s", - p, - url_err != NULL ? utstring_body (url_err) - : "unknown"); - free (url_copy); + if (ucl_strnstr(p, "://", strlen(p)) != NULL) { + if (!ucl_fetch_url(p, &url_buf, &url_buflen, &url_err, true)) { + + ucl_schema_create_error(err, + UCL_SCHEMA_INVALID_SCHEMA, + root, + "cannot fetch reference %s: %s", + p, + url_err != NULL ? utstring_body(url_err) + : "unknown"); + free(url_copy); return NULL; } } else { - if (!ucl_fetch_file (p, &url_buf, &url_buflen, &url_err, - true)) { - ucl_schema_create_error (err, - UCL_SCHEMA_INVALID_SCHEMA, - root, - "cannot fetch reference %s: %s", - p, - url_err != NULL ? utstring_body (url_err) - : "unknown"); - free (url_copy); + if (!ucl_fetch_file(p, &url_buf, &url_buflen, &url_err, + true)) { + ucl_schema_create_error(err, + UCL_SCHEMA_INVALID_SCHEMA, + root, + "cannot fetch reference %s: %s", + p, + url_err != NULL ? utstring_body(url_err) + : "unknown"); + free(url_copy); return NULL; } } - parser = ucl_parser_new (0); + parser = ucl_parser_new(0); - if (!ucl_parser_add_chunk (parser, url_buf, url_buflen)) { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, root, - "cannot fetch reference %s: %s", p, - ucl_parser_get_error (parser)); - ucl_parser_free (parser); - free (url_copy); + if (!ucl_parser_add_chunk(parser, url_buf, url_buflen)) { + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, root, + "cannot fetch reference %s: %s", p, + ucl_parser_get_error(parser)); + ucl_parser_free(parser); + free(url_copy); return NULL; } - url_obj = ucl_parser_get_object (parser); + url_obj = ucl_parser_get_object(parser); ext_obj = url_obj; - ucl_object_insert_key (ext_ref, url_obj, p, 0, true); - free (url_buf); + ucl_object_insert_key(ext_ref, url_obj, p, 0, true); + free(url_buf); } - free (url_copy); + free(url_copy); if (hash_ptr) { p = hash_ptr + 1; } else { p = ""; } } else { p = ref + 1; } res = ext_obj != NULL ? ext_obj : root; *nroot = res; if (*p == '/') { p++; } else if (*p == '\0') { return res; } c = p; while (*p != '\0') { if (*p == '/') { if (p - c == 0) { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, res, - "reference %s is invalid, empty path component", ref); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, res, + "reference %s is invalid, empty path component", ref); return NULL; } /* Now we have some url part, so we need to figure out where we are */ - res = ucl_schema_resolve_ref_component (res, c, p - c, err); + res = ucl_schema_resolve_ref_component(res, c, p - c, err); if (res == NULL) { return NULL; } c = p + 1; } - p ++; + p++; } if (p - c != 0) { - res = ucl_schema_resolve_ref_component (res, c, p - c, err); + res = ucl_schema_resolve_ref_component(res, c, p - c, err); } if (res == NULL || res->type != UCL_OBJECT) { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, res, - "reference %s is invalid, cannot find specified object", - ref); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, res, + "reference %s is invalid, cannot find specified object", + ref); return NULL; } return res; } static bool -ucl_schema_validate_values (const ucl_object_t *schema, const ucl_object_t *obj, - struct ucl_schema_error *err) +ucl_schema_validate_values(const ucl_object_t *schema, const ucl_object_t *obj, + struct ucl_schema_error *err) { const ucl_object_t *elt, *cur; int64_t constraint, i; - elt = ucl_object_lookup (schema, "maxValues"); + elt = ucl_object_lookup(schema, "maxValues"); if (elt != NULL && elt->type == UCL_INT) { - constraint = ucl_object_toint (elt); + constraint = ucl_object_toint(elt); cur = obj; i = 0; while (cur) { if (i > constraint) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "object has more values than defined: %ld", - (long int)constraint); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "object has more values than defined: %ld", + (long int) constraint); return false; } - i ++; + i++; cur = cur->next; } } - elt = ucl_object_lookup (schema, "minValues"); + elt = ucl_object_lookup(schema, "minValues"); if (elt != NULL && elt->type == UCL_INT) { - constraint = ucl_object_toint (elt); + constraint = ucl_object_toint(elt); cur = obj; i = 0; while (cur) { if (i >= constraint) { break; } - i ++; + i++; cur = cur->next; } if (i < constraint) { - ucl_schema_create_error (err, UCL_SCHEMA_CONSTRAINT, obj, - "object has less values than defined: %ld", - (long int)constraint); + ucl_schema_create_error(err, UCL_SCHEMA_CONSTRAINT, obj, + "object has less values than defined: %ld", + (long int) constraint); return false; } } return true; } static bool -ucl_schema_validate (const ucl_object_t *schema, - const ucl_object_t *obj, bool try_array, - struct ucl_schema_error *err, - const ucl_object_t *root, - ucl_object_t *external_refs) +ucl_schema_validate(const ucl_object_t *schema, + const ucl_object_t *obj, bool try_array, + struct ucl_schema_error *err, + const ucl_object_t *root, + ucl_object_t *external_refs) { const ucl_object_t *elt, *cur, *ref_root; ucl_object_iter_t iter = NULL; bool ret; if (schema->type != UCL_OBJECT) { - ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, schema, - "schema is %s instead of object", - ucl_object_type_to_string (schema->type)); + ucl_schema_create_error(err, UCL_SCHEMA_INVALID_SCHEMA, schema, + "schema is %s instead of object", + ucl_object_type_to_string(schema->type)); return false; } if (try_array) { /* * Special case for multiple values */ - if (!ucl_schema_validate_values (schema, obj, err)) { + if (!ucl_schema_validate_values(schema, obj, err)) { return false; } - LL_FOREACH (obj, cur) { - if (!ucl_schema_validate (schema, cur, false, err, root, external_refs)) { + LL_FOREACH(obj, cur) + { + if (!ucl_schema_validate(schema, cur, false, err, root, external_refs)) { return false; } } return true; } - elt = ucl_object_lookup (schema, "enum"); + elt = ucl_object_lookup(schema, "enum"); if (elt != NULL && elt->type == UCL_ARRAY) { - if (!ucl_schema_validate_enum (elt, obj, err)) { + if (!ucl_schema_validate_enum(elt, obj, err)) { return false; } } - elt = ucl_object_lookup (schema, "allOf"); + elt = ucl_object_lookup(schema, "allOf"); if (elt != NULL && elt->type == UCL_ARRAY) { iter = NULL; - while ((cur = ucl_object_iterate (elt, &iter, true)) != NULL) { - ret = ucl_schema_validate (cur, obj, true, err, root, external_refs); + while ((cur = ucl_object_iterate(elt, &iter, true)) != NULL) { + ret = ucl_schema_validate(cur, obj, true, err, root, external_refs); if (!ret) { return false; } } } - elt = ucl_object_lookup (schema, "anyOf"); + elt = ucl_object_lookup(schema, "anyOf"); if (elt != NULL && elt->type == UCL_ARRAY) { iter = NULL; - while ((cur = ucl_object_iterate (elt, &iter, true)) != NULL) { - ret = ucl_schema_validate (cur, obj, true, err, root, external_refs); + while ((cur = ucl_object_iterate(elt, &iter, true)) != NULL) { + ret = ucl_schema_validate(cur, obj, true, err, root, external_refs); if (ret) { break; } } if (!ret) { return false; } else { /* Reset error */ err->code = UCL_SCHEMA_OK; } } - elt = ucl_object_lookup (schema, "oneOf"); + elt = ucl_object_lookup(schema, "oneOf"); if (elt != NULL && elt->type == UCL_ARRAY) { iter = NULL; ret = false; - while ((cur = ucl_object_iterate (elt, &iter, true)) != NULL) { + while ((cur = ucl_object_iterate(elt, &iter, true)) != NULL) { if (!ret) { - ret = ucl_schema_validate (cur, obj, true, err, root, external_refs); + ret = ucl_schema_validate(cur, obj, true, err, root, external_refs); } - else if (ucl_schema_validate (cur, obj, true, err, root, external_refs)) { + else if (ucl_schema_validate(cur, obj, true, err, root, external_refs)) { ret = false; break; } } if (!ret) { return false; } } - elt = ucl_object_lookup (schema, "not"); + elt = ucl_object_lookup(schema, "not"); if (elt != NULL && elt->type == UCL_OBJECT) { - if (ucl_schema_validate (elt, obj, true, err, root, external_refs)) { + if (ucl_schema_validate(elt, obj, true, err, root, external_refs)) { return false; } else { /* Reset error */ err->code = UCL_SCHEMA_OK; } } - elt = ucl_object_lookup (schema, "$ref"); + elt = ucl_object_lookup(schema, "$ref"); if (elt != NULL) { ref_root = root; - cur = ucl_schema_resolve_ref (root, ucl_object_tostring (elt), - err, external_refs, &ref_root); + cur = ucl_schema_resolve_ref(root, ucl_object_tostring(elt), + err, external_refs, &ref_root); if (cur == NULL) { return false; } - if (!ucl_schema_validate (cur, obj, try_array, err, ref_root, - external_refs)) { + if (!ucl_schema_validate(cur, obj, try_array, err, ref_root, + external_refs)) { return false; } } - elt = ucl_object_lookup (schema, "type"); - if (!ucl_schema_type_is_allowed (elt, obj, err)) { + elt = ucl_object_lookup(schema, "type"); + if (!ucl_schema_type_is_allowed(elt, obj, err)) { return false; } switch (obj->type) { case UCL_OBJECT: - return ucl_schema_validate_object (schema, obj, err, root, external_refs); + return ucl_schema_validate_object(schema, obj, err, root, external_refs); break; case UCL_ARRAY: - return ucl_schema_validate_array (schema, obj, err, root, external_refs); + return ucl_schema_validate_array(schema, obj, err, root, external_refs); break; case UCL_INT: case UCL_FLOAT: - return ucl_schema_validate_number (schema, obj, err); + return ucl_schema_validate_number(schema, obj, err); break; case UCL_STRING: - return ucl_schema_validate_string (schema, obj, err); + return ucl_schema_validate_string(schema, obj, err); break; default: break; } return true; } -bool -ucl_object_validate (const ucl_object_t *schema, - const ucl_object_t *obj, struct ucl_schema_error *err) +bool ucl_object_validate(const ucl_object_t *schema, + const ucl_object_t *obj, struct ucl_schema_error *err) { - return ucl_object_validate_root_ext (schema, obj, schema, NULL, err); + return ucl_object_validate_root_ext(schema, obj, schema, NULL, err); } -bool -ucl_object_validate_root (const ucl_object_t *schema, - const ucl_object_t *obj, - const ucl_object_t *root, - struct ucl_schema_error *err) +bool ucl_object_validate_root(const ucl_object_t *schema, + const ucl_object_t *obj, + const ucl_object_t *root, + struct ucl_schema_error *err) { - return ucl_object_validate_root_ext (schema, obj, root, NULL, err); + return ucl_object_validate_root_ext(schema, obj, root, NULL, err); } -bool -ucl_object_validate_root_ext (const ucl_object_t *schema, - const ucl_object_t *obj, - const ucl_object_t *root, - ucl_object_t *ext_refs, - struct ucl_schema_error *err) +bool ucl_object_validate_root_ext(const ucl_object_t *schema, + const ucl_object_t *obj, + const ucl_object_t *root, + ucl_object_t *ext_refs, + struct ucl_schema_error *err) { bool ret, need_unref = false; if (ext_refs == NULL) { - ext_refs = ucl_object_typed_new (UCL_OBJECT); + ext_refs = ucl_object_typed_new(UCL_OBJECT); need_unref = true; } - ret = ucl_schema_validate (schema, obj, true, err, root, ext_refs); + ret = ucl_schema_validate(schema, obj, true, err, root, ext_refs); if (need_unref) { - ucl_object_unref (ext_refs); + ucl_object_unref(ext_refs); } return ret; } diff --git a/contrib/libucl/src/ucl_sexp.c b/contrib/libucl/src/ucl_sexp.c index 1ad93d23458e..e174cf45ca01 100644 --- a/contrib/libucl/src/ucl_sexp.c +++ b/contrib/libucl/src/ucl_sexp.c @@ -1,226 +1,229 @@ /* * Copyright (c) 2015, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "ucl.h" #include "ucl_internal.h" #include "utlist.h" -#define NEXT_STATE do { \ -if (p >= end) { \ - if (state != read_ebrace) { \ - ucl_create_err (&parser->err,\ - "extra data");\ - state = parse_err; \ - } \ -} \ -else { \ -switch (*p) { \ - case '(': \ - state = read_obrace; \ - break; \ - case ')': \ - state = read_ebrace; \ - break; \ - default: \ - len = 0; \ - mult = 1; \ - state = read_length; \ - break; \ - } \ -} \ -} while(0) - -bool -ucl_parse_csexp (struct ucl_parser *parser) +#define NEXT_STATE \ + do { \ + if (p >= end) { \ + if (state != read_ebrace) { \ + ucl_create_err(&parser->err, \ + "extra data"); \ + state = parse_err; \ + } \ + } \ + else { \ + switch (*p) { \ + case '(': \ + state = read_obrace; \ + break; \ + case ')': \ + state = read_ebrace; \ + break; \ + default: \ + len = 0; \ + mult = 1; \ + state = read_length; \ + break; \ + } \ + } \ + } while (0) + +bool ucl_parse_csexp(struct ucl_parser *parser) { const unsigned char *p, *end; ucl_object_t *obj; struct ucl_stack *st; uint64_t len = 0, mult = 1; enum { start_parse, read_obrace, read_length, read_value, read_ebrace, parse_err } state = start_parse; - assert (parser != NULL); - assert (parser->chunks != NULL); - assert (parser->chunks->begin != NULL); - assert (parser->chunks->remain != 0); + assert(parser != NULL); + assert(parser->chunks != NULL); + assert(parser->chunks->begin != NULL); + assert(parser->chunks->remain != 0); p = parser->chunks->begin; end = p + parser->chunks->remain; while (p < end) { switch (state) { case start_parse: /* At this point we expect open brace */ if (*p == '(') { state = read_obrace; } else { - ucl_create_err (&parser->err, "bad starting character for " - "sexp block: %x", (int)*p); + ucl_create_err(&parser->err, "bad starting character for " + "sexp block: %x", + (int) *p); state = parse_err; } break; case read_obrace: - st = calloc (1, sizeof (*st)); + st = calloc(1, sizeof(*st)); if (st == NULL) { - ucl_create_err (&parser->err, "no memory"); + ucl_create_err(&parser->err, "no memory"); state = parse_err; continue; } - st->obj = ucl_object_typed_new (UCL_ARRAY); + st->obj = ucl_object_typed_new(UCL_ARRAY); if (st->obj == NULL) { - ucl_create_err (&parser->err, "no memory"); + ucl_create_err(&parser->err, "no memory"); state = parse_err; - free (st); + free(st); continue; } if (parser->stack == NULL) { /* We have no stack */ parser->stack = st; if (parser->top_obj == NULL) { parser->top_obj = st->obj; } } else { /* Prepend new element to the stack */ - LL_PREPEND (parser->stack, st); + LL_PREPEND(parser->stack, st); } - p ++; + p++; NEXT_STATE; break; case read_length: if (*p == ':') { if (len == 0) { - ucl_create_err (&parser->err, "zero length element"); + ucl_create_err(&parser->err, "zero length element"); state = parse_err; continue; } state = read_value; } else if (*p >= '0' && *p <= '9') { len += (*p - '0') * mult; mult *= 10; if (len > UINT32_MAX) { - ucl_create_err (&parser->err, "too big length of an " - "element"); + ucl_create_err(&parser->err, "too big length of an " + "element"); state = parse_err; continue; } } else { - ucl_create_err (&parser->err, "bad length character: %x", - (int)*p); + ucl_create_err(&parser->err, "bad length character: %x", + (int) *p); state = parse_err; continue; } - p ++; + p++; break; case read_value: - if ((uint64_t)(end - p) > len || len == 0) { - ucl_create_err (&parser->err, "invalid length: %llu, %ld " - "remain", (long long unsigned)len, (long)(end - p)); + if ((uint64_t) (end - p) > len || len == 0) { + ucl_create_err(&parser->err, "invalid length: %llu, %ld " + "remain", + (long long unsigned) len, (long) (end - p)); state = parse_err; continue; } - obj = ucl_object_typed_new (UCL_STRING); + obj = ucl_object_typed_new(UCL_STRING); - obj->value.sv = (const char*)p; + obj->value.sv = (const char *) p; obj->len = len; obj->flags |= UCL_OBJECT_BINARY; if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { - ucl_copy_value_trash (obj); + ucl_copy_value_trash(obj); } - ucl_array_append (parser->stack->obj, obj); + ucl_array_append(parser->stack->obj, obj); p += len; NEXT_STATE; break; case read_ebrace: if (parser->stack == NULL) { /* We have an extra end brace */ - ucl_create_err (&parser->err, "invalid length: %llu, %ld " - "remain", (long long unsigned)len, (long)(end - p)); + ucl_create_err(&parser->err, "invalid length: %llu, %ld " + "remain", + (long long unsigned) len, (long) (end - p)); state = parse_err; continue; } /* Pop the container */ st = parser->stack; parser->stack = st->next; if (parser->stack->obj->type == UCL_ARRAY) { - ucl_array_append (parser->stack->obj, st->obj); + ucl_array_append(parser->stack->obj, st->obj); } else { - ucl_create_err (&parser->err, "bad container object, array " - "expected"); + ucl_create_err(&parser->err, "bad container object, array " + "expected"); state = parse_err; continue; } - free (st); + free(st); st = NULL; p++; NEXT_STATE; break; case parse_err: default: return false; } } if (state != read_ebrace) { - ucl_create_err (&parser->err, "invalid finishing state: %d", state); + ucl_create_err(&parser->err, "invalid finishing state: %d", state); return false; } return true; } diff --git a/contrib/libucl/src/ucl_util.c b/contrib/libucl/src/ucl_util.c index 8f97c20db503..3566632275a5 100644 --- a/contrib/libucl/src/ucl_util.c +++ b/contrib/libucl/src/ucl_util.c @@ -1,3968 +1,3981 @@ /* Copyright (c) 2013, Vsevolod Stakhov * Copyright (c) 2015 Allan Jude * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ucl.h" #include "ucl_internal.h" #include "ucl_chartable.h" #include "kvec.h" #include #include #include /* for snprintf */ #ifndef _WIN32 #include #include #else #ifndef NBBY #define NBBY 8 #endif #endif #ifdef HAVE_LIBGEN_H #ifndef _WIN32 -# include /* For dirname */ +#include /* For dirname */ #endif #endif typedef kvec_t(ucl_object_t *) ucl_array_t; #define UCL_ARRAY_GET(ar, obj) ucl_array_t *ar = \ - (ucl_array_t *)((obj) != NULL ? (obj)->value.av : NULL) + (ucl_array_t *) ((obj) != NULL ? (obj)->value.av : NULL) #ifdef HAVE_OPENSSL #include #include #include #include #include #endif #ifdef CURL_FOUND /* Seems to be broken */ #define CURL_DISABLE_TYPECHECK 1 #include #endif #ifdef HAVE_FETCH_H #include #endif #if defined(_WIN32) #include #include #include #ifndef PROT_READ -#define PROT_READ 1 +#define PROT_READ 1 #endif #ifndef PROT_WRITE -#define PROT_WRITE 2 +#define PROT_WRITE 2 #endif #ifndef PROT_READWRITE -#define PROT_READWRITE 3 +#define PROT_READWRITE 3 #endif #ifndef MAP_SHARED -#define MAP_SHARED 1 +#define MAP_SHARED 1 #endif #ifndef MAP_PRIVATE -#define MAP_PRIVATE 2 +#define MAP_PRIVATE 2 #endif #ifndef MAP_FAILED -#define MAP_FAILED ((void *) -1) +#define MAP_FAILED ((void *) -1) #endif #define getcwd _getcwd #define open _open #define close _close static void *ucl_mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset) { void *map = NULL; HANDLE handle = INVALID_HANDLE_VALUE; switch (prot) { default: - case PROT_READ: - { - handle = CreateFileMapping((HANDLE) _get_osfhandle(fd), 0, PAGE_READONLY, 0, length, 0); - if (!handle) break; - map = (void *) MapViewOfFile(handle, FILE_MAP_READ, 0, 0, length); - CloseHandle(handle); - break; - } - case PROT_WRITE: - { - handle = CreateFileMapping((HANDLE) _get_osfhandle(fd), 0, PAGE_READWRITE, 0, length, 0); - if (!handle) break; - map = (void *) MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, length); - CloseHandle(handle); - break; - } - case PROT_READWRITE: - { - handle = CreateFileMapping((HANDLE) _get_osfhandle(fd), 0, PAGE_READWRITE, 0, length, 0); - if (!handle) break; - map = (void *) MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, length); - CloseHandle(handle); - break; - } + case PROT_READ: { + handle = CreateFileMapping((HANDLE) _get_osfhandle(fd), 0, PAGE_READONLY, 0, length, 0); + if (!handle) break; + map = (void *) MapViewOfFile(handle, FILE_MAP_READ, 0, 0, length); + CloseHandle(handle); + break; + } + case PROT_WRITE: { + handle = CreateFileMapping((HANDLE) _get_osfhandle(fd), 0, PAGE_READWRITE, 0, length, 0); + if (!handle) break; + map = (void *) MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, length); + CloseHandle(handle); + break; + } + case PROT_READWRITE: { + handle = CreateFileMapping((HANDLE) _get_osfhandle(fd), 0, PAGE_READWRITE, 0, length, 0); + if (!handle) break; + map = (void *) MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, length); + CloseHandle(handle); + break; + } } if (map == (void *) NULL) { return (void *) MAP_FAILED; } return (void *) ((char *) map + offset); } -static int ucl_munmap(void *map,size_t length) +static int ucl_munmap(void *map, size_t length) { if (!UnmapViewOfFile(map)) { - return(-1); + return (-1); } - return(0); + return (0); } -static char* ucl_realpath(const char *path, char *resolved_path) +static char *ucl_realpath(const char *path, char *resolved_path) { char *p; char tmp[MAX_PATH + 1]; - strncpy(tmp, path, sizeof(tmp)-1); + strncpy(tmp, path, sizeof(tmp) - 1); p = tmp; - while(*p) { + while (*p) { if (*p == '/') *p = '\\'; p++; } return _fullpath(resolved_path, tmp, MAX_PATH); } char *dirname(char *path) { static char path_buffer[_MAX_PATH]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; - _splitpath (path, drive, dir, fname, ext); + _splitpath(path, drive, dir, fname, ext); _makepath(path_buffer, drive, dir, NULL, NULL); return path_buffer; } char *basename(char *path) { static char path_buffer[_MAX_PATH]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath(path, drive, dir, fname, ext); _makepath(path_buffer, NULL, NULL, fname, ext); return path_buffer; } #else #define ucl_mmap mmap #define ucl_munmap munmap #define ucl_realpath realpath #endif -typedef void (*ucl_object_dtor) (ucl_object_t *obj); -static void ucl_object_free_internal (ucl_object_t *obj, bool allow_rec, - ucl_object_dtor dtor); -static void ucl_object_dtor_unref (ucl_object_t *obj); +typedef void (*ucl_object_dtor)(ucl_object_t *obj); +static void ucl_object_free_internal(ucl_object_t *obj, bool allow_rec, + ucl_object_dtor dtor); +static void ucl_object_dtor_unref(ucl_object_t *obj); static void -ucl_object_dtor_free (ucl_object_t *obj) +ucl_object_dtor_free(ucl_object_t *obj) { if (obj->trash_stack[UCL_TRASH_KEY] != NULL) { - UCL_FREE (obj->hh.keylen, obj->trash_stack[UCL_TRASH_KEY]); + UCL_FREE(obj->hh.keylen, obj->trash_stack[UCL_TRASH_KEY]); } if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) { - UCL_FREE (obj->len, obj->trash_stack[UCL_TRASH_VALUE]); + UCL_FREE(obj->len, obj->trash_stack[UCL_TRASH_VALUE]); } /* Do not free ephemeral objects */ if ((obj->flags & UCL_OBJECT_EPHEMERAL) == 0) { if (obj->type != UCL_USERDATA) { - UCL_FREE (sizeof (ucl_object_t), obj); + UCL_FREE(sizeof(ucl_object_t), obj); } else { - struct ucl_object_userdata *ud = (struct ucl_object_userdata *)obj; + struct ucl_object_userdata *ud = (struct ucl_object_userdata *) obj; if (ud->dtor) { - ud->dtor (obj->value.ud); + ud->dtor(obj->value.ud); } - UCL_FREE (sizeof (*ud), obj); + UCL_FREE(sizeof(*ud), obj); } } } /* * This is a helper function that performs exactly the same as * `ucl_object_unref` but it doesn't iterate over elements allowing * to use it for individual elements of arrays and multiple values */ static void -ucl_object_dtor_unref_single (ucl_object_t *obj) +ucl_object_dtor_unref_single(ucl_object_t *obj) { if (obj != NULL) { #ifdef HAVE_ATOMIC_BUILTINS - unsigned int rc = __sync_sub_and_fetch (&obj->ref, 1); + unsigned int rc = __sync_sub_and_fetch(&obj->ref, 1); if (rc == 0) { #else if (--obj->ref == 0) { #endif - ucl_object_free_internal (obj, false, ucl_object_dtor_unref); + ucl_object_free_internal(obj, false, ucl_object_dtor_unref); } } } static void -ucl_object_dtor_unref (ucl_object_t *obj) +ucl_object_dtor_unref(ucl_object_t *obj) { if (obj->ref == 0) { - ucl_object_dtor_free (obj); + ucl_object_dtor_free(obj); } else { /* This may cause dtor unref being called one more time */ - ucl_object_dtor_unref_single (obj); + ucl_object_dtor_unref_single(obj); } } static void -ucl_object_free_internal (ucl_object_t *obj, bool allow_rec, ucl_object_dtor dtor) +ucl_object_free_internal(ucl_object_t *obj, bool allow_rec, ucl_object_dtor dtor) { ucl_object_t *tmp, *sub; while (obj != NULL) { if (obj->type == UCL_ARRAY) { - UCL_ARRAY_GET (vec, obj); + UCL_ARRAY_GET(vec, obj); unsigned int i; if (vec != NULL) { - for (i = 0; i < vec->n; i ++) { - sub = kv_A (*vec, i); + for (i = 0; i < vec->n; i++) { + sub = kv_A(*vec, i); if (sub != NULL) { tmp = sub; while (sub) { tmp = sub->next; - dtor (sub); + dtor(sub); sub = tmp; } } } - kv_destroy (*vec); - UCL_FREE (sizeof (*vec), vec); + kv_destroy(*vec); + UCL_FREE(sizeof(*vec), vec); } obj->value.av = NULL; } else if (obj->type == UCL_OBJECT) { if (obj->value.ov != NULL) { - ucl_hash_destroy (obj->value.ov, (ucl_hash_free_func)dtor); + ucl_hash_destroy(obj->value.ov, (ucl_hash_free_func) dtor); } obj->value.ov = NULL; } tmp = obj->next; - dtor (obj); + dtor(obj); obj = tmp; if (!allow_rec) { break; } } } -void -ucl_object_free (ucl_object_t *obj) +void ucl_object_free(ucl_object_t *obj) { - ucl_object_free_internal (obj, true, ucl_object_dtor_free); + ucl_object_free_internal(obj, true, ucl_object_dtor_free); } size_t -ucl_unescape_json_string (char *str, size_t len) +ucl_unescape_json_string(char *str, size_t len) { char *t = str, *h = str; int i, uval; if (len <= 1) { return len; } /* t is target (tortoise), h is source (hare) */ while (len) { if (*h == '\\') { - h ++; + h++; if (len == 1) { /* * If \ is last, then do not try to go further * Issue: #74 */ - len --; + len--; *t++ = '\\'; continue; } switch (*h) { case 'n': *t++ = '\n'; break; case 'r': *t++ = '\r'; break; case 'b': *t++ = '\b'; break; case 't': *t++ = '\t'; break; case 'f': *t++ = '\f'; break; case '\\': *t++ = '\\'; break; case '"': *t++ = '"'; break; case 'u': /* Unicode escape */ uval = 0; - h ++; /* u character */ - len --; + h++; /* u character */ + len--; if (len > 3) { for (i = 0; i < 4; i++) { uval <<= 4; - if (isdigit (h[i])) { + if (isdigit(h[i])) { uval += h[i] - '0'; } else if (h[i] >= 'a' && h[i] <= 'f') { uval += h[i] - 'a' + 10; } else if (h[i] >= 'A' && h[i] <= 'F') { uval += h[i] - 'A' + 10; } else { break; } } /* Encode */ - if(uval < 0x80) { - t[0] = (char)uval; - t ++; + if (uval < 0x80) { + t[0] = (char) uval; + t++; } - else if(uval < 0x800) { + else if (uval < 0x800) { t[0] = 0xC0 + ((uval & 0x7C0) >> 6); t[1] = 0x80 + ((uval & 0x03F)); t += 2; } - else if(uval < 0x10000) { + else if (uval < 0x10000) { t[0] = 0xE0 + ((uval & 0xF000) >> 12); t[1] = 0x80 + ((uval & 0x0FC0) >> 6); t[2] = 0x80 + ((uval & 0x003F)); t += 3; } #if 0 /* It's not actually supported now */ else if(uval <= 0x10FFFF) { t[0] = 0xF0 + ((uval & 0x1C0000) >> 18); t[1] = 0x80 + ((uval & 0x03F000) >> 12); t[2] = 0x80 + ((uval & 0x000FC0) >> 6); t[3] = 0x80 + ((uval & 0x00003F)); t += 4; } #endif else { *t++ = '?'; } /* Consume 4 characters of source */ h += 4; len -= 4; if (len > 0) { - len --; /* for '\' character */ + len--; /* for '\' character */ } continue; } else { *t++ = 'u'; } break; default: *t++ = *h; break; } - h ++; - len --; + h++; + len--; } else { *t++ = *h++; } if (len > 0) { - len --; + len--; } } *t = '\0'; return (t - str); } size_t -ucl_unescape_squoted_string (char *str, size_t len) +ucl_unescape_squoted_string(char *str, size_t len) { char *t = str, *h = str; if (len <= 1) { return len; } /* t is target (tortoise), h is source (hare) */ while (len) { if (*h == '\\') { - h ++; + h++; if (len == 1) { /* * If \ is last, then do not try to go further * Issue: #74 */ - len --; + len--; *t++ = '\\'; continue; } switch (*h) { case '\'': *t++ = '\''; break; case '\n': /* Ignore \ style stuff */ break; case '\r': /* Ignore \r and the following \n if needed */ if (len > 1 && h[1] == '\n') { - h ++; - len --; + h++; + len--; } break; default: /* Ignore \ */ *t++ = '\\'; *t++ = *h; break; } - h ++; - len --; + h++; + len--; } else { *t++ = *h++; } if (len > 0) { - len --; + len--; } } *t = '\0'; return (t - str); } char * -ucl_copy_key_trash (const ucl_object_t *obj) +ucl_copy_key_trash(const ucl_object_t *obj) { ucl_object_t *deconst; if (obj == NULL) { return NULL; } if (obj->trash_stack[UCL_TRASH_KEY] == NULL && obj->key != NULL) { - deconst = __DECONST (ucl_object_t *, obj); - deconst->trash_stack[UCL_TRASH_KEY] = malloc (obj->keylen + 1); + deconst = __DECONST(ucl_object_t *, obj); + deconst->trash_stack[UCL_TRASH_KEY] = malloc(obj->keylen + 1); if (deconst->trash_stack[UCL_TRASH_KEY] != NULL) { - memcpy (deconst->trash_stack[UCL_TRASH_KEY], obj->key, obj->keylen); + memcpy(deconst->trash_stack[UCL_TRASH_KEY], obj->key, obj->keylen); deconst->trash_stack[UCL_TRASH_KEY][obj->keylen] = '\0'; } deconst->key = obj->trash_stack[UCL_TRASH_KEY]; deconst->flags |= UCL_OBJECT_ALLOCATED_KEY; } return obj->trash_stack[UCL_TRASH_KEY]; } -void -ucl_chunk_free (struct ucl_chunk *chunk) +void ucl_chunk_free(struct ucl_chunk *chunk) { if (chunk) { struct ucl_parser_special_handler_chain *chain, *tmp; - LL_FOREACH_SAFE (chunk->special_handlers, chain, tmp) { + LL_FOREACH_SAFE(chunk->special_handlers, chain, tmp) + { if (chain->special_handler->free_function) { - chain->special_handler->free_function ( - chain->begin, - chain->len, - chain->special_handler->user_data); - } else { - UCL_FREE (chain->len, chain->begin); + chain->special_handler->free_function( + chain->begin, + chain->len, + chain->special_handler->user_data); + } + else { + UCL_FREE(chain->len, chain->begin); } - UCL_FREE (sizeof (*chain), chain); + UCL_FREE(sizeof(*chain), chain); } chunk->special_handlers = NULL; if (chunk->fname) { - free (chunk->fname); + free(chunk->fname); } - UCL_FREE (sizeof (*chunk), chunk); + UCL_FREE(sizeof(*chunk), chunk); } } char * -ucl_copy_value_trash (const ucl_object_t *obj) +ucl_copy_value_trash(const ucl_object_t *obj) { ucl_object_t *deconst; if (obj == NULL) { return NULL; } if (obj->trash_stack[UCL_TRASH_VALUE] == NULL) { - deconst = __DECONST (ucl_object_t *, obj); + deconst = __DECONST(ucl_object_t *, obj); if (obj->type == UCL_STRING) { /* Special case for strings */ if (obj->flags & UCL_OBJECT_BINARY) { - deconst->trash_stack[UCL_TRASH_VALUE] = malloc (obj->len); + deconst->trash_stack[UCL_TRASH_VALUE] = malloc(obj->len); if (deconst->trash_stack[UCL_TRASH_VALUE] != NULL) { - memcpy (deconst->trash_stack[UCL_TRASH_VALUE], - obj->value.sv, - obj->len); + memcpy(deconst->trash_stack[UCL_TRASH_VALUE], + obj->value.sv, + obj->len); deconst->value.sv = obj->trash_stack[UCL_TRASH_VALUE]; } } else { - deconst->trash_stack[UCL_TRASH_VALUE] = malloc (obj->len + 1); + deconst->trash_stack[UCL_TRASH_VALUE] = malloc(obj->len + 1); if (deconst->trash_stack[UCL_TRASH_VALUE] != NULL) { - memcpy (deconst->trash_stack[UCL_TRASH_VALUE], - obj->value.sv, - obj->len); + memcpy(deconst->trash_stack[UCL_TRASH_VALUE], + obj->value.sv, + obj->len); deconst->trash_stack[UCL_TRASH_VALUE][obj->len] = '\0'; deconst->value.sv = obj->trash_stack[UCL_TRASH_VALUE]; } } } else { /* Just emit value in json notation */ - deconst->trash_stack[UCL_TRASH_VALUE] = ucl_object_emit_single_json (obj); - deconst->len = strlen (obj->trash_stack[UCL_TRASH_VALUE]); + deconst->trash_stack[UCL_TRASH_VALUE] = ucl_object_emit_single_json(obj); + deconst->len = strlen(obj->trash_stack[UCL_TRASH_VALUE]); } deconst->flags |= UCL_OBJECT_ALLOCATED_VALUE; } return obj->trash_stack[UCL_TRASH_VALUE]; } -ucl_object_t* -ucl_parser_get_object (struct ucl_parser *parser) +ucl_object_t * +ucl_parser_get_object(struct ucl_parser *parser) { if (parser->state != UCL_STATE_ERROR && parser->top_obj != NULL) { - return ucl_object_ref (parser->top_obj); + return ucl_object_ref(parser->top_obj); } return NULL; } -void -ucl_parser_free (struct ucl_parser *parser) +void ucl_parser_free(struct ucl_parser *parser) { struct ucl_stack *stack, *stmp; struct ucl_macro *macro, *mtmp; struct ucl_chunk *chunk, *ctmp; struct ucl_pubkey *key, *ktmp; struct ucl_variable *var, *vtmp; ucl_object_t *tr, *trtmp; if (parser == NULL) { return; } if (parser->top_obj != NULL) { - ucl_object_unref (parser->top_obj); + ucl_object_unref(parser->top_obj); } if (parser->includepaths != NULL) { - ucl_object_unref (parser->includepaths); + ucl_object_unref(parser->includepaths); } - LL_FOREACH_SAFE (parser->stack, stack, stmp) { - free (stack); + LL_FOREACH_SAFE(parser->stack, stack, stmp) + { + free(stack); } - HASH_ITER (hh, parser->macroes, macro, mtmp) { - free (macro->name); - HASH_DEL (parser->macroes, macro); - UCL_FREE (sizeof (struct ucl_macro), macro); + HASH_ITER(hh, parser->macroes, macro, mtmp) + { + free(macro->name); + HASH_DEL(parser->macroes, macro); + UCL_FREE(sizeof(struct ucl_macro), macro); } - LL_FOREACH_SAFE (parser->chunks, chunk, ctmp) { - ucl_chunk_free (chunk); + LL_FOREACH_SAFE(parser->chunks, chunk, ctmp) + { + ucl_chunk_free(chunk); } - LL_FOREACH_SAFE (parser->keys, key, ktmp) { - UCL_FREE (sizeof (struct ucl_pubkey), key); + LL_FOREACH_SAFE(parser->keys, key, ktmp) + { + UCL_FREE(sizeof(struct ucl_pubkey), key); } - LL_FOREACH_SAFE (parser->variables, var, vtmp) { - free (var->value); - free (var->var); - UCL_FREE (sizeof (struct ucl_variable), var); + LL_FOREACH_SAFE(parser->variables, var, vtmp) + { + free(var->value); + free(var->var); + UCL_FREE(sizeof(struct ucl_variable), var); } - LL_FOREACH_SAFE (parser->trash_objs, tr, trtmp) { - ucl_object_free_internal (tr, false, ucl_object_dtor_free); + LL_FOREACH_SAFE(parser->trash_objs, tr, trtmp) + { + ucl_object_free_internal(tr, false, ucl_object_dtor_free); } if (parser->err != NULL) { - utstring_free (parser->err); + utstring_free(parser->err); } if (parser->cur_file) { - free (parser->cur_file); + UCL_FREE(strlen(parser->cur_file) + 1, parser->cur_file); } if (parser->comments) { - ucl_object_unref (parser->comments); + ucl_object_unref(parser->comments); } - UCL_FREE (sizeof (struct ucl_parser), parser); + UCL_FREE(sizeof(struct ucl_parser), parser); } const char * ucl_parser_get_error(struct ucl_parser *parser) { if (parser == NULL) { return NULL; } if (parser->err == NULL) { return NULL; } - return utstring_body (parser->err); + return utstring_body(parser->err); } -int -ucl_parser_get_error_code(struct ucl_parser *parser) +int ucl_parser_get_error_code(struct ucl_parser *parser) { if (parser == NULL) { return 0; } return parser->err_code; } unsigned ucl_parser_get_column(struct ucl_parser *parser) { if (parser == NULL || parser->chunks == NULL) { return 0; } return parser->chunks->column; } unsigned ucl_parser_get_linenum(struct ucl_parser *parser) { if (parser == NULL || parser->chunks == NULL) { return 0; } return parser->chunks->line; } -void -ucl_parser_clear_error(struct ucl_parser *parser) +void ucl_parser_clear_error(struct ucl_parser *parser) { if (parser != NULL && parser->err != NULL) { utstring_free(parser->err); parser->err = NULL; parser->err_code = 0; } } -bool -ucl_pubkey_add (struct ucl_parser *parser, const unsigned char *key, size_t len) +bool ucl_pubkey_add(struct ucl_parser *parser, const unsigned char *key, size_t len) { #ifndef HAVE_OPENSSL - ucl_create_err (&parser->err, "cannot check signatures without openssl"); + ucl_create_err(&parser->err, "cannot check signatures without openssl"); return false; #else -# if (OPENSSL_VERSION_NUMBER < 0x10000000L) - ucl_create_err (&parser->err, "cannot check signatures, openssl version is unsupported"); +#if (OPENSSL_VERSION_NUMBER < 0x10000000L) + ucl_create_err(&parser->err, "cannot check signatures, openssl version is unsupported"); return EXIT_FAILURE; -# else +#else struct ucl_pubkey *nkey; BIO *mem; - mem = BIO_new_mem_buf ((void *)key, len); - nkey = UCL_ALLOC (sizeof (struct ucl_pubkey)); + mem = BIO_new_mem_buf((void *) key, len); + nkey = UCL_ALLOC(sizeof(struct ucl_pubkey)); if (nkey == NULL) { - ucl_create_err (&parser->err, "cannot allocate memory for key"); + ucl_create_err(&parser->err, "cannot allocate memory for key"); return false; } - nkey->key = PEM_read_bio_PUBKEY (mem, &nkey->key, NULL, NULL); - BIO_free (mem); + nkey->key = PEM_read_bio_PUBKEY(mem, &nkey->key, NULL, NULL); + BIO_free(mem); if (nkey->key == NULL) { - UCL_FREE (sizeof (struct ucl_pubkey), nkey); - ucl_create_err (&parser->err, "%s", - ERR_error_string (ERR_get_error (), NULL)); + UCL_FREE(sizeof(struct ucl_pubkey), nkey); + ucl_create_err(&parser->err, "%s", + ERR_error_string(ERR_get_error(), NULL)); return false; } - LL_PREPEND (parser->keys, nkey); -# endif + LL_PREPEND(parser->keys, nkey); +#endif #endif return true; } -void ucl_parser_add_special_handler (struct ucl_parser *parser, - struct ucl_parser_special_handler *handler) +void ucl_parser_add_special_handler(struct ucl_parser *parser, + struct ucl_parser_special_handler *handler) { - LL_APPEND (parser->special_handlers, handler); + LL_APPEND(parser->special_handlers, handler); } #ifdef CURL_FOUND struct ucl_curl_cbdata { unsigned char *buf; size_t buflen; }; static size_t -ucl_curl_write_callback (void* contents, size_t size, size_t nmemb, void* ud) +ucl_curl_write_callback(void *contents, size_t size, size_t nmemb, void *ud) { struct ucl_curl_cbdata *cbdata = ud; size_t realsize = size * nmemb; - cbdata->buf = realloc (cbdata->buf, cbdata->buflen + realsize + 1); + cbdata->buf = realloc(cbdata->buf, cbdata->buflen + realsize + 1); if (cbdata->buf == NULL) { return 0; } - memcpy (&(cbdata->buf[cbdata->buflen]), contents, realsize); + memcpy(&(cbdata->buf[cbdata->buflen]), contents, realsize); cbdata->buflen += realsize; cbdata->buf[cbdata->buflen] = 0; return realsize; } #endif /** * Fetch a url and save results to the memory buffer * @param url url to fetch * @param len length of url * @param buf target buffer * @param buflen target length * @return */ -bool -ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen, - UT_string **err, bool must_exist) +bool ucl_fetch_url(const unsigned char *url, unsigned char **buf, size_t *buflen, + UT_string **err, bool must_exist) { #ifdef HAVE_FETCH_H struct url *fetch_url; struct url_stat us; FILE *in; - fetch_url = fetchParseURL (url); + fetch_url = fetchParseURL(url); if (fetch_url == NULL) { - ucl_create_err (err, "invalid URL %s: %s", - url, strerror (errno)); + ucl_create_err(err, "invalid URL %s: %s", + url, strerror(errno)); return false; } - if ((in = fetchXGet (fetch_url, &us, "")) == NULL) { + if ((in = fetchXGet(fetch_url, &us, "")) == NULL) { if (!must_exist) { - ucl_create_err (err, "cannot fetch URL %s: %s", - url, strerror (errno)); + ucl_create_err(err, "cannot fetch URL %s: %s", + url, strerror(errno)); } - fetchFreeURL (fetch_url); + fetchFreeURL(fetch_url); return false; } *buflen = us.size; - *buf = malloc (*buflen); + *buf = malloc(*buflen); if (*buf == NULL) { - ucl_create_err (err, "cannot allocate buffer for URL %s: %s", - url, strerror (errno)); - fclose (in); - fetchFreeURL (fetch_url); + ucl_create_err(err, "cannot allocate buffer for URL %s: %s", + url, strerror(errno)); + fclose(in); + fetchFreeURL(fetch_url); return false; } - if (fread (*buf, *buflen, 1, in) != 1) { - ucl_create_err (err, "cannot read URL %s: %s", - url, strerror (errno)); - fclose (in); - fetchFreeURL (fetch_url); + if (fread(*buf, *buflen, 1, in) != 1) { + ucl_create_err(err, "cannot read URL %s: %s", + url, strerror(errno)); + fclose(in); + fetchFreeURL(fetch_url); return false; } - fetchFreeURL (fetch_url); + fetchFreeURL(fetch_url); return true; #elif defined(CURL_FOUND) CURL *curl; int r; struct ucl_curl_cbdata cbdata; - curl = curl_easy_init (); + curl = curl_easy_init(); if (curl == NULL) { - ucl_create_err (err, "CURL interface is broken"); + ucl_create_err(err, "CURL interface is broken"); return false; } - if ((r = curl_easy_setopt (curl, CURLOPT_URL, url)) != CURLE_OK) { - ucl_create_err (err, "invalid URL %s: %s", - url, curl_easy_strerror (r)); - curl_easy_cleanup (curl); + if ((r = curl_easy_setopt(curl, CURLOPT_URL, url)) != CURLE_OK) { + ucl_create_err(err, "invalid URL %s: %s", + url, curl_easy_strerror(r)); + curl_easy_cleanup(curl); return false; } - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ucl_curl_write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ucl_curl_write_callback); cbdata.buf = NULL; cbdata.buflen = 0; - curl_easy_setopt (curl, CURLOPT_WRITEDATA, &cbdata); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &cbdata); - if ((r = curl_easy_perform (curl)) != CURLE_OK) { + if ((r = curl_easy_perform(curl)) != CURLE_OK) { if (!must_exist) { - ucl_create_err (err, "error fetching URL %s: %s", - url, curl_easy_strerror (r)); + ucl_create_err(err, "error fetching URL %s: %s", + url, curl_easy_strerror(r)); } - curl_easy_cleanup (curl); + curl_easy_cleanup(curl); if (cbdata.buf) { - free (cbdata.buf); + free(cbdata.buf); } return false; } *buf = cbdata.buf; *buflen = cbdata.buflen; - curl_easy_cleanup (curl); + curl_easy_cleanup(curl); return true; #else - ucl_create_err (err, "URL support is disabled"); + ucl_create_err(err, "URL support is disabled"); return false; #endif } /** * Fetch a file and save results to the memory buffer * @param filename filename to fetch * @param len length of filename * @param buf target buffer * @param buflen target length * @return */ -bool -ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *buflen, - UT_string **err, bool must_exist) +bool ucl_fetch_file(const unsigned char *filename, unsigned char **buf, size_t *buflen, + UT_string **err, bool must_exist) { int fd; struct stat st; - if ((fd = open (filename, O_RDONLY)) == -1) { - ucl_create_err (err, "cannot open file %s: %s", - filename, strerror (errno)); + if ((fd = open(filename, O_RDONLY)) == -1) { + ucl_create_err(err, "cannot open file %s: %s", + filename, strerror(errno)); return false; } - if (fstat (fd, &st) == -1) { + if (fstat(fd, &st) == -1) { if (must_exist || errno == EPERM) { - ucl_create_err (err, "cannot stat file %s: %s", - filename, strerror (errno)); + ucl_create_err(err, "cannot stat file %s: %s", + filename, strerror(errno)); } - close (fd); + close(fd); return false; } - if (!S_ISREG (st.st_mode)) { + if (!S_ISREG(st.st_mode)) { if (must_exist) { - ucl_create_err (err, "file %s is not a regular file", filename); + ucl_create_err(err, "file %s is not a regular file", filename); } - close (fd); + close(fd); return false; } if (st.st_size == 0) { /* Do not map empty files */ *buf = NULL; *buflen = 0; } else { if ((*buf = ucl_mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { close(fd); ucl_create_err(err, "cannot mmap file %s: %s", - filename, strerror(errno)); + filename, strerror(errno)); *buf = NULL; return false; } *buflen = st.st_size; } - close (fd); + close(fd); return true; } #if (defined(HAVE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10000000L) static inline bool -ucl_sig_check (const unsigned char *data, size_t datalen, - const unsigned char *sig, size_t siglen, struct ucl_parser *parser) +ucl_sig_check(const unsigned char *data, size_t datalen, + const unsigned char *sig, size_t siglen, struct ucl_parser *parser) { struct ucl_pubkey *key; char dig[EVP_MAX_MD_SIZE]; unsigned int diglen; EVP_PKEY_CTX *key_ctx; EVP_MD_CTX *sign_ctx = NULL; - sign_ctx = EVP_MD_CTX_create (); + sign_ctx = EVP_MD_CTX_create(); - LL_FOREACH (parser->keys, key) { - key_ctx = EVP_PKEY_CTX_new (key->key, NULL); + LL_FOREACH(parser->keys, key) + { + key_ctx = EVP_PKEY_CTX_new(key->key, NULL); if (key_ctx != NULL) { - if (EVP_PKEY_verify_init (key_ctx) <= 0) { - EVP_PKEY_CTX_free (key_ctx); + if (EVP_PKEY_verify_init(key_ctx) <= 0) { + EVP_PKEY_CTX_free(key_ctx); continue; } - if (EVP_PKEY_CTX_set_rsa_padding (key_ctx, RSA_PKCS1_PADDING) <= 0) { - EVP_PKEY_CTX_free (key_ctx); + if (EVP_PKEY_CTX_set_rsa_padding(key_ctx, RSA_PKCS1_PADDING) <= 0) { + EVP_PKEY_CTX_free(key_ctx); continue; } - if (EVP_PKEY_CTX_set_signature_md (key_ctx, EVP_sha256 ()) <= 0) { - EVP_PKEY_CTX_free (key_ctx); + if (EVP_PKEY_CTX_set_signature_md(key_ctx, EVP_sha256()) <= 0) { + EVP_PKEY_CTX_free(key_ctx); continue; } - EVP_DigestInit (sign_ctx, EVP_sha256 ()); - EVP_DigestUpdate (sign_ctx, data, datalen); - EVP_DigestFinal (sign_ctx, dig, &diglen); + EVP_DigestInit(sign_ctx, EVP_sha256()); + EVP_DigestUpdate(sign_ctx, data, datalen); + EVP_DigestFinal(sign_ctx, dig, &diglen); - if (EVP_PKEY_verify (key_ctx, sig, siglen, dig, diglen) == 1) { - EVP_MD_CTX_destroy (sign_ctx); - EVP_PKEY_CTX_free (key_ctx); + if (EVP_PKEY_verify(key_ctx, sig, siglen, dig, diglen) == 1) { + EVP_MD_CTX_destroy(sign_ctx); + EVP_PKEY_CTX_free(key_ctx); return true; } - EVP_PKEY_CTX_free (key_ctx); + EVP_PKEY_CTX_free(key_ctx); } } - EVP_MD_CTX_destroy (sign_ctx); + EVP_MD_CTX_destroy(sign_ctx); return false; } #endif struct ucl_include_params { bool check_signature; bool must_exist; bool use_glob; bool use_prefix; bool soft_fail; bool allow_glob; unsigned priority; enum ucl_duplicate_strategy strat; enum ucl_parse_type parse_type; const char *prefix; const char *target; }; /** * Include an url to configuration * @param data * @param len * @param parser * @param err * @return */ static bool -ucl_include_url (const unsigned char *data, size_t len, - struct ucl_parser *parser, - struct ucl_include_params *params) +ucl_include_url(const unsigned char *data, size_t len, + struct ucl_parser *parser, + struct ucl_include_params *params) { bool res; unsigned char *buf = NULL; size_t buflen = 0; struct ucl_chunk *chunk; char urlbuf[PATH_MAX]; int prev_state; - snprintf (urlbuf, sizeof (urlbuf), "%.*s", (int)len, data); + snprintf(urlbuf, sizeof(urlbuf), "%.*s", (int) len, data); - if (!ucl_fetch_url (urlbuf, &buf, &buflen, &parser->err, params->must_exist)) { + if (!ucl_fetch_url(urlbuf, &buf, &buflen, &parser->err, params->must_exist)) { if (!params->must_exist) { - ucl_parser_clear_error (parser); + ucl_parser_clear_error(parser); } return !params->must_exist; } if (params->check_signature) { #if (defined(HAVE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10000000L) unsigned char *sigbuf = NULL; size_t siglen = 0; /* We need to check signature first */ - snprintf (urlbuf, sizeof (urlbuf), "%.*s.sig", (int)len, data); - if (!ucl_fetch_url (urlbuf, &sigbuf, &siglen, &parser->err, true)) { + snprintf(urlbuf, sizeof(urlbuf), "%.*s.sig", (int) len, data); + if (!ucl_fetch_url(urlbuf, &sigbuf, &siglen, &parser->err, true)) { return false; } - if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) { - ucl_create_err (&parser->err, "cannot verify url %s: %s", - urlbuf, - ERR_error_string (ERR_get_error (), NULL)); + if (!ucl_sig_check(buf, buflen, sigbuf, siglen, parser)) { + ucl_create_err(&parser->err, "cannot verify url %s: %s", + urlbuf, + ERR_error_string(ERR_get_error(), NULL)); if (siglen > 0) { - ucl_munmap (sigbuf, siglen); + free(sigbuf); } return false; } if (siglen > 0) { - ucl_munmap (sigbuf, siglen); + free(sigbuf); } #endif } prev_state = parser->state; parser->state = UCL_STATE_INIT; - res = ucl_parser_add_chunk_full (parser, buf, buflen, params->priority, - params->strat, params->parse_type); + res = ucl_parser_add_chunk_full(parser, buf, buflen, params->priority, + params->strat, params->parse_type); if (res == true) { /* Remove chunk from the stack */ chunk = parser->chunks; if (chunk != NULL) { parser->chunks = chunk->next; - ucl_chunk_free (chunk); + ucl_chunk_free(chunk); } } parser->state = prev_state; - free (buf); + free(buf); return res; } /** * Include a single file to the parser * @param data * @param len * @param parser * @param check_signature * @param must_exist * @param allow_glob * @param priority * @return */ static bool -ucl_include_file_single (const unsigned char *data, size_t len, - struct ucl_parser *parser, struct ucl_include_params *params) +ucl_include_file_single(const unsigned char *data, size_t len, + struct ucl_parser *parser, struct ucl_include_params *params) { bool res; struct ucl_chunk *chunk; unsigned char *buf = NULL; char *old_curfile, *ext; size_t buflen = 0; char filebuf[PATH_MAX], realbuf[PATH_MAX]; int prev_state; struct ucl_variable *cur_var, *tmp_var, *old_curdir = NULL, - *old_filename = NULL; + *old_filename = NULL; ucl_object_t *nest_obj = NULL, *old_obj = NULL, *new_obj = NULL; ucl_hash_t *container = NULL; struct ucl_stack *st = NULL; if (parser->state == UCL_STATE_ERROR) { /* Return immediately if we are in the error state... */ return false; } - snprintf (filebuf, sizeof (filebuf), "%.*s", (int)len, data); - if (ucl_realpath (filebuf, realbuf) == NULL) { + snprintf(filebuf, sizeof(filebuf), "%.*s", (int) len, data); + if (ucl_realpath(filebuf, realbuf) == NULL) { if (params->soft_fail) { return false; } if (!params->must_exist && errno != EPERM) { return true; } - ucl_create_err (&parser->err, "cannot open file %s: %s", - filebuf, - strerror (errno)); + ucl_create_err(&parser->err, "cannot open file %s: %s", + filebuf, + strerror(errno)); return false; } - if (parser->cur_file && strcmp (realbuf, parser->cur_file) == 0) { + if (parser->cur_file && strcmp(realbuf, parser->cur_file) == 0) { /* We are likely including the file itself */ if (params->soft_fail) { return false; } - ucl_create_err (&parser->err, "trying to include the file %s from itself", - realbuf); + ucl_create_err(&parser->err, "trying to include the file %s from itself", + realbuf); return false; } - if (!ucl_fetch_file (realbuf, &buf, &buflen, &parser->err, params->must_exist)) { + if (!ucl_fetch_file(realbuf, &buf, &buflen, &parser->err, params->must_exist)) { if (params->soft_fail) { return false; } if (params->must_exist || parser->err != NULL) { /* The case of fatal errors */ return false; } - ucl_parser_clear_error (parser); + ucl_parser_clear_error(parser); return true; } if (params->check_signature) { #if (defined(HAVE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10000000L) unsigned char *sigbuf = NULL; size_t siglen = 0; /* We need to check signature first */ - snprintf (filebuf, sizeof (filebuf), "%s.sig", realbuf); - if (!ucl_fetch_file (filebuf, &sigbuf, &siglen, &parser->err, true)) { + snprintf(filebuf, sizeof(filebuf), "%s.sig", realbuf); + if (!ucl_fetch_file(filebuf, &sigbuf, &siglen, &parser->err, true)) { if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return false; } - if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) { - ucl_create_err (&parser->err, "cannot verify file %s: %s", - filebuf, - ERR_error_string (ERR_get_error (), NULL)); + if (!ucl_sig_check(buf, buflen, sigbuf, siglen, parser)) { + ucl_create_err(&parser->err, "cannot verify file %s: %s", + filebuf, + ERR_error_string(ERR_get_error(), NULL)); if (sigbuf) { - ucl_munmap (sigbuf, siglen); + ucl_munmap(sigbuf, siglen); } if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return false; } if (sigbuf) { - ucl_munmap (sigbuf, siglen); + ucl_munmap(sigbuf, siglen); } #endif } old_curfile = parser->cur_file; parser->cur_file = NULL; /* Store old file vars */ - DL_FOREACH_SAFE (parser->variables, cur_var, tmp_var) { - if (strcmp (cur_var->var, "CURDIR") == 0) { + DL_FOREACH_SAFE(parser->variables, cur_var, tmp_var) + { + if (strcmp(cur_var->var, "CURDIR") == 0) { old_curdir = cur_var; - DL_DELETE (parser->variables, cur_var); + DL_DELETE(parser->variables, cur_var); } - else if (strcmp (cur_var->var, "FILENAME") == 0) { + else if (strcmp(cur_var->var, "FILENAME") == 0) { old_filename = cur_var; - DL_DELETE (parser->variables, cur_var); + DL_DELETE(parser->variables, cur_var); } } - ucl_parser_set_filevars (parser, realbuf, false); + ucl_parser_set_filevars(parser, realbuf, false); prev_state = parser->state; parser->state = UCL_STATE_INIT; if (params->use_prefix && params->prefix == NULL) { /* Auto generate a key name based on the included filename */ - params->prefix = basename (realbuf); - ext = strrchr (params->prefix, '.'); - if (ext != NULL && (strcmp (ext, ".conf") == 0 || strcmp (ext, ".ucl") == 0)) { + params->prefix = basename(realbuf); + ext = strrchr(params->prefix, '.'); + if (ext != NULL && (strcmp(ext, ".conf") == 0 || strcmp(ext, ".ucl") == 0)) { /* Strip off .conf or .ucl */ *ext = '\0'; } } if (params->prefix != NULL) { /* This is a prefixed include */ container = parser->stack->obj->value.ov; - old_obj = __DECONST (ucl_object_t *, ucl_hash_search (container, - params->prefix, strlen (params->prefix))); + old_obj = __DECONST(ucl_object_t *, ucl_hash_search(container, + params->prefix, strlen(params->prefix))); - if (strcasecmp (params->target, "array") == 0) { + if (strcasecmp(params->target, "array") == 0) { if (old_obj == NULL) { /* Create an array with key: prefix */ - old_obj = ucl_object_new_full (UCL_ARRAY, params->priority); + old_obj = ucl_object_new_full(UCL_ARRAY, params->priority); old_obj->key = params->prefix; - old_obj->keylen = strlen (params->prefix); - ucl_copy_key_trash (old_obj); + old_obj->keylen = strlen(params->prefix); + ucl_copy_key_trash(old_obj); old_obj->prev = old_obj; old_obj->next = NULL; - container = ucl_hash_insert_object (container, old_obj, - parser->flags & UCL_PARSER_KEY_LOWERCASE); + container = ucl_hash_insert_object(container, old_obj, + parser->flags & UCL_PARSER_KEY_LOWERCASE); parser->stack->obj->len++; - nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority); + nest_obj = ucl_object_new_full(UCL_OBJECT, params->priority); nest_obj->prev = nest_obj; nest_obj->next = NULL; - ucl_array_append (old_obj, nest_obj); + ucl_array_append(old_obj, nest_obj); } else { - if (ucl_object_type (old_obj) == UCL_ARRAY) { + if (ucl_object_type(old_obj) == UCL_ARRAY) { /* Append to the existing array */ - nest_obj = ucl_object_new_full (UCL_OBJECT, - params->priority); + nest_obj = ucl_object_new_full(UCL_OBJECT, + params->priority); if (nest_obj == NULL) { - ucl_create_err (&parser->err, - "cannot allocate memory for an object"); + ucl_create_err(&parser->err, + "cannot allocate memory for an object"); if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return false; } nest_obj->prev = nest_obj; nest_obj->next = NULL; - ucl_array_append (old_obj, nest_obj); + ucl_array_append(old_obj, nest_obj); } else { /* Convert the object to an array */ - new_obj = ucl_object_typed_new (UCL_ARRAY); + new_obj = ucl_object_typed_new(UCL_ARRAY); if (new_obj == NULL) { - ucl_create_err (&parser->err, - "cannot allocate memory for an object"); + ucl_create_err(&parser->err, + "cannot allocate memory for an object"); if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return false; } new_obj->key = old_obj->key; new_obj->keylen = old_obj->keylen; new_obj->flags |= UCL_OBJECT_MULTIVALUE; new_obj->prev = new_obj; new_obj->next = NULL; - nest_obj = ucl_object_new_full (UCL_OBJECT, - params->priority); + nest_obj = ucl_object_new_full(UCL_OBJECT, + params->priority); if (nest_obj == NULL) { - ucl_create_err (&parser->err, - "cannot allocate memory for an object"); + ucl_create_err(&parser->err, + "cannot allocate memory for an object"); if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } - ucl_object_unref (new_obj); + ucl_object_unref(new_obj); return false; } nest_obj->prev = nest_obj; nest_obj->next = NULL; - ucl_array_append (new_obj, old_obj); - ucl_array_append (new_obj, nest_obj); - ucl_hash_replace (container, old_obj, new_obj); + ucl_array_append(new_obj, old_obj); + ucl_array_append(new_obj, nest_obj); + ucl_hash_replace(container, old_obj, new_obj); } } } else { /* Case of object */ if (old_obj == NULL) { /* Create an object with key: prefix */ - nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority); + nest_obj = ucl_object_new_full(UCL_OBJECT, params->priority); if (nest_obj == NULL) { - ucl_create_err (&parser->err, "cannot allocate memory for an object"); + ucl_create_err(&parser->err, "cannot allocate memory for an object"); if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return false; } nest_obj->key = params->prefix; - nest_obj->keylen = strlen (params->prefix); + nest_obj->keylen = strlen(params->prefix); ucl_copy_key_trash(nest_obj); nest_obj->prev = nest_obj; nest_obj->next = NULL; - container = ucl_hash_insert_object (container, nest_obj, - parser->flags & UCL_PARSER_KEY_LOWERCASE); - parser->stack->obj->len ++; + container = ucl_hash_insert_object(container, nest_obj, + parser->flags & UCL_PARSER_KEY_LOWERCASE); + parser->stack->obj->len++; } else { - if (ucl_object_type (old_obj) == UCL_OBJECT) { + if (ucl_object_type(old_obj) == UCL_OBJECT) { /* Append to existing Object*/ nest_obj = old_obj; } else { /* The key is not an object */ - ucl_create_err (&parser->err, - "Conflicting type for key: %s, asked %s, has %s", - params->prefix, params->target, - ucl_object_type_to_string (ucl_object_type (old_obj))); + ucl_create_err(&parser->err, + "Conflicting type for key: %s, asked %s, has %s", + params->prefix, params->target, + ucl_object_type_to_string(ucl_object_type(old_obj))); if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return false; } } } /* Put all of the content of the include inside that object */ parser->stack->obj->value.ov = container; - st = UCL_ALLOC (sizeof (struct ucl_stack)); + st = UCL_ALLOC(sizeof(struct ucl_stack)); if (st == NULL) { - ucl_create_err (&parser->err, "cannot allocate memory for an object"); - ucl_object_unref (nest_obj); + ucl_create_err(&parser->err, "cannot allocate memory for an object"); + ucl_object_unref(nest_obj); if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return false; } st->obj = nest_obj; st->e.params.level = parser->stack->e.params.level; st->e.params.flags = parser->stack->e.params.flags; st->e.params.line = parser->stack->e.params.line; st->chunk = parser->chunks; - LL_PREPEND (parser->stack, st); + LL_PREPEND(parser->stack, st); parser->cur_obj = nest_obj; } - res = ucl_parser_add_chunk_full (parser, buf, buflen, params->priority, - params->strat, params->parse_type); + res = ucl_parser_add_chunk_full(parser, buf, buflen, params->priority, + params->strat, params->parse_type); if (res) { /* Stop nesting the include, take 1 level off the stack */ if (params->prefix != NULL && nest_obj != NULL) { parser->stack = st->next; - UCL_FREE (sizeof (struct ucl_stack), st); + UCL_FREE(sizeof(struct ucl_stack), st); } /* Remove chunk from the stack */ chunk = parser->chunks; if (chunk != NULL) { parser->chunks = chunk->next; - ucl_chunk_free (chunk); + ucl_chunk_free(chunk); parser->recursion--; } /* Restore old file vars */ if (parser->cur_file) { - free (parser->cur_file); + UCL_FREE(strlen(parser->cur_file) + 1, parser->cur_file); } parser->cur_file = old_curfile; - DL_FOREACH_SAFE (parser->variables, cur_var, tmp_var) { - if (strcmp (cur_var->var, "CURDIR") == 0 && old_curdir) { - DL_DELETE (parser->variables, cur_var); - free (cur_var->var); - free (cur_var->value); - UCL_FREE (sizeof (struct ucl_variable), cur_var); - } else if (strcmp (cur_var->var, "FILENAME") == 0 && old_filename) { - DL_DELETE (parser->variables, cur_var); - free (cur_var->var); - free (cur_var->value); - UCL_FREE (sizeof (struct ucl_variable), cur_var); + DL_FOREACH_SAFE(parser->variables, cur_var, tmp_var) + { + if (strcmp(cur_var->var, "CURDIR") == 0 && old_curdir) { + DL_DELETE(parser->variables, cur_var); + free(cur_var->var); + free(cur_var->value); + UCL_FREE(sizeof(struct ucl_variable), cur_var); + } + else if (strcmp(cur_var->var, "FILENAME") == 0 && old_filename) { + DL_DELETE(parser->variables, cur_var); + free(cur_var->var); + free(cur_var->value); + UCL_FREE(sizeof(struct ucl_variable), cur_var); } } if (old_filename) { - DL_APPEND (parser->variables, old_filename); + DL_APPEND(parser->variables, old_filename); } if (old_curdir) { - DL_APPEND (parser->variables, old_curdir); + DL_APPEND(parser->variables, old_curdir); } parser->state = prev_state; } if (buflen > 0) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return res; } /** * Include a file to configuration * @param data * @param len * @param parser * @param err * @return */ static bool -ucl_include_file (const unsigned char *data, size_t len, - struct ucl_parser *parser, - struct ucl_include_params *params, - const ucl_object_t *args) +ucl_include_file(const unsigned char *data, size_t len, + struct ucl_parser *parser, + struct ucl_include_params *params, + const ucl_object_t *args) { const unsigned char *p = data, *end = data + len; bool need_glob = false; int cnt = 0; char glob_pattern[PATH_MAX]; size_t i; #ifndef _WIN32 if (!params->allow_glob) { - return ucl_include_file_single (data, len, parser, params); + return ucl_include_file_single(data, len, parser, params); } else { /* Check for special symbols in a filename */ while (p != end) { if (*p == '*' || *p == '?') { need_glob = true; break; } - p ++; + p++; } if (need_glob) { glob_t globbuf; - memset (&globbuf, 0, sizeof (globbuf)); - ucl_strlcpy (glob_pattern, (const char *)data, - (len + 1 < sizeof (glob_pattern) ? len + 1 : sizeof (glob_pattern))); - if (glob (glob_pattern, 0, NULL, &globbuf) != 0) { + memset(&globbuf, 0, sizeof(globbuf)); + ucl_strlcpy(glob_pattern, (const char *) data, + (len + 1 < sizeof(glob_pattern) ? len + 1 : sizeof(glob_pattern))); + if (glob(glob_pattern, 0, NULL, &globbuf) != 0) { return (!params->must_exist || false); } - for (i = 0; i < globbuf.gl_pathc; i ++) { + for (i = 0; i < globbuf.gl_pathc; i++) { if (parser->include_trace_func) { const ucl_object_t *parent = NULL; if (parser->stack) { parent = parser->stack->obj; } - parser->include_trace_func (parser, parent, NULL, - globbuf.gl_pathv[i], - strlen (globbuf.gl_pathv[i]), - parser->include_trace_ud); + parser->include_trace_func(parser, parent, NULL, + globbuf.gl_pathv[i], + strlen(globbuf.gl_pathv[i]), + parser->include_trace_ud); } - if (!ucl_include_file_single ((unsigned char *)globbuf.gl_pathv[i], - strlen (globbuf.gl_pathv[i]), parser, params)) { + if (!ucl_include_file_single((unsigned char *) globbuf.gl_pathv[i], + strlen(globbuf.gl_pathv[i]), parser, params)) { if (params->soft_fail) { continue; } - globfree (&globbuf); + globfree(&globbuf); return false; } - cnt ++; + cnt++; } - globfree (&globbuf); + globfree(&globbuf); if (cnt == 0 && params->must_exist) { - ucl_create_err (&parser->err, "cannot match any files for pattern %s", - glob_pattern); + ucl_create_err(&parser->err, "cannot match any files for pattern %s", + glob_pattern); return false; } } else { - return ucl_include_file_single (data, len, parser, params); + return ucl_include_file_single(data, len, parser, params); } } #else /* Win32 compilers do not support globbing. Therefore, for Win32, treat allow_glob/need_glob as a NOOP and just return */ - return ucl_include_file_single (data, len, parser, params); + return ucl_include_file_single(data, len, parser, params); #endif return true; } /** * Common function to handle .*include* macros * @param data * @param len * @param args * @param parser * @param default_try * @param default_sign * @return */ static bool -ucl_include_common (const unsigned char *data, size_t len, - const ucl_object_t *args, struct ucl_parser *parser, - bool default_try, - bool default_sign) +ucl_include_common(const unsigned char *data, size_t len, + const ucl_object_t *args, struct ucl_parser *parser, + bool default_try, + bool default_sign) { bool allow_url = false, search = false; const char *duplicate; const ucl_object_t *param; ucl_object_iter_t it = NULL, ip = NULL; char ipath[PATH_MAX]; struct ucl_include_params params; /* Default values */ params.soft_fail = default_try; params.allow_glob = false; params.check_signature = default_sign; params.use_prefix = false; params.target = "object"; params.prefix = NULL; params.priority = 0; params.parse_type = UCL_PARSE_UCL; params.strat = UCL_DUPLICATE_APPEND; params.must_exist = !default_try; if (parser->include_trace_func) { const ucl_object_t *parent = NULL; if (parser->stack) { parent = parser->stack->obj; } - parser->include_trace_func (parser, parent, args, - data, len, parser->include_trace_ud); + parser->include_trace_func(parser, parent, args, + data, len, parser->include_trace_ud); } /* Process arguments */ if (args != NULL && args->type == UCL_OBJECT) { - while ((param = ucl_object_iterate (args, &it, true)) != NULL) { + while ((param = ucl_object_iterate(args, &it, true)) != NULL) { if (param->type == UCL_BOOLEAN) { - if (strncmp (param->key, "try", param->keylen) == 0) { - params.must_exist = !ucl_object_toboolean (param); + if (strncmp(param->key, "try", param->keylen) == 0) { + params.must_exist = !ucl_object_toboolean(param); } - else if (strncmp (param->key, "sign", param->keylen) == 0) { - params.check_signature = ucl_object_toboolean (param); + else if (strncmp(param->key, "sign", param->keylen) == 0) { + params.check_signature = ucl_object_toboolean(param); } - else if (strncmp (param->key, "glob", param->keylen) == 0) { - params.allow_glob = ucl_object_toboolean (param); + else if (strncmp(param->key, "glob", param->keylen) == 0) { + params.allow_glob = ucl_object_toboolean(param); } - else if (strncmp (param->key, "url", param->keylen) == 0) { - allow_url = ucl_object_toboolean (param); + else if (strncmp(param->key, "url", param->keylen) == 0) { + allow_url = ucl_object_toboolean(param); } - else if (strncmp (param->key, "prefix", param->keylen) == 0) { - params.use_prefix = ucl_object_toboolean (param); + else if (strncmp(param->key, "prefix", param->keylen) == 0) { + params.use_prefix = ucl_object_toboolean(param); } } else if (param->type == UCL_STRING) { - if (strncmp (param->key, "key", param->keylen) == 0) { - params.prefix = ucl_object_tostring (param); + if (strncmp(param->key, "key", param->keylen) == 0) { + params.prefix = ucl_object_tostring(param); } - else if (strncmp (param->key, "target", param->keylen) == 0) { - params.target = ucl_object_tostring (param); + else if (strncmp(param->key, "target", param->keylen) == 0) { + params.target = ucl_object_tostring(param); } - else if (strncmp (param->key, "duplicate", param->keylen) == 0) { - duplicate = ucl_object_tostring (param); + else if (strncmp(param->key, "duplicate", param->keylen) == 0) { + duplicate = ucl_object_tostring(param); - if (strcmp (duplicate, "append") == 0) { + if (strcmp(duplicate, "append") == 0) { params.strat = UCL_DUPLICATE_APPEND; } - else if (strcmp (duplicate, "merge") == 0) { + else if (strcmp(duplicate, "merge") == 0) { params.strat = UCL_DUPLICATE_MERGE; } - else if (strcmp (duplicate, "rewrite") == 0) { + else if (strcmp(duplicate, "rewrite") == 0) { params.strat = UCL_DUPLICATE_REWRITE; } - else if (strcmp (duplicate, "error") == 0) { + else if (strcmp(duplicate, "error") == 0) { params.strat = UCL_DUPLICATE_ERROR; } } } else if (param->type == UCL_ARRAY) { - if (strncmp (param->key, "path", param->keylen) == 0) { - ucl_set_include_path (parser, __DECONST(ucl_object_t *, param)); + if (strncmp(param->key, "path", param->keylen) == 0) { + ucl_set_include_path(parser, __DECONST(ucl_object_t *, param)); } } else if (param->type == UCL_INT) { - if (strncmp (param->key, "priority", param->keylen) == 0) { - params.priority = ucl_object_toint (param); + if (strncmp(param->key, "priority", param->keylen) == 0) { + params.priority = ucl_object_toint(param); } } } } if (parser->includepaths == NULL) { - if (allow_url && ucl_strnstr (data, "://", len) != NULL) { + if (allow_url && ucl_strnstr(data, "://", len) != NULL) { /* Globbing is not used for URL's */ - return ucl_include_url (data, len, parser, ¶ms); + return ucl_include_url(data, len, parser, ¶ms); } else if (data != NULL) { /* Try to load a file */ - return ucl_include_file (data, len, parser, ¶ms, args); + return ucl_include_file(data, len, parser, ¶ms, args); } } else { - if (allow_url && ucl_strnstr (data, "://", len) != NULL) { + if (allow_url && ucl_strnstr(data, "://", len) != NULL) { /* Globbing is not used for URL's */ - return ucl_include_url (data, len, parser, ¶ms); + return ucl_include_url(data, len, parser, ¶ms); } - ip = ucl_object_iterate_new (parser->includepaths); - while ((param = ucl_object_iterate_safe (ip, true)) != NULL) { + ip = ucl_object_iterate_new(parser->includepaths); + while ((param = ucl_object_iterate_safe(ip, true)) != NULL) { if (ucl_object_type(param) == UCL_STRING) { - snprintf (ipath, sizeof (ipath), "%s/%.*s", ucl_object_tostring(param), - (int)len, data); - if ((search = ucl_include_file (ipath, strlen (ipath), - parser, ¶ms, args))) { + snprintf(ipath, sizeof(ipath), "%s/%.*s", ucl_object_tostring(param), + (int) len, data); + if ((search = ucl_include_file(ipath, strlen(ipath), + parser, ¶ms, args))) { if (!params.allow_glob) { break; } } } } - ucl_object_iterate_free (ip); + ucl_object_iterate_free(ip); if (search == true) { return true; } else { - ucl_create_err (&parser->err, - "cannot find file: %.*s in search path", - (int)len, data); + ucl_create_err(&parser->err, + "cannot find file: %.*s in search path", + (int) len, data); return false; } } return false; } /** * Handle include macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool -ucl_include_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud) +bool ucl_include_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud) { struct ucl_parser *parser = ud; - return ucl_include_common (data, len, args, parser, false, false); + return ucl_include_common(data, len, args, parser, false, false); } /** * Handle includes macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool -ucl_includes_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud) +bool ucl_includes_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud) { struct ucl_parser *parser = ud; - return ucl_include_common (data, len, args, parser, false, true); + return ucl_include_common(data, len, args, parser, false, true); } /** * Handle tryinclude macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool -ucl_try_include_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud) +bool ucl_try_include_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud) { struct ucl_parser *parser = ud; - return ucl_include_common (data, len, args, parser, true, false); + return ucl_include_common(data, len, args, parser, true, false); } /** * Handle priority macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool -ucl_priority_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud) +bool ucl_priority_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud) { struct ucl_parser *parser = ud; unsigned priority = 255; const ucl_object_t *param; bool found = false; char *value = NULL, *leftover = NULL; ucl_object_iter_t it = NULL; if (parser == NULL) { return false; } /* Process arguments */ if (args != NULL && args->type == UCL_OBJECT) { - while ((param = ucl_object_iterate (args, &it, true)) != NULL) { + while ((param = ucl_object_iterate(args, &it, true)) != NULL) { if (param->type == UCL_INT) { - if (strncmp (param->key, "priority", param->keylen) == 0) { - priority = ucl_object_toint (param); + if (strncmp(param->key, "priority", param->keylen) == 0) { + priority = ucl_object_toint(param); found = true; } } } } if (len > 0) { value = malloc(len + 1); - ucl_strlcpy(value, (const char *)data, len + 1); + ucl_strlcpy(value, (const char *) data, len + 1); priority = strtol(value, &leftover, 10); if (*leftover != '\0') { - ucl_create_err (&parser->err, "Invalid priority value in macro: %s", - value); + ucl_create_err(&parser->err, "Invalid priority value in macro: %s", + value); free(value); return false; } free(value); found = true; } if (found == true) { parser->chunks->priority = priority; return true; } - ucl_create_err (&parser->err, "Unable to parse priority macro"); + ucl_create_err(&parser->err, "Unable to parse priority macro"); return false; } /** * Handle load macro * @param data include data * @param len length of data * @param args UCL object representing arguments to the macro * @param ud user data * @return */ -bool -ucl_load_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, void* ud) +bool ucl_load_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, void *ud) { struct ucl_parser *parser = ud; const ucl_object_t *param; ucl_object_t *obj, *old_obj; ucl_object_iter_t it = NULL; bool try_load, multiline, test; const char *target, *prefix; char *load_file, *tmp; unsigned char *buf; size_t buflen; unsigned priority; int64_t iv; ucl_object_t *container = NULL; enum ucl_string_flags flags; /* Default values */ try_load = false; multiline = false; test = false; target = "string"; prefix = NULL; load_file = NULL; buf = NULL; buflen = 0; priority = 0; obj = NULL; old_obj = NULL; flags = 0; if (parser == NULL) { return false; } /* Process arguments */ if (args != NULL && args->type == UCL_OBJECT) { - while ((param = ucl_object_iterate (args, &it, true)) != NULL) { + while ((param = ucl_object_iterate(args, &it, true)) != NULL) { if (param->type == UCL_BOOLEAN) { - if (strncmp (param->key, "try", param->keylen) == 0) { - try_load = ucl_object_toboolean (param); + if (strncmp(param->key, "try", param->keylen) == 0) { + try_load = ucl_object_toboolean(param); } - else if (strncmp (param->key, "multiline", param->keylen) == 0) { - multiline = ucl_object_toboolean (param); + else if (strncmp(param->key, "multiline", param->keylen) == 0) { + multiline = ucl_object_toboolean(param); } - else if (strncmp (param->key, "escape", param->keylen) == 0) { - test = ucl_object_toboolean (param); + else if (strncmp(param->key, "escape", param->keylen) == 0) { + test = ucl_object_toboolean(param); if (test) { flags |= UCL_STRING_ESCAPE; } } - else if (strncmp (param->key, "trim", param->keylen) == 0) { - test = ucl_object_toboolean (param); + else if (strncmp(param->key, "trim", param->keylen) == 0) { + test = ucl_object_toboolean(param); if (test) { flags |= UCL_STRING_TRIM; } } } else if (param->type == UCL_STRING) { - if (strncmp (param->key, "key", param->keylen) == 0) { - prefix = ucl_object_tostring (param); + if (strncmp(param->key, "key", param->keylen) == 0) { + prefix = ucl_object_tostring(param); } - else if (strncmp (param->key, "target", param->keylen) == 0) { - target = ucl_object_tostring (param); + else if (strncmp(param->key, "target", param->keylen) == 0) { + target = ucl_object_tostring(param); } } else if (param->type == UCL_INT) { - if (strncmp (param->key, "priority", param->keylen) == 0) { - priority = ucl_object_toint (param); + if (strncmp(param->key, "priority", param->keylen) == 0) { + priority = ucl_object_toint(param); } } } } - if (prefix == NULL || strlen (prefix) == 0) { - ucl_create_err (&parser->err, "No Key specified in load macro"); + if (prefix == NULL || strlen(prefix) == 0) { + ucl_create_err(&parser->err, "No Key specified in load macro"); return false; } if (len > 0) { - load_file = malloc (len + 1); + load_file = malloc(len + 1); if (!load_file) { - ucl_create_err (&parser->err, "cannot allocate memory for suffix"); + ucl_create_err(&parser->err, "cannot allocate memory for suffix"); return false; } - snprintf (load_file, len + 1, "%.*s", (int)len, data); + snprintf(load_file, len + 1, "%.*s", (int) len, data); - if (!ucl_fetch_file (load_file, &buf, &buflen, &parser->err, - !try_load)) { - free (load_file); + if (!ucl_fetch_file(load_file, &buf, &buflen, &parser->err, + !try_load)) { + free(load_file); if (try_load) { - ucl_parser_clear_error (parser); + ucl_parser_clear_error(parser); } return (try_load || false); } - free (load_file); + free(load_file); container = parser->stack->obj; - old_obj = __DECONST (ucl_object_t *, ucl_object_lookup (container, - prefix)); + old_obj = __DECONST(ucl_object_t *, ucl_object_lookup(container, + prefix)); if (old_obj != NULL) { - ucl_create_err (&parser->err, "Key %s already exists", prefix); + ucl_create_err(&parser->err, "Key %s already exists", prefix); if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return false; } - if (strcasecmp (target, "string") == 0) { - obj = ucl_object_fromstring_common (buf, buflen, flags); - ucl_copy_value_trash (obj); + if (strcasecmp(target, "string") == 0) { + obj = ucl_object_fromstring_common(buf, buflen, flags); + ucl_copy_value_trash(obj); if (multiline) { obj->flags |= UCL_OBJECT_MULTILINE; } } - else if (strcasecmp (target, "int") == 0) { - tmp = malloc (buflen + 1); + else if (strcasecmp(target, "int") == 0) { + tmp = malloc(buflen + 1); if (tmp == NULL) { - ucl_create_err (&parser->err, "Memory allocation failed"); + ucl_create_err(&parser->err, "Memory allocation failed"); if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } return false; } - snprintf (tmp, buflen + 1, "%.*s", (int)buflen, buf); - iv = strtoll (tmp, NULL, 10); - obj = ucl_object_fromint (iv); - free (tmp); + snprintf(tmp, buflen + 1, "%.*s", (int) buflen, buf); + iv = strtoll(tmp, NULL, 10); + obj = ucl_object_fromint(iv); + free(tmp); } if (buf) { - ucl_munmap (buf, buflen); + ucl_munmap(buf, buflen); } if (obj != NULL) { obj->key = prefix; - obj->keylen = strlen (prefix); - ucl_copy_key_trash (obj); + obj->keylen = strlen(prefix); + ucl_copy_key_trash(obj); obj->prev = obj; obj->next = NULL; - ucl_object_set_priority (obj, priority); - ucl_object_insert_key (container, obj, obj->key, obj->keylen, false); + ucl_object_set_priority(obj, priority); + ucl_object_insert_key(container, obj, obj->key, obj->keylen, false); } return true; } - ucl_create_err (&parser->err, "Unable to parse load macro"); + ucl_create_err(&parser->err, "Unable to parse load macro"); return false; } -bool -ucl_inherit_handler (const unsigned char *data, size_t len, - const ucl_object_t *args, const ucl_object_t *ctx, void* ud) +bool ucl_inherit_handler(const unsigned char *data, size_t len, + const ucl_object_t *args, const ucl_object_t *ctx, void *ud) { const ucl_object_t *parent, *cur; ucl_object_t *target, *copy; ucl_object_iter_t it = NULL; bool replace = false; struct ucl_parser *parser = ud; - parent = ucl_object_lookup_len (ctx, data, len); + parent = ucl_object_lookup_len(ctx, data, len); /* Some sanity checks */ - if (parent == NULL || ucl_object_type (parent) != UCL_OBJECT) { - ucl_create_err (&parser->err, "Unable to find inherited object %.*s", - (int)len, data); + if (parent == NULL || ucl_object_type(parent) != UCL_OBJECT) { + ucl_create_err(&parser->err, "Unable to find inherited object %.*s", + (int) len, data); return false; } if (parser->stack == NULL || parser->stack->obj == NULL || - ucl_object_type (parser->stack->obj) != UCL_OBJECT) { - ucl_create_err (&parser->err, "Invalid inherit context"); + ucl_object_type(parser->stack->obj) != UCL_OBJECT) { + ucl_create_err(&parser->err, "Invalid inherit context"); return false; } target = parser->stack->obj; - if (args && (cur = ucl_object_lookup (args, "replace")) != NULL) { - replace = ucl_object_toboolean (cur); + if (args && (cur = ucl_object_lookup(args, "replace")) != NULL) { + replace = ucl_object_toboolean(cur); } - while ((cur = ucl_object_iterate (parent, &it, true))) { + while ((cur = ucl_object_iterate(parent, &it, true))) { /* We do not replace existing keys */ - if (!replace && ucl_object_lookup_len (target, cur->key, cur->keylen)) { + if (!replace && ucl_object_lookup_len(target, cur->key, cur->keylen)) { continue; } - copy = ucl_object_copy (cur); + copy = ucl_object_copy(cur); if (!replace) { copy->flags |= UCL_OBJECT_INHERITED; } - ucl_object_insert_key (target, copy, copy->key, - copy->keylen, false); + ucl_object_insert_key(target, copy, copy->key, + copy->keylen, false); } return true; } -bool -ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, bool need_expand) +bool ucl_parser_set_filevars(struct ucl_parser *parser, const char *filename, bool need_expand) { char realbuf[PATH_MAX], *curdir; if (filename != NULL) { if (need_expand) { - if (ucl_realpath (filename, realbuf) == NULL) { + if (ucl_realpath(filename, realbuf) == NULL) { return false; } } else { - ucl_strlcpy (realbuf, filename, sizeof (realbuf)); + ucl_strlcpy(realbuf, filename, sizeof(realbuf)); } if (parser->cur_file) { - free (parser->cur_file); + UCL_FREE(strlen(parser->cur_file) + 1, parser->cur_file); } - parser->cur_file = strdup (realbuf); + parser->cur_file = UCL_STRDUP(realbuf); /* Define variables */ - ucl_parser_register_variable (parser, "FILENAME", realbuf); - curdir = dirname (realbuf); - ucl_parser_register_variable (parser, "CURDIR", curdir); + ucl_parser_register_variable(parser, "FILENAME", realbuf); + curdir = dirname(realbuf); + ucl_parser_register_variable(parser, "CURDIR", curdir); } else { /* Set everything from the current dir */ - curdir = getcwd (realbuf, sizeof (realbuf)); - ucl_parser_register_variable (parser, "FILENAME", "undef"); - ucl_parser_register_variable (parser, "CURDIR", curdir); + curdir = getcwd(realbuf, sizeof(realbuf)); + ucl_parser_register_variable(parser, "FILENAME", "undef"); + ucl_parser_register_variable(parser, "CURDIR", curdir); } return true; } -bool -ucl_parser_add_file_full (struct ucl_parser *parser, const char *filename, - unsigned priority, enum ucl_duplicate_strategy strat, - enum ucl_parse_type parse_type) +bool ucl_parser_add_file_full(struct ucl_parser *parser, const char *filename, + unsigned priority, enum ucl_duplicate_strategy strat, + enum ucl_parse_type parse_type) { unsigned char *buf; size_t len; bool ret; char realbuf[PATH_MAX]; - if (ucl_realpath (filename, realbuf) == NULL) { - ucl_create_err (&parser->err, "cannot open file %s: %s", - filename, - strerror (errno)); + if (ucl_realpath(filename, realbuf) == NULL) { + ucl_create_err(&parser->err, "cannot open file %s: %s", + filename, + strerror(errno)); return false; } - if (!ucl_fetch_file (realbuf, &buf, &len, &parser->err, true)) { + if (!ucl_fetch_file(realbuf, &buf, &len, &parser->err, true)) { return false; } - ucl_parser_set_filevars (parser, realbuf, false); - ret = ucl_parser_add_chunk_full (parser, buf, len, priority, strat, - parse_type); + ucl_parser_set_filevars(parser, realbuf, false); + ret = ucl_parser_add_chunk_full(parser, buf, len, priority, strat, + parse_type); if (len > 0) { - ucl_munmap (buf, len); + ucl_munmap(buf, len); } return ret; } -bool -ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename, - unsigned priority) +bool ucl_parser_add_file_priority(struct ucl_parser *parser, const char *filename, + unsigned priority) { if (parser == NULL) { return false; } return ucl_parser_add_file_full(parser, filename, priority, - UCL_DUPLICATE_APPEND, UCL_PARSE_UCL); + UCL_DUPLICATE_APPEND, UCL_PARSE_UCL); } -bool -ucl_parser_add_file (struct ucl_parser *parser, const char *filename) +bool ucl_parser_add_file(struct ucl_parser *parser, const char *filename) { if (parser == NULL) { return false; } return ucl_parser_add_file_full(parser, filename, - parser->default_priority, UCL_DUPLICATE_APPEND, - UCL_PARSE_UCL); + parser->default_priority, UCL_DUPLICATE_APPEND, + UCL_PARSE_UCL); } -bool -ucl_parser_add_fd_full (struct ucl_parser *parser, int fd, - unsigned priority, enum ucl_duplicate_strategy strat, - enum ucl_parse_type parse_type) +bool ucl_parser_add_fd_full(struct ucl_parser *parser, int fd, + unsigned priority, enum ucl_duplicate_strategy strat, + enum ucl_parse_type parse_type) { unsigned char *buf; size_t len; bool ret; struct stat st; - if (fstat (fd, &st) == -1) { - ucl_create_err (&parser->err, "cannot stat fd %d: %s", - fd, strerror (errno)); + if (fstat(fd, &st) == -1) { + ucl_create_err(&parser->err, "cannot stat fd %d: %s", + fd, strerror(errno)); return false; } if (st.st_size == 0) { return true; } - if ((buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { - ucl_create_err (&parser->err, "cannot mmap fd %d: %s", - fd, strerror (errno)); + if ((buf = ucl_mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { + ucl_create_err(&parser->err, "cannot mmap fd %d: %s", + fd, strerror(errno)); return false; } if (parser->cur_file) { - free (parser->cur_file); + UCL_FREE(strlen(parser->cur_file) + 1, parser->cur_file); } parser->cur_file = NULL; len = st.st_size; - ret = ucl_parser_add_chunk_full (parser, buf, len, priority, strat, - parse_type); + ret = ucl_parser_add_chunk_full(parser, buf, len, priority, strat, + parse_type); if (len > 0) { - ucl_munmap (buf, len); + ucl_munmap(buf, len); } return ret; } -bool -ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd, - unsigned priority) +bool ucl_parser_add_fd_priority(struct ucl_parser *parser, int fd, + unsigned priority) { if (parser == NULL) { return false; } return ucl_parser_add_fd_full(parser, fd, parser->default_priority, - UCL_DUPLICATE_APPEND, UCL_PARSE_UCL); + UCL_DUPLICATE_APPEND, UCL_PARSE_UCL); } -bool -ucl_parser_add_fd (struct ucl_parser *parser, int fd) +bool ucl_parser_add_fd(struct ucl_parser *parser, int fd) { if (parser == NULL) { return false; } return ucl_parser_add_fd_priority(parser, fd, parser->default_priority); } size_t -ucl_strlcpy (char *dst, const char *src, size_t siz) +ucl_strlcpy(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0) { while (--n != 0) { if ((*d++ = *s++) == '\0') { break; } } } if (n == 0 && siz != 0) { *d = '\0'; } - return (s - src - 1); /* count does not include NUL */ + return (s - src - 1); /* count does not include NUL */ } size_t -ucl_strlcpy_unsafe (char *dst, const char *src, size_t siz) +ucl_strlcpy_unsafe(char *dst, const char *src, size_t siz) { - memcpy (dst, src, siz - 1); + memcpy(dst, src, siz - 1); dst[siz - 1] = '\0'; return siz - 1; } size_t -ucl_strlcpy_tolower (char *dst, const char *src, size_t siz) +ucl_strlcpy_tolower(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0) { while (--n != 0) { - if ((*d++ = tolower (*s++)) == '\0') { + if ((*d++ = tolower(*s++)) == '\0') { break; } } } if (n == 0 && siz != 0) { *d = '\0'; } - return (s - src); /* count does not include NUL */ + return (s - src); /* count does not include NUL */ } /* * Find the first occurrence of find in s */ char * -ucl_strnstr (const char *s, const char *find, int len) +ucl_strnstr(const char *s, const char *find, int len) { char c, sc; int mlen; if ((c = *find++) != 0) { - mlen = strlen (find); + mlen = strlen(find); do { do { if ((sc = *s++) == 0 || len-- < mlen) return (NULL); } while (sc != c); - } while (strncmp (s, find, mlen) != 0); + } while (strncmp(s, find, mlen) != 0); s--; } - return ((char *)s); + return ((char *) s); } /* * Find the first occurrence of find in s, ignore case. */ char * -ucl_strncasestr (const char *s, const char *find, int len) +ucl_strncasestr(const char *s, const char *find, int len) { char c, sc; int mlen; if ((c = *find++) != 0) { - c = tolower (c); - mlen = strlen (find); + c = tolower(c); + mlen = strlen(find); do { do { if ((sc = *s++) == 0 || len-- == 0) return (NULL); - } while (tolower (sc) != c); - } while (strncasecmp (s, find, mlen) != 0); + } while (tolower(sc) != c); + } while (strncasecmp(s, find, mlen) != 0); s--; } - return ((char *)s); + return ((char *) s); } ucl_object_t * -ucl_object_fromstring_common (const char *str, size_t len, enum ucl_string_flags flags) +ucl_object_fromstring_common(const char *str, size_t len, enum ucl_string_flags flags) { ucl_object_t *obj; const char *start, *end, *p, *pos; char *dst, *d; size_t escaped_len; if (str == NULL) { return NULL; } - obj = ucl_object_new (); + obj = ucl_object_new(); if (obj) { if (len == 0) { - len = strlen (str); + len = strlen(str); } if (flags & UCL_STRING_TRIM) { /* Skip leading spaces */ - for (start = str; (size_t)(start - str) < len; start ++) { - if (!ucl_test_character (*start, UCL_CHARACTER_WHITESPACE_UNSAFE)) { + for (start = str; (size_t) (start - str) < len; start++) { + if (!ucl_test_character(*start, UCL_CHARACTER_WHITESPACE_UNSAFE)) { break; } } /* Skip trailing spaces */ - for (end = str + len - 1; end > start; end --) { - if (!ucl_test_character (*end, UCL_CHARACTER_WHITESPACE_UNSAFE)) { + for (end = str + len - 1; end > start; end--) { + if (!ucl_test_character(*end, UCL_CHARACTER_WHITESPACE_UNSAFE)) { break; } } - end ++; + end++; } else { start = str; end = str + len; } obj->type = UCL_STRING; if (flags & UCL_STRING_ESCAPE) { - for (p = start, escaped_len = 0; p < end; p ++, escaped_len ++) { - if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_WHITESPACE_UNSAFE)) { + for (p = start, escaped_len = 0; p < end; p++, escaped_len++) { + if (ucl_test_character(*p, UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_WHITESPACE_UNSAFE)) { switch (*p) { case '\v': case '\0': escaped_len += 5; break; case ' ': break; default: - escaped_len ++; + escaped_len++; break; } } } - dst = malloc (escaped_len + 1); + dst = malloc(escaped_len + 1); if (dst != NULL) { - for (p = start, d = dst; p < end; p ++, d ++) { - if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_WHITESPACE_UNSAFE)) { + for (p = start, d = dst; p < end; p++, d++) { + if (ucl_test_character(*p, UCL_CHARACTER_JSON_UNSAFE | UCL_CHARACTER_WHITESPACE_UNSAFE)) { switch (*p) { case '\n': *d++ = '\\'; *d = 'n'; break; case '\r': *d++ = '\\'; *d = 'r'; break; case '\b': *d++ = '\\'; *d = 'b'; break; case '\t': *d++ = '\\'; *d = 't'; break; case '\f': *d++ = '\\'; *d = 'f'; break; case '\0': *d++ = '\\'; *d++ = 'u'; *d++ = '0'; *d++ = '0'; *d++ = '0'; - *d = '0'; + *d = '0'; break; case '\v': *d++ = '\\'; *d++ = 'u'; *d++ = '0'; *d++ = '0'; *d++ = '0'; - *d = 'B'; + *d = 'B'; break; case '\\': *d++ = '\\'; *d = '\\'; break; case ' ': *d = ' '; break; case '"': *d++ = '\\'; *d = '"'; break; } } else { *d = *p; } } *d = '\0'; obj->value.sv = dst; obj->trash_stack[UCL_TRASH_VALUE] = dst; obj->len = escaped_len; } } else { - dst = malloc (end - start + 1); + dst = malloc(end - start + 1); if (dst != NULL) { - ucl_strlcpy_unsafe (dst, start, end - start + 1); + ucl_strlcpy_unsafe(dst, start, end - start + 1); obj->value.sv = dst; obj->trash_stack[UCL_TRASH_VALUE] = dst; obj->len = end - start; } } if ((flags & UCL_STRING_PARSE) && dst != NULL) { /* Parse what we have */ if (flags & UCL_STRING_PARSE_BOOLEAN) { - if (!ucl_maybe_parse_boolean (obj, dst, obj->len) && (flags & UCL_STRING_PARSE_NUMBER)) { - ucl_maybe_parse_number (obj, dst, dst + obj->len, &pos, - flags & UCL_STRING_PARSE_DOUBLE, - flags & UCL_STRING_PARSE_BYTES, - flags & UCL_STRING_PARSE_TIME); + if (!ucl_maybe_parse_boolean(obj, dst, obj->len) && (flags & UCL_STRING_PARSE_NUMBER)) { + ucl_maybe_parse_number(obj, dst, dst + obj->len, &pos, + flags & UCL_STRING_PARSE_DOUBLE, + flags & UCL_STRING_PARSE_BYTES, + flags & UCL_STRING_PARSE_TIME); } } else { - ucl_maybe_parse_number (obj, dst, dst + obj->len, &pos, - flags & UCL_STRING_PARSE_DOUBLE, - flags & UCL_STRING_PARSE_BYTES, - flags & UCL_STRING_PARSE_TIME); + ucl_maybe_parse_number(obj, dst, dst + obj->len, &pos, + flags & UCL_STRING_PARSE_DOUBLE, + flags & UCL_STRING_PARSE_BYTES, + flags & UCL_STRING_PARSE_TIME); } } } return obj; } static bool -ucl_object_insert_key_common (ucl_object_t *top, ucl_object_t *elt, - const char *key, size_t keylen, bool copy_key, bool merge, bool replace) +ucl_object_insert_key_common(ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key, bool merge, bool replace) { ucl_object_t *found, *tmp; const ucl_object_t *cur; ucl_object_iter_t it = NULL; const char *p; int ret = true; if (elt == NULL || key == NULL) { return false; } if (top == NULL) { return false; } if (top->type != UCL_OBJECT) { /* It is possible to convert NULL type to an object */ if (top->type == UCL_NULL) { top->type = UCL_OBJECT; } else { /* Refuse converting of other object types */ return false; } } if (top->value.ov == NULL) { - top->value.ov = ucl_hash_create (false); + top->value.ov = ucl_hash_create(false); } if (keylen == 0) { - keylen = strlen (key); + keylen = strlen(key); } - for (p = key; p < key + keylen; p ++) { - if (ucl_test_character (*p, UCL_CHARACTER_UCL_UNSAFE)) { + for (p = key; p < key + keylen; p++) { + if (ucl_test_character(*p, UCL_CHARACTER_UCL_UNSAFE)) { elt->flags |= UCL_OBJECT_NEED_KEY_ESCAPE; break; } } /* workaround for some use cases */ if (elt->trash_stack[UCL_TRASH_KEY] != NULL && - key != (const char *)elt->trash_stack[UCL_TRASH_KEY]) { + key != (const char *) elt->trash_stack[UCL_TRASH_KEY]) { /* Remove copied key */ - free (elt->trash_stack[UCL_TRASH_KEY]); + free(elt->trash_stack[UCL_TRASH_KEY]); elt->trash_stack[UCL_TRASH_KEY] = NULL; elt->flags &= ~UCL_OBJECT_ALLOCATED_KEY; } elt->key = key; elt->keylen = keylen; if (copy_key) { - ucl_copy_key_trash (elt); + ucl_copy_key_trash(elt); } - found = __DECONST (ucl_object_t *, ucl_hash_search_obj (top->value.ov, elt)); + found = __DECONST(ucl_object_t *, ucl_hash_search_obj(top->value.ov, elt)); if (found == NULL) { - top->value.ov = ucl_hash_insert_object (top->value.ov, elt, false); - top->len ++; + top->value.ov = ucl_hash_insert_object(top->value.ov, elt, false); + top->len++; if (replace) { ret = false; } } else { if (replace) { - ucl_hash_replace (top->value.ov, found, elt); - ucl_object_unref (found); + ucl_hash_replace(top->value.ov, found, elt); + ucl_object_unref(found); } else if (merge) { if (found->type != UCL_OBJECT && elt->type == UCL_OBJECT) { /* Insert old elt to new one */ - ucl_object_insert_key_common (elt, found, found->key, - found->keylen, copy_key, false, false); - ucl_hash_delete (top->value.ov, found); - top->value.ov = ucl_hash_insert_object (top->value.ov, elt, false); + ucl_object_insert_key_common(elt, found, found->key, + found->keylen, copy_key, false, false); + ucl_hash_delete(top->value.ov, found); + top->value.ov = ucl_hash_insert_object(top->value.ov, elt, false); } else if (found->type == UCL_OBJECT && elt->type != UCL_OBJECT) { /* Insert new to old */ - ucl_object_insert_key_common (found, elt, elt->key, - elt->keylen, copy_key, false, false); + ucl_object_insert_key_common(found, elt, elt->key, + elt->keylen, copy_key, false, false); } else if (found->type == UCL_OBJECT && elt->type == UCL_OBJECT) { /* Mix two hashes */ - while ((cur = ucl_object_iterate (elt, &it, true)) != NULL) { - tmp = ucl_object_ref (cur); - ucl_object_insert_key_common (found, tmp, cur->key, - cur->keylen, copy_key, true, false); + while ((cur = ucl_object_iterate(elt, &it, true)) != NULL) { + tmp = ucl_object_ref(cur); + ucl_object_insert_key_common(found, tmp, cur->key, + cur->keylen, copy_key, true, false); } - ucl_object_unref (elt); + ucl_object_unref(elt); } else { /* Just make a list of scalars */ - DL_CONCAT (found, elt); + DL_CONCAT(found, elt); } } else { - DL_CONCAT (found, elt); + DL_CONCAT(found, elt); } } return ret; } -bool -ucl_object_delete_keyl (ucl_object_t *top, const char *key, size_t keylen) +bool ucl_object_delete_keyl(ucl_object_t *top, const char *key, size_t keylen) { ucl_object_t *found; if (top == NULL || key == NULL) { return false; } - found = __DECONST (ucl_object_t *, ucl_object_lookup_len (top, key, keylen)); + found = __DECONST(ucl_object_t *, ucl_object_lookup_len(top, key, keylen)); if (found == NULL) { return false; } - ucl_hash_delete (top->value.ov, found); - ucl_object_unref (found); - top->len --; + ucl_hash_delete(top->value.ov, found); + ucl_object_unref(found); + top->len--; return true; } -bool -ucl_object_delete_key (ucl_object_t *top, const char *key) +bool ucl_object_delete_key(ucl_object_t *top, const char *key) { - return ucl_object_delete_keyl (top, key, strlen (key)); + return ucl_object_delete_keyl(top, key, strlen(key)); } -ucl_object_t* -ucl_object_pop_keyl (ucl_object_t *top, const char *key, size_t keylen) +ucl_object_t * +ucl_object_pop_keyl(ucl_object_t *top, const char *key, size_t keylen) { const ucl_object_t *found; if (top == NULL || key == NULL) { return false; } - found = ucl_object_lookup_len (top, key, keylen); + found = ucl_object_lookup_len(top, key, keylen); if (found == NULL) { return NULL; } - ucl_hash_delete (top->value.ov, found); - top->len --; + ucl_hash_delete(top->value.ov, found); + top->len--; - return __DECONST (ucl_object_t *, found); + return __DECONST(ucl_object_t *, found); } -ucl_object_t* -ucl_object_pop_key (ucl_object_t *top, const char *key) +ucl_object_t * +ucl_object_pop_key(ucl_object_t *top, const char *key) { - return ucl_object_pop_keyl (top, key, strlen (key)); + return ucl_object_pop_keyl(top, key, strlen(key)); } -bool -ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, - const char *key, size_t keylen, bool copy_key) +bool ucl_object_insert_key(ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key) { - return ucl_object_insert_key_common (top, elt, key, keylen, copy_key, false, false); + return ucl_object_insert_key_common(top, elt, key, keylen, copy_key, false, false); } -bool -ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt, - const char *key, size_t keylen, bool copy_key) +bool ucl_object_insert_key_merged(ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key) { - return ucl_object_insert_key_common (top, elt, key, keylen, copy_key, true, false); + return ucl_object_insert_key_common(top, elt, key, keylen, copy_key, true, false); } -bool -ucl_object_replace_key (ucl_object_t *top, ucl_object_t *elt, - const char *key, size_t keylen, bool copy_key) +bool ucl_object_replace_key(ucl_object_t *top, ucl_object_t *elt, + const char *key, size_t keylen, bool copy_key) { - return ucl_object_insert_key_common (top, elt, key, keylen, copy_key, false, true); + return ucl_object_insert_key_common(top, elt, key, keylen, copy_key, false, true); } -bool -ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy) +bool ucl_object_merge(ucl_object_t *top, ucl_object_t *elt, bool copy) { ucl_object_t *cur = NULL, *cp = NULL, *found = NULL; ucl_object_iter_t iter = NULL; if (top == NULL || elt == NULL) { return false; } if (top->type == UCL_ARRAY) { if (elt->type == UCL_ARRAY) { /* Merge two arrays */ - return ucl_array_merge (top, elt, copy); + return ucl_array_merge(top, elt, copy); } else { if (copy) { - ucl_array_append (top, ucl_object_copy (elt)); + ucl_array_append(top, ucl_object_copy(elt)); return true; } else { - ucl_array_append (top, ucl_object_ref (elt)); + ucl_array_append(top, ucl_object_ref(elt)); return true; } } } else if (top->type == UCL_OBJECT) { if (elt->type == UCL_OBJECT) { /* Mix two hashes */ - while ((cur = (ucl_object_t *) ucl_hash_iterate (elt->value.ov, - &iter))) { + while ((cur = (ucl_object_t *) ucl_hash_iterate(elt->value.ov, + &iter))) { if (copy) { - cp = ucl_object_copy (cur); - } else { - cp = ucl_object_ref (cur); + cp = ucl_object_copy(cur); + } + else { + cp = ucl_object_ref(cur); } found = __DECONST(ucl_object_t *, - ucl_hash_search (top->value.ov, cp->key, cp->keylen)); + ucl_hash_search(top->value.ov, cp->key, cp->keylen)); if (found == NULL) { /* The key does not exist */ - top->value.ov = ucl_hash_insert_object (top->value.ov, cp, - false); + top->value.ov = ucl_hash_insert_object(top->value.ov, cp, + false); top->len++; } else { /* The key already exists, merge it recursively */ if (found->type == UCL_OBJECT || found->type == UCL_ARRAY) { - if (!ucl_object_merge (found, cp, copy)) { + if (!ucl_object_merge(found, cp, copy)) { return false; } - ucl_object_unref (cp); + ucl_object_unref(cp); } else { - ucl_hash_replace (top->value.ov, found, cp); - ucl_object_unref (found); + ucl_hash_replace(top->value.ov, found, cp); + ucl_object_unref(found); } } } } else { if (copy) { - cp = ucl_object_copy (elt); + cp = ucl_object_copy(elt); } else { - cp = ucl_object_ref (elt); + cp = ucl_object_ref(elt); } found = __DECONST(ucl_object_t *, - ucl_hash_search (top->value.ov, cp->key, cp->keylen)); + ucl_hash_search(top->value.ov, cp->key, cp->keylen)); if (found == NULL) { /* The key does not exist */ - top->value.ov = ucl_hash_insert_object (top->value.ov, cp, - false); + top->value.ov = ucl_hash_insert_object(top->value.ov, cp, + false); top->len++; } else { /* The key already exists, merge it recursively */ if (found->type == UCL_OBJECT || found->type == UCL_ARRAY) { - if (!ucl_object_merge (found, cp, copy)) { + if (!ucl_object_merge(found, cp, copy)) { return false; } - ucl_object_unref (cp); + ucl_object_unref(cp); } else { - ucl_hash_replace (top->value.ov, found, cp); - ucl_object_unref (found); + ucl_hash_replace(top->value.ov, found, cp); + ucl_object_unref(found); } } } } else { /* Cannot merge trivial objects */ return false; } return true; } const ucl_object_t * -ucl_object_lookup_len (const ucl_object_t *obj, const char *key, size_t klen) +ucl_object_lookup_len(const ucl_object_t *obj, const char *key, size_t klen) { const ucl_object_t *ret; ucl_object_t srch; if (obj == NULL || obj->type != UCL_OBJECT || key == NULL) { return NULL; } srch.key = key; srch.keylen = klen; - ret = ucl_hash_search_obj (obj->value.ov, &srch); + ret = ucl_hash_search_obj(obj->value.ov, &srch); return ret; } const ucl_object_t * -ucl_object_lookup (const ucl_object_t *obj, const char *key) +ucl_object_lookup(const ucl_object_t *obj, const char *key) { if (key == NULL) { return NULL; } - return ucl_object_lookup_len (obj, key, strlen (key)); + return ucl_object_lookup_len(obj, key, strlen(key)); } -const ucl_object_t* -ucl_object_lookup_any (const ucl_object_t *obj, - const char *key, ...) +const ucl_object_t * +ucl_object_lookup_any(const ucl_object_t *obj, + const char *key, ...) { va_list ap; const ucl_object_t *ret = NULL; const char *nk = NULL; if (obj == NULL || key == NULL) { return NULL; } - ret = ucl_object_lookup_len (obj, key, strlen (key)); + ret = ucl_object_lookup_len(obj, key, strlen(key)); if (ret == NULL) { - va_start (ap, key); + va_start(ap, key); while (ret == NULL) { - nk = va_arg (ap, const char *); + nk = va_arg(ap, const char *); if (nk == NULL) { break; } else { - ret = ucl_object_lookup_len (obj, nk, strlen (nk)); + ret = ucl_object_lookup_len(obj, nk, strlen(nk)); } } - va_end (ap); + va_end(ap); } return ret; } -const ucl_object_t* -ucl_object_iterate_with_error (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values, - int *ep) +const ucl_object_t * +ucl_object_iterate_with_error(const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values, + int *ep) { const ucl_object_t *elt = NULL; if (obj == NULL || iter == NULL) { return NULL; } if (expand_values) { switch (obj->type) { case UCL_OBJECT: - return (const ucl_object_t*)ucl_hash_iterate2 (obj->value.ov, iter, ep); + return (const ucl_object_t *) ucl_hash_iterate2(obj->value.ov, iter, ep); break; case UCL_ARRAY: { unsigned int idx; - UCL_ARRAY_GET (vec, obj); - idx = (unsigned int)(uintptr_t)(*iter); + UCL_ARRAY_GET(vec, obj); + idx = (unsigned int) (uintptr_t) (*iter); if (vec != NULL) { - while (idx < kv_size (*vec)) { - if ((elt = kv_A (*vec, idx)) != NULL) { - idx ++; + while (idx < kv_size(*vec)) { + if ((elt = kv_A(*vec, idx)) != NULL) { + idx++; break; } - idx ++; + idx++; } - *iter = (void *)(uintptr_t)idx; + *iter = (void *) (uintptr_t) idx; } return elt; break; } default: /* Go to linear iteration */ break; } } /* Treat everything as a linear list */ elt = *iter; if (elt == NULL) { elt = obj; } else if (elt == obj) { return NULL; } - *iter = __DECONST (void *, elt->next ? elt->next : obj); + *iter = __DECONST(void *, elt->next ? elt->next : obj); return elt; /* Not reached */ return NULL; } enum ucl_safe_iter_flags { UCL_ITERATE_FLAG_UNDEFINED = 0, UCL_ITERATE_FLAG_INSIDE_ARRAY, UCL_ITERATE_FLAG_INSIDE_OBJECT, UCL_ITERATE_FLAG_IMPLICIT, UCL_ITERATE_FLAG_EXCEPTION }; static const char safe_iter_magic[4] = {'u', 'i', 't', 'e'}; struct ucl_object_safe_iter { char magic[4]; /* safety check */ uint32_t flags; const ucl_object_t *impl_it; /* implicit object iteration */ - ucl_object_iter_t expl_it; /* explicit iteration */ + ucl_object_iter_t expl_it; /* explicit iteration */ }; -#define UCL_SAFE_ITER(ptr) (struct ucl_object_safe_iter *)(ptr) -#define UCL_SAFE_ITER_CHECK(it) do { \ - assert (it != NULL); \ - assert (memcmp (it->magic, safe_iter_magic, sizeof (it->magic)) == 0); \ - } while (0) +#define UCL_SAFE_ITER(ptr) (struct ucl_object_safe_iter *) (ptr) +#define UCL_SAFE_ITER_CHECK(it) \ + do { \ + assert(it != NULL); \ + assert(memcmp(it->magic, safe_iter_magic, sizeof(it->magic)) == 0); \ + } while (0) ucl_object_iter_t -ucl_object_iterate_new (const ucl_object_t *obj) +ucl_object_iterate_new(const ucl_object_t *obj) { struct ucl_object_safe_iter *it; - it = UCL_ALLOC (sizeof (*it)); + it = UCL_ALLOC(sizeof(*it)); if (it != NULL) { - memcpy (it->magic, safe_iter_magic, sizeof (it->magic)); + memcpy(it->magic, safe_iter_magic, sizeof(it->magic)); it->flags = UCL_ITERATE_FLAG_UNDEFINED; it->expl_it = NULL; it->impl_it = obj; } - return (ucl_object_iter_t)it; + return (ucl_object_iter_t) it; } -bool -ucl_object_iter_chk_excpn(ucl_object_iter_t *it) +bool ucl_object_iter_chk_excpn(ucl_object_iter_t *it) { - struct ucl_object_safe_iter *rit = UCL_SAFE_ITER (it); + struct ucl_object_safe_iter *rit = UCL_SAFE_ITER(it); - UCL_SAFE_ITER_CHECK (rit); + UCL_SAFE_ITER_CHECK(rit); return (rit->flags == UCL_ITERATE_FLAG_EXCEPTION); } ucl_object_iter_t -ucl_object_iterate_reset (ucl_object_iter_t it, const ucl_object_t *obj) +ucl_object_iterate_reset(ucl_object_iter_t it, const ucl_object_t *obj) { - struct ucl_object_safe_iter *rit = UCL_SAFE_ITER (it); + struct ucl_object_safe_iter *rit = UCL_SAFE_ITER(it); - UCL_SAFE_ITER_CHECK (rit); + UCL_SAFE_ITER_CHECK(rit); if (rit->expl_it != NULL) { if (rit->flags == UCL_ITERATE_FLAG_INSIDE_OBJECT) { - UCL_FREE (sizeof (*rit->expl_it), rit->expl_it); + UCL_FREE(sizeof(*rit->expl_it), rit->expl_it); } } rit->impl_it = obj; rit->expl_it = NULL; rit->flags = UCL_ITERATE_FLAG_UNDEFINED; return it; } -const ucl_object_t* -ucl_object_iterate_safe (ucl_object_iter_t it, bool expand_values) +const ucl_object_t * +ucl_object_iterate_safe(ucl_object_iter_t it, bool expand_values) { - return ucl_object_iterate_full (it, expand_values ? UCL_ITERATE_BOTH : - UCL_ITERATE_IMPLICIT); + return ucl_object_iterate_full(it, expand_values ? UCL_ITERATE_BOTH : UCL_ITERATE_IMPLICIT); } -const ucl_object_t* -ucl_object_iterate_full (ucl_object_iter_t it, enum ucl_iterate_type type) +const ucl_object_t * +ucl_object_iterate_full(ucl_object_iter_t it, enum ucl_iterate_type type) { - struct ucl_object_safe_iter *rit = UCL_SAFE_ITER (it); + struct ucl_object_safe_iter *rit = UCL_SAFE_ITER(it); const ucl_object_t *ret = NULL; int ern; - UCL_SAFE_ITER_CHECK (rit); + UCL_SAFE_ITER_CHECK(rit); if (rit->impl_it == NULL) { return NULL; } if (rit->impl_it->type == UCL_OBJECT) { rit->flags = UCL_ITERATE_FLAG_INSIDE_OBJECT; - ret = ucl_object_iterate_with_error (rit->impl_it, &rit->expl_it, true, &ern); + ret = ucl_object_iterate_with_error(rit->impl_it, &rit->expl_it, true, &ern); if (ret == NULL && ern != 0) { rit->flags = UCL_ITERATE_FLAG_EXCEPTION; return NULL; } if (ret == NULL && (type & UCL_ITERATE_IMPLICIT)) { /* Need to switch to another implicit object in chain */ rit->impl_it = rit->impl_it->next; rit->expl_it = NULL; - return ucl_object_iterate_safe (it, type); + return ucl_object_iterate_safe(it, type); } } else if (rit->impl_it->type == UCL_ARRAY) { rit->flags = UCL_ITERATE_FLAG_INSIDE_ARRAY; - ret = ucl_object_iterate (rit->impl_it, &rit->expl_it, true); + ret = ucl_object_iterate(rit->impl_it, &rit->expl_it, true); if (ret == NULL && (type & UCL_ITERATE_IMPLICIT)) { /* Need to switch to another implicit object in chain */ rit->impl_it = rit->impl_it->next; rit->expl_it = NULL; - return ucl_object_iterate_safe (it, type); + return ucl_object_iterate_safe(it, type); } } else { /* Just iterate over the implicit array */ rit->flags = UCL_ITERATE_FLAG_IMPLICIT; ret = rit->impl_it; rit->impl_it = rit->impl_it->next; if (type & UCL_ITERATE_EXPLICIT) { /* We flatten objects if need to expand values */ if (ret->type == UCL_OBJECT || ret->type == UCL_ARRAY) { - return ucl_object_iterate_safe (it, type); + return ucl_object_iterate_safe(it, type); } } } return ret; } -void -ucl_object_iterate_free (ucl_object_iter_t it) +void ucl_object_iterate_free(ucl_object_iter_t it) { - struct ucl_object_safe_iter *rit = UCL_SAFE_ITER (it); + struct ucl_object_safe_iter *rit = UCL_SAFE_ITER(it); - UCL_SAFE_ITER_CHECK (rit); + UCL_SAFE_ITER_CHECK(rit); if (rit->expl_it != NULL) { if (rit->flags == UCL_ITERATE_FLAG_INSIDE_OBJECT) { - UCL_FREE (sizeof (*rit->expl_it), rit->expl_it); + UCL_FREE(sizeof(*rit->expl_it), rit->expl_it); } } - UCL_FREE (sizeof (*rit), it); + UCL_FREE(sizeof(*rit), it); } const ucl_object_t * -ucl_object_lookup_path (const ucl_object_t *top, const char *path_in) { - return ucl_object_lookup_path_char (top, path_in, '.'); +ucl_object_lookup_path(const ucl_object_t *top, const char *path_in) +{ + return ucl_object_lookup_path_char(top, path_in, '.'); } const ucl_object_t * -ucl_object_lookup_path_char (const ucl_object_t *top, const char *path_in, const char sep) { +ucl_object_lookup_path_char(const ucl_object_t *top, const char *path_in, const char sep) +{ const ucl_object_t *o = NULL, *found; const char *p, *c; char *err_str; unsigned index; if (path_in == NULL || top == NULL) { return NULL; } found = NULL; p = path_in; /* Skip leading dots */ while (*p == sep) { - p ++; + p++; } c = p; while (*p != '\0') { - p ++; + p++; if (*p == sep || *p == '\0') { if (p > c) { switch (top->type) { case UCL_ARRAY: /* Key should be an int */ - index = strtoul (c, &err_str, 10); + index = strtoul(c, &err_str, 10); if (err_str != NULL && (*err_str != sep && *err_str != '\0')) { return NULL; } - o = ucl_array_find_index (top, index); + o = ucl_array_find_index(top, index); break; default: - o = ucl_object_lookup_len (top, c, p - c); + o = ucl_object_lookup_len(top, c, p - c); break; } if (o == NULL) { return NULL; } top = o; } if (*p != '\0') { c = p + 1; } } } found = o; return found; } ucl_object_t * -ucl_object_new (void) +ucl_object_new(void) { - return ucl_object_typed_new (UCL_NULL); + return ucl_object_typed_new(UCL_NULL); } ucl_object_t * -ucl_object_typed_new (ucl_type_t type) +ucl_object_typed_new(ucl_type_t type) { - return ucl_object_new_full (type, 0); + return ucl_object_new_full(type, 0); } ucl_object_t * -ucl_object_new_full (ucl_type_t type, unsigned priority) +ucl_object_new_full(ucl_type_t type, unsigned priority) { ucl_object_t *new; if (type != UCL_USERDATA) { - new = UCL_ALLOC (sizeof (ucl_object_t)); + new = UCL_ALLOC(sizeof(ucl_object_t)); if (new != NULL) { - memset (new, 0, sizeof (ucl_object_t)); + memset(new, 0, sizeof(ucl_object_t)); new->ref = 1; new->type = (type <= UCL_NULL ? type : UCL_NULL); new->next = NULL; new->prev = new; - ucl_object_set_priority (new, priority); + ucl_object_set_priority(new, priority); if (type == UCL_ARRAY) { - new->value.av = UCL_ALLOC (sizeof (ucl_array_t)); + new->value.av = UCL_ALLOC(sizeof(ucl_array_t)); if (new->value.av) { - memset (new->value.av, 0, sizeof (ucl_array_t)); - UCL_ARRAY_GET (vec, new); + memset(new->value.av, 0, sizeof(ucl_array_t)); + UCL_ARRAY_GET(vec, new); /* Preallocate some space for arrays */ - kv_resize_safe (ucl_object_t *, *vec, 8, enomem); + kv_resize_safe(ucl_object_t *, *vec, 8, enomem); } } } } else { - new = ucl_object_new_userdata (NULL, NULL, NULL); - ucl_object_set_priority (new, priority); + new = ucl_object_new_userdata(NULL, NULL, NULL); + ucl_object_set_priority(new, priority); } enomem: return new; } -bool ucl_object_reserve (ucl_object_t *obj, size_t reserved) +bool ucl_object_reserve(ucl_object_t *obj, size_t reserved) { if (obj->type == UCL_ARRAY) { - UCL_ARRAY_GET (vec, obj); + UCL_ARRAY_GET(vec, obj); if (vec->m < reserved) { /* Preallocate some space for arrays */ - kv_resize_safe (ucl_object_t *, *vec, reserved, e0); + kv_resize_safe(ucl_object_t *, *vec, reserved, e0); } } else if (obj->type == UCL_OBJECT) { - ucl_hash_reserve (obj->value.ov, reserved); + ucl_hash_reserve(obj->value.ov, reserved); } return true; e0: return false; } -ucl_object_t* -ucl_object_new_userdata (ucl_userdata_dtor dtor, - ucl_userdata_emitter emitter, - void *ptr) +ucl_object_t * +ucl_object_new_userdata(ucl_userdata_dtor dtor, + ucl_userdata_emitter emitter, + void *ptr) { struct ucl_object_userdata *new; - size_t nsize = sizeof (*new); + size_t nsize = sizeof(*new); - new = UCL_ALLOC (nsize); + new = UCL_ALLOC(nsize); if (new != NULL) { - memset (new, 0, nsize); + memset(new, 0, nsize); new->obj.ref = 1; new->obj.type = UCL_USERDATA; new->obj.next = NULL; - new->obj.prev = (ucl_object_t *)new; + new->obj.prev = (ucl_object_t *) new; new->dtor = dtor; new->emitter = emitter; new->obj.value.ud = ptr; } - return (ucl_object_t *)new; + return (ucl_object_t *) new; } ucl_type_t -ucl_object_type (const ucl_object_t *obj) +ucl_object_type(const ucl_object_t *obj) { if (obj == NULL) { return UCL_NULL; } return obj->type; } -ucl_object_t* -ucl_object_fromstring (const char *str) +ucl_object_t * +ucl_object_fromstring(const char *str) { - return ucl_object_fromstring_common (str, 0, UCL_STRING_RAW); + return ucl_object_fromstring_common(str, 0, UCL_STRING_RAW); } ucl_object_t * -ucl_object_fromlstring (const char *str, size_t len) +ucl_object_fromlstring(const char *str, size_t len) { - return ucl_object_fromstring_common (str, len, UCL_STRING_RAW); + return ucl_object_fromstring_common(str, len, UCL_STRING_RAW); } ucl_object_t * -ucl_object_fromint (int64_t iv) +ucl_object_fromint(int64_t iv) { ucl_object_t *obj; - obj = ucl_object_new (); + obj = ucl_object_new(); if (obj != NULL) { obj->type = UCL_INT; obj->value.iv = iv; } return obj; } ucl_object_t * -ucl_object_fromdouble (double dv) +ucl_object_fromdouble(double dv) { ucl_object_t *obj; - obj = ucl_object_new (); + obj = ucl_object_new(); if (obj != NULL) { obj->type = UCL_FLOAT; obj->value.dv = dv; } return obj; } -ucl_object_t* -ucl_object_frombool (bool bv) +ucl_object_t * +ucl_object_frombool(bool bv) { ucl_object_t *obj; - obj = ucl_object_new (); + obj = ucl_object_new(); if (obj != NULL) { obj->type = UCL_BOOLEAN; obj->value.iv = bv; } return obj; } -bool -ucl_array_append (ucl_object_t *top, ucl_object_t *elt) +bool ucl_array_append(ucl_object_t *top, ucl_object_t *elt) { - UCL_ARRAY_GET (vec, top); + if (top->type != UCL_ARRAY) { + return false; + } + + UCL_ARRAY_GET(vec, top); if (elt == NULL || top == NULL) { return false; } if (vec == NULL) { - vec = UCL_ALLOC (sizeof (*vec)); + vec = UCL_ALLOC(sizeof(*vec)); if (vec == NULL) { return false; } - kv_init (*vec); - top->value.av = (void *)vec; + kv_init(*vec); + top->value.av = (void *) vec; } - kv_push_safe (ucl_object_t *, *vec, elt, e0); + kv_push_safe(ucl_object_t *, *vec, elt, e0); - top->len ++; + top->len++; return true; e0: return false; } -bool -ucl_array_prepend (ucl_object_t *top, ucl_object_t *elt) +bool ucl_array_prepend(ucl_object_t *top, ucl_object_t *elt) { - UCL_ARRAY_GET (vec, top); + if (top->type != UCL_ARRAY) { + return false; + } + + UCL_ARRAY_GET(vec, top); if (elt == NULL || top == NULL) { return false; } if (vec == NULL) { - vec = UCL_ALLOC (sizeof (*vec)); - kv_init (*vec); - top->value.av = (void *)vec; - kv_push_safe (ucl_object_t *, *vec, elt, e0); + vec = UCL_ALLOC(sizeof(*vec)); + kv_init(*vec); + top->value.av = (void *) vec; + kv_push_safe(ucl_object_t *, *vec, elt, e0); } else { /* Slow O(n) algorithm */ - kv_prepend_safe (ucl_object_t *, *vec, elt, e0); + kv_prepend_safe(ucl_object_t *, *vec, elt, e0); } - top->len ++; + top->len++; return true; e0: return false; } -bool -ucl_array_merge (ucl_object_t *top, ucl_object_t *elt, bool copy) +bool ucl_array_merge(ucl_object_t *top, ucl_object_t *elt, bool copy) { unsigned i; ucl_object_t *cp = NULL; ucl_object_t **obj; if (elt == NULL || top == NULL || top->type != UCL_ARRAY || elt->type != UCL_ARRAY) { return false; } if (copy) { - cp = ucl_object_copy (elt); + cp = ucl_object_copy(elt); } else { - cp = ucl_object_ref (elt); + cp = ucl_object_ref(elt); } - UCL_ARRAY_GET (v1, top); - UCL_ARRAY_GET (v2, cp); + UCL_ARRAY_GET(v1, top); + UCL_ARRAY_GET(v2, cp); if (v1 && v2) { - kv_concat_safe (ucl_object_t *, *v1, *v2, e0); + kv_concat_safe(ucl_object_t *, *v1, *v2, e0); - for (i = v2->n; i < v1->n; i ++) { - obj = &kv_A (*v1, i); + for (i = v2->n; i < v1->n; i++) { + obj = &kv_A(*v1, i); if (*obj == NULL) { continue; } - top->len ++; + top->len++; } } return true; e0: return false; } ucl_object_t * -ucl_array_delete (ucl_object_t *top, ucl_object_t *elt) +ucl_array_delete(ucl_object_t *top, ucl_object_t *elt) { - UCL_ARRAY_GET (vec, top); + if (top->type != UCL_ARRAY) { + return NULL; + } + + UCL_ARRAY_GET(vec, top); ucl_object_t *ret = NULL; unsigned i; if (vec == NULL) { return NULL; } - for (i = 0; i < vec->n; i ++) { - if (kv_A (*vec, i) == elt) { - kv_del (ucl_object_t *, *vec, i); + for (i = 0; i < vec->n; i++) { + if (kv_A(*vec, i) == elt) { + kv_del(ucl_object_t *, *vec, i); ret = elt; - top->len --; + top->len--; break; } } return ret; } const ucl_object_t * -ucl_array_head (const ucl_object_t *top) +ucl_array_head(const ucl_object_t *top) { - UCL_ARRAY_GET (vec, top); + UCL_ARRAY_GET(vec, top); if (vec == NULL || top == NULL || top->type != UCL_ARRAY || - top->value.av == NULL) { + top->value.av == NULL) { return NULL; } return (vec->n > 0 ? vec->a[0] : NULL); } const ucl_object_t * -ucl_array_tail (const ucl_object_t *top) +ucl_array_tail(const ucl_object_t *top) { - UCL_ARRAY_GET (vec, top); + UCL_ARRAY_GET(vec, top); if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { return NULL; } return (vec->n > 0 ? vec->a[vec->n - 1] : NULL); } ucl_object_t * -ucl_array_pop_last (ucl_object_t *top) +ucl_array_pop_last(ucl_object_t *top) { - UCL_ARRAY_GET (vec, top); + if (top->type != UCL_ARRAY) { + return NULL; + } + + UCL_ARRAY_GET(vec, top); ucl_object_t **obj, *ret = NULL; if (vec != NULL && vec->n > 0) { - obj = &kv_A (*vec, vec->n - 1); + obj = &kv_A(*vec, vec->n - 1); ret = *obj; - kv_del (ucl_object_t *, *vec, vec->n - 1); - top->len --; + kv_del(ucl_object_t *, *vec, vec->n - 1); + top->len--; } return ret; } ucl_object_t * -ucl_array_pop_first (ucl_object_t *top) +ucl_array_pop_first(ucl_object_t *top) { - UCL_ARRAY_GET (vec, top); + if (top->type != UCL_ARRAY) { + return NULL; + } + + UCL_ARRAY_GET(vec, top); ucl_object_t **obj, *ret = NULL; if (vec != NULL && vec->n > 0) { - obj = &kv_A (*vec, 0); + obj = &kv_A(*vec, 0); ret = *obj; - kv_del (ucl_object_t *, *vec, 0); - top->len --; + kv_del(ucl_object_t *, *vec, 0); + top->len--; } return ret; } unsigned int -ucl_array_size (const ucl_object_t *top) +ucl_array_size(const ucl_object_t *top) { if (top == NULL || top->type != UCL_ARRAY) { return 0; } - UCL_ARRAY_GET (vec, top); + UCL_ARRAY_GET(vec, top); if (vec != NULL) { return kv_size(*vec); } return 0; } const ucl_object_t * -ucl_array_find_index (const ucl_object_t *top, unsigned int index) +ucl_array_find_index(const ucl_object_t *top, unsigned int index) { - UCL_ARRAY_GET (vec, top); + if (top->type != UCL_ARRAY) { + return NULL; + } + + UCL_ARRAY_GET(vec, top); if (vec != NULL && vec->n > 0 && index < vec->n) { - return kv_A (*vec, index); + return kv_A(*vec, index); } return NULL; } unsigned int -ucl_array_index_of (ucl_object_t *top, ucl_object_t *elt) +ucl_array_index_of(ucl_object_t *top, ucl_object_t *elt) { - UCL_ARRAY_GET (vec, top); + if (top->type != UCL_ARRAY) { + return (unsigned int) (-1); + } + + UCL_ARRAY_GET(vec, top); unsigned i; if (vec == NULL) { - return (unsigned int)(-1); + return (unsigned int) (-1); } - for (i = 0; i < vec->n; i ++) { - if (kv_A (*vec, i) == elt) { + for (i = 0; i < vec->n; i++) { + if (kv_A(*vec, i) == elt) { return i; } } - return (unsigned int)(-1); + return (unsigned int) (-1); } ucl_object_t * -ucl_array_replace_index (ucl_object_t *top, ucl_object_t *elt, - unsigned int index) +ucl_array_replace_index(ucl_object_t *top, ucl_object_t *elt, + unsigned int index) { - UCL_ARRAY_GET (vec, top); + if (top->type != UCL_ARRAY) { + return NULL; + } + + UCL_ARRAY_GET(vec, top); ucl_object_t *ret = NULL; if (vec != NULL && vec->n > 0 && index < vec->n) { - ret = kv_A (*vec, index); - kv_A (*vec, index) = elt; + ret = kv_A(*vec, index); + kv_A(*vec, index) = elt; } return ret; } ucl_object_t * -ucl_elt_append (ucl_object_t *head, ucl_object_t *elt) +ucl_elt_append(ucl_object_t *head, ucl_object_t *elt) { if (head == NULL) { elt->next = NULL; elt->prev = elt; head = elt; } else { - elt->prev = head->prev; - head->prev->next = elt; - head->prev = elt; - elt->next = NULL; + if (head->type == UCL_USERDATA) { + /* Userdata objects are VERY special! */ + struct ucl_object_userdata *ud = (struct ucl_object_userdata *) head; + elt->prev = ud->obj.prev; + ud->obj.prev->next = elt; + ud->obj.prev = elt; + elt->next = NULL; + } + else { + elt->prev = head->prev; + head->prev->next = elt; + head->prev = elt; + elt->next = NULL; + } } return head; } -bool -ucl_object_todouble_safe (const ucl_object_t *obj, double *target) +bool ucl_object_todouble_safe(const ucl_object_t *obj, double *target) { if (obj == NULL || target == NULL) { return false; } switch (obj->type) { case UCL_INT: *target = obj->value.iv; /* Probably could cause overflow */ break; case UCL_FLOAT: case UCL_TIME: *target = obj->value.dv; break; default: return false; } return true; } double -ucl_object_todouble (const ucl_object_t *obj) +ucl_object_todouble(const ucl_object_t *obj) { double result = 0.; - ucl_object_todouble_safe (obj, &result); + ucl_object_todouble_safe(obj, &result); return result; } -bool -ucl_object_toint_safe (const ucl_object_t *obj, int64_t *target) +bool ucl_object_toint_safe(const ucl_object_t *obj, int64_t *target) { if (obj == NULL || target == NULL) { return false; } switch (obj->type) { case UCL_INT: *target = obj->value.iv; break; case UCL_FLOAT: case UCL_TIME: *target = obj->value.dv; /* Losing of decimal points */ break; default: return false; } return true; } int64_t -ucl_object_toint (const ucl_object_t *obj) +ucl_object_toint(const ucl_object_t *obj) { int64_t result = 0; - ucl_object_toint_safe (obj, &result); + ucl_object_toint_safe(obj, &result); return result; } -bool -ucl_object_toboolean_safe (const ucl_object_t *obj, bool *target) +bool ucl_object_toboolean_safe(const ucl_object_t *obj, bool *target) { if (obj == NULL || target == NULL) { return false; } switch (obj->type) { case UCL_BOOLEAN: *target = (obj->value.iv == true); break; default: return false; } return true; } -bool -ucl_object_toboolean (const ucl_object_t *obj) +bool ucl_object_toboolean(const ucl_object_t *obj) { bool result = false; - ucl_object_toboolean_safe (obj, &result); + ucl_object_toboolean_safe(obj, &result); return result; } -bool -ucl_object_tostring_safe (const ucl_object_t *obj, const char **target) +bool ucl_object_tostring_safe(const ucl_object_t *obj, const char **target) { if (obj == NULL || target == NULL) { return false; } switch (obj->type) { case UCL_STRING: if (!(obj->flags & UCL_OBJECT_BINARY)) { - *target = ucl_copy_value_trash (obj); + *target = ucl_copy_value_trash(obj); } break; default: return false; } return true; } const char * -ucl_object_tostring (const ucl_object_t *obj) +ucl_object_tostring(const ucl_object_t *obj) { const char *result = NULL; - ucl_object_tostring_safe (obj, &result); + ucl_object_tostring_safe(obj, &result); return result; } const char * -ucl_object_tostring_forced (const ucl_object_t *obj) +ucl_object_tostring_forced(const ucl_object_t *obj) { /* TODO: For binary strings we might encode string here */ if (!(obj->flags & UCL_OBJECT_BINARY)) { - return ucl_copy_value_trash (obj); + return ucl_copy_value_trash(obj); } return NULL; } -bool -ucl_object_tolstring_safe (const ucl_object_t *obj, const char **target, size_t *tlen) +bool ucl_object_tolstring_safe(const ucl_object_t *obj, const char **target, size_t *tlen) { if (obj == NULL || target == NULL) { return false; } switch (obj->type) { case UCL_STRING: *target = obj->value.sv; if (tlen != NULL) { *tlen = obj->len; } break; default: return false; } return true; } const char * -ucl_object_tolstring (const ucl_object_t *obj, size_t *tlen) +ucl_object_tolstring(const ucl_object_t *obj, size_t *tlen) { const char *result = NULL; - ucl_object_tolstring_safe (obj, &result, tlen); + ucl_object_tolstring_safe(obj, &result, tlen); return result; } const char * -ucl_object_key (const ucl_object_t *obj) +ucl_object_key(const ucl_object_t *obj) { - return ucl_copy_key_trash (obj); + return ucl_copy_key_trash(obj); } const char * -ucl_object_keyl (const ucl_object_t *obj, size_t *len) +ucl_object_keyl(const ucl_object_t *obj, size_t *len) { if (len == NULL || obj == NULL) { return NULL; } *len = obj->keylen; return obj->key; } ucl_object_t * -ucl_object_ref (const ucl_object_t *obj) +ucl_object_ref(const ucl_object_t *obj) { ucl_object_t *res = NULL; if (obj != NULL) { if (obj->flags & UCL_OBJECT_EPHEMERAL) { /* * Use deep copy for ephemeral objects, note that its refcount * is NOT increased, since ephemeral objects does not need refcount * at all */ - res = ucl_object_copy (obj); + res = ucl_object_copy(obj); } else { - res = __DECONST (ucl_object_t *, obj); + res = __DECONST(ucl_object_t *, obj); #ifdef HAVE_ATOMIC_BUILTINS - (void)__sync_add_and_fetch (&res->ref, 1); + (void) __sync_add_and_fetch(&res->ref, 1); #else - res->ref ++; + res->ref++; #endif } } return res; } static ucl_object_t * -ucl_object_copy_internal (const ucl_object_t *other, bool allow_array) +ucl_object_copy_internal(const ucl_object_t *other, bool allow_array) { ucl_object_t *new; ucl_object_iter_t it = NULL; const ucl_object_t *cur; + size_t sz = sizeof(*new); - new = malloc (sizeof (*new)); + if (other->type == UCL_USERDATA) { + sz = sizeof(struct ucl_object_userdata); + } + new = UCL_ALLOC(sz); if (new != NULL) { - memcpy (new, other, sizeof (*new)); + memcpy(new, other, sz); if (other->flags & UCL_OBJECT_EPHEMERAL) { /* Copied object is always non ephemeral */ new->flags &= ~UCL_OBJECT_EPHEMERAL; } new->ref = 1; /* Unlink from others */ new->next = NULL; new->prev = new; /* deep copy of values stored */ if (other->trash_stack[UCL_TRASH_KEY] != NULL) { new->trash_stack[UCL_TRASH_KEY] = NULL; - if (other->key == (const char *)other->trash_stack[UCL_TRASH_KEY]) { - new->trash_stack[UCL_TRASH_KEY] = malloc(other->keylen + 1); + if (other->key == (const char *) other->trash_stack[UCL_TRASH_KEY]) { + new->trash_stack[UCL_TRASH_KEY] = UCL_ALLOC(other->keylen + 1); memcpy(new->trash_stack[UCL_TRASH_KEY], other->trash_stack[UCL_TRASH_KEY], other->keylen); new->trash_stack[UCL_TRASH_KEY][other->keylen] = '\0'; new->key = new->trash_stack[UCL_TRASH_KEY]; } } if (other->trash_stack[UCL_TRASH_VALUE] != NULL) { new->trash_stack[UCL_TRASH_VALUE] = - strdup (other->trash_stack[UCL_TRASH_VALUE]); + UCL_STRDUP(other->trash_stack[UCL_TRASH_VALUE]); if (new->type == UCL_STRING) { new->value.sv = new->trash_stack[UCL_TRASH_VALUE]; } } if (other->type == UCL_ARRAY || other->type == UCL_OBJECT) { /* reset old value */ - memset (&new->value, 0, sizeof (new->value)); + memset(&new->value, 0, sizeof(new->value)); - while ((cur = ucl_object_iterate (other, &it, true)) != NULL) { + while ((cur = ucl_object_iterate(other, &it, true)) != NULL) { if (other->type == UCL_ARRAY) { - ucl_array_append (new, ucl_object_copy_internal (cur, false)); + ucl_array_append(new, ucl_object_copy_internal(cur, false)); } else { - ucl_object_t *cp = ucl_object_copy_internal (cur, true); + ucl_object_t *cp = ucl_object_copy_internal(cur, true); if (cp != NULL) { - ucl_object_insert_key (new, cp, cp->key, cp->keylen, - false); + ucl_object_insert_key(new, cp, cp->key, cp->keylen, + false); } } } } else if (allow_array && other->next != NULL) { - LL_FOREACH (other->next, cur) { - ucl_object_t *cp = ucl_object_copy_internal (cur, false); + LL_FOREACH(other->next, cur) + { + ucl_object_t *cp = ucl_object_copy_internal(cur, false); if (cp != NULL) { - DL_APPEND (new, cp); + DL_APPEND(new, cp); } } } } return new; } ucl_object_t * -ucl_object_copy (const ucl_object_t *other) +ucl_object_copy(const ucl_object_t *other) { - return ucl_object_copy_internal (other, true); + return ucl_object_copy_internal(other, true); } -void -ucl_object_unref (ucl_object_t *obj) +void ucl_object_unref(ucl_object_t *obj) { if (obj != NULL) { #ifdef HAVE_ATOMIC_BUILTINS - unsigned int rc = __sync_sub_and_fetch (&obj->ref, 1); + unsigned int rc = __sync_sub_and_fetch(&obj->ref, 1); if (rc == 0) { #else if (--obj->ref == 0) { #endif - ucl_object_free_internal (obj, true, ucl_object_dtor_unref); + ucl_object_free_internal(obj, true, ucl_object_dtor_unref); } } } -int -ucl_object_compare (const ucl_object_t *o1, const ucl_object_t *o2) +int ucl_object_compare(const ucl_object_t *o1, const ucl_object_t *o2) { const ucl_object_t *it1, *it2; ucl_object_iter_t iter = NULL; int ret = 0; if (o1->type != o2->type) { return (o1->type) - (o2->type); } switch (o1->type) { case UCL_STRING: if (o1->len == o2->len && o1->len > 0) { - ret = strcmp (ucl_object_tostring(o1), ucl_object_tostring(o2)); + ret = strcmp(ucl_object_tostring(o1), ucl_object_tostring(o2)); } else { ret = o1->len - o2->len; } break; case UCL_FLOAT: case UCL_INT: case UCL_TIME: - ret = ucl_object_todouble (o1) - ucl_object_todouble (o2); + ret = ucl_object_todouble(o1) - ucl_object_todouble(o2); break; case UCL_BOOLEAN: - ret = ucl_object_toboolean (o1) - ucl_object_toboolean (o2); + ret = ucl_object_toboolean(o1) - ucl_object_toboolean(o2); break; case UCL_ARRAY: if (o1->len == o2->len && o1->len > 0) { - UCL_ARRAY_GET (vec1, o1); - UCL_ARRAY_GET (vec2, o2); + UCL_ARRAY_GET(vec1, o1); + UCL_ARRAY_GET(vec2, o2); unsigned i; /* Compare all elements in both arrays */ - for (i = 0; i < vec1->n; i ++) { - it1 = kv_A (*vec1, i); - it2 = kv_A (*vec2, i); + for (i = 0; i < vec1->n; i++) { + it1 = kv_A(*vec1, i); + it2 = kv_A(*vec2, i); if (it1 == NULL && it2 != NULL) { return -1; } else if (it2 == NULL && it1 != NULL) { return 1; } else if (it1 != NULL && it2 != NULL) { - ret = ucl_object_compare (it1, it2); + ret = ucl_object_compare(it1, it2); if (ret != 0) { break; } } } } else { ret = o1->len - o2->len; } break; case UCL_OBJECT: if (o1->len == o2->len && o1->len > 0) { - while ((it1 = ucl_object_iterate (o1, &iter, true)) != NULL) { - it2 = ucl_object_lookup (o2, ucl_object_key (it1)); + while ((it1 = ucl_object_iterate(o1, &iter, true)) != NULL) { + it2 = ucl_object_lookup(o2, ucl_object_key(it1)); if (it2 == NULL) { ret = 1; break; } - ret = ucl_object_compare (it1, it2); + ret = ucl_object_compare(it1, it2); if (ret != 0) { break; } } } else { ret = o1->len - o2->len; } break; default: ret = 0; break; } return ret; } -int -ucl_object_compare_qsort (const ucl_object_t **o1, - const ucl_object_t **o2) +int ucl_object_compare_qsort(const ucl_object_t **o1, + const ucl_object_t **o2) { - return ucl_object_compare (*o1, *o2); + return ucl_object_compare(*o1, *o2); } -void -ucl_object_array_sort (ucl_object_t *ar, - int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2)) +void ucl_object_array_sort(ucl_object_t *ar, + int (*cmp)(const ucl_object_t **o1, const ucl_object_t **o2)) { - UCL_ARRAY_GET (vec, ar); + UCL_ARRAY_GET(vec, ar); if (cmp == NULL || ar == NULL || ar->type != UCL_ARRAY) { return; } - qsort (vec->a, vec->n, sizeof (ucl_object_t *), - (int (*)(const void *, const void *))cmp); + qsort(vec->a, vec->n, sizeof(ucl_object_t *), + (int (*)(const void *, const void *)) cmp); } -void ucl_object_sort_keys (ucl_object_t *obj, - enum ucl_object_keys_sort_flags how) +void ucl_object_sort_keys(ucl_object_t *obj, + enum ucl_object_keys_sort_flags how) { if (obj != NULL && obj->type == UCL_OBJECT) { - ucl_hash_sort (obj->value.ov, how); + ucl_hash_sort(obj->value.ov, how); } } #define PRIOBITS 4 unsigned int -ucl_object_get_priority (const ucl_object_t *obj) +ucl_object_get_priority(const ucl_object_t *obj) { if (obj == NULL) { return 0; } - return (obj->flags >> ((sizeof (obj->flags) * NBBY) - PRIOBITS)); + return (obj->flags >> ((sizeof(obj->flags) * NBBY) - PRIOBITS)); } -void -ucl_object_set_priority (ucl_object_t *obj, - unsigned int priority) +void ucl_object_set_priority(ucl_object_t *obj, + unsigned int priority) { if (obj != NULL) { priority &= (0x1 << PRIOBITS) - 1; - priority <<= ((sizeof (obj->flags) * NBBY) - PRIOBITS); - priority |= obj->flags & ((1 << ((sizeof (obj->flags) * NBBY) - - PRIOBITS)) - 1); + priority <<= ((sizeof(obj->flags) * NBBY) - PRIOBITS); + priority |= obj->flags & ((1 << ((sizeof(obj->flags) * NBBY) - + PRIOBITS)) - + 1); obj->flags = priority; } } -bool -ucl_object_string_to_type (const char *input, ucl_type_t *res) +bool ucl_object_string_to_type(const char *input, ucl_type_t *res) { - if (strcasecmp (input, "object") == 0) { + if (strcasecmp(input, "object") == 0) { *res = UCL_OBJECT; } - else if (strcasecmp (input, "array") == 0) { + else if (strcasecmp(input, "array") == 0) { *res = UCL_ARRAY; } - else if (strcasecmp (input, "integer") == 0) { + else if (strcasecmp(input, "integer") == 0) { *res = UCL_INT; } - else if (strcasecmp (input, "number") == 0) { + else if (strcasecmp(input, "number") == 0) { *res = UCL_FLOAT; } - else if (strcasecmp (input, "string") == 0) { + else if (strcasecmp(input, "string") == 0) { *res = UCL_STRING; } - else if (strcasecmp (input, "boolean") == 0) { + else if (strcasecmp(input, "boolean") == 0) { *res = UCL_BOOLEAN; } - else if (strcasecmp (input, "null") == 0) { + else if (strcasecmp(input, "null") == 0) { *res = UCL_NULL; } - else if (strcasecmp (input, "userdata") == 0) { + else if (strcasecmp(input, "userdata") == 0) { *res = UCL_USERDATA; } else { return false; } return true; } const char * -ucl_object_type_to_string (ucl_type_t type) +ucl_object_type_to_string(ucl_type_t type) { const char *res = "unknown"; switch (type) { case UCL_OBJECT: res = "object"; break; case UCL_ARRAY: res = "array"; break; case UCL_INT: res = "integer"; break; case UCL_FLOAT: case UCL_TIME: res = "number"; break; case UCL_STRING: res = "string"; break; case UCL_BOOLEAN: res = "boolean"; break; case UCL_USERDATA: res = "userdata"; break; case UCL_NULL: res = "null"; break; } return res; } const ucl_object_t * -ucl_parser_get_comments (struct ucl_parser *parser) +ucl_parser_get_comments(struct ucl_parser *parser) { if (parser && parser->comments) { return parser->comments; } return NULL; } const ucl_object_t * -ucl_comments_find (const ucl_object_t *comments, - const ucl_object_t *srch) +ucl_comments_find(const ucl_object_t *comments, + const ucl_object_t *srch) { if (comments && srch) { - return ucl_object_lookup_len (comments, (const char *)&srch, - sizeof (void *)); + return ucl_object_lookup_len(comments, (const char *) &srch, + sizeof(void *)); } return NULL; } -bool -ucl_comments_move (ucl_object_t *comments, - const ucl_object_t *from, const ucl_object_t *to) +bool ucl_comments_move(ucl_object_t *comments, + const ucl_object_t *from, const ucl_object_t *to) { const ucl_object_t *found; ucl_object_t *obj; if (comments && from && to) { - found = ucl_object_lookup_len (comments, - (const char *)&from, sizeof (void *)); + found = ucl_object_lookup_len(comments, + (const char *) &from, sizeof(void *)); if (found) { /* Replace key */ - obj = ucl_object_ref (found); - ucl_object_delete_keyl (comments, (const char *)&from, - sizeof (void *)); - ucl_object_insert_key (comments, obj, (const char *)&to, - sizeof (void *), true); + obj = ucl_object_ref(found); + ucl_object_delete_keyl(comments, (const char *) &from, + sizeof(void *)); + ucl_object_insert_key(comments, obj, (const char *) &to, + sizeof(void *), true); return true; } } return false; } -void -ucl_comments_add (ucl_object_t *comments, const ucl_object_t *obj, - const char *comment) +void ucl_comments_add(ucl_object_t *comments, const ucl_object_t *obj, + const char *comment) { if (comments && obj && comment) { - ucl_object_insert_key (comments, ucl_object_fromstring (comment), - (const char *)&obj, sizeof (void *), true); + ucl_object_insert_key(comments, ucl_object_fromstring(comment), + (const char *) &obj, sizeof(void *), true); } } -void -ucl_parser_set_include_tracer (struct ucl_parser *parser, - ucl_include_trace_func_t func, - void *user_data) +void ucl_parser_set_include_tracer(struct ucl_parser *parser, + ucl_include_trace_func_t func, + void *user_data) { parser->include_trace_func = func; parser->include_trace_ud = user_data; } const char * -ucl_parser_get_cur_file (struct ucl_parser *parser) +ucl_parser_get_cur_file(struct ucl_parser *parser) { return parser->cur_file; } diff --git a/contrib/libucl/tests/CMakeLists.txt b/contrib/libucl/tests/CMakeLists.txt new file mode 100644 index 000000000000..e66c3d10a60a --- /dev/null +++ b/contrib/libucl/tests/CMakeLists.txt @@ -0,0 +1,31 @@ +set(COMMON_TEST_INCLUDES + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_SOURCE_DIR}/uthash +) + +set(COMMON_TEST_LIBS ucl) + +set(TEST_ENV_VARS + "TEST_DIR=${CMAKE_SOURCE_DIR}/tests" + "TEST_OUT_DIR=${CMAKE_BINARY_DIR}/tests" + "TEST_BINARY_DIR=${CMAKE_BINARY_DIR}/tests" +) + +macro(add_ucl_test testname sourcefile wrapper) + add_executable(${testname} ${sourcefile}) + target_include_directories(${testname} PRIVATE ${COMMON_TEST_INCLUDES}) + target_link_libraries(${testname} PRIVATE ${COMMON_TEST_LIBS}) + IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + add_test(NAME ${testname} COMMAND ${CMAKE_SOURCE_DIR}/tests/${wrapper}) + set_tests_properties(${testname} PROPERTIES ENVIRONMENT "${TEST_ENV_VARS}") + ENDIF() +endmacro() + +# Build test binaries always (not just for testing) +add_ucl_test(test_basic test_basic.c basic.test) +add_ucl_test(test_speed test_speed.c speed.test) +add_ucl_test(test_schema test_schema.c schema.test) +add_ucl_test(test_msgpack test_msgpack.c msgpack.test) +add_ucl_test(test_generate test_generate.c generate.test) + diff --git a/contrib/libucl/tests/basic/23-json-with-braces.inc b/contrib/libucl/tests/basic/23-json-with-braces.inc new file mode 100644 index 000000000000..b6f13e15edb7 --- /dev/null +++ b/contrib/libucl/tests/basic/23-json-with-braces.inc @@ -0,0 +1 @@ +{ "a": "b" } diff --git a/contrib/libucl/tests/basic/23-json-without-braces.inc b/contrib/libucl/tests/basic/23-json-without-braces.inc new file mode 100644 index 000000000000..bfad85f2f011 --- /dev/null +++ b/contrib/libucl/tests/basic/23-json-without-braces.inc @@ -0,0 +1,2 @@ +# Note: This is arguably not a valid JSON file, but it is supposed to be parsable UCL. +"b": "c" diff --git a/contrib/libucl/tests/basic/23-ucl-with-braces.inc b/contrib/libucl/tests/basic/23-ucl-with-braces.inc new file mode 100644 index 000000000000..38f5a8708dc3 --- /dev/null +++ b/contrib/libucl/tests/basic/23-ucl-with-braces.inc @@ -0,0 +1 @@ +{ c = "d"; } diff --git a/contrib/libucl/tests/basic/23-ucl-without-braces.inc b/contrib/libucl/tests/basic/23-ucl-without-braces.inc new file mode 100644 index 000000000000..1072dfc8682b --- /dev/null +++ b/contrib/libucl/tests/basic/23-ucl-without-braces.inc @@ -0,0 +1 @@ +d = "e"; diff --git a/contrib/libucl/tests/basic/23.in b/contrib/libucl/tests/basic/23.in new file mode 100644 index 000000000000..8778a5060d09 --- /dev/null +++ b/contrib/libucl/tests/basic/23.in @@ -0,0 +1,8 @@ +a = 1; +b = 2; +.include() "${CURDIR}/23-json-with-braces.inc" +.include() "${CURDIR}/23-json-without-braces.inc" +.include() "${CURDIR}/23-ucl-with-braces.inc" +.include() "${CURDIR}/23-ucl-without-braces.inc" +c = 3; +d = 4; diff --git a/contrib/libucl/tests/basic/23.res b/contrib/libucl/tests/basic/23.res new file mode 100644 index 000000000000..a98313c4e421 --- /dev/null +++ b/contrib/libucl/tests/basic/23.res @@ -0,0 +1,9 @@ +a = 1; +a = "b"; +b = 2; +b = "c"; +c = "d"; +c = 3; +d = "e"; +d = 4; + diff --git a/contrib/libucl/tests/basic/comments.in b/contrib/libucl/tests/basic/comments.in index 3144fa004fa2..fbaa009e6465 100644 --- a/contrib/libucl/tests/basic/comments.in +++ b/contrib/libucl/tests/basic/comments.in @@ -1,25 +1,29 @@ # This test is intended to check various comments in ucl +/***/ +/* + * "" + */ obj { key = value key = "/* value" /* key = value */ # Nested comments key = nested /* adasdasdads /* asdasdasd */asjdasjldaskd /* asdsadasd */ /* /* /* /* /* */ */ */ */ */ # some */ key = quotes # quoted # Quotes /* key = "/* value" key = "*/value" */ } diff --git a/contrib/libucl/tests/basic/issue319.in b/contrib/libucl/tests/basic/issue319.in new file mode 100644 index 000000000000..f21900f1086f --- /dev/null +++ b/contrib/libucl/tests/basic/issue319.in @@ -0,0 +1,3 @@ +key = < #include #include #include "ucl.h" static void ud_dtor (void *ptr) { assert (ptr == NULL); } static const char * ud_emit (void *ptr) { return "test userdata emit"; } int main (int argc, char **argv) { ucl_object_t *obj, *cur, *ar, *ar1, *ref, *test_obj, *comments; ucl_object_iter_t it; const ucl_object_t *found, *it_obj, *test; struct ucl_emitter_functions *fn; FILE *out; unsigned char *emitted; const char *fname_out = NULL; struct ucl_parser *parser; int ret = 0; switch (argc) { case 2: fname_out = argv[1]; break; } if (fname_out != NULL) { out = fopen (fname_out, "w"); if (out == NULL) { exit (-errno); } } else { out = stdout; } obj = ucl_object_typed_new (UCL_OBJECT); /* Keys replacing */ cur = ucl_object_fromstring_common ("value1", 0, UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key0", 0, false); cur = ucl_object_fromdouble (0.1); - assert (ucl_object_replace_key (obj, cur, "key0", 0, false)); + ucl_object_replace_key (obj, cur, "key0", 0, false); /* Create some strings */ cur = ucl_object_fromstring_common (" test string ", 0, UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key1", 0, false); cur = ucl_object_fromstring_common (" test \nstring\n\r\n\b\t\f\\\" ", 0, UCL_STRING_TRIM | UCL_STRING_ESCAPE); ucl_object_insert_key (obj, cur, "key2", 0, false); cur = ucl_object_fromstring_common (" test string \n", 0, 0); ucl_object_insert_key (obj, cur, "key3", 0, false); /* Array of numbers */ ar = ucl_object_typed_new (UCL_ARRAY); cur = ucl_object_fromint (10); ucl_array_append (ar, cur); assert (ucl_array_index_of (ar, cur) == 0); cur = ucl_object_fromdouble (10.1); ucl_array_append (ar, cur); assert (ucl_array_index_of (ar, cur) == 1); cur = ucl_object_fromdouble (9.999); ucl_array_prepend (ar, cur); assert (ucl_array_index_of (ar, cur) == 0); ar1 = ucl_object_copy (ar); cur = ucl_object_fromstring ("abc"); ucl_array_prepend (ar1, cur); cur = ucl_object_fromstring ("cde"); ucl_array_prepend (ar1, cur); cur = ucl_object_fromstring ("абв"); /* UTF8 */ ucl_array_prepend (ar1, cur); cur = ucl_object_fromstring ("Ебв"); /* UTF8 */ ucl_array_prepend (ar1, cur); /* * This is usually broken or fragile as utf collate is far from perfect cur = ucl_object_fromstring ("ёбв"); ucl_array_prepend (ar1, cur); cur = ucl_object_fromstring ("Ёбв"); // hello to @bapt ucl_array_prepend (ar1, cur); */ cur = ucl_object_fromstring ("😎"); /* everybody likes emoji in the code */ ucl_array_prepend (ar1, cur); ucl_object_array_sort (ar1, ucl_object_compare_qsort); /* Removing from an array */ cur = ucl_object_fromdouble (1.0); ucl_array_append (ar, cur); cur = ucl_array_delete (ar, cur); assert (ucl_object_todouble (cur) == 1.0); ucl_object_unref (cur); cur = ucl_object_fromdouble (2.0); ucl_array_append (ar, cur); cur = ucl_array_pop_last (ar); assert (ucl_object_todouble (cur) == 2.0); ucl_object_unref (cur); cur = ucl_object_fromdouble (3.0); ucl_array_prepend (ar, cur); cur = ucl_array_pop_first (ar); assert (ucl_object_todouble (cur) == 3.0); ucl_object_unref (cur); ucl_object_insert_key (obj, ar, "key4", 0, false); cur = ucl_object_frombool (true); /* Ref object to test refcounts */ ref = ucl_object_ref (cur); ucl_object_insert_key (obj, cur, "key4", 0, false); /* Empty strings */ cur = ucl_object_fromstring_common (" ", 0, UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key5", 0, false); cur = ucl_object_fromstring_common ("", 0, UCL_STRING_ESCAPE); ucl_object_insert_key (obj, cur, "key6", 0, false); cur = ucl_object_fromstring_common (" \n", 0, UCL_STRING_ESCAPE); ucl_object_insert_key (obj, cur, "key7", 0, false); /* Numbers and booleans */ cur = ucl_object_fromstring_common ("1mb", 0, UCL_STRING_ESCAPE | UCL_STRING_PARSE); ucl_object_insert_key (obj, cur, "key8", 0, false); cur = ucl_object_fromstring_common ("3.14", 0, UCL_STRING_PARSE); ucl_object_insert_key (obj, cur, "key9", 0, false); cur = ucl_object_fromstring_common ("true", 0, UCL_STRING_PARSE); ucl_object_insert_key (obj, cur, "key10", 0, false); cur = ucl_object_fromstring_common (" off ", 0, UCL_STRING_PARSE | UCL_STRING_TRIM); ucl_object_insert_key (obj, cur, "key11", 0, false); cur = ucl_object_fromstring_common ("gslin@gslin.org", 0, UCL_STRING_PARSE_INT); ucl_object_insert_key (obj, cur, "key12", 0, false); cur = ucl_object_fromstring_common ("#test", 0, UCL_STRING_PARSE_INT); ucl_object_insert_key (obj, cur, "key13", 0, false); cur = ucl_object_frombool (true); ucl_object_insert_key (obj, cur, "k=3", 0, false); ucl_object_insert_key (obj, ar1, "key14", 0, false); cur = ucl_object_new_userdata (ud_dtor, ud_emit, NULL); ucl_object_insert_key (obj, cur, "key15", 0, false); /* More tests for keys */ cur = ucl_object_fromlstring ("test", 3); ucl_object_insert_key (obj, cur, "key16", 0, false); test = ucl_object_lookup_any (obj, "key100", "key200", "key300", "key16", NULL); assert (test == cur); test = ucl_object_lookup_len (obj, "key160", 5); assert (test == cur); cur = ucl_object_pop_key (obj, "key16"); assert (test == cur); test = ucl_object_pop_key (obj, "key16"); assert (test == NULL); test = ucl_object_lookup_len (obj, "key160", 5); assert (test == NULL); /* Objects merging tests */ test_obj = ucl_object_new_full (UCL_OBJECT, 2); ucl_object_insert_key (test_obj, cur, "key16", 0, true); ucl_object_merge (obj, test_obj, true); ucl_object_unref (test_obj); /* Array merging test */ test_obj = ucl_object_new_full (UCL_ARRAY, 3); ucl_array_append (test_obj, ucl_object_fromstring ("test")); ucl_array_merge (test_obj, ar1, false); ucl_object_insert_key (obj, test_obj, "key17", 0, true); /* Object deletion */ cur = ucl_object_fromstring ("test"); ucl_object_insert_key (obj, cur, "key18", 0, true); - assert (ucl_object_delete_key (obj, "key18")); - assert (!ucl_object_delete_key (obj, "key18")); + ucl_object_delete_key (obj, "key18"); + ucl_object_delete_key (obj, "key18"); cur = ucl_object_fromlstring ("test", 4); ucl_object_insert_key (obj, cur, "key18\0\0", 7, true); - assert (ucl_object_lookup_len (obj, "key18\0\0", 7) == cur); - assert (ucl_object_lookup (obj, "key18") == NULL); - assert (ucl_object_lookup_len (obj, "key18\0\1", 7) == NULL); - assert (ucl_object_delete_keyl (obj, "key18\0\0", 7)); + ucl_object_lookup_len (obj, "key18\0\0", 7); + ucl_object_lookup (obj, "key18"); + ucl_object_lookup_len (obj, "key18\0\1", 7); + ucl_object_delete_keyl (obj, "key18\0\0", 7); /* Comments */ comments = ucl_object_typed_new (UCL_OBJECT); found = ucl_object_lookup (obj, "key17"); test = ucl_object_lookup (obj, "key16"); ucl_comments_add (comments, found, "# test comment"); assert (ucl_comments_find (comments, found) != NULL); assert (ucl_comments_find (comments, test) == NULL); ucl_comments_move (comments, found, test); assert (ucl_comments_find (comments, found) == NULL); assert (ucl_comments_find (comments, test) != NULL); /* Array replace */ ar1 = ucl_object_typed_new (UCL_ARRAY); cur = ucl_object_fromstring ("test"); cur = ucl_elt_append (cur, ucl_object_fromstring ("test1")); ucl_array_append (ar1, cur); test = ucl_array_replace_index (ar1, ucl_object_fromstring ("test2"), 0); assert (test == cur); /* Try to find using path */ /* Should exist */ found = ucl_object_lookup_path (obj, "key4.1"); assert (found != NULL && ucl_object_toint (found) == 10); /* . should be ignored */ found = ucl_object_lookup_path (obj, ".key4.1"); assert (found != NULL && ucl_object_toint (found) == 10); /* moar dots... */ found = ucl_object_lookup_path (obj, ".key4........1..."); assert (found != NULL && ucl_object_toint (found) == 10); /* No such index */ found = ucl_object_lookup_path (obj, ".key4.3"); assert (found == NULL); /* No such key */ found = ucl_object_lookup_path (obj, "key9..key1"); assert (found == NULL); /* Test iteration */ it = ucl_object_iterate_new (obj); it_obj = ucl_object_iterate_safe (it, true); assert (!ucl_object_iter_chk_excpn (it)); /* key0 = 0.1 */ assert (ucl_object_type (it_obj) == UCL_FLOAT); it_obj = ucl_object_iterate_safe (it, true); assert (!ucl_object_iter_chk_excpn (it)); /* key1 = "" */ assert (ucl_object_type (it_obj) == UCL_STRING); it_obj = ucl_object_iterate_safe (it, true); assert (!ucl_object_iter_chk_excpn (it)); /* key2 = "" */ assert (ucl_object_type (it_obj) == UCL_STRING); it_obj = ucl_object_iterate_safe (it, true); assert (!ucl_object_iter_chk_excpn (it)); /* key3 = "" */ assert (ucl_object_type (it_obj) == UCL_STRING); it_obj = ucl_object_iterate_safe (it, true); assert (!ucl_object_iter_chk_excpn (it)); /* key4 = ([float, int, float], boolean) */ ucl_object_iterate_reset (it, it_obj); it_obj = ucl_object_iterate_safe (it, true); assert (!ucl_object_iter_chk_excpn (it)); assert (ucl_object_type (it_obj) == UCL_FLOAT); it_obj = ucl_object_iterate_safe (it, true); assert (!ucl_object_iter_chk_excpn (it)); assert (ucl_object_type (it_obj) == UCL_INT); it_obj = ucl_object_iterate_safe (it, true); assert (!ucl_object_iter_chk_excpn (it)); assert (ucl_object_type (it_obj) == UCL_FLOAT); it_obj = ucl_object_iterate_safe (it, true); assert (!ucl_object_iter_chk_excpn (it)); assert (ucl_object_type (it_obj) == UCL_BOOLEAN); ucl_object_iterate_free (it); fn = ucl_object_emit_memory_funcs ((void **)&emitted); - assert (ucl_object_emit_full (obj, UCL_EMIT_CONFIG, fn, comments)); + ucl_object_emit_full (obj, UCL_EMIT_CONFIG, fn, comments); fprintf (out, "%s\n", emitted); ucl_object_emit_funcs_free (fn); ucl_object_unref (obj); ucl_object_unref (comments); parser = ucl_parser_new (UCL_PARSER_NO_IMPLICIT_ARRAYS); if (ucl_parser_add_chunk_full (parser, emitted, strlen (emitted), 3, UCL_DUPLICATE_ERROR, UCL_PARSE_UCL)) { /* Should fail due to duplicate */ assert (0); } else { assert (ucl_parser_get_error (parser) != NULL); ucl_parser_clear_error (parser); ucl_parser_free (parser); parser = ucl_parser_new (0); ucl_parser_add_chunk_full (parser, emitted, strlen (emitted), 3, UCL_DUPLICATE_MERGE, UCL_PARSE_UCL); } assert (ucl_parser_get_column (parser) == 0); assert (ucl_parser_get_linenum (parser) != 0); ucl_parser_clear_error (parser); assert (ucl_parser_get_error_code (parser) == 0); obj = ucl_parser_get_object (parser); ucl_parser_free (parser); ucl_object_unref (obj); if (emitted != NULL) { free (emitted); } fclose (out); /* Ref should still be accessible */ ref->value.iv = 100500; ucl_object_unref (ref); return ret; } diff --git a/contrib/libucl/tests/test_schema.c b/contrib/libucl/tests/test_schema.c index 675764925507..cfc6aafdefe1 100644 --- a/contrib/libucl/tests/test_schema.c +++ b/contrib/libucl/tests/test_schema.c @@ -1,164 +1,169 @@ /* Copyright (c) 2014, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "ucl.h" +#include "ucl_internal.h" + #include #include + +#ifndef _WIN32 #include -#include "ucl.h" +#endif static int read_stdin (char **buf) { int size = BUFSIZ, remain, ret; char *p; *buf = malloc (size); if (*buf == NULL) { return -1; } p = *buf; remain = size; while ((ret = read (STDIN_FILENO, p, remain - 1)) > 0) { remain -= ret; p += ret; if (remain <= 1) { *buf = realloc (*buf, size * 2); if (*buf == NULL) { return -1; } p = *buf + size - 1; remain = size + 1; size *= 2; } } *p = '\0'; return ret; } static bool perform_test (const ucl_object_t *schema, const ucl_object_t *obj, struct ucl_schema_error *err) { const ucl_object_t *valid, *data, *description; bool match; data = ucl_object_lookup (obj, "data"); description = ucl_object_lookup (obj, "description"); valid = ucl_object_lookup (obj, "valid"); if (data == NULL || description == NULL || valid == NULL) { fprintf (stdout, "Bad test case\n"); return false; } match = ucl_object_validate (schema, data, err); if (match != ucl_object_toboolean (valid)) { fprintf (stdout, "Test case '%s' failed (expected %s): '%s'\n", ucl_object_tostring (description), ucl_object_toboolean (valid) ? "valid" : "invalid", err->msg); fprintf (stdout, "%s\n", ucl_object_emit (data, UCL_EMIT_CONFIG)); fprintf (stdout, "%s\n", ucl_object_emit (schema, UCL_EMIT_CONFIG)); return false; } return true; } static int perform_tests (const ucl_object_t *obj) { struct ucl_schema_error err; ucl_object_iter_t iter = NULL; const ucl_object_t *schema, *tests, *description, *test; if (obj->type != UCL_OBJECT) { fprintf (stdout, "Bad test case\n"); return EXIT_FAILURE; } schema = ucl_object_lookup (obj, "schema"); tests = ucl_object_lookup (obj, "tests"); description = ucl_object_lookup (obj, "description"); if (schema == NULL || tests == NULL || description == NULL) { fprintf (stdout, "Bad test case\n"); return EXIT_FAILURE; } memset (&err, 0, sizeof (err)); while ((test = ucl_object_iterate (tests, &iter, true)) != NULL) { if (!perform_test (schema, test, &err)) { fprintf (stdout, "Test suite '%s' failed\n", ucl_object_tostring (description)); return EXIT_FAILURE; } } return 0; } int main (int argc, char **argv) { char *buf = NULL; struct ucl_parser *parser; ucl_object_t *obj = NULL; const ucl_object_t *elt; ucl_object_iter_t iter = NULL; int ret = 0; if (read_stdin (&buf) == -1) { exit (EXIT_FAILURE); } parser = ucl_parser_new (0); ucl_parser_add_string (parser, buf, 0); if (ucl_parser_get_error (parser) != NULL) { fprintf (stdout, "Error occurred: %s\n", ucl_parser_get_error (parser)); ret = 1; return EXIT_FAILURE; } obj = ucl_parser_get_object (parser); ucl_parser_free (parser); while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) { ret = perform_tests (elt); if (ret != 0) { break; } } ucl_object_unref (obj); return ret; } diff --git a/contrib/libucl/tests/test_speed.c b/contrib/libucl/tests/test_speed.c index 51476c94940b..ed539402067b 100644 --- a/contrib/libucl/tests/test_speed.c +++ b/contrib/libucl/tests/test_speed.c @@ -1,151 +1,160 @@ /* Copyright (c) 2013, Vsevolod Stakhov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "ucl.h" +#include "ucl_internal.h" + #include + +#ifndef _WIN32 #include -#include #include +#endif + +#include #include #include + +#ifndef _WIN32 #include +#endif + #include #include #ifdef __APPLE__ #ifdef HAVE_MACH_MACH_TIME_H #include #endif #endif -#include "ucl.h" - static double get_ticks (void) { double res; #if defined(__APPLE__) && defined(HAVE_MACH_MACH_TIME_H) res = mach_absolute_time () / 1000000000.; #else struct timespec ts; clock_gettime (CLOCK_MONOTONIC, &ts); res = (double)ts.tv_sec + ts.tv_nsec / 1000000000.; #endif return res; } int main (int argc, char **argv) { void *map; struct ucl_parser *parser; ucl_object_t *obj; int fin; unsigned char *emitted; struct stat st; const char *fname_in = NULL; int ret = 0; double start, end, seconds; switch (argc) { case 2: fname_in = argv[1]; break; } fin = open (fname_in, O_RDONLY); if (fin == -1) { perror ("open failed"); exit (EXIT_FAILURE); } parser = ucl_parser_new (UCL_PARSER_ZEROCOPY); (void)fstat (fin, &st); map = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fin, 0); if (map == MAP_FAILED) { perror ("mmap failed"); exit (EXIT_FAILURE); } close (fin); start = get_ticks (); ucl_parser_add_chunk (parser, map, st.st_size); obj = ucl_parser_get_object (parser); end = get_ticks (); seconds = end - start; printf ("ucl: parsed input in %.4f seconds\n", seconds); if (ucl_parser_get_error(parser)) { printf ("Error occurred: %s\n", ucl_parser_get_error(parser)); ret = 1; goto err; } start = get_ticks (); emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG); end = get_ticks (); seconds = end - start; printf ("ucl: emitted config in %.4f seconds\n", seconds); free (emitted); start = get_ticks (); emitted = ucl_object_emit (obj, UCL_EMIT_JSON); end = get_ticks (); seconds = end - start; printf ("ucl: emitted json in %.4f seconds\n", seconds); free (emitted); start = get_ticks (); emitted = ucl_object_emit (obj, UCL_EMIT_JSON_COMPACT); end = get_ticks (); seconds = end - start; printf ("ucl: emitted compact json in %.4f seconds\n", seconds); free (emitted); start = get_ticks (); emitted = ucl_object_emit (obj, UCL_EMIT_YAML); end = get_ticks (); seconds = end - start; printf ("ucl: emitted yaml in %.4f seconds\n", seconds); free (emitted); ucl_parser_free (parser); ucl_object_unref (obj); err: munmap (map, st.st_size); return ret; }