mirror of
https://git.freebsd.org/src.git
synced 2026-01-11 19:57:22 +00:00
Import libucl 0.9.3
This commit is contained in:
parent
1e2f270469
commit
1dd83cf7e5
40 changed files with 4977 additions and 4770 deletions
67
.clang-format
Normal file
67
.clang-format
Normal file
|
|
@ -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
|
||||
2
.github/workflows/cmake-multi-platform.yml
vendored
2
.github/workflows/cmake-multi-platform.yml
vendored
|
|
@ -72,4 +72,4 @@ jobs:
|
|||
working-directory: ${{ steps.strings.outputs.build-output-dir }}
|
||||
# Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: ctest --build-config ${{ matrix.build_type }}
|
||||
run: ctest --progress --output-on-failure --build-config ${{ matrix.build_type }}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0 FATAL_ERROR)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5.0 FATAL_ERROR)
|
||||
PROJECT(libucl C)
|
||||
|
||||
SET(LIBUCL_VERSION_MAJOR 0)
|
||||
SET(LIBUCL_VERSION_MINOR 9)
|
||||
SET(LIBUCL_VERSION_PATCH 2)
|
||||
SET(LIBUCL_VERSION_PATCH 3)
|
||||
|
||||
SET(LIBUCL_VERSION
|
||||
"${LIBUCL_VERSION_MAJOR}.${LIBUCL_VERSION_MINOR}.${LIBUCL_VERSION_PATCH}")
|
||||
|
|
@ -19,6 +19,9 @@ OPTION(BUILD_SHARED_LIBS "Build Shared Libraries [default: OFF]" OFF)
|
|||
OPTION(ENABLE_LUA "Enable lua support [default: OFF]" OFF)
|
||||
OPTION(ENABLE_LUAJIT "Enable luajit support [default: OFF]" OFF)
|
||||
OPTION(ENABLE_UTILS "Enable building utility binaries [default: OFF]" OFF)
|
||||
OPTION(ENABLE_SANITIZERS "Enable sanitizers (address, undefined, etc.) [default: OFF]" OFF)
|
||||
SET(SANITIZE_TYPE "address" CACHE STRING "Type of sanitizer to use (address, thread, undefined, memory, leak)")
|
||||
SET_PROPERTY(CACHE SANITIZE_TYPE PROPERTY STRINGS address thread undefined memory leak)
|
||||
|
||||
# Find lua installation
|
||||
MACRO(FindLua)
|
||||
|
|
@ -195,6 +198,23 @@ ENDIF(SUPPORT_WUNUSED_PARAMETER)
|
|||
|
||||
SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_WARN_FLAGS}" )
|
||||
|
||||
IF(ENABLE_SANITIZERS MATCHES "ON")
|
||||
SET(SANITIZE_FLAGS "-fsanitize=${SANITIZE_TYPE} -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
SET(CMAKE_REQUIRED_FLAGS "${SANITIZE_FLAGS}")
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "${SANITIZE_FLAGS}")
|
||||
CHECK_C_SOURCE_COMPILES("int main() { return 0; }" COMPILER_SUPPORTS_SANITIZE)
|
||||
UNSET(CMAKE_REQUIRED_FLAGS)
|
||||
UNSET(CMAKE_REQUIRED_LIBRARIES)
|
||||
IF(COMPILER_SUPPORTS_SANITIZE)
|
||||
MESSAGE(STATUS "Enabling sanitizer: ${SANITIZE_TYPE}")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZE_FLAGS}")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SANITIZE_FLAGS}")
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Compiler does not support -fsanitize=${SANITIZE_TYPE}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(ENABLE_URL_SIGN MATCHES "ON")
|
||||
IF(OPENSSL_FOUND)
|
||||
SET(HAVE_OPENSSL 1)
|
||||
|
|
@ -258,10 +278,12 @@ IF(ENABLE_LUA MATCHES "ON")
|
|||
INCLUDE_DIRECTORIES("${LUA_INCLUDE_DIR}")
|
||||
ENDIF(NOT LUA_FOUND)
|
||||
ELSE(ENABLE_LUAJIT MATCHES "ON")
|
||||
FindLua(VERSION_MAJOR "5" VERSION_MINOR "2" ROOT "${LUA_ROOT}")
|
||||
IF(NOT LUA_FOUND)
|
||||
FindLua(VERSION_MAJOR "5" VERSION_MINOR "1" ROOT "${LUA_ROOT}")
|
||||
ENDIF(NOT LUA_FOUND)
|
||||
FOREACH(LUA_MINOR RANGE 4 1 -1)
|
||||
FindLua(VERSION_MAJOR "5" VERSION_MINOR ${LUA_MINOR} ROOT "${LUA_ROOT}")
|
||||
IF(LUA_FOUND)
|
||||
BREAK()
|
||||
ENDIF(LUA_FOUND)
|
||||
ENDFOREACH(LUA_MINOR RANGE 4 1 -1)
|
||||
IF(NOT LUA_FOUND)
|
||||
MESSAGE(FATAL_ERROR "Lua not found, lua support is required")
|
||||
ELSE(NOT LUA_FOUND)
|
||||
|
|
@ -309,6 +331,9 @@ SET_TARGET_PROPERTIES(ucl PROPERTIES
|
|||
INSTALL(TARGETS ucl EXPORT uclConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
ENABLE_TESTING()
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
|
||||
IF(ENABLE_UTILS MATCHES "ON")
|
||||
ADD_SUBDIRECTORY(utils)
|
||||
ENDIF()
|
||||
|
|
|
|||
10
ChangeLog.md
10
ChangeLog.md
|
|
@ -1,5 +1,15 @@
|
|||
# Version history
|
||||
|
||||
## Libucl 0.9.3
|
||||
|
||||
- Fix invalid JSON emission when merging objects (Fixes #312)
|
||||
- Fix heap-buffer-overflow in ucl_maybe_parse_number (Fixes #344, #328)
|
||||
- Fix Use-After-Free in ucl_hash_insert by ignoring duplicates in different containers (Fixes #347)
|
||||
- Fix heap-buffer-overflow in ucl_parse_multiline_string
|
||||
- Add support of sanitizers to cmake
|
||||
- Fix allocator mismatches in libucl
|
||||
- Various other fixes and improvements
|
||||
|
||||
## Libucl 0.9.0
|
||||
|
||||
* 803b588 Breaking: Try to fix streamline embedding
|
||||
|
|
|
|||
11
configure.ac
11
configure.ac
|
|
@ -1,12 +1,14 @@
|
|||
m4_define([maj_ver], [0])
|
||||
m4_define([med_ver], [9])
|
||||
m4_define([min_ver], [2])
|
||||
m4_define([so_version], [9:0:2])
|
||||
m4_define([min_ver], [3])
|
||||
m4_define([so_version], [9:0:3])
|
||||
m4_define([ucl_version], [maj_ver.med_ver.min_ver])
|
||||
|
||||
AC_PREREQ([2.70])
|
||||
|
||||
AC_INIT([libucl],[ucl_version],[https://github.com/vstakhov/libucl],[libucl])
|
||||
AC_CONFIG_SRCDIR([configure.ac])
|
||||
AM_INIT_AUTOMAKE([1.11 foreign -Wall -Wportability no-dist-gzip dist-xz])
|
||||
AM_INIT_AUTOMAKE([foreign -Wall -Wportability no-dist-gzip dist-xz 1.14])
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
UCL_VERSION=ucl_version
|
||||
|
|
@ -15,8 +17,7 @@ SO_VERSION=so_version
|
|||
AC_SUBST(UCL_VERSION)
|
||||
AC_SUBST(SO_VERSION)
|
||||
|
||||
AC_PROG_CC_C99
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CC
|
||||
AM_PROG_AR
|
||||
LT_INIT
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ struct ucl_lua_funcdata {
|
|||
/**
|
||||
* 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
|
||||
|
|
@ -52,7 +52,7 @@ UCL_EXTERN int luaopen_ucl (lua_State *L);
|
|||
* @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
|
||||
|
|
@ -60,7 +60,7 @@ UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx);
|
|||
* @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
|
||||
|
|
@ -68,18 +68,18 @@ UCL_EXTERN ucl_object_t* ucl_object_lua_import_escape (lua_State *L, int idx);
|
|||
* @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_ */
|
||||
|
|
|
|||
570
include/ucl++.h
570
include/ucl++.h
|
|
@ -37,57 +37,57 @@
|
|||
|
||||
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<std::string *>(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<std::string *>(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<std::string *>(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<std::string *>(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()
|
||||
|
|
@ -98,26 +98,25 @@ private:
|
|||
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<std::set<std::string> *>(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;
|
||||
|
||||
|
|
@ -126,89 +125,96 @@ private:
|
|||
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 <typename C, typename P>
|
||||
static Ucl parse_with_strategy_function (C config_func, P parse_func, std::string &err)
|
||||
template<typename C, typename P>
|
||||
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<ucl_object_t, ucl_deleter> 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<void> it;
|
||||
std::unique_ptr<Ucl> cur;
|
||||
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
const_iterator(const Ucl &obj) {
|
||||
it = std::shared_ptr<void>(ucl_object_iterate_new (obj.obj.get()),
|
||||
ucl_iter_deleter());
|
||||
cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true)));
|
||||
const_iterator(const Ucl &obj)
|
||||
{
|
||||
it = std::shared_ptr<void>(ucl_object_iterate_new(obj.obj.get()),
|
||||
ucl_iter_deleter());
|
||||
cur.reset(new Ucl(ucl_object_iterate_safe(it.get(), true)));
|
||||
if (!cur->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
|
||||
{
|
||||
|
|
@ -224,135 +230,154 @@ public:
|
|||
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 bool is_variable (const std::string &str) const
|
||||
virtual ~variable_replacer()
|
||||
{
|
||||
return !str.empty ();
|
||||
}
|
||||
|
||||
virtual std::string replace (const std::string &var) const = 0;
|
||||
virtual bool is_variable(const std::string &str) const
|
||||
{
|
||||
return !str.empty();
|
||||
}
|
||||
|
||||
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<int64_t>(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 <class T, class = decltype(&T::to_ucl)>
|
||||
Ucl(const T &t) : Ucl(t.to_ucl()) {}
|
||||
template<class T, class = decltype(&T::to_ucl)>
|
||||
Ucl(const T &t)
|
||||
: Ucl(t.to_ucl())
|
||||
{
|
||||
}
|
||||
|
||||
// Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
|
||||
template <class M, typename std::enable_if<
|
||||
std::is_constructible<std::string, typename M::key_type>::value
|
||||
&& std::is_constructible<Ucl, typename M::mapped_type>::value,
|
||||
int>::type = 0>
|
||||
Ucl(const M &m) {
|
||||
obj.reset (ucl_object_typed_new (UCL_OBJECT));
|
||||
auto cobj = obj.get ();
|
||||
template<class M, typename std::enable_if<
|
||||
std::is_constructible<std::string, typename M::key_type>::value && std::is_constructible<Ucl, typename M::mapped_type>::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 <class V, typename std::enable_if<
|
||||
std::is_constructible<Ucl, typename V::value_type>::value,
|
||||
int>::type = 0>
|
||||
Ucl(const V &v) {
|
||||
obj.reset (ucl_object_typed_new (UCL_ARRAY));
|
||||
auto cobj = obj.get ();
|
||||
template<class V, typename std::enable_if<
|
||||
std::is_constructible<Ucl, typename V::value_type>::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;
|
||||
|
||||
|
|
@ -363,7 +388,7 @@ public:
|
|||
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;
|
||||
|
||||
|
|
@ -374,7 +399,7 @@ public:
|
|||
return default_val;
|
||||
}
|
||||
|
||||
bool bool_value (const bool default_val = false) const
|
||||
bool bool_value(const bool default_val = false) const
|
||||
{
|
||||
bool res;
|
||||
|
||||
|
|
@ -385,9 +410,9 @@ public:
|
|||
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;
|
||||
|
|
@ -396,35 +421,40 @@ public:
|
|||
return default_val;
|
||||
}
|
||||
|
||||
size_t size () const
|
||||
std::string forced_string_value() const
|
||||
{
|
||||
if (type () == UCL_ARRAY) {
|
||||
return ucl_array_size (obj.get());
|
||||
return ucl_object_tostring_forced(obj.get());
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
@ -434,285 +464,297 @@ public:
|
|||
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<void *>(&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<std::string, std::string>(), err, duplicate_strategy);
|
||||
return parse(in, std::map<std::string, std::string>(), err, duplicate_strategy);
|
||||
}
|
||||
|
||||
static Ucl parse (const std::string &in, const std::map<std::string, std::string> &vars,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
static Ucl parse(const std::string &in, const std::map<std::string, std::string> &vars,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
{
|
||||
std::vector< std::tuple< std::string, macro_handler_s, void * > > emptyVector;
|
||||
return parse ( in, vars, emptyVector, err, duplicate_strategy );
|
||||
std::vector<std::tuple<std::string, macro_handler_s, void *>> emptyVector;
|
||||
return parse(in, vars, emptyVector, err, duplicate_strategy);
|
||||
}
|
||||
|
||||
//Macro handler will receive a macro_userdata_s as void *ud
|
||||
static Ucl parse (const std::string &in,
|
||||
std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
static Ucl parse(const std::string &in,
|
||||
std::vector<std::tuple<std::string /*name*/, macro_handler_s, void * /*userdata*/>> ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
{
|
||||
return parse (in, std::map<std::string, std::string>(), macros, err, duplicate_strategy);
|
||||
return parse(in, std::map<std::string, std::string>(), macros, err, duplicate_strategy);
|
||||
}
|
||||
|
||||
//Macro handler will receive a macro_userdata_s as void *ud
|
||||
static Ucl parse (const std::string &in, const std::map<std::string, std::string> &vars,
|
||||
std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
static Ucl parse(const std::string &in, const std::map<std::string, std::string> &vars,
|
||||
std::vector<std::tuple<std::string /*name*/, macro_handler_s, void * /*userdata*/>> ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
{
|
||||
//Preserve macro_userdata_s memory for later use in parse_with_strategy_function()
|
||||
std::vector<macro_userdata_s> userdata_list;
|
||||
userdata_list.reserve (macros.size());
|
||||
auto config_func = [&userdata_list, &vars, ¯os] (ucl_parser *parser) {
|
||||
for (const auto & item : vars) {
|
||||
ucl_parser_register_variable (parser, item.first.c_str (), item.second.c_str ());
|
||||
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<void*>(&userdata_list.back()));
|
||||
ucl_parser_register_macro(parser,
|
||||
std::get<0>(macro).c_str(),
|
||||
std::get<1>(macro).handler,
|
||||
reinterpret_cast<void *>(&userdata_list.back()));
|
||||
}
|
||||
else if (std::get<1>(macro).ctx_handler != NULL) {
|
||||
ucl_parser_register_context_macro (parser,
|
||||
std::get<0>(macro).c_str(),
|
||||
std::get<1>(macro).ctx_handler,
|
||||
reinterpret_cast<void*>(&userdata_list.back()));
|
||||
ucl_parser_register_context_macro(parser,
|
||||
std::get<0>(macro).c_str(),
|
||||
std::get<1>(macro).ctx_handler,
|
||||
reinterpret_cast<void *>(&userdata_list.back()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto parse_func = [&in, &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<std::tuple<std::string, macro_handler_s, void *>> emptyVector;
|
||||
return parse(in, replacer, emptyVector, err, duplicate_strategy);
|
||||
}
|
||||
|
||||
//Macro handler will receive a macro_userdata_s as void *ud
|
||||
static Ucl parse (const std::string &in, const variable_replacer &replacer,
|
||||
std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
static Ucl parse(const std::string &in, const variable_replacer &replacer,
|
||||
std::vector<std::tuple<std::string /*name*/, macro_handler_s, void * /*userdata*/>> ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
{
|
||||
//Preserve macro_userdata_s memory for later use in parse_with_strategy_function()
|
||||
std::vector<macro_userdata_s> userdata_list;
|
||||
userdata_list.reserve (macros.size());
|
||||
auto config_func = [&userdata_list, &replacer, ¯os] (ucl_parser *parser) {
|
||||
ucl_parser_set_variables_handler (parser, ucl_variable_replacer, &const_cast<variable_replacer &>(replacer));
|
||||
for (auto & macro : macros) {
|
||||
userdata_list.push_back ({parser, std::get<2>(macro)});
|
||||
userdata_list.reserve(macros.size());
|
||||
auto config_func = [&userdata_list, &replacer, ¯os](ucl_parser *parser) {
|
||||
ucl_parser_set_variables_handler(parser, ucl_variable_replacer, &const_cast<variable_replacer &>(replacer));
|
||||
for (auto ¯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<void*>(&userdata_list.back()));
|
||||
ucl_parser_register_macro(parser,
|
||||
std::get<0>(macro).c_str(),
|
||||
std::get<1>(macro).handler,
|
||||
reinterpret_cast<void *>(&userdata_list.back()));
|
||||
}
|
||||
else if (std::get<1>(macro).ctx_handler != NULL) {
|
||||
ucl_parser_register_context_macro (parser,
|
||||
std::get<0>(macro).c_str(),
|
||||
std::get<1>(macro).ctx_handler,
|
||||
reinterpret_cast<void*>(&userdata_list.back()));
|
||||
ucl_parser_register_context_macro(parser,
|
||||
std::get<0>(macro).c_str(),
|
||||
std::get<1>(macro).ctx_handler,
|
||||
reinterpret_cast<void *>(&userdata_list.back()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto parse_func = [&in, &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<std::string, std::string>(), err, duplicate_strategy);
|
||||
return parse(in, std::map<std::string, std::string>(), err, duplicate_strategy);
|
||||
}
|
||||
|
||||
static Ucl parse (const char *in, const std::map<std::string, std::string> &vars, std::string &err)
|
||||
static Ucl parse(const char *in, const std::map<std::string, std::string> &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<std::tuple<std::string /*name*/, macro_handler_s, void * /*userdata*/>> ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
{
|
||||
return parse (in, std::map<std::string, std::string>(), macros, err, duplicate_strategy);
|
||||
return parse(in, std::map<std::string, std::string>(), macros, err, duplicate_strategy);
|
||||
}
|
||||
|
||||
//Macro handler will receive a macro_userdata_s as void *ud
|
||||
static Ucl parse (const char *in, const std::map<std::string, std::string> &vars,
|
||||
std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
static Ucl parse(const char *in, const std::map<std::string, std::string> &vars,
|
||||
std::vector<std::tuple<std::string /*name*/, macro_handler_s, void * /*userdata*/>> ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
{
|
||||
if (!in) {
|
||||
err = "null input";
|
||||
return nullptr;
|
||||
}
|
||||
return parse (std::string (in), vars, macros, err, duplicate_strategy);
|
||||
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<std::tuple<std::string /*name*/, macro_handler_s, void * /*userdata*/>> ¯os,
|
||||
std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND)
|
||||
{
|
||||
if (!in) {
|
||||
err = "null input";
|
||||
return nullptr;
|
||||
}
|
||||
return parse (std::string (in), replacer, 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<std::string, std::string>(), err);
|
||||
return parse_from_file(filename, std::map<std::string, std::string>(), err);
|
||||
}
|
||||
|
||||
static Ucl parse_from_file (const std::string &filename, const std::map<std::string, std::string> &vars, std::string &err)
|
||||
static Ucl parse_from_file(const std::string &filename, const std::map<std::string, std::string> &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<variable_replacer &>(replacer));
|
||||
auto config_func = [&replacer](ucl_parser *parser) {
|
||||
ucl_parser_set_variables_handler(parser, ucl_variable_replacer,
|
||||
&const_cast<variable_replacer &>(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<std::string> find_variable (const std::string &in)
|
||||
static std::vector<std::string> find_variable(const std::string &in)
|
||||
{
|
||||
auto parser = ucl_parser_new (UCL_PARSER_DEFAULT);
|
||||
auto parser = ucl_parser_new(UCL_PARSER_DEFAULT);
|
||||
|
||||
std::set<std::string> 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<std::string> 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<std::string> find_variable (const char *in)
|
||||
static std::vector<std::string> find_variable(const char *in)
|
||||
{
|
||||
if (!in) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
return find_variable (std::string (in));
|
||||
return find_variable(std::string(in));
|
||||
}
|
||||
|
||||
static std::vector<std::string> find_variable_from_file (const std::string &filename)
|
||||
static std::vector<std::string> 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<std::string> 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<std::string> 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;
|
||||
|
|
@ -736,4 +778,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
};
|
||||
};// namespace ucl
|
||||
|
|
|
|||
681
include/ucl.h
681
include/ucl.h
File diff suppressed because it is too large
Load diff
|
|
@ -648,7 +648,13 @@ 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);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
AC_DEFUN([AX_CODE_COVERAGE],
|
||||
[
|
||||
|
||||
AC_ARG_ENABLE(coverage, AC_HELP_STRING([--enable-coverage],[configure code coverage analysis tools]))
|
||||
AC_ARG_ENABLE(coverage, AS_HELP_STRING([--enable-coverage],[configure code coverage analysis tools]))
|
||||
|
||||
HAVE_GCOV_TOOLS=0
|
||||
|
||||
|
|
|
|||
355
src/mum.h
355
src/mum.h
|
|
@ -69,14 +69,14 @@ typedef unsigned __int64 uint64_t;
|
|||
#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)
|
||||
|
|
@ -95,93 +95,108 @@ 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;
|
||||
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
|
||||
/* 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 <libkern/OSByteOrder.h>
|
||||
#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 <byteswap.h>
|
||||
#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
|
||||
|
|
@ -214,71 +229,74 @@ _mum_le32 (uint32_t v) {
|
|||
#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;
|
||||
_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
|
||||
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)
|
||||
|
|
@ -288,16 +306,14 @@ _mum_final (uint64_t h) {
|
|||
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
|
||||
|
|
@ -317,101 +333,108 @@ _mum_hash_avx2 (const void * key, size_t len, uint64_t seed) {
|
|||
|
||||
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)];
|
||||
_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);
|
||||
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;
|
||||
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 ();
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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
|
||||
|
|
|
|||
300
src/tree.h
300
src/tree.h
|
|
@ -43,177 +43,167 @@
|
|||
#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_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_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_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_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_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_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_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_INIT(head, cmp) \
|
||||
do { \
|
||||
(head)->th_root = 0; \
|
||||
(head)->th_cmp = (cmp); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#endif /* __tree_h */
|
||||
|
|
|
|||
|
|
@ -27,240 +27,239 @@
|
|||
#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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,20 +40,20 @@
|
|||
* 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);
|
||||
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)
|
||||
#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
|
||||
|
|
@ -64,27 +64,25 @@ 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))
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -93,11 +91,11 @@ const struct ucl_emitter_operations ucl_standartd_emitter_ops[] = {
|
|||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,8 +105,8 @@ ucl_add_tabs (const struct ucl_emitter_functions *func, unsigned int tabs,
|
|||
* @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;
|
||||
|
||||
|
|
@ -118,52 +116,52 @@ ucl_emitter_print_key (bool print_key, struct ucl_emitter_context *ctx,
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -171,15 +169,15 @@ ucl_emitter_finish_object (struct ucl_emitter_context *ctx,
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -190,27 +188,27 @@ ucl_emitter_finish_object (struct ucl_emitter_context *ctx,
|
|||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -219,25 +217,25 @@ ucl_emitter_common_end_object (struct ucl_emitter_context *ctx,
|
|||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -247,8 +245,8 @@ ucl_emitter_common_end_array (struct ucl_emitter_context *ctx,
|
|||
* @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;
|
||||
|
|
@ -257,33 +255,34 @@ ucl_emitter_common_start_array (struct ucl_emitter_context *ctx,
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -291,13 +290,11 @@ ucl_emitter_common_start_array (struct ucl_emitter_context *ctx,
|
|||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -307,8 +304,8 @@ ucl_emitter_common_start_array (struct ucl_emitter_context *ctx,
|
|||
* @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;
|
||||
|
|
@ -317,57 +314,53 @@ ucl_emitter_common_start_object (struct ucl_emitter_context *ctx,
|
|||
|
||||
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 <ident_level>{
|
||||
* <ident_level + 1><object content>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -384,8 +377,8 @@ ucl_emitter_common_start_object (struct ucl_emitter_context *ctx,
|
|||
* @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;
|
||||
|
|
@ -395,31 +388,33 @@ ucl_emitter_common_elt (struct ucl_emitter_context *ctx,
|
|||
|
||||
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;
|
||||
|
|
@ -429,81 +424,84 @@ ucl_emitter_common_elt (struct ucl_emitter_context *ctx,
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -512,26 +510,31 @@ ucl_emitter_common_elt (struct ucl_emitter_context *ctx,
|
|||
/*
|
||||
* 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)
|
||||
|
|
@ -540,8 +543,8 @@ 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;
|
||||
|
|
@ -550,46 +553,47 @@ ucl_emit_msgpack_elt (struct ucl_emitter_context *ctx,
|
|||
|
||||
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
|
||||
|
|
@ -602,68 +606,66 @@ ucl_emit_msgpack_elt (struct ucl_emitter_context *ctx,
|
|||
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;
|
||||
|
|
@ -673,40 +675,39 @@ ucl_object_emit_len (const ucl_object_t *obj, enum ucl_emitter emit_type,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,39 +57,38 @@ struct ucl_emitter_context_streamline {
|
|||
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;
|
||||
|
|
@ -101,7 +100,7 @@ ucl_object_emit_streamline_start_container (struct ucl_emitter_context *ctx,
|
|||
}
|
||||
|
||||
top = sctx->containers;
|
||||
st = malloc (sizeof (*st));
|
||||
st = malloc(sizeof(*st));
|
||||
if (st != NULL) {
|
||||
st->empty = true;
|
||||
if (top && !top->is_array) {
|
||||
|
|
@ -111,19 +110,26 @@ ucl_object_emit_streamline_start_container (struct ucl_emitter_context *ctx,
|
|||
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 if (obj != NULL && obj->type == UCL_OBJECT) {
|
||||
st->is_array = false;
|
||||
sctx->ops->ucl_emitter_start_object(ctx, obj, top == NULL, print_key);
|
||||
}
|
||||
else {
|
||||
st->is_array = false;
|
||||
sctx->ops->ucl_emitter_start_object (ctx, obj, top == NULL, print_key);
|
||||
/* API MISUSE */
|
||||
free(st);
|
||||
|
||||
return false;
|
||||
}
|
||||
LL_PREPEND (sctx->containers, st);
|
||||
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;
|
||||
|
|
@ -138,11 +144,10 @@ ucl_object_emit_streamline_add_object (
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -151,24 +156,23 @@ ucl_object_emit_streamline_end_container (struct ucl_emitter_context *ctx)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,39 +43,17 @@ static const struct ucl_emitter_context ucl_standard_emitters[] = {
|
|||
.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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -84,7 +62,7 @@ _ucl_emitter_free(void *p)
|
|||
* @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];
|
||||
|
|
@ -98,132 +76,129 @@ ucl_emit_get_standard_context (enum ucl_emitter emit_type)
|
|||
* @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 ("<<EOD\n", sizeof ("<<EOD\n") - 1, func->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("<<EOD\n", sizeof("<<EOD\n") - 1, func->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';
|
||||
}
|
||||
|
|
@ -232,39 +207,39 @@ ucl_utstring_append_character (unsigned char c, size_t len, void *ud)
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
@ -274,52 +249,52 @@ ucl_utstring_append_double (double val, void *ud)
|
|||
* 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;
|
||||
|
|
@ -329,31 +304,31 @@ ucl_file_append_double (double val, void *ud)
|
|||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -361,51 +336,51 @@ ucl_fd_append_character (unsigned char c, size_t len, void *ud)
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
@ -413,7 +388,7 @@ ucl_object_emit_memory_funcs (void **pmem)
|
|||
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;
|
||||
|
|
@ -422,12 +397,12 @@ ucl_object_emit_memory_funcs (void **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;
|
||||
|
|
@ -441,22 +416,22 @@ ucl_object_emit_file_funcs (FILE *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;
|
||||
|
|
@ -468,20 +443,19 @@ ucl_object_emit_fd_funcs (int fd)
|
|||
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;
|
||||
|
|
@ -490,43 +464,43 @@ ucl_object_emit_single_json (const ucl_object_t *obj)
|
|||
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;
|
||||
|
|
@ -534,12 +508,11 @@ ucl_object_emit_single_json (const ucl_object_t *obj)
|
|||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
312
src/ucl_hash.c
312
src/ucl_hash.c
|
|
@ -42,7 +42,7 @@ struct ucl_hash_struct {
|
|||
};
|
||||
|
||||
static uint64_t
|
||||
ucl_hash_seed (void)
|
||||
ucl_hash_seed(void)
|
||||
{
|
||||
static uint64_t seed;
|
||||
if (seed == 0) {
|
||||
|
|
@ -50,7 +50,7 @@ ucl_hash_seed (void)
|
|||
seed = UCL_RANDOM_FUNCTION;
|
||||
#else
|
||||
/* Not very random but can be useful for our purposes */
|
||||
seed = time (NULL);
|
||||
seed = time(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -58,72 +58,71 @@ ucl_hash_seed (void)
|
|||
}
|
||||
|
||||
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
|
||||
};
|
||||
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) || \
|
||||
#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;
|
||||
|
|
@ -133,7 +132,7 @@ ucl_hash_caseless_func (const ucl_object_t *o)
|
|||
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];
|
||||
|
|
@ -146,40 +145,40 @@ ucl_hash_caseless_func (const ucl_object_t *o)
|
|||
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;
|
||||
|
|
@ -212,7 +211,7 @@ ucl_hash_caseless_equal (const ucl_object_t *k1, const ucl_object_t *k2)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -226,27 +225,27 @@ ucl_hash_caseless_equal (const ucl_object_t *k1, const ucl_object_t *k2)
|
|||
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;
|
||||
|
|
@ -254,7 +253,7 @@ ucl_hash_create (bool ignore_case)
|
|||
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) {
|
||||
|
|
@ -264,16 +263,16 @@ void ucl_hash_destroy (ucl_hash_t* hashlin, ucl_hash_free_func func)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -282,27 +281,27 @@ void ucl_hash_destroy (ucl_hash_t* hashlin, ucl_hash_free_func func)
|
|||
|
||||
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;
|
||||
|
|
@ -314,11 +313,11 @@ ucl_hash_insert (ucl_hash_t* hashlin, const ucl_object_t *obj,
|
|||
|
||||
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;
|
||||
|
|
@ -329,15 +328,16 @@ ucl_hash_insert (ucl_hash_t* hashlin, const ucl_object_t *obj,
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -346,8 +346,8 @@ 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;
|
||||
|
|
@ -359,12 +359,12 @@ void ucl_hash_replace (ucl_hash_t* hashlin, const ucl_object_t *old,
|
|||
|
||||
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;
|
||||
|
|
@ -374,12 +374,12 @@ void ucl_hash_replace (ucl_hash_t* hashlin, const ucl_object_t *old,
|
|||
}
|
||||
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;
|
||||
|
|
@ -393,12 +393,15 @@ 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) {
|
||||
|
|
@ -407,7 +410,7 @@ ucl_hash_iterate2 (ucl_hash_t *hashlin, ucl_hash_iter_t *iter, int *ep)
|
|||
}
|
||||
|
||||
if (it == NULL) {
|
||||
it = UCL_ALLOC (sizeof (*it));
|
||||
it = UCL_ALLOC(sizeof(*it));
|
||||
|
||||
if (it == NULL) {
|
||||
UHI_SETERR(ep, ENOMEM);
|
||||
|
|
@ -423,7 +426,7 @@ ucl_hash_iterate2 (ucl_hash_t *hashlin, ucl_hash_iter_t *iter, int *ep)
|
|||
it->cur = it->cur->next;
|
||||
}
|
||||
else {
|
||||
UCL_FREE (sizeof (*it), it);
|
||||
UCL_FREE(sizeof(*it), it);
|
||||
*iter = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -433,17 +436,16 @@ ucl_hash_iterate2 (ucl_hash_t *hashlin, ucl_hash_iter_t *iter, int *ep)
|
|||
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;
|
||||
|
|
@ -459,20 +461,20 @@ ucl_hash_search (ucl_hash_t* hashlin, const char *key, unsigned keylen)
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -480,8 +482,7 @@ ucl_hash_search (ucl_hash_t* hashlin, const char *key, unsigned keylen)
|
|||
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;
|
||||
|
|
@ -492,52 +493,53 @@ ucl_hash_delete (ucl_hash_t* hashlin, const ucl_object_t *obj)
|
|||
|
||||
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;
|
||||
|
|
@ -569,7 +571,7 @@ ucl_lc_cmp (const char *s, const char *d, size_t l)
|
|||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
|
|
@ -581,33 +583,32 @@ ucl_lc_cmp (const char *s, const char *d, size_t l)
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -620,9 +621,10 @@ ucl_hash_sort (ucl_hash_t *hashlin, enum ucl_object_keys_sort_flags fl)
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@
|
|||
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;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -46,36 +46,36 @@ 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);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -85,7 +85,7 @@ const ucl_object_t* ucl_hash_search (ucl_hash_t* hashlin, const char *key,
|
|||
* @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
|
||||
|
|
@ -95,15 +95,15 @@ const void* ucl_hash_iterate2 (ucl_hash_t *hashlin, ucl_hash_iter_t *iter, int *
|
|||
/**
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
#define HAVE_STDINT_H
|
||||
#define HAVE_STDARG_H
|
||||
#ifndef _WIN32
|
||||
# define HAVE_REGEX_H
|
||||
#define HAVE_REGEX_H
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -55,17 +55,17 @@
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# ifndef _WIN32
|
||||
# include <sys/mman.h>
|
||||
# endif
|
||||
#ifndef _WIN32
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
# ifndef _WIN32
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
#ifndef _WIN32
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
|
|
@ -78,9 +78,9 @@
|
|||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
|
|
@ -132,7 +132,7 @@ typedef SSIZE_T ssize_t;
|
|||
#endif
|
||||
|
||||
#ifndef __DECONST
|
||||
#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
|
||||
#define __DECONST(type, var) ((type) (uintptr_t) (const void *) (var))
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
@ -182,14 +182,15 @@ struct 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 {
|
||||
|
|
@ -284,14 +285,14 @@ struct ucl_object_userdata {
|
|||
* 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
|
||||
|
|
@ -301,8 +302,8 @@ size_t ucl_unescape_squoted_string (char *str, size_t len);
|
|||
* @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
|
||||
|
|
@ -312,8 +313,8 @@ bool ucl_include_handler (const unsigned char *data, size_t len,
|
|||
* @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
|
||||
|
|
@ -323,8 +324,8 @@ bool ucl_try_include_handler (const unsigned char *data, size_t len,
|
|||
* @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
|
||||
|
|
@ -334,8 +335,8 @@ bool ucl_includes_handler (const unsigned char *data, size_t len,
|
|||
* @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
|
||||
|
|
@ -345,8 +346,8 @@ bool ucl_priority_handler (const unsigned char *data, size_t len,
|
|||
* @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
|
||||
|
|
@ -356,37 +357,37 @@ bool ucl_load_handler (const unsigned char *data, size_t len,
|
|||
* @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
|
||||
}
|
||||
|
||||
|
|
@ -398,39 +399,39 @@ ucl_create_err (UT_string **err, const char *fmt, ...)
|
|||
* @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;
|
||||
}
|
||||
|
|
@ -453,37 +454,38 @@ ucl_maybe_parse_boolean (ucl_object_t *obj, const unsigned char *start, size_t l
|
|||
* @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);
|
||||
}
|
||||
|
|
@ -499,15 +501,15 @@ ucl_hash_insert_object (ucl_hash_t *hashlin,
|
|||
* @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);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -515,9 +517,8 @@ void ucl_elt_string_write_json (const char *str, size_t size,
|
|||
* @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
|
||||
|
|
@ -525,15 +526,15 @@ ucl_elt_string_write_squoted (const char *str, size_t size,
|
|||
* @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
|
||||
|
|
@ -541,37 +542,37 @@ unsigned char * ucl_object_emit_single_json (const ucl_object_t *obj);
|
|||
* @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
|
||||
|
|
@ -579,38 +580,38 @@ void ucl_emitter_print_string_msgpack (struct ucl_emitter_context *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
|
||||
|
|
@ -620,11 +621,11 @@ void ucl_emitter_print_key_msgpack (bool print_key,
|
|||
* @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
|
||||
|
|
@ -634,11 +635,11 @@ bool ucl_fetch_url (const unsigned char *url,
|
|||
* @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
|
||||
|
|
@ -646,22 +647,22 @@ bool ucl_fetch_file (const unsigned char *filename,
|
|||
* @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_ */
|
||||
|
|
|
|||
1182
src/ucl_msgpack.c
1182
src/ucl_msgpack.c
File diff suppressed because it is too large
Load diff
1470
src/ucl_parser.c
1470
src/ucl_parser.c
File diff suppressed because it is too large
Load diff
695
src/ucl_schema.c
695
src/ucl_schema.c
File diff suppressed because it is too large
Load diff
121
src/ucl_sexp.c
121
src/ucl_sexp.c
|
|
@ -31,33 +31,33 @@
|
|||
#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)
|
||||
#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)
|
||||
bool ucl_parse_csexp(struct ucl_parser *parser)
|
||||
{
|
||||
const unsigned char *p, *end;
|
||||
ucl_object_t *obj;
|
||||
|
|
@ -72,10 +72,10 @@ ucl_parse_csexp (struct ucl_parser *parser)
|
|||
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;
|
||||
|
|
@ -88,27 +88,28 @@ ucl_parse_csexp (struct ucl_parser *parser)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -122,10 +123,10 @@ ucl_parse_csexp (struct ucl_parser *parser)
|
|||
}
|
||||
else {
|
||||
/* Prepend new element to the stack */
|
||||
LL_PREPEND (parser->stack, st);
|
||||
LL_PREPEND(parser->stack, st);
|
||||
}
|
||||
|
||||
p ++;
|
||||
p++;
|
||||
NEXT_STATE;
|
||||
|
||||
break;
|
||||
|
|
@ -133,7 +134,7 @@ ucl_parse_csexp (struct ucl_parser *parser)
|
|||
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;
|
||||
}
|
||||
|
|
@ -145,40 +146,41 @@ ucl_parse_csexp (struct ucl_parser *parser)
|
|||
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;
|
||||
|
|
@ -186,8 +188,9 @@ ucl_parse_csexp (struct ucl_parser *parser)
|
|||
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;
|
||||
}
|
||||
|
|
@ -196,16 +199,16 @@ ucl_parse_csexp (struct ucl_parser *parser)
|
|||
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;
|
||||
|
|
@ -218,7 +221,7 @@ ucl_parse_csexp (struct ucl_parser *parser)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
2011
src/ucl_util.c
2011
src/ucl_util.c
File diff suppressed because it is too large
Load diff
31
tests/CMakeLists.txt
Normal file
31
tests/CMakeLists.txt
Normal file
|
|
@ -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)
|
||||
|
||||
|
|
@ -5,8 +5,8 @@ TESTS = basic.test \
|
|||
generate.test \
|
||||
schema.test \
|
||||
msgpack.test \
|
||||
speed.test \
|
||||
msgpack.test
|
||||
speed.test
|
||||
|
||||
TESTS_ENVIRONMENT = $(SH) \
|
||||
TEST_DIR=$(top_srcdir)/tests \
|
||||
TEST_OUT_DIR=$(top_builddir)/tests \
|
||||
|
|
@ -41,5 +41,5 @@ test_msgpack_SOURCES = test_msgpack.c
|
|||
test_msgpack_LDADD = $(common_test_ldadd)
|
||||
test_msgpack_CFLAGS = $(common_test_cflags)
|
||||
|
||||
check_PROGRAMS = test_basic test_speed test_generate test_schema test_streamline \
|
||||
test_msgpack
|
||||
check_PROGRAMS = test_basic test_speed test_generate test_schema \
|
||||
test_streamline test_msgpack
|
||||
|
|
|
|||
1
tests/basic/23-json-with-braces.inc
Normal file
1
tests/basic/23-json-with-braces.inc
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ "a": "b" }
|
||||
2
tests/basic/23-json-without-braces.inc
Normal file
2
tests/basic/23-json-without-braces.inc
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Note: This is arguably not a valid JSON file, but it is supposed to be parsable UCL.
|
||||
"b": "c"
|
||||
1
tests/basic/23-ucl-with-braces.inc
Normal file
1
tests/basic/23-ucl-with-braces.inc
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ c = "d"; }
|
||||
1
tests/basic/23-ucl-without-braces.inc
Normal file
1
tests/basic/23-ucl-without-braces.inc
Normal file
|
|
@ -0,0 +1 @@
|
|||
d = "e";
|
||||
8
tests/basic/23.in
Normal file
8
tests/basic/23.in
Normal file
|
|
@ -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;
|
||||
9
tests/basic/23.res
Normal file
9
tests/basic/23.res
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
a = 1;
|
||||
a = "b";
|
||||
b = 2;
|
||||
b = "c";
|
||||
c = "d";
|
||||
c = 3;
|
||||
d = "e";
|
||||
d = 4;
|
||||
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
# This test is intended to check various comments in ucl
|
||||
/***/
|
||||
/*
|
||||
* ""
|
||||
*/
|
||||
|
||||
obj {
|
||||
|
||||
|
|
|
|||
3
tests/basic/issue319.in
Normal file
3
tests/basic/issue319.in
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
key = <<EOD
|
||||
value
|
||||
EOD
|
||||
2
tests/basic/issue319.res
Normal file
2
tests/basic/issue319.res
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
key = "value";
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ main (int argc, char **argv)
|
|||
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);
|
||||
|
|
@ -191,14 +191,14 @@ main (int argc, char **argv)
|
|||
/* 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 */
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ main (int argc, char **argv)
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -21,10 +21,15 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ucl.h"
|
||||
#include "ucl_internal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include "ucl.h"
|
||||
#endif
|
||||
|
||||
static int
|
||||
read_stdin (char **buf)
|
||||
|
|
|
|||
|
|
@ -21,13 +21,24 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ucl.h"
|
||||
#include "ucl_internal.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
||||
|
|
@ -37,8 +48,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#include "ucl.h"
|
||||
|
||||
static double
|
||||
get_ticks (void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ PROJECT(libucl-utils C)
|
|||
FUNCTION(MAKE_UTIL UTIL_NAME UTIL_SRCS)
|
||||
ADD_EXECUTABLE(${UTIL_NAME} ${UTIL_SRCS})
|
||||
TARGET_LINK_LIBRARIES(${UTIL_NAME} ucl)
|
||||
TARGET_INCLUDE_DIRECTORIES(${UTIL_NAME} PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
INSTALL(TARGETS ${UTIL_NAME} DESTINATION bin)
|
||||
ENDFUNCTION()
|
||||
|
||||
|
|
|
|||
273
utils/ucl-tool.c
273
utils/ucl-tool.c
|
|
@ -22,149 +22,160 @@
|
|||
|
||||
#include "ucl.h"
|
||||
|
||||
void usage(const char *name, FILE *out) {
|
||||
fprintf(out, "Usage: %s [--help] [-i|--in file] [-o|--out file]\n", name);
|
||||
fprintf(out, " [-s|--schema file] [-f|--format format]\n\n");
|
||||
fprintf(out, " --help - print this message and exit\n");
|
||||
fprintf(out, " --in - specify input filename "
|
||||
"(default: standard input)\n");
|
||||
fprintf(out, " --out - specify output filename "
|
||||
"(default: standard output)\n");
|
||||
fprintf(out, " --schema - specify schema file for validation\n");
|
||||
fprintf(out, " --format - output format. Options: ucl (default), "
|
||||
"json, compact_json, yaml, msgpack\n");
|
||||
void usage(const char *name, FILE *out)
|
||||
{
|
||||
fprintf(out, "Usage: %s [--help] [-i|--in file] [-o|--out file]\n", name);
|
||||
fprintf(out, " [-s|--schema file] [-f|--format format]\n\n");
|
||||
fprintf(out, " --help - print this message and exit\n");
|
||||
fprintf(out, " --in - specify input filename "
|
||||
"(default: standard input)\n");
|
||||
fprintf(out, " --out - specify output filename "
|
||||
"(default: standard output)\n");
|
||||
fprintf(out, " --schema - specify schema file for validation\n");
|
||||
fprintf(out, " --format - output format. Options: ucl (default), "
|
||||
"json, compact_json, yaml, msgpack\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i;
|
||||
char ch;
|
||||
FILE *in = stdin, *out = stdout;
|
||||
const char *schema = NULL, *parm, *val;
|
||||
unsigned char *buf = NULL;
|
||||
size_t size = 0, r = 0;
|
||||
struct ucl_parser *parser = NULL;
|
||||
ucl_object_t *obj = NULL;
|
||||
ucl_emitter_t emitter = UCL_EMIT_CONFIG;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char ch;
|
||||
FILE *in = stdin, *out = stdout;
|
||||
const char *schema = NULL, *parm, *val;
|
||||
unsigned char *buf = NULL;
|
||||
size_t size = 0, r = 0;
|
||||
struct ucl_parser *parser = NULL;
|
||||
ucl_object_t *obj = NULL;
|
||||
ucl_emitter_t emitter = UCL_EMIT_CONFIG;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
parm = argv[i];
|
||||
val = ((i + 1) < argc) ? argv[++i] : NULL;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
parm = argv[i];
|
||||
val = ((i + 1) < argc) ? argv[++i] : NULL;
|
||||
|
||||
if ((strcmp(parm, "--help") == 0) || (strcmp(parm, "-h") == 0)) {
|
||||
usage(argv[0], stdout);
|
||||
exit(0);
|
||||
if ((strcmp(parm, "--help") == 0) || (strcmp(parm, "-h") == 0)) {
|
||||
usage(argv[0], stdout);
|
||||
exit(0);
|
||||
}
|
||||
else if ((strcmp(parm, "--in") == 0) || (strcmp(parm, "-i") == 0)) {
|
||||
if (!val)
|
||||
goto err_val;
|
||||
|
||||
} else if ((strcmp(parm, "--in") == 0) || (strcmp(parm, "-i") == 0)) {
|
||||
if (!val)
|
||||
goto err_val;
|
||||
in = fopen(val, "r");
|
||||
if (in == NULL) {
|
||||
perror("fopen on input file");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if ((strcmp(parm, "--out") == 0) || (strcmp(parm, "-o") == 0)) {
|
||||
if (!val)
|
||||
goto err_val;
|
||||
|
||||
in = fopen(val, "r");
|
||||
if (in == NULL) {
|
||||
perror("fopen on input file");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if ((strcmp(parm, "--out") == 0) || (strcmp(parm, "-o") == 0)) {
|
||||
if (!val)
|
||||
goto err_val;
|
||||
out = fopen(val, "w");
|
||||
if (out == NULL) {
|
||||
perror("fopen on output file");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if ((strcmp(parm, "--schema") == 0) || (strcmp(parm, "-s") == 0)) {
|
||||
if (!val)
|
||||
goto err_val;
|
||||
schema = val;
|
||||
}
|
||||
else if ((strcmp(parm, "--format") == 0) || (strcmp(parm, "-f") == 0)) {
|
||||
if (!val)
|
||||
goto err_val;
|
||||
|
||||
out = fopen(val, "w");
|
||||
if (out == NULL) {
|
||||
perror("fopen on output file");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if ((strcmp(parm, "--schema") == 0) || (strcmp(parm, "-s") == 0)) {
|
||||
if (!val)
|
||||
goto err_val;
|
||||
schema = val;
|
||||
if (strcmp(val, "ucl") == 0) {
|
||||
emitter = UCL_EMIT_CONFIG;
|
||||
}
|
||||
else if (strcmp(val, "json") == 0) {
|
||||
emitter = UCL_EMIT_JSON;
|
||||
}
|
||||
else if (strcmp(val, "yaml") == 0) {
|
||||
emitter = UCL_EMIT_YAML;
|
||||
}
|
||||
else if (strcmp(val, "compact_json") == 0) {
|
||||
emitter = UCL_EMIT_JSON_COMPACT;
|
||||
}
|
||||
else if (strcmp(val, "msgpack") == 0) {
|
||||
emitter = UCL_EMIT_MSGPACK;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Unknown output format: %s\n", val);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
usage(argv[0], stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((strcmp(parm, "--format") == 0) || (strcmp(parm, "-f") == 0)) {
|
||||
if (!val)
|
||||
goto err_val;
|
||||
parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS | UCL_PARSER_DISABLE_MACRO);
|
||||
buf = malloc(BUFSIZ);
|
||||
size = BUFSIZ;
|
||||
while (!feof(in) && !ferror(in)) {
|
||||
if (r == size) {
|
||||
buf = realloc(buf, size * 2);
|
||||
size *= 2;
|
||||
if (buf == NULL) {
|
||||
perror("realloc");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
r += fread(buf + r, 1, size - r, in);
|
||||
}
|
||||
if (ferror(in)) {
|
||||
fprintf(stderr, "Failed to read the input file.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(in);
|
||||
if (!ucl_parser_add_chunk(parser, buf, r)) {
|
||||
fprintf(stderr, "Failed to parse input file: %s\n",
|
||||
ucl_parser_get_error(parser));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((obj = ucl_parser_get_object(parser)) == NULL) {
|
||||
fprintf(stderr, "Failed to get root object: %s\n",
|
||||
ucl_parser_get_error(parser));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (schema != NULL) {
|
||||
struct ucl_parser *schema_parser = ucl_parser_new(0);
|
||||
ucl_object_t *schema_obj = NULL;
|
||||
struct ucl_schema_error error;
|
||||
|
||||
if (strcmp(val, "ucl") == 0) {
|
||||
emitter = UCL_EMIT_CONFIG;
|
||||
} else if (strcmp(val, "json") == 0) {
|
||||
emitter = UCL_EMIT_JSON;
|
||||
} else if (strcmp(val, "yaml") == 0) {
|
||||
emitter = UCL_EMIT_YAML;
|
||||
} else if (strcmp(val, "compact_json") == 0) {
|
||||
emitter = UCL_EMIT_JSON_COMPACT;
|
||||
} else if (strcmp(val, "msgpack") == 0) {
|
||||
emitter = UCL_EMIT_MSGPACK;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown output format: %s\n", val);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
usage(argv[0], stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (!ucl_parser_add_file(schema_parser, schema)) {
|
||||
fprintf(stderr, "Failed to parse schema file: %s\n",
|
||||
ucl_parser_get_error(schema_parser));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((schema_obj = ucl_parser_get_object(schema_parser)) == NULL) {
|
||||
fprintf(stderr, "Failed to get root object: %s\n",
|
||||
ucl_parser_get_error(schema_parser));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!ucl_object_validate(schema_obj, obj, &error)) {
|
||||
fprintf(stderr, "Validation failed: %s\n", error.msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
parser = ucl_parser_new(0);
|
||||
buf = malloc(BUFSIZ);
|
||||
size = BUFSIZ;
|
||||
while (!feof(in) && !ferror(in)) {
|
||||
if (r == size) {
|
||||
buf = realloc(buf, size*2);
|
||||
size *= 2;
|
||||
if (buf == NULL) {
|
||||
perror("realloc");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
r += fread(buf + r, 1, size - r, in);
|
||||
}
|
||||
if (ferror(in)) {
|
||||
fprintf(stderr, "Failed to read the input file.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(in);
|
||||
if (!ucl_parser_add_chunk(parser, buf, r)) {
|
||||
fprintf(stderr, "Failed to parse input file: %s\n",
|
||||
ucl_parser_get_error(parser));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((obj = ucl_parser_get_object(parser)) == NULL) {
|
||||
fprintf(stderr, "Failed to get root object: %s\n",
|
||||
ucl_parser_get_error(parser));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (schema != NULL) {
|
||||
struct ucl_parser *schema_parser = ucl_parser_new(0);
|
||||
ucl_object_t *schema_obj = NULL;
|
||||
struct ucl_schema_error error;
|
||||
if (emitter != UCL_EMIT_MSGPACK) {
|
||||
fprintf(out, "%s\n", ucl_object_emit(obj, emitter));
|
||||
}
|
||||
else {
|
||||
size_t len;
|
||||
unsigned char *res;
|
||||
|
||||
if (!ucl_parser_add_file(schema_parser, schema)) {
|
||||
fprintf(stderr, "Failed to parse schema file: %s\n",
|
||||
ucl_parser_get_error(schema_parser));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((schema_obj = ucl_parser_get_object(schema_parser)) == NULL) {
|
||||
fprintf(stderr, "Failed to get root object: %s\n",
|
||||
ucl_parser_get_error(schema_parser));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!ucl_object_validate(schema_obj, obj, &error)) {
|
||||
fprintf(stderr, "Validation failed: %s\n", error.msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
res = ucl_object_emit_len(obj, emitter, &len);
|
||||
fwrite(res, 1, len, out);
|
||||
}
|
||||
|
||||
if (emitter != UCL_EMIT_MSGPACK) {
|
||||
fprintf(out, "%s\n", ucl_object_emit(obj, emitter));
|
||||
} else {
|
||||
size_t len;
|
||||
unsigned char *res;
|
||||
|
||||
res = ucl_object_emit_len(obj, emitter, &len);
|
||||
fwrite(res, 1, len, out);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
err_val:
|
||||
fprintf(stderr, "Parameter %s is missing mandatory value\n", parm);
|
||||
usage(argv[0], stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "Parameter %s is missing mandatory value\n", parm);
|
||||
usage(argv[0], stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue