summaryrefslogtreecommitdiffstats
path: root/contrib/libucl/include
diff options
context:
space:
mode:
authorbapt <bapt@FreeBSD.org>2016-10-22 20:49:07 +0000
committerbapt <bapt@FreeBSD.org>2016-10-22 20:49:07 +0000
commitffafe3ab704ae77aebac04aed2a2f970475312d8 (patch)
tree1c03c20541f231404e89ca3807016bc85a56cb7d /contrib/libucl/include
parent62cb4b26b932c652b62b8eba73976e4b9584ec97 (diff)
downloadFreeBSD-src-ffafe3ab704ae77aebac04aed2a2f970475312d8.zip
FreeBSD-src-ffafe3ab704ae77aebac04aed2a2f970475312d8.tar.gz
MFC r306544:
Import libucl 20160812
Diffstat (limited to 'contrib/libucl/include')
-rw-r--r--contrib/libucl/include/ucl++.h228
-rw-r--r--contrib/libucl/include/ucl.h16
2 files changed, 212 insertions, 32 deletions
diff --git a/contrib/libucl/include/ucl++.h b/contrib/libucl/include/ucl++.h
index 00297e7..2c2bdde 100644
--- a/contrib/libucl/include/ucl++.h
+++ b/contrib/libucl/include/ucl++.h
@@ -24,6 +24,9 @@
#pragma once
#include <string>
+#include <vector>
+#include <map>
+#include <set>
#include <memory>
#include <iostream>
@@ -100,6 +103,68 @@ private:
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)
+ {
+ *need_free = false;
+
+ auto vars = reinterpret_cast<std::set<std::string> *>(ud);
+ if (vars && data && len != 0) {
+ 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)
+ {
+ *need_free = false;
+
+ auto replacer = reinterpret_cast<variable_replacer *>(ud);
+ if (!replacer) {
+ return false;
+ }
+
+ std::string var_name (data, data + len);
+ if (!replacer->is_variable (var_name)) {
+ return false;
+ }
+
+ std::string var_value = replacer->replace (var_name);
+ if (var_value.empty ()) {
+ return false;
+ }
+
+ *replace = (unsigned char *)UCL_ALLOC (var_value.size ());
+ memcpy (*replace, var_value.data (), var_value.size ());
+
+ *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)
+ {
+ auto parser = ucl_parser_new (UCL_PARSER_DEFAULT);
+
+ config_func (parser);
+
+ if (!parse_func (parser)) {
+ err.assign (ucl_parser_get_error (parser));
+ ucl_parser_free (parser);
+
+ return nullptr;
+ }
+
+ auto obj = ucl_parser_get_object (parser);
+ ucl_parser_free (parser);
+
+ // Obj will handle ownership
+ return Ucl (obj);
+ }
+
std::unique_ptr<ucl_object_t, ucl_deleter> obj;
public:
@@ -117,9 +182,9 @@ public:
const_iterator(const Ucl &obj) {
it = std::shared_ptr<void>(ucl_object_iterate_new (obj.obj.get()),
- ucl_iter_deleter());
+ ucl_iter_deleter());
cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true)));
- if (!*cur) {
+ if (cur->type() == UCL_NULL) {
it.reset ();
cur.reset ();
}
@@ -153,7 +218,7 @@ public:
cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true)));
}
- if (!*cur) {
+ if (cur && cur->type() == UCL_NULL) {
it.reset ();
cur.reset ();
}
@@ -171,6 +236,17 @@ public:
}
};
+ struct variable_replacer {
+ virtual ~variable_replacer() {}
+
+ 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);
@@ -211,20 +287,20 @@ public:
obj.reset (ucl_object_fromstring_common (value.data (), value.size (),
UCL_STRING_RAW));
}
- Ucl(const char * value) {
+ 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()) {}
+ 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) {
+ Ucl(const M &m) {
obj.reset (ucl_object_typed_new (UCL_OBJECT));
auto cobj = obj.get ();
@@ -238,7 +314,7 @@ public:
template <class V, typename std::enable_if<
std::is_constructible<Ucl, typename V::value_type>::value,
int>::type = 0>
- Ucl(const V & v) {
+ Ucl(const V &v) {
obj.reset (ucl_object_typed_new (UCL_ARRAY));
auto cobj = obj.get ();
@@ -356,46 +432,138 @@ public:
return out;
}
- static Ucl parse (const std::string & in, std::string & err)
+ static Ucl parse (const std::string &in, std::string &err)
{
- auto parser = ucl_parser_new (UCL_PARSER_DEFAULT);
+ return parse (in, std::map<std::string, std::string>(), err);
+ }
- if (!ucl_parser_add_chunk (parser, (const unsigned char *)in.data (),
- in.size ())) {
- err.assign (ucl_parser_get_error (parser));
- ucl_parser_free (parser);
+ static Ucl parse (const std::string &in, 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 parse_func = [&in] (ucl_parser *parser) {
+ return ucl_parser_add_chunk (parser, (unsigned char *)in.data (), in.size ());
+ };
+
+ return parse_with_strategy_function (config_func, parse_func, err);
+ }
+ static Ucl parse (const std::string &in, 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 parse_func = [&in] (ucl_parser *parser) {
+ return ucl_parser_add_chunk (parser, (unsigned char *) in.data (), in.size ());
+ };
+
+ return parse_with_strategy_function (config_func, parse_func, err);
+ }
+
+ static Ucl parse (const char *in, std::string &err)
+ {
+ return parse (in, std::map<std::string, 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);
+ }
- auto obj = ucl_parser_get_object (parser);
+ static Ucl parse (const char *in, const variable_replacer &replacer, std::string &err)
+ {
+ if (!in) {
+ err = "null input";
+ return nullptr;
+ }
+ return parse (std::string(in), replacer, 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);
+ }
+
+ 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 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);
+ }
+
+ 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 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);
+ }
+
+ static std::vector<std::string> find_variable (const std::string &in)
+ {
+ 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);
- // Obj will handle ownership
- return Ucl (obj);
+ std::vector<std::string> result;
+ std::move (vars.begin (), vars.end (), std::back_inserter (result));
+ return result;
}
- static Ucl parse (const char * in, std::string & err)
+ static std::vector<std::string> find_variable (const char *in)
{
- if (in) {
- return parse (std::string(in), err);
- } else {
- err = "null input";
- return nullptr;
+ if (!in) {
+ return std::vector<std::string>();
}
+ return find_variable (std::string (in));
}
- static Ucl parse (std::istream &ifs, std::string &err)
+ static std::vector<std::string> find_variable_from_file (const std::string &filename)
{
- return Ucl::parse (std::string(std::istreambuf_iterator<char>(ifs),
- std::istreambuf_iterator<char>()), err);
+ 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);
+
+ std::vector<std::string> result;
+ std::move (vars.begin (), vars.end (), std::back_inserter (result));
+ return std::move (result);
}
- Ucl& operator= (Ucl rhs)
- {
- obj.swap (rhs.obj);
- return *this;
- }
+ Ucl& operator= (Ucl rhs)
+ {
+ obj.swap (rhs.obj);
+ return *this;
+ }
bool operator== (const Ucl &rhs) const
{
diff --git a/contrib/libucl/include/ucl.h b/contrib/libucl/include/ucl.h
index 024f5dd..304d329 100644
--- a/contrib/libucl/include/ucl.h
+++ b/contrib/libucl/include/ucl.h
@@ -1016,7 +1016,6 @@ UCL_EXTERN bool ucl_parser_add_string_priority (struct ucl_parser *parser,
* Load and add data from a file
* @param parser parser structure
* @param filename the name of file
- * @param err if *err is NULL it is set to parser error
* @return true if chunk has been added and false in case of error
*/
UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser,
@@ -1026,7 +1025,6 @@ UCL_EXTERN bool ucl_parser_add_file (struct ucl_parser *parser,
* Load and add data from a file
* @param parser parser structure
* @param filename the name of file
- * @param err if *err is NULL it is set to parser error
* @param priority the desired priority of a chunk (only 4 least significant bits
* are considered for this parameter)
* @return true if chunk has been added and false in case of error
@@ -1035,6 +1033,20 @@ UCL_EXTERN bool ucl_parser_add_file_priority (struct ucl_parser *parser,
const char *filename, unsigned priority);
/**
+ * Load and add data from a file
+ * @param parser parser structure
+ * @param filename the name of file
+ * @param priority the desired priority of a chunk (only 4 least significant bits
+ * are considered for this parameter)
+ * @param strat Merge strategy to use while parsing this file
+ * @param parse_type Parser type to use while parsing this file
+ * @return true if chunk has been added and false in case of error
+ */
+UCL_EXTERN bool ucl_parser_add_file_full (struct ucl_parser *parser, const char *filename,
+ unsigned priority, enum ucl_duplicate_strategy strat,
+ enum ucl_parse_type parse_type);
+
+/**
* Load and add data from a file descriptor
* @param parser parser structure
* @param filename the name of file
OpenPOWER on IntegriCloud