Author: bapt
Date: Sat Oct  1 00:14:01 2016
New Revision: 306544
URL: https://svnweb.freebsd.org/changeset/base/306544

Log:
  Import libucl 20160812

Added:
  head/contrib/libucl/haskell/
     - copied from r306543, vendor/libucl/dist/haskell/
  head/contrib/libucl/m4/gcov.m4
     - copied unchanged from r306543, vendor/libucl/dist/m4/gcov.m4
  head/contrib/libucl/python/tests/
     - copied from r306543, vendor/libucl/dist/python/tests/
Deleted:
  head/contrib/libucl/python/test.sh
  head/contrib/libucl/python/test_uclmodule.py
Modified:
  head/contrib/libucl/CMakeLists.txt
  head/contrib/libucl/Makefile.unix
  head/contrib/libucl/Makefile.w32
  head/contrib/libucl/README.md
  head/contrib/libucl/include/ucl++.h
  head/contrib/libucl/include/ucl.h
  head/contrib/libucl/python/setup.py
  head/contrib/libucl/python/src/uclmodule.c
  head/contrib/libucl/src/ucl_parser.c
  head/contrib/libucl/src/ucl_schema.c
  head/contrib/libucl/src/ucl_util.c
  head/contrib/libucl/tests/schema/patternProperties.json
  head/contrib/libucl/tests/schema/refRemote.json
Directory Properties:
  head/contrib/libucl/   (props changed)

Modified: head/contrib/libucl/CMakeLists.txt
==============================================================================
--- head/contrib/libucl/CMakeLists.txt  Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/CMakeLists.txt  Sat Oct  1 00:14:01 2016        
(r306544)
@@ -205,8 +205,7 @@ SET(UCLSRC src/ucl_util.c
                src/ucl_hash.c
                src/ucl_schema.c
                src/ucl_msgpack.c
-               src/ucl_sexp.c
-               src/xxhash.c)
+               src/ucl_sexp.c)
 
 
 SET (LIB_TYPE STATIC)

Modified: head/contrib/libucl/Makefile.unix
==============================================================================
--- head/contrib/libucl/Makefile.unix   Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/Makefile.unix   Sat Oct  1 00:14:01 2016        
(r306544)
@@ -1,7 +1,7 @@
 CC ?= gcc
 DESTDIR ?= /usr/local
 LD ?= gcc
-C_COMMON_FLAGS ?= -fPIC -Wall -W -Wno-unused-parameter -Wno-pointer-sign 
-I./include -I./uthash -I./src
+C_COMMON_FLAGS ?= -fPIC -Wall -W -Wno-unused-parameter -Wno-pointer-sign 
-I./include -I./uthash -I./src -I./klib
 MAJOR_VERSION = 0
 MINOR_VERSION = 2
 PATCH_VERSION = 9
@@ -25,13 +25,12 @@ HDEPS = $(SRCDIR)/ucl_hash.h \
                $(SRCDIR)/ucl_chartable.h \
                $(SRCDIR)/ucl_internal.h \
                $(INCLUDEDIR)/ucl.h \
-               $(SRCDIR)/xxhash.h
+               $(SRCDIR)/mum.h
 OBJECTS = $(OBJDIR)/ucl_hash.o \
                $(OBJDIR)/ucl_util.o \
                $(OBJDIR)/ucl_parser.o \
                $(OBJDIR)/ucl_emitter.o \
-               $(OBJDIR)/ucl_schema.o \
-               $(OBJDIR)/xxhash.o
+               $(OBJDIR)/ucl_schema.o
 
 all: $(OBJDIR) $(OBJDIR)/$(SONAME)
 
@@ -55,8 +54,6 @@ $(OBJDIR)/ucl_hash.o: $(SRCDIR)/ucl_hash
        $(CC) -o $(OBJDIR)/ucl_hash.o $(CPPFLAGS) $(COPT_FLAGS) $(CFLAGS) 
$(C_COMMON_FLAGS) $(SSL_CFLAGS) $(FETCH_FLAGS) -c $(SRCDIR)/ucl_hash.c
 $(OBJDIR)/ucl_schema.o: $(SRCDIR)/ucl_schema.c $(HDEPS)
        $(CC) -o $(OBJDIR)/ucl_schema.o $(CPPFLAGS) $(COPT_FLAGS) $(CFLAGS) 
$(C_COMMON_FLAGS) $(SSL_CFLAGS) $(FETCH_FLAGS) -c $(SRCDIR)/ucl_schema.c
-$(OBJDIR)/xxhash.o: $(SRCDIR)/xxhash.c $(HDEPS)
-       $(CC) -o $(OBJDIR)/xxhash.o $(CPPFLAGS) $(COPT_FLAGS) $(CFLAGS) 
$(C_COMMON_FLAGS) $(SSL_CFLAGS) $(FETCH_FLAGS) -c $(SRCDIR)/xxhash.c
 
 clean:
        $(RM) $(OBJDIR)/*.o $(OBJDIR)/$(SONAME_FULL) $(OBJDIR)/$(SONAME) 
$(OBJDIR)/chargen $(OBJDIR)/test_basic $(OBJDIR)/test_speed $(OBJDIR)/objdump 
$(OBJDIR)/test_generate $(OBJDIR)/test_schema || true

Modified: head/contrib/libucl/Makefile.w32
==============================================================================
--- head/contrib/libucl/Makefile.w32    Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/Makefile.w32    Sat Oct  1 00:14:01 2016        
(r306544)
@@ -28,14 +28,13 @@ HDEPS = $(SRCDIR)/ucl_hash.h \
                $(SRCDIR)/ucl_chartable.h \
                $(SRCDIR)/ucl_internal.h \
                $(INCLUDEDIR)/ucl.h \
-               $(SRCDIR)/xxhash.h
+               $(SRCDIR)/mum.h
 OBJECTS = $(OBJDIR)/ucl_hash.o \
                $(OBJDIR)/ucl_util.o \
                $(OBJDIR)/ucl_parser.o \
                $(OBJDIR)/ucl_emitter.o \
                $(OBJDIR)/ucl_emitter_utils.o \
-               $(OBJDIR)/ucl_schema.o \
-               $(OBJDIR)/xxhash.o
+               $(OBJDIR)/ucl_schema.o
 
 all: $(OBJDIR) $(OBJDIR)/$(SONAME)
 

Modified: head/contrib/libucl/README.md
==============================================================================
--- head/contrib/libucl/README.md       Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/README.md       Sat Oct  1 00:14:01 2016        
(r306544)
@@ -12,7 +12,7 @@
        - [Named keys hierarchy](#named-keys-hierarchy)
        - [Convenient numbers and booleans](#convenient-numbers-and-booleans)
 - [General improvements](#general-improvements)
-       - [Commments](#commments)
+       - [Comments](#comments)
        - [Macros support](#macros-support)
        - [Variables support](#variables-support)
        - [Multiline strings](#multiline-strings)
@@ -21,7 +21,7 @@
 - [Performance](#performance)
 - [Conclusion](#conclusion)
 
-## Introduction 
+## Introduction
 
 This document describes the main features and principles of the configuration
 language called `UCL` - universal configuration language.
@@ -47,7 +47,7 @@ section {
     string = "something";
     subsection {
         host = {
-            host = "hostname"; 
+            host = "hostname";
             port = 900;
         }
         host = {
@@ -163,9 +163,9 @@ section {
        }
 }
 ```
-    
+
 Plain definitions may be more complex and contain more than a single level of 
nested objects:
-   
+
 ```nginx
 section "blah" "foo" {
        key = value;
@@ -174,7 +174,7 @@ section "blah" "foo" {
 
 is presented as:
 
-```nginx    
+```nginx
 section {
        blah {
                foo {
@@ -196,17 +196,17 @@ section {
 
 ## General improvements
 
-### Commments
+### Comments
 
 UCL supports different style of comments:
 
-* single line: `#` 
+* single line: `#`
 * multiline: `/* ... */`
 
 Multiline comments may be nested:
 ```c
 # Sample single line comment
-/* 
+/*
  some comment
  /* nested comment */
  end of comment
@@ -263,7 +263,7 @@ all files that matches the specified pat
 for your operating system). This option is meaningless for URL includes.
 * `url` (default: **true**) - allow URL includes.
 * `path` (default: empty) - A UCL_ARRAY of directories to search for the 
include file.
-Search ends after the first patch, unless `glob` is true, then all matches are 
included.
+Search ends after the first match, unless `glob` is true, then all matches are 
included.
 * `prefix` (default false) - Put included contents inside an object, instead
 of loading them into the root. If no `key` is provided, one is automatically 
generated based on each files basename()
 * `key` (default: <empty string>) - Key to load contents of include into. If
@@ -273,7 +273,7 @@ object or an array.
 * `priority` (default: 0) - specify priority for the include (see below).
 * `duplicate` (default: 'append') - specify policy of duplicates resolving:
        - `append` - default strategy, if we have new object of higher priority 
then it replaces old one, if we have new object with less priority it is 
ignored completely, and if we have two duplicate objects with the same priority 
then we have a multi-value key (implicit array)
-       - `merge` - if we have object or array, then new keys are merged 
inside, if we have a plain object then an implicit array is formed (regardeless 
of priorities)
+       - `merge` - if we have object or array, then new keys are merged 
inside, if we have a plain object then an implicit array is formed (regardless 
of priorities)
        - `error` - create error on duplicate keys and stop parsing
        - `rewrite` - always rewrite an old value with new one (ignoring 
priorities)
 
@@ -320,7 +320,7 @@ Here are some rules for this syntax:
 * Multiline terminator must start just after `<<` symbols and it must consist 
of capital letters only (e.g. `<<eof` or `<< EOF` won't work);
 * Terminator must end with a single newline character (and no spaces are 
allowed between terminator and newline character);
 * To finish multiline string you need to include a terminator string just 
after newline and followed by a newline (no spaces or other characters are 
allowed as well);
-* The initial and the final newlines are not inserted to the resulting string, 
but you can still specify newlines at the begin and at the end of a value, for 
example:
+* The initial and the final newlines are not inserted to the resulting string, 
but you can still specify newlines at the beginning and at the end of a value, 
for example:
 
 ```
 key <<EOD
@@ -347,7 +347,7 @@ UCL allows validation of objects. It use
 ## Performance
 
 Are UCL parser and emitter fast enough? Well, there are some numbers.
-I got a 19Mb file that consist of ~700 thousands lines of json (obtained via
+I got a 19Mb file that consist of ~700 thousand lines of json (obtained via
 http://www.json-generator.com/). Then I checked jansson library that performs 
json
 parsing and emitting and compared it with UCL. Here are results:
 
@@ -377,6 +377,6 @@ You can do your own benchmarks by runnin
 ## Conclusion
 
 UCL has clear design that should be very convenient for reading and writing. 
At the same time it is compatible with
-JSON language and therefore can be used as a simple JSON parser. Macroes logic 
provides an ability to extend configuration
-language (for example by including some lua code) and comments allows to 
disable or enable the parts of a configuration
+JSON language and therefore can be used as a simple JSON parser. Macro logic 
provides an ability to extend configuration
+language (for example by including some lua code) and comments allow to 
disable or enable the parts of a configuration
 quickly.

Modified: head/contrib/libucl/include/ucl++.h
==============================================================================
--- head/contrib/libucl/include/ucl++.h Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/include/ucl++.h Sat Oct  1 00:14:01 2016        
(r306544)
@@ -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
        {

Modified: head/contrib/libucl/include/ucl.h
==============================================================================
--- head/contrib/libucl/include/ucl.h   Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/include/ucl.h   Sat Oct  1 00:14:01 2016        
(r306544)
@@ -1016,7 +1016,6 @@ UCL_EXTERN bool ucl_parser_add_string_pr
  * 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 (str
  * 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_prio
                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

Copied: head/contrib/libucl/m4/gcov.m4 (from r306543, 
vendor/libucl/dist/m4/gcov.m4)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/contrib/libucl/m4/gcov.m4      Sat Oct  1 00:14:01 2016        
(r306544, copy of r306543, vendor/libucl/dist/m4/gcov.m4)
@@ -0,0 +1,89 @@
+# SYNOPSIS
+#
+#   Add code coverage support with gcov/lcov.
+#
+#   AX_CODE_COVERAGE()
+#
+# DESCRIPTION
+#
+#   Provides a --enable-coverage option which checks for available
+#   gcov/lcov binaries and provides ENABLE_CODE_COVERAGE conditional.
+#
+# LAST MODIFICATION
+#
+#   $Id: coverage.m4 40881 2013-08-20 17:54:39Z damon $
+#
+# COPYLEFT
+#
+#   Copyright (c) 2012 Roy H. Stogner <royst...@ices.utexas.edu>
+#   Copyright (c) 2010 Karl W. Schulz <k...@ices.utexas.edu>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_CODE_COVERAGE],
+[
+
+AC_ARG_ENABLE(coverage, AC_HELP_STRING([--enable-coverage],[configure code 
coverage analysis tools]))
+
+HAVE_GCOV_TOOLS=0
+
+GCOV_FLAGS=""
+
+if test "x$enable_coverage" = "xyes"; then
+
+   # ----------------------------
+   # Check for gcov/lcov binaries
+   # ----------------------------
+
+   AC_ARG_VAR([GCOV], [Coverage testing command])
+   if test "x$GCOV" = "x"; then
+    AC_PATH_PROG(GCOV, gcov, no)
+   else
+    AC_PATH_PROG(GCOV, $GCOV, no)
+   fi
+
+   AC_PATH_PROG(LCOV, lcov, no)
+   AC_PATH_PROG(GENHTML, genhtml)
+
+   # ----------------------------------
+   # include coverage compiler options
+   # ----------------------------------
+   AC_MSG_CHECKING([for clang])
+
+   AC_COMPILE_IFELSE(
+   [AC_LANG_PROGRAM([], [[
+ #ifndef __clang__
+   not clang
+ #endif
+ ]])],
+ [CLANG=yes], [CLANG=no])
+
+   AC_MSG_RESULT([$CLANG])
+   HAVE_GCOV_TOOLS=1
+   COVERAGE_CFLAGS="-fprofile-arcs -ftest-coverage"
+   COVERAGE_LDFLAGS="--coverage -fprofile-arcs -ftest-coverage"
+   COVERAGE_OPTFLAGS="-O0"
+
+   # Test for C...
+   CFLAGS="${GCOV_FLAGS} ${CFLAGS}"
+   CXXFLAGS="${GCOV_FLAGS} ${CXXFLAGS}"
+   if test "x$GCC" = "xyes" -a "x$CLANG" = "xno"; then
+     COVERAGE_LIBS="-lgcov"
+   else
+     COVERAGE_LIBS=""
+   fi
+fi
+
+AC_SUBST([GCOV])
+AC_SUBST([LCOV])
+AC_SUBST([GENHTML])
+AC_SUBST([GENHTML_OPTIONS])
+AC_SUBST([COVERAGE_CFLAGS])
+AC_SUBST([COVERAGE_OPTFLAGS])
+AC_SUBST([COVERAGE_LDFLAGS])
+AC_SUBST([COVERAGE_LIBS])
+AM_CONDITIONAL(CODE_COVERAGE_ENABLED,test x$HAVE_GCOV_TOOLS = x1)
+
+])

Modified: head/contrib/libucl/python/setup.py
==============================================================================
--- head/contrib/libucl/python/setup.py Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/python/setup.py Sat Oct  1 00:14:01 2016        
(r306544)
@@ -1,37 +1,43 @@
-import distutils.ccompiler
-import distutils.sysconfig
-from distutils.core import setup, Extension
+try:
+    from setuptools import setup, Extension
+except ImportError:
+    from distutils.core import setup, Extension
+
 import os
+import sys
 
+tests_require = []
 
-compiler  = distutils.ccompiler.new_compiler()
-search_paths=[os.path.expanduser('~/{}'), '/opt/local/{}', '/usr/local/{}', 
'/usr/{}']
-lib_paths = [ a.format("lib") for a in search_paths]
-inc_paths = [ a.format("include") for a in search_paths]
+if sys.version < '2.7':
+    tests_require.append('unittest2')
 
-uclmodule = Extension('ucl',
-        include_dirs = inc_paths,
-        library_dirs = lib_paths,
-        libraries = ['ucl'],
-        sources = ['src/uclmodule.c'],
-        runtime_library_dirs = lib_paths,
-        language='c')
+uclmodule = Extension(
+    'ucl',
+    libraries = ['ucl'],
+    sources = ['src/uclmodule.c'],
+    language = 'c'
+)
 
-setup(name='ucl',
-    version='1.0',
-    description='ucl parser and emmitter',
+setup(
+    name = 'ucl',
+    version = '0.8',
+    description = 'ucl parser and emmitter',
     ext_modules = [uclmodule],
-    author="Eitan Adler",
-    author_email="li...@eitanadler.com",
-    url="https://github.com/vstakhov/libucl/";,
-    license="MIT",
-    classifiers=["Development Status :: 3 - Alpha",
+    test_suite = 'tests',
+    tests_require = tests_require,
+    author = "Eitan Adler, Denis Volpato Martins",
+    author_email = "li...@eitanadler.com",
+    url = "https://github.com/vstakhov/libucl/";,
+    license = "MIT",
+    classifiers = [
+        "Development Status :: 3 - Alpha",
         "Intended Audience :: Developers",
         "License :: DFSG approved",
         "License :: OSI Approved :: MIT License",
         "Programming Language :: C",
+        "Programming Language :: Python :: 2",
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: Implementation :: CPython",
         "Topic :: Software Development :: Libraries",
-        ]
-    )
+    ]
+)

Modified: head/contrib/libucl/python/src/uclmodule.c
==============================================================================
--- head/contrib/libucl/python/src/uclmodule.c  Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/python/src/uclmodule.c  Sat Oct  1 00:14:01 2016        
(r306544)
@@ -2,6 +2,8 @@
 #include <ucl.h>
 #include <Python.h>
 
+static PyObject *SchemaError;
+
 static PyObject *
 _basic_ucl_type (ucl_object_t const *obj)
 {
@@ -13,9 +15,11 @@ _basic_ucl_type (ucl_object_t const *obj
        case UCL_STRING:
                return Py_BuildValue ("s", ucl_object_tostring (obj));
        case UCL_BOOLEAN:
-               return ucl_object_toboolean (obj) ? Py_True : Py_False;
+               return PyBool_FromLong (ucl_object_toboolean (obj));
        case UCL_TIME:
                return Py_BuildValue ("d", ucl_object_todouble (obj));
+       case UCL_NULL:
+               Py_RETURN_NONE;
        }
        return NULL;
 }
@@ -124,26 +128,60 @@ _iterate_python (PyObject *obj)
 {
        if (obj == Py_None) {
                return ucl_object_new();
-       } else if (PyBool_Check (obj)) {
+       }
+       else if (PyBool_Check (obj)) {
                return ucl_object_frombool (obj == Py_True);
-       } else if (PyInt_Check (obj)) {
+       }
+#if PY_MAJOR_VERSION < 3
+       else if (PyInt_Check (obj)) {
                return ucl_object_fromint (PyInt_AsLong (obj));
-       } else if (PyFloat_Check (obj)) {
+       }
+#endif
+       else if (PyLong_Check (obj)) {
+               return ucl_object_fromint (PyLong_AsLong (obj));
+       }
+       else if (PyFloat_Check (obj)) {
                return ucl_object_fromdouble (PyFloat_AsDouble (obj));
-       } else if (PyString_Check (obj)) {
+       }
+       else if (PyUnicode_Check (obj)) {
+               ucl_object_t *ucl_str;
+               PyObject *str = PyUnicode_AsASCIIString(obj);
+               ucl_str = ucl_object_fromstring (PyBytes_AsString (str));
+               Py_DECREF(str);
+               return ucl_str;
+       }
+#if PY_MAJOR_VERSION < 3
+       else if (PyString_Check (obj)) {
                return ucl_object_fromstring (PyString_AsString (obj));
-       // } else if (PyDateTime_Check (obj)) {
        }
+#endif
        else if (PyDict_Check(obj)) {
                PyObject *key, *value;
                Py_ssize_t pos = 0;
                ucl_object_t *top, *elm;
+               char *keystr = NULL;
 
                top = ucl_object_typed_new (UCL_OBJECT);
 
                while (PyDict_Next(obj, &pos, &key, &value)) {
                        elm = _iterate_python(value);
-                       ucl_object_insert_key (top, elm, 
PyString_AsString(key), 0, true);
+                       
+                       if (PyUnicode_Check(key)) {
+                               PyObject *keyascii = 
PyUnicode_AsASCIIString(key);
+                               keystr = PyBytes_AsString(keyascii);
+                               Py_DECREF(keyascii);
+                       }
+#if PY_MAJOR_VERSION < 3
+                       else if (PyString_Check(key)) {
+                               keystr = PyString_AsString(key);
+                       }
+#endif
+                       else {
+                               PyErr_SetString(PyExc_TypeError, "Unknown key 
type");
+                               return NULL;
+                       }
+
+                       ucl_object_insert_key (top, elm, keystr, 0, true);
                }
 
                return top;
@@ -195,11 +233,6 @@ ucl_dump (PyObject *self, PyObject *args
                Py_RETURN_NONE;
        }
 
-       if (!PyDict_Check(obj)) {
-               PyErr_SetString(PyExc_TypeError, "Argument must be dict");
-               return NULL;
-       }
-
        root = _iterate_python(obj);
        if (root) {
                PyObject *ret;
@@ -207,7 +240,11 @@ ucl_dump (PyObject *self, PyObject *args
 
                buf = (char *) ucl_object_emit (root, emitter);
                ucl_object_unref (root);
+#if PY_MAJOR_VERSION < 3
                ret = PyString_FromString (buf);
+#else
+               ret = PyUnicode_FromString (buf);
+#endif
                free(buf);
 
                return ret;
@@ -219,17 +256,35 @@ ucl_dump (PyObject *self, PyObject *args
 static PyObject *
 ucl_validate (PyObject *self, PyObject *args)
 {
-       char *uclstr, *schema;
+       PyObject *dataobj, *schemaobj;
+       ucl_object_t *data, *schema;
+       bool r;
+       struct ucl_schema_error err;
 
-       if (PyArg_ParseTuple(args, "zz", &uclstr, &schema)) {
-               if (!uclstr || !schema) {
-                       Py_RETURN_NONE;
-               }
+       if (!PyArg_ParseTuple (args, "OO", &schemaobj, &dataobj)) {
+               PyErr_SetString (PyExc_TypeError, "Unhandled object type");
+               return NULL;
+       }
 
-               PyErr_SetString(PyExc_NotImplementedError, "schema validation 
is not yet supported");
+       schema = _iterate_python(schemaobj);
+       if (!schema)
+               return NULL;
+
+       data = _iterate_python(dataobj);
+       if (!data)
+               return NULL;
+
+       // validation
+       r = ucl_object_validate (schema, data, &err);
+       ucl_object_unref (schema);
+       ucl_object_unref (data);
+
+       if (!r) {
+               PyErr_SetString (SchemaError, err.msg);
+               return NULL;
        }
 
-       return NULL;
+       Py_RETURN_TRUE;
 }
 
 static PyMethodDef uclMethods[] = {
@@ -247,6 +302,10 @@ init_macros(PyObject *mod)
        PyModule_AddIntMacro(mod, UCL_EMIT_CONFIG);
        PyModule_AddIntMacro(mod, UCL_EMIT_YAML);
        PyModule_AddIntMacro(mod, UCL_EMIT_MSGPACK);
+
+       SchemaError = PyErr_NewException("ucl.SchemaError", NULL, NULL);
+       Py_INCREF(SchemaError);
+       PyModule_AddObject(mod, "SchemaError", SchemaError);
 }
 
 #if PY_MAJOR_VERSION >= 3

Modified: head/contrib/libucl/src/ucl_parser.c
==============================================================================
--- head/contrib/libucl/src/ucl_parser.c        Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/src/ucl_parser.c        Sat Oct  1 00:14:01 2016        
(r306544)
@@ -342,6 +342,7 @@ ucl_check_variable_safe (struct ucl_pars
                /* Call generic handler */
                if (parser->var_handler (ptr, remain, &dst, &dstlen, &need_free,
                                parser->var_data)) {
+                       *out_len += dstlen;
                        *found = true;
                        if (need_free) {
                                free (dst);
@@ -458,11 +459,18 @@ ucl_expand_single_variable (struct ucl_p
        }
        if (!found) {
                if (strict && parser->var_handler != NULL) {
-                       if (parser->var_handler (ptr, remain, &dst, &dstlen, 
&need_free,
+                       size_t var_len = 0;
+                       while (var_len < remain && p[var_len] != '}')
+                               var_len ++;
+
+                       if (parser->var_handler (p, var_len, &dst, &dstlen, 
&need_free,
                                                        parser->var_data)) {
                                memcpy (d, dst, dstlen);
-                               ret += dstlen;
-                               d += remain;
+                               ret += var_len;
+                               d += dstlen;
+                               if (need_free) {
+                                       free (dst);
+                               }
                                found = true;
                        }
                }

Modified: head/contrib/libucl/src/ucl_schema.c
==============================================================================
--- head/contrib/libucl/src/ucl_schema.c        Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/src/ucl_schema.c        Sat Oct  1 00:14:01 2016        
(r306544)
@@ -69,7 +69,7 @@ ucl_schema_create_error (struct ucl_sche
  * Check whether we have a pattern specified
  */
 static const ucl_object_t *
-ucl_schema_test_pattern (const ucl_object_t *obj, const char *pattern)
+ucl_schema_test_pattern (const ucl_object_t *obj, const char *pattern, bool 
recursive)
 {
        const ucl_object_t *res = NULL;
 #ifdef HAVE_REGEX_H
@@ -78,11 +78,16 @@ ucl_schema_test_pattern (const ucl_objec
        ucl_object_iter_t iter = NULL;
 
        if (regcomp (&reg, pattern, REG_EXTENDED | REG_NOSUB) == 0) {
-               while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) {
-                       if (regexec (&reg, ucl_object_key (elt), 0, NULL, 0) == 
0) {
-                               res = elt;
-                               break;
+               if (recursive) {
+                       while ((elt = ucl_object_iterate (obj, &iter, true)) != 
NULL) {
+                               if (regexec (&reg, ucl_object_key (elt), 0, 
NULL, 0) == 0) {
+                                       res = elt;
+                                       break;
+                               }
                        }
+               } else {
+                       if (regexec (&reg, ucl_object_key (obj), 0, NULL, 0) == 
0)
+                               res = obj;
                }
                regfree (&reg);
        }
@@ -205,12 +210,17 @@ ucl_schema_validate_object (const ucl_ob
                        }
                }
                else if (strcmp (ucl_object_key (elt), "patternProperties") == 
0) {
+                       const ucl_object_t *vobj;
+                       ucl_object_iter_t viter;
                        piter = NULL;
                        while (ret && (prop = ucl_object_iterate (elt, &piter, 
true)) != NULL) {
-                               found = ucl_schema_test_pattern (obj, 
ucl_object_key (prop));
-                               if (found) {
-                                       ret = ucl_schema_validate (prop, found, 
true, err, root,
-                                                       ext_ref);
+                               viter = NULL;
+                               while (ret && (vobj = ucl_object_iterate (obj, 
&viter, true)) != NULL) {
+                                       found = ucl_schema_test_pattern (vobj, 
ucl_object_key (prop), false);
+                                       if (found) {
+                                               ret = ucl_schema_validate 
(prop, found, true, err, root,
+                                                               ext_ref);
+                                       }
                                }
                        }
                }
@@ -234,7 +244,7 @@ ucl_schema_validate_object (const ucl_ob
                                        piter = NULL;
                                        pat = ucl_object_lookup (schema, 
"patternProperties");
                                        while ((pelt = ucl_object_iterate (pat, 
&piter, true)) != NULL) {
-                                               found = ucl_schema_test_pattern 
(obj, ucl_object_key (pelt));
+                                               found = ucl_schema_test_pattern 
(obj, ucl_object_key (pelt), true);
                                                if (found != NULL) {
                                                        break;
                                                }

Modified: head/contrib/libucl/src/ucl_util.c
==============================================================================
--- head/contrib/libucl/src/ucl_util.c  Sat Oct  1 00:12:03 2016        
(r306543)
+++ head/contrib/libucl/src/ucl_util.c  Sat Oct  1 00:14:01 2016        
(r306544)
@@ -1795,8 +1795,9 @@ ucl_parser_set_filevars (struct ucl_pars
 }
 
 bool
-ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename,
-               unsigned priority)
+ucl_parser_add_file_full (struct ucl_parser *parser, const char *filename,
+               unsigned priority, enum ucl_duplicate_strategy strat,
+               enum ucl_parse_type parse_type)
 {
        unsigned char *buf;
        size_t len;
@@ -1819,7 +1820,8 @@ ucl_parser_add_file_priority (struct ucl
        }
        parser->cur_file = strdup (realbuf);
        ucl_parser_set_filevars (parser, realbuf, false);
-       ret = ucl_parser_add_chunk_priority (parser, buf, len, priority);
+       ret = ucl_parser_add_chunk_full (parser, buf, len, priority, strat,
+                       parse_type);
 
        if (len > 0) {
                ucl_munmap (buf, len);
@@ -1829,14 +1831,27 @@ ucl_parser_add_file_priority (struct ucl
 }
 
 bool
+ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename,
+               unsigned priority)
+{
+       if (parser == NULL) {
+               return false;
+       }
+
+       return ucl_parser_add_file_full(parser, filename, priority,
+                       UCL_DUPLICATE_APPEND, UCL_PARSE_UCL);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to