139ee7a7aSBaptiste Daroussin /* 239ee7a7aSBaptiste Daroussin * Copyright (c) 2015, Vsevolod Stakhov 339ee7a7aSBaptiste Daroussin * All rights reserved. 439ee7a7aSBaptiste Daroussin * 539ee7a7aSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 639ee7a7aSBaptiste Daroussin * modification, are permitted provided that the following conditions are met: 739ee7a7aSBaptiste Daroussin * * Redistributions of source code must retain the above copyright 839ee7a7aSBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 939ee7a7aSBaptiste Daroussin * * Redistributions in binary form must reproduce the above copyright 1039ee7a7aSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 1139ee7a7aSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 1239ee7a7aSBaptiste Daroussin * 1339ee7a7aSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY 1439ee7a7aSBaptiste Daroussin * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 1539ee7a7aSBaptiste Daroussin * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 1639ee7a7aSBaptiste Daroussin * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 1739ee7a7aSBaptiste Daroussin * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 1839ee7a7aSBaptiste Daroussin * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 1939ee7a7aSBaptiste Daroussin * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 2039ee7a7aSBaptiste Daroussin * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2139ee7a7aSBaptiste Daroussin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 2239ee7a7aSBaptiste Daroussin * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2339ee7a7aSBaptiste Daroussin */ 2439ee7a7aSBaptiste Daroussin 2539ee7a7aSBaptiste Daroussin #pragma once 2639ee7a7aSBaptiste Daroussin #include <string> 27273c26a3SBaptiste Daroussin #include <vector> 28273c26a3SBaptiste Daroussin #include <map> 29273c26a3SBaptiste Daroussin #include <set> 3039ee7a7aSBaptiste Daroussin #include <memory> 3139ee7a7aSBaptiste Daroussin #include <iostream> 32*a0409676SBaptiste Daroussin #include <tuple> 3339ee7a7aSBaptiste Daroussin 3439ee7a7aSBaptiste Daroussin #include "ucl.h" 3539ee7a7aSBaptiste Daroussin 3639ee7a7aSBaptiste Daroussin // C++11 API inspired by json11: https://github.com/dropbox/json11/ 3739ee7a7aSBaptiste Daroussin 3839ee7a7aSBaptiste Daroussin namespace ucl { 3939ee7a7aSBaptiste Daroussin 4039ee7a7aSBaptiste Daroussin struct ucl_map_construct_t { }; 4139ee7a7aSBaptiste Daroussin constexpr ucl_map_construct_t ucl_map_construct = ucl_map_construct_t(); 4239ee7a7aSBaptiste Daroussin struct ucl_array_construct_t { }; 4339ee7a7aSBaptiste Daroussin constexpr ucl_array_construct_t ucl_array_construct = ucl_array_construct_t(); 4439ee7a7aSBaptiste Daroussin 4539ee7a7aSBaptiste Daroussin class Ucl final { 4639ee7a7aSBaptiste Daroussin private: 4739ee7a7aSBaptiste Daroussin 4839ee7a7aSBaptiste Daroussin struct ucl_deleter { operatorucl_deleter4939ee7a7aSBaptiste Daroussin void operator() (ucl_object_t *obj) { 5039ee7a7aSBaptiste Daroussin ucl_object_unref (obj); 5139ee7a7aSBaptiste Daroussin } 5239ee7a7aSBaptiste Daroussin }; 5339ee7a7aSBaptiste Daroussin 5439ee7a7aSBaptiste Daroussin static int append_char(unsigned char c,size_t nchars,void * ud)5539ee7a7aSBaptiste Daroussin append_char (unsigned char c, size_t nchars, void *ud) 5639ee7a7aSBaptiste Daroussin { 5739ee7a7aSBaptiste Daroussin std::string *out = reinterpret_cast<std::string *>(ud); 5839ee7a7aSBaptiste Daroussin 5939ee7a7aSBaptiste Daroussin out->append (nchars, (char)c); 6039ee7a7aSBaptiste Daroussin 6139ee7a7aSBaptiste Daroussin return nchars; 6239ee7a7aSBaptiste Daroussin } 6339ee7a7aSBaptiste Daroussin static int append_len(unsigned const char * str,size_t len,void * ud)6439ee7a7aSBaptiste Daroussin append_len (unsigned const char *str, size_t len, void *ud) 6539ee7a7aSBaptiste Daroussin { 6639ee7a7aSBaptiste Daroussin std::string *out = reinterpret_cast<std::string *>(ud); 6739ee7a7aSBaptiste Daroussin 6839ee7a7aSBaptiste Daroussin out->append ((const char *)str, len); 6939ee7a7aSBaptiste Daroussin 7039ee7a7aSBaptiste Daroussin return len; 7139ee7a7aSBaptiste Daroussin } 7239ee7a7aSBaptiste Daroussin static int append_int(int64_t elt,void * ud)7339ee7a7aSBaptiste Daroussin append_int (int64_t elt, void *ud) 7439ee7a7aSBaptiste Daroussin { 7539ee7a7aSBaptiste Daroussin std::string *out = reinterpret_cast<std::string *>(ud); 7639ee7a7aSBaptiste Daroussin auto nstr = std::to_string (elt); 7739ee7a7aSBaptiste Daroussin 7839ee7a7aSBaptiste Daroussin out->append (nstr); 7939ee7a7aSBaptiste Daroussin 8039ee7a7aSBaptiste Daroussin return nstr.size (); 8139ee7a7aSBaptiste Daroussin } 8239ee7a7aSBaptiste Daroussin static int append_double(double elt,void * ud)8339ee7a7aSBaptiste Daroussin append_double (double elt, void *ud) 8439ee7a7aSBaptiste Daroussin { 8539ee7a7aSBaptiste Daroussin std::string *out = reinterpret_cast<std::string *>(ud); 8639ee7a7aSBaptiste Daroussin auto nstr = std::to_string (elt); 8739ee7a7aSBaptiste Daroussin 8839ee7a7aSBaptiste Daroussin out->append (nstr); 8939ee7a7aSBaptiste Daroussin 9039ee7a7aSBaptiste Daroussin return nstr.size (); 9139ee7a7aSBaptiste Daroussin } 9239ee7a7aSBaptiste Daroussin default_emit_funcs()9339ee7a7aSBaptiste Daroussin static struct ucl_emitter_functions default_emit_funcs() 9439ee7a7aSBaptiste Daroussin { 9539ee7a7aSBaptiste Daroussin struct ucl_emitter_functions func = { 9639ee7a7aSBaptiste Daroussin Ucl::append_char, 9739ee7a7aSBaptiste Daroussin Ucl::append_len, 9839ee7a7aSBaptiste Daroussin Ucl::append_int, 9939ee7a7aSBaptiste Daroussin Ucl::append_double, 10039ee7a7aSBaptiste Daroussin nullptr, 10139ee7a7aSBaptiste Daroussin nullptr 10239ee7a7aSBaptiste Daroussin }; 10339ee7a7aSBaptiste Daroussin 10439ee7a7aSBaptiste Daroussin return func; 10539ee7a7aSBaptiste Daroussin }; 10639ee7a7aSBaptiste Daroussin ucl_variable_getter(const unsigned char * data,size_t len,unsigned char **,size_t *,bool * need_free,void * ud)107273c26a3SBaptiste Daroussin static bool ucl_variable_getter(const unsigned char *data, size_t len, 108273c26a3SBaptiste Daroussin unsigned char ** /*replace*/, size_t * /*replace_len*/, bool *need_free, void* ud) 109273c26a3SBaptiste Daroussin { 110273c26a3SBaptiste Daroussin *need_free = false; 111273c26a3SBaptiste Daroussin 112273c26a3SBaptiste Daroussin auto vars = reinterpret_cast<std::set<std::string> *>(ud); 113273c26a3SBaptiste Daroussin if (vars && data && len != 0) { 114273c26a3SBaptiste Daroussin vars->emplace (data, data + len); 115273c26a3SBaptiste Daroussin } 116273c26a3SBaptiste Daroussin return false; 117273c26a3SBaptiste Daroussin } 118273c26a3SBaptiste Daroussin ucl_variable_replacer(const unsigned char * data,size_t len,unsigned char ** replace,size_t * replace_len,bool * need_free,void * ud)119273c26a3SBaptiste Daroussin static bool ucl_variable_replacer (const unsigned char *data, size_t len, 120273c26a3SBaptiste Daroussin unsigned char **replace, size_t *replace_len, bool *need_free, void* ud) 121273c26a3SBaptiste Daroussin { 122273c26a3SBaptiste Daroussin *need_free = false; 123273c26a3SBaptiste Daroussin 124273c26a3SBaptiste Daroussin auto replacer = reinterpret_cast<variable_replacer *>(ud); 125273c26a3SBaptiste Daroussin if (!replacer) { 126273c26a3SBaptiste Daroussin return false; 127273c26a3SBaptiste Daroussin } 128273c26a3SBaptiste Daroussin 129273c26a3SBaptiste Daroussin std::string var_name (data, data + len); 130273c26a3SBaptiste Daroussin if (!replacer->is_variable (var_name)) { 131273c26a3SBaptiste Daroussin return false; 132273c26a3SBaptiste Daroussin } 133273c26a3SBaptiste Daroussin 134273c26a3SBaptiste Daroussin std::string var_value = replacer->replace (var_name); 135273c26a3SBaptiste Daroussin if (var_value.empty ()) { 136273c26a3SBaptiste Daroussin return false; 137273c26a3SBaptiste Daroussin } 138273c26a3SBaptiste Daroussin 139273c26a3SBaptiste Daroussin *replace = (unsigned char *)UCL_ALLOC (var_value.size ()); 140273c26a3SBaptiste Daroussin memcpy (*replace, var_value.data (), var_value.size ()); 141273c26a3SBaptiste Daroussin 142273c26a3SBaptiste Daroussin *replace_len = var_value.size (); 143273c26a3SBaptiste Daroussin *need_free = true; 144273c26a3SBaptiste Daroussin 145273c26a3SBaptiste Daroussin return true; 146273c26a3SBaptiste Daroussin } 147273c26a3SBaptiste Daroussin 148273c26a3SBaptiste Daroussin template <typename C, typename P> parse_with_strategy_function(C config_func,P parse_func,std::string & err)149273c26a3SBaptiste Daroussin static Ucl parse_with_strategy_function (C config_func, P parse_func, std::string &err) 150273c26a3SBaptiste Daroussin { 151273c26a3SBaptiste Daroussin auto parser = ucl_parser_new (UCL_PARSER_DEFAULT); 152273c26a3SBaptiste Daroussin 153273c26a3SBaptiste Daroussin config_func (parser); 154273c26a3SBaptiste Daroussin 155273c26a3SBaptiste Daroussin if (!parse_func (parser)) { 156*a0409676SBaptiste Daroussin const char *error = ucl_parser_get_error (parser); //Assigning here without checking result first causes a 157*a0409676SBaptiste Daroussin if( error != NULL ) err.assign(error); // crash if ucl_parser_get_error returns NULL 158273c26a3SBaptiste Daroussin ucl_parser_free (parser); 159273c26a3SBaptiste Daroussin 160273c26a3SBaptiste Daroussin return nullptr; 161273c26a3SBaptiste Daroussin } 162273c26a3SBaptiste Daroussin 163273c26a3SBaptiste Daroussin auto obj = ucl_parser_get_object (parser); 164273c26a3SBaptiste Daroussin ucl_parser_free (parser); 165273c26a3SBaptiste Daroussin 166273c26a3SBaptiste Daroussin // Obj will handle ownership 167273c26a3SBaptiste Daroussin return Ucl (obj); 168273c26a3SBaptiste Daroussin } 169273c26a3SBaptiste Daroussin 17039ee7a7aSBaptiste Daroussin std::unique_ptr<ucl_object_t, ucl_deleter> obj; 17139ee7a7aSBaptiste Daroussin 17239ee7a7aSBaptiste Daroussin public: 173*a0409676SBaptiste Daroussin struct macro_handler_s { 174*a0409676SBaptiste Daroussin ucl_macro_handler handler; 175*a0409676SBaptiste Daroussin ucl_context_macro_handler ctx_handler; 176*a0409676SBaptiste Daroussin }; 177*a0409676SBaptiste Daroussin 178*a0409676SBaptiste Daroussin struct macro_userdata_s { 179*a0409676SBaptiste Daroussin ucl_parser *parser; 180*a0409676SBaptiste Daroussin void *userdata; 181*a0409676SBaptiste Daroussin }; 182*a0409676SBaptiste Daroussin 18339ee7a7aSBaptiste Daroussin class const_iterator { 18439ee7a7aSBaptiste Daroussin private: 18539ee7a7aSBaptiste Daroussin struct ucl_iter_deleter { operatorucl_iter_deleter18639ee7a7aSBaptiste Daroussin void operator() (ucl_object_iter_t it) { 18739ee7a7aSBaptiste Daroussin ucl_object_iterate_free (it); 18839ee7a7aSBaptiste Daroussin } 18939ee7a7aSBaptiste Daroussin }; 19039ee7a7aSBaptiste Daroussin std::shared_ptr<void> it; 19139ee7a7aSBaptiste Daroussin std::unique_ptr<Ucl> cur; 19239ee7a7aSBaptiste Daroussin public: 19339ee7a7aSBaptiste Daroussin typedef std::forward_iterator_tag iterator_category; 19439ee7a7aSBaptiste Daroussin const_iterator(const Ucl & obj)19539ee7a7aSBaptiste Daroussin const_iterator(const Ucl &obj) { 19639ee7a7aSBaptiste Daroussin it = std::shared_ptr<void>(ucl_object_iterate_new (obj.obj.get()), 19739ee7a7aSBaptiste Daroussin ucl_iter_deleter()); 19839ee7a7aSBaptiste Daroussin cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true))); 199*a0409676SBaptiste Daroussin if (!cur->obj) { 200d9f0ce31SBaptiste Daroussin it.reset (); 201d9f0ce31SBaptiste Daroussin cur.reset (); 202d9f0ce31SBaptiste Daroussin } 20339ee7a7aSBaptiste Daroussin } 20439ee7a7aSBaptiste Daroussin const_iterator()20539ee7a7aSBaptiste Daroussin const_iterator() {} 206d9f0ce31SBaptiste Daroussin const_iterator(const const_iterator &other) = delete; 207d9f0ce31SBaptiste Daroussin const_iterator(const_iterator &&other) = default; ~const_iterator()20839ee7a7aSBaptiste Daroussin ~const_iterator() {} 20939ee7a7aSBaptiste Daroussin 210d9f0ce31SBaptiste Daroussin const_iterator& operator=(const const_iterator &other) = delete; 211d9f0ce31SBaptiste Daroussin const_iterator& operator=(const_iterator &&other) = default; 21239ee7a7aSBaptiste Daroussin 21339ee7a7aSBaptiste Daroussin bool operator==(const const_iterator &other) const 21439ee7a7aSBaptiste Daroussin { 21539ee7a7aSBaptiste Daroussin if (cur && other.cur) { 21639ee7a7aSBaptiste Daroussin return cur->obj.get() == other.cur->obj.get(); 21739ee7a7aSBaptiste Daroussin } 21839ee7a7aSBaptiste Daroussin 21939ee7a7aSBaptiste Daroussin return !cur && !other.cur; 22039ee7a7aSBaptiste Daroussin } 22139ee7a7aSBaptiste Daroussin 22239ee7a7aSBaptiste Daroussin bool operator!=(const const_iterator &other) const 22339ee7a7aSBaptiste Daroussin { 22439ee7a7aSBaptiste Daroussin return !(*this == other); 22539ee7a7aSBaptiste Daroussin } 22639ee7a7aSBaptiste Daroussin 22739ee7a7aSBaptiste Daroussin const_iterator& operator++() 22839ee7a7aSBaptiste Daroussin { 22939ee7a7aSBaptiste Daroussin if (it) { 23039ee7a7aSBaptiste Daroussin cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true))); 23139ee7a7aSBaptiste Daroussin } 23239ee7a7aSBaptiste Daroussin 233*a0409676SBaptiste Daroussin if (cur && !cur->obj) { 23439ee7a7aSBaptiste Daroussin it.reset (); 23539ee7a7aSBaptiste Daroussin cur.reset (); 23639ee7a7aSBaptiste Daroussin } 23739ee7a7aSBaptiste Daroussin 23839ee7a7aSBaptiste Daroussin return *this; 23939ee7a7aSBaptiste Daroussin } 24039ee7a7aSBaptiste Daroussin 24139ee7a7aSBaptiste Daroussin const Ucl& operator*() const 24239ee7a7aSBaptiste Daroussin { 24339ee7a7aSBaptiste Daroussin return *cur; 24439ee7a7aSBaptiste Daroussin } 24539ee7a7aSBaptiste Daroussin const Ucl* operator->() const 24639ee7a7aSBaptiste Daroussin { 24739ee7a7aSBaptiste Daroussin return cur.get(); 24839ee7a7aSBaptiste Daroussin } 24939ee7a7aSBaptiste Daroussin }; 25039ee7a7aSBaptiste Daroussin 251273c26a3SBaptiste Daroussin struct variable_replacer { ~variable_replacervariable_replacer252273c26a3SBaptiste Daroussin virtual ~variable_replacer() {} 253273c26a3SBaptiste Daroussin is_variablevariable_replacer254273c26a3SBaptiste Daroussin virtual bool is_variable (const std::string &str) const 255273c26a3SBaptiste Daroussin { 256273c26a3SBaptiste Daroussin return !str.empty (); 257273c26a3SBaptiste Daroussin } 258273c26a3SBaptiste Daroussin 259273c26a3SBaptiste Daroussin virtual std::string replace (const std::string &var) const = 0; 260273c26a3SBaptiste Daroussin }; 261273c26a3SBaptiste Daroussin 26239ee7a7aSBaptiste Daroussin // We grab ownership if get non-const ucl_object_t Ucl(ucl_object_t * other)26339ee7a7aSBaptiste Daroussin Ucl(ucl_object_t *other) { 26439ee7a7aSBaptiste Daroussin obj.reset (other); 26539ee7a7aSBaptiste Daroussin } 26639ee7a7aSBaptiste Daroussin 26739ee7a7aSBaptiste Daroussin // Shared ownership Ucl(const ucl_object_t * other)26839ee7a7aSBaptiste Daroussin Ucl(const ucl_object_t *other) { 26939ee7a7aSBaptiste Daroussin obj.reset (ucl_object_ref (other)); 27039ee7a7aSBaptiste Daroussin } 27139ee7a7aSBaptiste Daroussin Ucl(const Ucl & other)27239ee7a7aSBaptiste Daroussin Ucl(const Ucl &other) { 27339ee7a7aSBaptiste Daroussin obj.reset (ucl_object_ref (other.obj.get())); 27439ee7a7aSBaptiste Daroussin } 27539ee7a7aSBaptiste Daroussin Ucl(Ucl && other)27639ee7a7aSBaptiste Daroussin Ucl(Ucl &&other) { 27739ee7a7aSBaptiste Daroussin obj.swap (other.obj); 27839ee7a7aSBaptiste Daroussin } 27939ee7a7aSBaptiste Daroussin Ucl()28039ee7a7aSBaptiste Daroussin Ucl() noexcept { 28139ee7a7aSBaptiste Daroussin obj.reset (ucl_object_typed_new (UCL_NULL)); 28239ee7a7aSBaptiste Daroussin } Ucl(std::nullptr_t)28339ee7a7aSBaptiste Daroussin Ucl(std::nullptr_t) noexcept { 28439ee7a7aSBaptiste Daroussin obj.reset (ucl_object_typed_new (UCL_NULL)); 28539ee7a7aSBaptiste Daroussin } Ucl(double value)28639ee7a7aSBaptiste Daroussin Ucl(double value) { 28739ee7a7aSBaptiste Daroussin obj.reset (ucl_object_typed_new (UCL_FLOAT)); 28839ee7a7aSBaptiste Daroussin obj->value.dv = value; 28939ee7a7aSBaptiste Daroussin } Ucl(int64_t value)29039ee7a7aSBaptiste Daroussin Ucl(int64_t value) { 29139ee7a7aSBaptiste Daroussin obj.reset (ucl_object_typed_new (UCL_INT)); 29239ee7a7aSBaptiste Daroussin obj->value.iv = value; 29339ee7a7aSBaptiste Daroussin } Ucl(bool value)29439ee7a7aSBaptiste Daroussin Ucl(bool value) { 29539ee7a7aSBaptiste Daroussin obj.reset (ucl_object_typed_new (UCL_BOOLEAN)); 29639ee7a7aSBaptiste Daroussin obj->value.iv = static_cast<int64_t>(value); 29739ee7a7aSBaptiste Daroussin } Ucl(const std::string & value)29839ee7a7aSBaptiste Daroussin Ucl(const std::string &value) { 29939ee7a7aSBaptiste Daroussin obj.reset (ucl_object_fromstring_common (value.data (), value.size (), 30039ee7a7aSBaptiste Daroussin UCL_STRING_RAW)); 30139ee7a7aSBaptiste Daroussin } Ucl(const char * value)30239ee7a7aSBaptiste Daroussin Ucl(const char *value) { 30339ee7a7aSBaptiste Daroussin obj.reset (ucl_object_fromstring_common (value, 0, UCL_STRING_RAW)); 30439ee7a7aSBaptiste Daroussin } 30539ee7a7aSBaptiste Daroussin 30639ee7a7aSBaptiste Daroussin // Implicit constructor: anything with a to_json() function. 30739ee7a7aSBaptiste Daroussin template <class T, class = decltype(&T::to_ucl)> Ucl(const T & t)30839ee7a7aSBaptiste Daroussin Ucl(const T &t) : Ucl(t.to_ucl()) {} 30939ee7a7aSBaptiste Daroussin 31039ee7a7aSBaptiste Daroussin // Implicit constructor: map-like objects (std::map, std::unordered_map, etc) 31139ee7a7aSBaptiste Daroussin template <class M, typename std::enable_if< 31239ee7a7aSBaptiste Daroussin std::is_constructible<std::string, typename M::key_type>::value 31339ee7a7aSBaptiste Daroussin && std::is_constructible<Ucl, typename M::mapped_type>::value, 31439ee7a7aSBaptiste Daroussin int>::type = 0> Ucl(const M & m)31539ee7a7aSBaptiste Daroussin Ucl(const M &m) { 31639ee7a7aSBaptiste Daroussin obj.reset (ucl_object_typed_new (UCL_OBJECT)); 31739ee7a7aSBaptiste Daroussin auto cobj = obj.get (); 31839ee7a7aSBaptiste Daroussin 31939ee7a7aSBaptiste Daroussin for (const auto &e : m) { 32039ee7a7aSBaptiste Daroussin ucl_object_insert_key (cobj, ucl_object_ref (e.second.obj.get()), 32139ee7a7aSBaptiste Daroussin e.first.data (), e.first.size (), true); 32239ee7a7aSBaptiste Daroussin } 32339ee7a7aSBaptiste Daroussin } 32439ee7a7aSBaptiste Daroussin 32539ee7a7aSBaptiste Daroussin // Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc) 32639ee7a7aSBaptiste Daroussin template <class V, typename std::enable_if< 32739ee7a7aSBaptiste Daroussin std::is_constructible<Ucl, typename V::value_type>::value, 32839ee7a7aSBaptiste Daroussin int>::type = 0> Ucl(const V & v)32939ee7a7aSBaptiste Daroussin Ucl(const V &v) { 33039ee7a7aSBaptiste Daroussin obj.reset (ucl_object_typed_new (UCL_ARRAY)); 33139ee7a7aSBaptiste Daroussin auto cobj = obj.get (); 33239ee7a7aSBaptiste Daroussin 33339ee7a7aSBaptiste Daroussin for (const auto &e : v) { 33439ee7a7aSBaptiste Daroussin ucl_array_append (cobj, ucl_object_ref (e.obj.get())); 33539ee7a7aSBaptiste Daroussin } 33639ee7a7aSBaptiste Daroussin } 33739ee7a7aSBaptiste Daroussin type()33839ee7a7aSBaptiste Daroussin ucl_type_t type () const { 33939ee7a7aSBaptiste Daroussin if (obj) { 34039ee7a7aSBaptiste Daroussin return ucl_object_type (obj.get ()); 34139ee7a7aSBaptiste Daroussin } 34239ee7a7aSBaptiste Daroussin return UCL_NULL; 34339ee7a7aSBaptiste Daroussin } 34439ee7a7aSBaptiste Daroussin key()345*a0409676SBaptiste Daroussin std::string key () const { 34639ee7a7aSBaptiste Daroussin std::string res; 34739ee7a7aSBaptiste Daroussin 34839ee7a7aSBaptiste Daroussin if (obj->key) { 34939ee7a7aSBaptiste Daroussin res.assign (obj->key, obj->keylen); 35039ee7a7aSBaptiste Daroussin } 35139ee7a7aSBaptiste Daroussin 35239ee7a7aSBaptiste Daroussin return res; 35339ee7a7aSBaptiste Daroussin } 35439ee7a7aSBaptiste Daroussin 355d9f0ce31SBaptiste Daroussin double number_value (const double default_val = 0.0) const 35639ee7a7aSBaptiste Daroussin { 357d9f0ce31SBaptiste Daroussin double res; 35839ee7a7aSBaptiste Daroussin 359d9f0ce31SBaptiste Daroussin if (ucl_object_todouble_safe(obj.get(), &res)) { 36039ee7a7aSBaptiste Daroussin return res; 36139ee7a7aSBaptiste Daroussin } 36239ee7a7aSBaptiste Daroussin 363d9f0ce31SBaptiste Daroussin return default_val; 364d9f0ce31SBaptiste Daroussin } 365d9f0ce31SBaptiste Daroussin 366d9f0ce31SBaptiste Daroussin int64_t int_value (const int64_t default_val = 0) const 367d9f0ce31SBaptiste Daroussin { 368d9f0ce31SBaptiste Daroussin int64_t res; 369d9f0ce31SBaptiste Daroussin 370d9f0ce31SBaptiste Daroussin if (ucl_object_toint_safe(obj.get(), &res)) { 371d9f0ce31SBaptiste Daroussin return res; 372d9f0ce31SBaptiste Daroussin } 373d9f0ce31SBaptiste Daroussin 374d9f0ce31SBaptiste Daroussin return default_val; 375d9f0ce31SBaptiste Daroussin } 376d9f0ce31SBaptiste Daroussin 377d9f0ce31SBaptiste Daroussin bool bool_value (const bool default_val = false) const 378d9f0ce31SBaptiste Daroussin { 379d9f0ce31SBaptiste Daroussin bool res; 380d9f0ce31SBaptiste Daroussin 381d9f0ce31SBaptiste Daroussin if (ucl_object_toboolean_safe(obj.get(), &res)) { 382d9f0ce31SBaptiste Daroussin return res; 383d9f0ce31SBaptiste Daroussin } 384d9f0ce31SBaptiste Daroussin 385d9f0ce31SBaptiste Daroussin return default_val; 386d9f0ce31SBaptiste Daroussin } 387d9f0ce31SBaptiste Daroussin 388*a0409676SBaptiste Daroussin std::string string_value (const std::string& default_val = "") const 389d9f0ce31SBaptiste Daroussin { 390d9f0ce31SBaptiste Daroussin const char* res = nullptr; 391d9f0ce31SBaptiste Daroussin 392d9f0ce31SBaptiste Daroussin if (ucl_object_tostring_safe(obj.get(), &res)) { 393d9f0ce31SBaptiste Daroussin return res; 394d9f0ce31SBaptiste Daroussin } 395d9f0ce31SBaptiste Daroussin 396d9f0ce31SBaptiste Daroussin return default_val; 397d9f0ce31SBaptiste Daroussin } 398d9f0ce31SBaptiste Daroussin size()399*a0409676SBaptiste Daroussin size_t size () const 400*a0409676SBaptiste Daroussin { 401*a0409676SBaptiste Daroussin if (type () == UCL_ARRAY) { 402*a0409676SBaptiste Daroussin return ucl_array_size (obj.get()); 403*a0409676SBaptiste Daroussin } 404*a0409676SBaptiste Daroussin 405*a0409676SBaptiste Daroussin return 0; 406*a0409676SBaptiste Daroussin } 407*a0409676SBaptiste Daroussin at(size_t i)408*a0409676SBaptiste Daroussin Ucl at (size_t i) const 40939ee7a7aSBaptiste Daroussin { 41039ee7a7aSBaptiste Daroussin if (type () == UCL_ARRAY) { 41139ee7a7aSBaptiste Daroussin return Ucl (ucl_array_find_index (obj.get(), i)); 41239ee7a7aSBaptiste Daroussin } 41339ee7a7aSBaptiste Daroussin 41439ee7a7aSBaptiste Daroussin return Ucl (nullptr); 41539ee7a7aSBaptiste Daroussin } 41639ee7a7aSBaptiste Daroussin lookup(const std::string & key)417*a0409676SBaptiste Daroussin Ucl lookup (const std::string &key) const 41839ee7a7aSBaptiste Daroussin { 41939ee7a7aSBaptiste Daroussin if (type () == UCL_OBJECT) { 420d9f0ce31SBaptiste Daroussin return Ucl (ucl_object_lookup_len (obj.get(), 42139ee7a7aSBaptiste Daroussin key.data (), key.size ())); 42239ee7a7aSBaptiste Daroussin } 42339ee7a7aSBaptiste Daroussin 42439ee7a7aSBaptiste Daroussin return Ucl (nullptr); 42539ee7a7aSBaptiste Daroussin } 426d9f0ce31SBaptiste Daroussin 427*a0409676SBaptiste Daroussin inline Ucl operator[] (size_t i) const 428d9f0ce31SBaptiste Daroussin { 429d9f0ce31SBaptiste Daroussin return at(i); 430d9f0ce31SBaptiste Daroussin } 431d9f0ce31SBaptiste Daroussin 432*a0409676SBaptiste Daroussin inline Ucl operator[](const std::string &key) const 433d9f0ce31SBaptiste Daroussin { 434d9f0ce31SBaptiste Daroussin return lookup(key); 435d9f0ce31SBaptiste Daroussin } 43639ee7a7aSBaptiste Daroussin // Serialize. 43739ee7a7aSBaptiste Daroussin void dump (std::string &out, ucl_emitter_t type = UCL_EMIT_JSON) const 43839ee7a7aSBaptiste Daroussin { 43939ee7a7aSBaptiste Daroussin struct ucl_emitter_functions cbdata; 44039ee7a7aSBaptiste Daroussin 44139ee7a7aSBaptiste Daroussin cbdata = Ucl::default_emit_funcs(); 44239ee7a7aSBaptiste Daroussin cbdata.ud = reinterpret_cast<void *>(&out); 44339ee7a7aSBaptiste Daroussin 444d9f0ce31SBaptiste Daroussin ucl_object_emit_full (obj.get(), type, &cbdata, nullptr); 44539ee7a7aSBaptiste Daroussin } 44639ee7a7aSBaptiste Daroussin 44739ee7a7aSBaptiste Daroussin std::string dump (ucl_emitter_t type = UCL_EMIT_JSON) const 44839ee7a7aSBaptiste Daroussin { 44939ee7a7aSBaptiste Daroussin std::string out; 45039ee7a7aSBaptiste Daroussin 45139ee7a7aSBaptiste Daroussin dump (out, type); 45239ee7a7aSBaptiste Daroussin 45339ee7a7aSBaptiste Daroussin return out; 45439ee7a7aSBaptiste Daroussin } 45539ee7a7aSBaptiste Daroussin 456*a0409676SBaptiste Daroussin static Ucl parse (const std::string &in, std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 45739ee7a7aSBaptiste Daroussin { 458*a0409676SBaptiste Daroussin return parse (in, std::map<std::string, std::string>(), err, duplicate_strategy); 45939ee7a7aSBaptiste Daroussin } 46039ee7a7aSBaptiste Daroussin 461*a0409676SBaptiste Daroussin static Ucl parse (const std::string &in, const std::map<std::string, std::string> &vars, 462*a0409676SBaptiste Daroussin std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 463273c26a3SBaptiste Daroussin { 464*a0409676SBaptiste Daroussin std::vector< std::tuple< std::string, macro_handler_s, void * > > emptyVector; 465*a0409676SBaptiste Daroussin return parse ( in, vars, emptyVector, err, duplicate_strategy ); 466*a0409676SBaptiste Daroussin } 467*a0409676SBaptiste Daroussin 468*a0409676SBaptiste Daroussin //Macro handler will receive a macro_userdata_s as void *ud 469*a0409676SBaptiste Daroussin static Ucl parse (const std::string &in, 470*a0409676SBaptiste Daroussin std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, 471*a0409676SBaptiste Daroussin std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 472*a0409676SBaptiste Daroussin { 473*a0409676SBaptiste Daroussin return parse (in, std::map<std::string, std::string>(), macros, err, duplicate_strategy); 474*a0409676SBaptiste Daroussin } 475*a0409676SBaptiste Daroussin 476*a0409676SBaptiste Daroussin //Macro handler will receive a macro_userdata_s as void *ud 477*a0409676SBaptiste Daroussin static Ucl parse (const std::string &in, const std::map<std::string, std::string> &vars, 478*a0409676SBaptiste Daroussin std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, 479*a0409676SBaptiste Daroussin std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 480*a0409676SBaptiste Daroussin { 481*a0409676SBaptiste Daroussin //Preserve macro_userdata_s memory for later use in parse_with_strategy_function() 482*a0409676SBaptiste Daroussin std::vector<macro_userdata_s> userdata_list; 483*a0409676SBaptiste Daroussin userdata_list.reserve (macros.size()); 484*a0409676SBaptiste Daroussin auto config_func = [&userdata_list, &vars, ¯os] (ucl_parser *parser) { 485273c26a3SBaptiste Daroussin for (const auto & item : vars) { 486273c26a3SBaptiste Daroussin ucl_parser_register_variable (parser, item.first.c_str (), item.second.c_str ()); 487273c26a3SBaptiste Daroussin } 488*a0409676SBaptiste Daroussin for (auto & macro : macros) { 489*a0409676SBaptiste Daroussin userdata_list.push_back ({parser, std::get<2>(macro)}); 490*a0409676SBaptiste Daroussin if (std::get<1>(macro).handler != NULL) { 491*a0409676SBaptiste Daroussin ucl_parser_register_macro (parser, 492*a0409676SBaptiste Daroussin std::get<0>(macro).c_str(), 493*a0409676SBaptiste Daroussin std::get<1>(macro).handler, 494*a0409676SBaptiste Daroussin reinterpret_cast<void*>(&userdata_list.back())); 495*a0409676SBaptiste Daroussin } 496*a0409676SBaptiste Daroussin else if (std::get<1>(macro).ctx_handler != NULL) { 497*a0409676SBaptiste Daroussin ucl_parser_register_context_macro (parser, 498*a0409676SBaptiste Daroussin std::get<0>(macro).c_str(), 499*a0409676SBaptiste Daroussin std::get<1>(macro).ctx_handler, 500*a0409676SBaptiste Daroussin reinterpret_cast<void*>(&userdata_list.back())); 501*a0409676SBaptiste Daroussin } 502*a0409676SBaptiste Daroussin } 503273c26a3SBaptiste Daroussin }; 50439ee7a7aSBaptiste Daroussin 505*a0409676SBaptiste Daroussin auto parse_func = [&in, &duplicate_strategy] (struct ucl_parser *parser) -> bool { 506*a0409676SBaptiste Daroussin return ucl_parser_add_chunk_full (parser, 507*a0409676SBaptiste Daroussin (unsigned char *) in.data (), 508*a0409676SBaptiste Daroussin in.size (), 509*a0409676SBaptiste Daroussin (unsigned int)ucl_parser_get_default_priority (parser), 510*a0409676SBaptiste Daroussin duplicate_strategy, 511*a0409676SBaptiste Daroussin UCL_PARSE_UCL); 512273c26a3SBaptiste Daroussin }; 513273c26a3SBaptiste Daroussin 514273c26a3SBaptiste Daroussin return parse_with_strategy_function (config_func, parse_func, err); 515273c26a3SBaptiste Daroussin } 516273c26a3SBaptiste Daroussin 517*a0409676SBaptiste Daroussin static Ucl parse (const std::string &in, const variable_replacer &replacer, 518*a0409676SBaptiste Daroussin std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 519273c26a3SBaptiste Daroussin { 520*a0409676SBaptiste Daroussin std::vector< std::tuple< std::string, macro_handler_s, void * > > emptyVector; 521*a0409676SBaptiste Daroussin return parse ( in, replacer, emptyVector, err, duplicate_strategy ); 522*a0409676SBaptiste Daroussin } 523*a0409676SBaptiste Daroussin 524*a0409676SBaptiste Daroussin //Macro handler will receive a macro_userdata_s as void *ud 525*a0409676SBaptiste Daroussin static Ucl parse (const std::string &in, const variable_replacer &replacer, 526*a0409676SBaptiste Daroussin std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, 527*a0409676SBaptiste Daroussin std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 528*a0409676SBaptiste Daroussin { 529*a0409676SBaptiste Daroussin //Preserve macro_userdata_s memory for later use in parse_with_strategy_function() 530*a0409676SBaptiste Daroussin std::vector<macro_userdata_s> userdata_list; 531*a0409676SBaptiste Daroussin userdata_list.reserve (macros.size()); 532*a0409676SBaptiste Daroussin auto config_func = [&userdata_list, &replacer, ¯os] (ucl_parser *parser) { 533*a0409676SBaptiste Daroussin ucl_parser_set_variables_handler (parser, ucl_variable_replacer, &const_cast<variable_replacer &>(replacer)); 534*a0409676SBaptiste Daroussin for (auto & macro : macros) { 535*a0409676SBaptiste Daroussin userdata_list.push_back ({parser, std::get<2>(macro)}); 536*a0409676SBaptiste Daroussin if (std::get<1>(macro).handler != NULL) { 537*a0409676SBaptiste Daroussin ucl_parser_register_macro (parser, 538*a0409676SBaptiste Daroussin std::get<0>(macro).c_str(), 539*a0409676SBaptiste Daroussin std::get<1>(macro).handler, 540*a0409676SBaptiste Daroussin reinterpret_cast<void*>(&userdata_list.back())); 541*a0409676SBaptiste Daroussin } 542*a0409676SBaptiste Daroussin else if (std::get<1>(macro).ctx_handler != NULL) { 543*a0409676SBaptiste Daroussin ucl_parser_register_context_macro (parser, 544*a0409676SBaptiste Daroussin std::get<0>(macro).c_str(), 545*a0409676SBaptiste Daroussin std::get<1>(macro).ctx_handler, 546*a0409676SBaptiste Daroussin reinterpret_cast<void*>(&userdata_list.back())); 547*a0409676SBaptiste Daroussin } 548*a0409676SBaptiste Daroussin } 549273c26a3SBaptiste Daroussin }; 550273c26a3SBaptiste Daroussin 551*a0409676SBaptiste Daroussin auto parse_func = [&in, &duplicate_strategy] (struct ucl_parser *parser) -> bool { 552*a0409676SBaptiste Daroussin return ucl_parser_add_chunk_full (parser, 553*a0409676SBaptiste Daroussin (unsigned char *) in.data (), 554*a0409676SBaptiste Daroussin in.size (), 555*a0409676SBaptiste Daroussin (unsigned int)ucl_parser_get_default_priority (parser), 556*a0409676SBaptiste Daroussin duplicate_strategy, 557*a0409676SBaptiste Daroussin UCL_PARSE_UCL); 558273c26a3SBaptiste Daroussin }; 559273c26a3SBaptiste Daroussin 560273c26a3SBaptiste Daroussin return parse_with_strategy_function (config_func, parse_func, err); 56139ee7a7aSBaptiste Daroussin } 56239ee7a7aSBaptiste Daroussin 563*a0409676SBaptiste Daroussin static Ucl parse (const char *in, std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 56439ee7a7aSBaptiste Daroussin { 565*a0409676SBaptiste Daroussin return parse (in, std::map<std::string, std::string>(), err, duplicate_strategy); 566273c26a3SBaptiste Daroussin } 567273c26a3SBaptiste Daroussin parse(const char * in,const std::map<std::string,std::string> & vars,std::string & err)568273c26a3SBaptiste Daroussin static Ucl parse (const char *in, const std::map<std::string, std::string> &vars, std::string &err) 569273c26a3SBaptiste Daroussin { 570273c26a3SBaptiste Daroussin if (!in) { 57139ee7a7aSBaptiste Daroussin err = "null input"; 57239ee7a7aSBaptiste Daroussin return nullptr; 57339ee7a7aSBaptiste Daroussin } 574273c26a3SBaptiste Daroussin return parse (std::string (in), vars, err); 57539ee7a7aSBaptiste Daroussin } 57639ee7a7aSBaptiste Daroussin 577*a0409676SBaptiste Daroussin //Macro handler will receive a macro_userdata_s as void *ud 578*a0409676SBaptiste Daroussin static Ucl parse (const char *in, 579*a0409676SBaptiste Daroussin std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, 580*a0409676SBaptiste Daroussin std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 581*a0409676SBaptiste Daroussin { 582*a0409676SBaptiste Daroussin return parse (in, std::map<std::string, std::string>(), macros, err, duplicate_strategy); 583*a0409676SBaptiste Daroussin } 584*a0409676SBaptiste Daroussin 585*a0409676SBaptiste Daroussin //Macro handler will receive a macro_userdata_s as void *ud 586*a0409676SBaptiste Daroussin static Ucl parse (const char *in, const std::map<std::string, std::string> &vars, 587*a0409676SBaptiste Daroussin std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, 588*a0409676SBaptiste Daroussin std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 58939ee7a7aSBaptiste Daroussin { 590273c26a3SBaptiste Daroussin if (!in) { 591273c26a3SBaptiste Daroussin err = "null input"; 592273c26a3SBaptiste Daroussin return nullptr; 593273c26a3SBaptiste Daroussin } 594*a0409676SBaptiste Daroussin return parse (std::string (in), vars, macros, err, duplicate_strategy); 595*a0409676SBaptiste Daroussin } 596*a0409676SBaptiste Daroussin 597*a0409676SBaptiste Daroussin static Ucl parse (const char *in, const variable_replacer &replacer, 598*a0409676SBaptiste Daroussin std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 599*a0409676SBaptiste Daroussin { 600*a0409676SBaptiste Daroussin if (!in) { 601*a0409676SBaptiste Daroussin err = "null input"; 602*a0409676SBaptiste Daroussin return nullptr; 603*a0409676SBaptiste Daroussin } 604*a0409676SBaptiste Daroussin return parse (std::string(in), replacer, err, duplicate_strategy); 605*a0409676SBaptiste Daroussin } 606*a0409676SBaptiste Daroussin 607*a0409676SBaptiste Daroussin //Macro handler will receive a macro_userdata_s as void *ud 608*a0409676SBaptiste Daroussin static Ucl parse (const char *in, const variable_replacer &replacer, 609*a0409676SBaptiste Daroussin std::vector< std::tuple< std::string /*name*/, macro_handler_s, void * /*userdata*/ > > ¯os, 610*a0409676SBaptiste Daroussin std::string &err, enum ucl_duplicate_strategy duplicate_strategy = UCL_DUPLICATE_APPEND) 611*a0409676SBaptiste Daroussin { 612*a0409676SBaptiste Daroussin if (!in) { 613*a0409676SBaptiste Daroussin err = "null input"; 614*a0409676SBaptiste Daroussin return nullptr; 615*a0409676SBaptiste Daroussin } 616*a0409676SBaptiste Daroussin return parse (std::string (in), replacer, macros, err, duplicate_strategy); 617273c26a3SBaptiste Daroussin } 618273c26a3SBaptiste Daroussin parse_from_file(const std::string & filename,std::string & err)619273c26a3SBaptiste Daroussin static Ucl parse_from_file (const std::string &filename, std::string &err) 620273c26a3SBaptiste Daroussin { 621273c26a3SBaptiste Daroussin return parse_from_file (filename, std::map<std::string, std::string>(), err); 622273c26a3SBaptiste Daroussin } 623273c26a3SBaptiste Daroussin parse_from_file(const std::string & filename,const std::map<std::string,std::string> & vars,std::string & err)624273c26a3SBaptiste Daroussin static Ucl parse_from_file (const std::string &filename, const std::map<std::string, std::string> &vars, std::string &err) 625273c26a3SBaptiste Daroussin { 626273c26a3SBaptiste Daroussin auto config_func = [&vars] (ucl_parser *parser) { 627273c26a3SBaptiste Daroussin for (const auto & item : vars) { 628273c26a3SBaptiste Daroussin ucl_parser_register_variable (parser, item.first.c_str (), item.second.c_str ()); 629273c26a3SBaptiste Daroussin } 630273c26a3SBaptiste Daroussin }; 631273c26a3SBaptiste Daroussin 632273c26a3SBaptiste Daroussin auto parse_func = [&filename] (ucl_parser *parser) { 633273c26a3SBaptiste Daroussin return ucl_parser_add_file (parser, filename.c_str ()); 634273c26a3SBaptiste Daroussin }; 635273c26a3SBaptiste Daroussin 636273c26a3SBaptiste Daroussin return parse_with_strategy_function (config_func, parse_func, err); 637273c26a3SBaptiste Daroussin } 638273c26a3SBaptiste Daroussin parse_from_file(const std::string & filename,const variable_replacer & replacer,std::string & err)639273c26a3SBaptiste Daroussin static Ucl parse_from_file (const std::string &filename, const variable_replacer &replacer, std::string &err) 640273c26a3SBaptiste Daroussin { 641273c26a3SBaptiste Daroussin auto config_func = [&replacer] (ucl_parser *parser) { 642273c26a3SBaptiste Daroussin ucl_parser_set_variables_handler (parser, ucl_variable_replacer, 643273c26a3SBaptiste Daroussin &const_cast<variable_replacer &>(replacer)); 644273c26a3SBaptiste Daroussin }; 645273c26a3SBaptiste Daroussin 646273c26a3SBaptiste Daroussin auto parse_func = [&filename] (ucl_parser *parser) { 647273c26a3SBaptiste Daroussin return ucl_parser_add_file (parser, filename.c_str ()); 648273c26a3SBaptiste Daroussin }; 649273c26a3SBaptiste Daroussin 650273c26a3SBaptiste Daroussin return parse_with_strategy_function (config_func, parse_func, err); 651273c26a3SBaptiste Daroussin } 652273c26a3SBaptiste Daroussin find_variable(const std::string & in)653273c26a3SBaptiste Daroussin static std::vector<std::string> find_variable (const std::string &in) 654273c26a3SBaptiste Daroussin { 655273c26a3SBaptiste Daroussin auto parser = ucl_parser_new (UCL_PARSER_DEFAULT); 656273c26a3SBaptiste Daroussin 657273c26a3SBaptiste Daroussin std::set<std::string> vars; 658273c26a3SBaptiste Daroussin ucl_parser_set_variables_handler (parser, ucl_variable_getter, &vars); 659273c26a3SBaptiste Daroussin ucl_parser_add_chunk (parser, (const unsigned char *)in.data (), in.size ()); 660273c26a3SBaptiste Daroussin ucl_parser_free (parser); 661273c26a3SBaptiste Daroussin 662273c26a3SBaptiste Daroussin std::vector<std::string> result; 663273c26a3SBaptiste Daroussin std::move (vars.begin (), vars.end (), std::back_inserter (result)); 664273c26a3SBaptiste Daroussin return result; 665273c26a3SBaptiste Daroussin } 666273c26a3SBaptiste Daroussin find_variable(const char * in)667273c26a3SBaptiste Daroussin static std::vector<std::string> find_variable (const char *in) 668273c26a3SBaptiste Daroussin { 669273c26a3SBaptiste Daroussin if (!in) { 670273c26a3SBaptiste Daroussin return std::vector<std::string>(); 671273c26a3SBaptiste Daroussin } 672273c26a3SBaptiste Daroussin return find_variable (std::string (in)); 673273c26a3SBaptiste Daroussin } 674273c26a3SBaptiste Daroussin find_variable_from_file(const std::string & filename)675273c26a3SBaptiste Daroussin static std::vector<std::string> find_variable_from_file (const std::string &filename) 676273c26a3SBaptiste Daroussin { 677273c26a3SBaptiste Daroussin auto parser = ucl_parser_new (UCL_PARSER_DEFAULT); 678273c26a3SBaptiste Daroussin 679273c26a3SBaptiste Daroussin std::set<std::string> vars; 680273c26a3SBaptiste Daroussin ucl_parser_set_variables_handler (parser, ucl_variable_getter, &vars); 681273c26a3SBaptiste Daroussin ucl_parser_add_file (parser, filename.c_str ()); 682273c26a3SBaptiste Daroussin ucl_parser_free (parser); 683273c26a3SBaptiste Daroussin 684273c26a3SBaptiste Daroussin std::vector<std::string> result; 685273c26a3SBaptiste Daroussin std::move (vars.begin (), vars.end (), std::back_inserter (result)); 686*a0409676SBaptiste Daroussin return result; 68739ee7a7aSBaptiste Daroussin } 68839ee7a7aSBaptiste Daroussin 689d9f0ce31SBaptiste Daroussin Ucl& operator= (Ucl rhs) 690d9f0ce31SBaptiste Daroussin { 691d9f0ce31SBaptiste Daroussin obj.swap (rhs.obj); 692d9f0ce31SBaptiste Daroussin return *this; 693d9f0ce31SBaptiste Daroussin } 694d9f0ce31SBaptiste Daroussin 69539ee7a7aSBaptiste Daroussin bool operator== (const Ucl &rhs) const 69639ee7a7aSBaptiste Daroussin { 69739ee7a7aSBaptiste Daroussin return ucl_object_compare (obj.get(), rhs.obj.get ()) == 0; 69839ee7a7aSBaptiste Daroussin } 69939ee7a7aSBaptiste Daroussin bool operator< (const Ucl &rhs) const 70039ee7a7aSBaptiste Daroussin { 70139ee7a7aSBaptiste Daroussin return ucl_object_compare (obj.get(), rhs.obj.get ()) < 0; 70239ee7a7aSBaptiste Daroussin } 70339ee7a7aSBaptiste Daroussin bool operator!= (const Ucl &rhs) const { return !(*this == rhs); } 70439ee7a7aSBaptiste Daroussin bool operator<= (const Ucl &rhs) const { return !(rhs < *this); } 70539ee7a7aSBaptiste Daroussin bool operator> (const Ucl &rhs) const { return (rhs < *this); } 70639ee7a7aSBaptiste Daroussin bool operator>= (const Ucl &rhs) const { return !(*this < rhs); } 70739ee7a7aSBaptiste Daroussin 708d9f0ce31SBaptiste Daroussin explicit operator bool () const 70939ee7a7aSBaptiste Daroussin { 71039ee7a7aSBaptiste Daroussin if (!obj || type() == UCL_NULL) { 71139ee7a7aSBaptiste Daroussin return false; 71239ee7a7aSBaptiste Daroussin } 71339ee7a7aSBaptiste Daroussin 71439ee7a7aSBaptiste Daroussin if (type () == UCL_BOOLEAN) { 71539ee7a7aSBaptiste Daroussin return bool_value (); 71639ee7a7aSBaptiste Daroussin } 71739ee7a7aSBaptiste Daroussin 71839ee7a7aSBaptiste Daroussin return true; 71939ee7a7aSBaptiste Daroussin } 72039ee7a7aSBaptiste Daroussin begin()72139ee7a7aSBaptiste Daroussin const_iterator begin() const 72239ee7a7aSBaptiste Daroussin { 72339ee7a7aSBaptiste Daroussin return const_iterator(*this); 72439ee7a7aSBaptiste Daroussin } cbegin()72539ee7a7aSBaptiste Daroussin const_iterator cbegin() const 72639ee7a7aSBaptiste Daroussin { 72739ee7a7aSBaptiste Daroussin return const_iterator(*this); 72839ee7a7aSBaptiste Daroussin } end()72939ee7a7aSBaptiste Daroussin const_iterator end() const 73039ee7a7aSBaptiste Daroussin { 73139ee7a7aSBaptiste Daroussin return const_iterator(); 73239ee7a7aSBaptiste Daroussin } cend()73339ee7a7aSBaptiste Daroussin const_iterator cend() const 73439ee7a7aSBaptiste Daroussin { 73539ee7a7aSBaptiste Daroussin return const_iterator(); 73639ee7a7aSBaptiste Daroussin } 73739ee7a7aSBaptiste Daroussin }; 73839ee7a7aSBaptiste Daroussin 73939ee7a7aSBaptiste Daroussin }; 740