Date: Sat, 29 Nov 2014 00:45:10 +0000 (UTC) From: Baptiste Daroussin <bapt@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r275223 - in head: contrib/libucl contrib/libucl/cmake contrib/libucl/doc contrib/libucl/include contrib/libucl/lua contrib/libucl/m4 contrib/libucl/src contrib/libucl/tests contrib/lib... Message-ID: <201411290045.sAT0jAwd031798@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bapt Date: Sat Nov 29 00:45:09 2014 New Revision: 275223 URL: https://svnweb.freebsd.org/changeset/base/275223 Log: Update libucl to latest version While here correctly link libucl to libm and register the dependency on libm for static building Added: head/contrib/libucl/COPYING - copied unchanged from r275222, vendor/libucl/dist/COPYING head/contrib/libucl/doc/lua_api.md - copied unchanged from r275222, vendor/libucl/dist/doc/lua_api.md head/contrib/libucl/include/lua_ucl.h - copied unchanged from r275222, vendor/libucl/dist/include/lua_ucl.h head/contrib/libucl/lua/ - copied from r275222, vendor/libucl/dist/lua/ head/contrib/libucl/m4/ - copied from r275222, vendor/libucl/dist/m4/ head/contrib/libucl/tests/basic/12.in - copied unchanged from r275222, vendor/libucl/dist/tests/basic/12.in head/contrib/libucl/tests/basic/12.res - copied unchanged from r275222, vendor/libucl/dist/tests/basic/12.res head/contrib/libucl/tests/basic/13.in - copied unchanged from r275222, vendor/libucl/dist/tests/basic/13.in head/contrib/libucl/tests/basic/13.res - copied unchanged from r275222, vendor/libucl/dist/tests/basic/13.res head/contrib/libucl/tests/basic/comments.in - copied unchanged from r275222, vendor/libucl/dist/tests/basic/comments.in head/contrib/libucl/tests/basic/comments.res - copied unchanged from r275222, vendor/libucl/dist/tests/basic/comments.res head/contrib/libucl/tests/basic/include_dir/ - copied from r275222, vendor/libucl/dist/tests/basic/include_dir/ Modified: head/contrib/libucl/ChangeLog.md head/contrib/libucl/Makefile.am head/contrib/libucl/Makefile.w32 head/contrib/libucl/README.md head/contrib/libucl/cmake/CMakeLists.txt head/contrib/libucl/configure.ac head/contrib/libucl/include/ucl.h head/contrib/libucl/libucl.pc.in head/contrib/libucl/src/ucl_emitter.c head/contrib/libucl/src/ucl_emitter_streamline.c head/contrib/libucl/src/ucl_emitter_utils.c head/contrib/libucl/src/ucl_hash.c head/contrib/libucl/src/ucl_hash.h head/contrib/libucl/src/ucl_internal.h head/contrib/libucl/src/ucl_parser.c head/contrib/libucl/src/ucl_util.c head/contrib/libucl/tests/Makefile.am head/contrib/libucl/tests/basic/4.res head/contrib/libucl/tests/generate.res head/contrib/libucl/tests/test_basic.c head/contrib/libucl/tests/test_generate.c head/contrib/libucl/tests/test_schema.c head/contrib/libucl/utils/objdump.c head/lib/libucl/Makefile head/share/mk/src.libnames.mk Directory Properties: head/contrib/libucl/ (props changed) Copied: head/contrib/libucl/COPYING (from r275222, vendor/libucl/dist/COPYING) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/contrib/libucl/COPYING Sat Nov 29 00:45:09 2014 (r275223, copy of r275222, vendor/libucl/dist/COPYING) @@ -0,0 +1,23 @@ +Copyright (c) 2013-2014, Vsevolod Stakhov <vsevolod@highsecure.ru> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Modified: head/contrib/libucl/ChangeLog.md ============================================================================== --- head/contrib/libucl/ChangeLog.md Sat Nov 29 00:34:47 2014 (r275222) +++ head/contrib/libucl/ChangeLog.md Sat Nov 29 00:45:09 2014 (r275223) @@ -4,3 +4,19 @@ - Streamline emitter has been added, so it is now possible to output partial `ucl` objects - Emitter now is more flexible due to emitter_context structure + +### 0.5.1 +- Fixed number of bugs and memory leaks + +### 0.5.2 + +- Allow userdata objects to be emitted and destructed +- Use userdata objects to store lua function references + +### Libucl 0.6 + +- Reworked macro interface + +### Libucl 0.6.1 + +- Various utilities fixes Modified: head/contrib/libucl/Makefile.am ============================================================================== --- head/contrib/libucl/Makefile.am Sat Nov 29 00:34:47 2014 (r275222) +++ head/contrib/libucl/Makefile.am Sat Nov 29 00:45:09 2014 (r275223) @@ -4,4 +4,8 @@ EXTRA_DIST = uthash README.md pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libucl.pc -SUBDIRS = src tests utils doc +if LUA_SUB + LUA_SUBDIR = lua +endif + +SUBDIRS = src tests utils doc $(LUA_SUBDIR) \ No newline at end of file Modified: head/contrib/libucl/Makefile.w32 ============================================================================== --- head/contrib/libucl/Makefile.w32 Sat Nov 29 00:34:47 2014 (r275222) +++ head/contrib/libucl/Makefile.w32 Sat Nov 29 00:45:09 2014 (r275223) @@ -33,6 +33,7 @@ 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 @@ -51,6 +52,8 @@ $(OBJDIR)/ucl_parser.o: $(SRCDIR)/ucl_pa $(CC) -o $(OBJDIR)/ucl_parser.o $(CPPFLAGS) $(COPT_FLAGS) $(CFLAGS) $(C_COMMON_FLAGS) $(SSL_CFLAGS) $(FETCH_FLAGS) -c $(SRCDIR)/ucl_parser.c $(OBJDIR)/ucl_emitter.o: $(SRCDIR)/ucl_emitter.c $(HDEPS) $(CC) -o $(OBJDIR)/ucl_emitter.o $(CPPFLAGS) $(COPT_FLAGS) $(CFLAGS) $(C_COMMON_FLAGS) $(SSL_CFLAGS) $(FETCH_FLAGS) -c $(SRCDIR)/ucl_emitter.c +$(OBJDIR)/ucl_emitter_utils.o: $(SRCDIR)/ucl_emitter_utils.c $(HDEPS) + $(CC) -o $(OBJDIR)/ucl_emitter_utils.o $(CPPFLAGS) $(COPT_FLAGS) $(CFLAGS) $(C_COMMON_FLAGS) $(SSL_CFLAGS) $(FETCH_FLAGS) -c $(SRCDIR)/ucl_emitter_utils.c $(OBJDIR)/ucl_hash.o: $(SRCDIR)/ucl_hash.c $(HDEPS) $(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) @@ -61,7 +64,7 @@ $(OBJDIR)/xxhash.o: $(SRCDIR)/xxhash.c $ clean: $(RM) $(OBJDIR)/*.o $(OBJDIR)/$(SONAME) $(OBJDIR)/$(SONAME) $(OBJDIR)/chargen $(OBJDIR)/test_basic $(OBJDIR)/test_speed $(OBJDIR)/objdump $(OBJDIR)/test_generate $(RMDIR) $(OBJDIR) - + # Utils chargen: utils/chargen.c $(OBJDIR)/$(SONAME) @@ -75,7 +78,7 @@ test: $(OBJDIR) $(OBJDIR)/$(SONAME) $(OB run-test: test TEST_DIR=$(TESTDIR) $(TESTDIR)/run_tests.sh $(OBJDIR)/test_basic $(OBJDIR)/test_speed $(OBJDIR)/test_generate - + $(OBJDIR)/test_basic: $(TESTDIR)/test_basic.c $(OBJDIR)/$(SONAME) $(CC) -o $(OBJDIR)/test_basic $(CPPFLAGS) $(COPT_FLAGS) $(CFLAGS) $(C_COMMON_FLAGS) $(SSL_CFLAGS) $(FETCH_FLAGS) $(LDFLAGS) $(TESTDIR)/test_basic.c $(LD_UCL_FLAGS) $(OBJDIR)/test_speed: $(TESTDIR)/test_speed.c $(OBJDIR)/$(SONAME) Modified: head/contrib/libucl/README.md ============================================================================== --- head/contrib/libucl/README.md Sat Nov 29 00:34:47 2014 (r275222) +++ head/contrib/libucl/README.md Sat Nov 29 00:45:09 2014 (r275223) @@ -223,15 +223,57 @@ UCL supports external macros both multil .... }; ``` -There are two internal macros provided by UCL: -* `include` - read a file `/path/to/file` or an url `http://example.com/file` and include it to the current place of -UCL configuration; -* `try\_include` - try to read a file or url and include it but do not create a fatal error if a file or url is not accessible; -* `includes` - read a file or an url like the previous macro, but fetch and check the signature file (which is obtained -by `.sig` suffix appending). - -Public keys which are used for the last command are specified by the concrete UCL user. +Moreover, each macro can accept an optional list of arguments in braces. These +arguments themselves are the UCL object that is parsed and passed to a macro as +options: + +```nginx +.macro(param=value) "something"; +.macro(param={key=value}) "something"; +.macro(.include "params.conf") "something"; +.macro(#this is multiline macro +param = [value1, value2]) "something"; +.macro(key="()") "something"; +``` + +UCL also provide a convenient `include` macro to load content from another files +to the current UCL object. This macro accepts either path to file: + +```nginx +.include "/full/path.conf" +.include "./relative/path.conf" +.include "${CURDIR}/path.conf" +``` + +or URL (if ucl is built with url support provided by either `libcurl` or `libfetch`): + + .include "http://example.com/file.conf" + +`.include` macro supports a set of options: + +* `try` (default: **false**) - if this option is `true` than UCL treats errors on loading of +this file as non-fatal. For example, such a file can be absent but it won't stop the parsing +of the top-level document. +* `sign` (default: **false**) - if this option is `true` UCL loads and checks the signature for +a file from path named `<FILEPATH>.sig`. Trusted public keys should be provided for UCL API after +parser is created but before any configurations are parsed. +* `glob` (default: **false**) - if this option is `true` UCL treats the filename as GLOB pattern and load +all files that matches the specified pattern (normally the format of patterns is defined in `glob` manual page +for your operating system). This option is meaningless for URL includes. +* `url` (default: **true**) - allow URL includes. +* `priority` (default: 0) - specify priority for the include (see below). + +Priorities are used by UCL parser to manage the policy of objects rewriting during including other files +as following: + +* If we have two objects with the same priority then we form an implicit array +* If a new object has bigger priority then we overwrite an old one +* If a new object has lower priority then we ignore it + +By default, the priority of top-level object is set to zero (lowest priority). Currently, +you can define up to 16 priorities (from 0 to 15). Includes with bigger priorities will +rewrite keys from the objects with lower priorities as specified by the policy. ### Variables support @@ -317,7 +359,7 @@ ucl: emitted compact json in 0.0991 seco ucl: emitted yaml in 0.1354 seconds ``` -You can do your own benchmarks by running `make test` in libucl top directory. +You can do your own benchmarks by running `make check` in libucl top directory. ## Conclusion Modified: head/contrib/libucl/cmake/CMakeLists.txt ============================================================================== --- head/contrib/libucl/cmake/CMakeLists.txt Sat Nov 29 00:34:47 2014 (r275222) +++ head/contrib/libucl/cmake/CMakeLists.txt Sat Nov 29 00:45:09 2014 (r275223) @@ -1,8 +1,8 @@ PROJECT(libucl C) SET(LIBUCL_VERSION_MAJOR 0) -SET(LIBUCL_VERSION_MINOR 2) -SET(LIBUCL_VERSION_PATCH 9) +SET(LIBUCL_VERSION_MINOR 5) +SET(LIBUCL_VERSION_PATCH 0) SET(LIBUCL_VERSION "${LIBUCL_VERSION_MAJOR}.${LIBUCL_VERSION_MINOR}.${LIBUCL_VERSION_PATCH}") @@ -86,6 +86,8 @@ INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOU SET(UCLSRC ../src/ucl_util.c ../src/ucl_parser.c ../src/ucl_emitter.c + ../src/ucl_emitter_streamline.c + ../src/ucl_emitter_utils.c ../src/ucl_hash.c ../src/ucl_schema.c ../src/xxhash.c) @@ -98,6 +100,18 @@ ENDIF (BUILD_SHARED_LIBS) ADD_LIBRARY(ucl ${LIB_TYPE} ${UCLSRC}) SET_TARGET_PROPERTIES(ucl PROPERTIES VERSION ${LIBUCL_VERSION} SOVERSION ${LIBUCL_VERSION_MAJOR}) +IF(WITH_LUA) + SET(UCL_LUA_SRC ../lua/lua_ucl.c) + ADD_LIBRARY(lua-ucl ${LIB_TYPE} ${UCL_LUA_SRC}) + IF(ENABLE_LUAJIT MATCHES "ON") + TARGET_LINK_LIBRARIES(lua-ucl "${LUAJIT_LIBRARY}") + ELSE(ENABLE_LUAJIT MATCHES "ON") + TARGET_LINK_LIBRARIES(lua-ucl "${LUA_LIBRARY}") + ENDIF(ENABLE_LUAJIT MATCHES "ON") + TARGET_LINK_LIBRARIES(lua-ucl ucl) + SET_TARGET_PROPERTIES(lua-ucl PROPERTIES VERSION ${LIBUCL_VERSION} SOVERSION ${LIBUCL_VERSION_MAJOR}) +ENDIF(WITH_LUA) + IF(HAVE_FETCH_H) TARGET_LINK_LIBRARIES(ucl fetch) ELSE(HAVE_FETCH_H) Modified: head/contrib/libucl/configure.ac ============================================================================== --- head/contrib/libucl/configure.ac Sat Nov 29 00:34:47 2014 (r275222) +++ head/contrib/libucl/configure.ac Sat Nov 29 00:45:09 2014 (r275223) @@ -1,12 +1,13 @@ m4_define([maj_ver], [0]) -m4_define([med_ver], [5]) -m4_define([min_ver], [0]) -m4_define([so_version], [2:0:0]) +m4_define([med_ver], [6]) +m4_define([min_ver], [1]) +m4_define([so_version], [3:0:1]) m4_define([ucl_version], [maj_ver.med_ver.min_ver]) AC_INIT([libucl],[ucl_version],[https://github.com/vstakhov/libucl],[libucl]) AC_CONFIG_SRCDIR([configure.ac]) -AM_INIT_AUTOMAKE([1.11 foreign silent-rules -Wall -Wportability no-dist-gzip dist-xz]) +AM_INIT_AUTOMAKE([1.11 foreign -Wall -Wportability no-dist-gzip dist-xz]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) UCL_VERSION=ucl_version SO_VERSION=so_version @@ -57,6 +58,9 @@ AC_ARG_ENABLE([regex], AS_HELP_STRING([- AC_ARG_ENABLE([signatures], AS_HELP_STRING([--enable-signatures], [Enable signatures check (requires openssl) @<:@default=no@:>@]), [], [enable_signatures=no]) +AC_ARG_ENABLE([lua], AS_HELP_STRING([--enable-lua], + [Enable lua API build (requires lua libraries and headers) @<:@default=no@:>@]), [], + [enable_lua=no]) AC_ARG_ENABLE([utils], AS_HELP_STRING([--enable-utils], [Build and install utils @<:@default=no@:>@]), [case "${enableval}" in @@ -99,6 +103,21 @@ AS_IF([test "x$enable_regex" = "xyes"], ]) AC_SUBST(LIBREGEX_LIB) +AS_IF([test "x$enable_lua" = "xyes"], [ + AX_PROG_LUA([5.1], [], [ + AX_LUA_HEADERS([ + AX_LUA_LIBS([ + AC_DEFINE(HAVE_LUA, 1, [Define to 1 for lua support.]) + with_lua="yes" + ], [AC_MSG_ERROR([unable to find the lua libraries]) + ]) + ], [AC_MSG_ERROR([unable to find the lua header files]) + ]) + ], [AC_MSG_ERROR([unable to find the lua interpreter])]) +], [with_lua="no"]) + +AM_CONDITIONAL([LUA_SUB], [test "$with_lua" = "yes"]) + AS_IF([test "x$enable_urls" = "xyes"], [ AC_CHECK_HEADER([fetch.h], [ AC_DEFINE(HAVE_FETCH_H, 1, [Define to 1 if you have the <fetch.h> header file.]) @@ -155,9 +174,11 @@ AC_LINK_IFELSE([ AC_CONFIG_FILES(Makefile \ src/Makefile \ + lua/Makefile tests/Makefile \ utils/Makefile \ doc/Makefile \ + lua/libucl.rockspec \ libucl.pc) AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) AC_OUTPUT Copied: head/contrib/libucl/doc/lua_api.md (from r275222, vendor/libucl/dist/doc/lua_api.md) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/contrib/libucl/doc/lua_api.md Sat Nov 29 00:45:09 2014 (r275223, copy of r275222, vendor/libucl/dist/doc/lua_api.md) @@ -0,0 +1,194 @@ +## Module `ucl` + +This lua module allows to parse objects from strings and to store data into +ucl objects. It uses `libucl` C library to parse and manipulate with ucl objects. + +Example: + +~~~lua +local ucl = require("ucl") + +local parser = ucl.parser() +local res,err = parser:parse_string('{key=value}') + +if not res then + print('parser error: ' .. err) +else + local obj = parser:get_object() + local got = ucl.to_format(obj, 'json') +endif + +local table = { + str = 'value', + num = 100500, + null = ucl.null, + func = function () + return 'huh' + end + + +print(ucl.to_format(table, 'ucl')) +-- Output: +--[[ +num = 100500; +str = "value"; +null = null; +func = "huh"; +--]] +~~~ + +###Brief content: + +**Functions**: + +> [`ucl_object_push_lua(L, obj, allow_array)`](#function-ucl_object_push_lual-obj-allow_array) + +> [`ucl.to_format(var, format)`](#function-uclto_formatvar-format) + + + +**Methods**: + +> [`parser:parse_file(name)`](#method-parserparse_filename) + +> [`parser:parse_string(input)`](#method-parserparse_stringinput) + +> [`parser:get_object()`](#method-parserget_object) + + +## Functions + +The module `ucl` defines the following functions. + +### Function `ucl_object_push_lua(L, obj, allow_array)` + +This is a `C` function to push `UCL` object as lua variable. This function +converts `obj` to lua representation using the following conversions: + +- *scalar* values are directly presented by lua objects +- *userdata* values are converted to lua function objects using `LUA_REGISTRYINDEX`, +this can be used to pass functions from lua to c and vice-versa +- *arrays* are converted to lua tables with numeric indicies suitable for `ipairs` iterations +- *objects* are converted to lua tables with string indicies + +**Parameters:** + +- `L {lua_State}`: lua state pointer +- `obj {ucl_object_t}`: object to push +- `allow_array {bool}`: expand implicit arrays (should be true for all but partial arrays) + +**Returns:** + +- `{int}`: `1` if an object is pushed to lua + +Back to [module description](#module-ucl). + +### Function `ucl.to_format(var, format)` + +Converts lua variable `var` to the specified `format`. Formats supported are: + +- `json` - fine printed json +- `json-compact` - compacted json +- `config` - fine printed configuration +- `ucl` - same as `config` +- `yaml` - embedded yaml + +If `var` contains function, they are called during output formatting and if +they return string value, then this value is used for ouptut. + +**Parameters:** + +- `var {variant}`: any sort of lua variable (if userdata then metafield `__to_ucl` is searched for output) +- `format {string}`: any available format + +**Returns:** + +- `{string}`: string representation of `var` in the specific `format`. + +Example: + +~~~lua +local table = { + str = 'value', + num = 100500, + null = ucl.null, + func = function () + return 'huh' + end + + +print(ucl.to_format(table, 'ucl')) +-- Output: +--[[ +num = 100500; +str = "value"; +null = null; +func = "huh"; +--]] +~~~ + +Back to [module description](#module-ucl). + + +## Methods + +The module `ucl` defines the following methods. + +### Method `parser:parse_file(name)` + +Parse UCL object from file. + +**Parameters:** + +- `name {string}`: filename to parse + +**Returns:** + +- `{bool[, string]}`: if res is `true` then file has been parsed successfully, otherwise an error string is also returned + +Example: + +~~~lua +local parser = ucl.parser() +local res,err = parser:parse_file('/some/file.conf') + +if not res then + print('parser error: ' .. err) +else + -- Do something with object +end +~~~ + +Back to [module description](#module-ucl). + +### Method `parser:parse_string(input)` + +Parse UCL object from file. + +**Parameters:** + +- `input {string}`: string to parse + +**Returns:** + +- `{bool[, string]}`: if res is `true` then file has been parsed successfully, otherwise an error string is also returned + +Back to [module description](#module-ucl). + +### Method `parser:get_object()` + +Get top object from parser and export it to lua representation. + +**Parameters:** + + nothing + +**Returns:** + +- `{variant or nil}`: ucl object as lua native variable + +Back to [module description](#module-ucl). + + +Back to [top](#). + Copied: head/contrib/libucl/include/lua_ucl.h (from r275222, vendor/libucl/dist/include/lua_ucl.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/contrib/libucl/include/lua_ucl.h Sat Nov 29 00:45:09 2014 (r275223, copy of r275222, vendor/libucl/dist/include/lua_ucl.h) @@ -0,0 +1,69 @@ +/* Copyright (c) 2014, Vsevolod Stakhov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef LUA_UCL_H_ +#define LUA_UCL_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +#include "ucl.h" + +/** + * Closure structure for lua function storing inside UCL + */ +struct ucl_lua_funcdata { + lua_State *L; + int idx; + char *ret; +}; + +/** + * Initialize lua UCL API + */ +UCL_EXTERN int luaopen_ucl (lua_State *L); + +/** + * Import UCL object from lua state + * @param L lua state + * @param idx index of object at the lua stack to convert to UCL + * @return new UCL object or NULL, the caller should unref object after using + */ +UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx); + +/** + * Push an object to lua + * @param L lua state + * @param obj object to push + * @param allow_array traverse over implicit arrays + */ +UCL_EXTERN int ucl_object_push_lua (lua_State *L, + const ucl_object_t *obj, bool allow_array); + +UCL_EXTERN struct ucl_lua_funcdata* ucl_object_toclosure ( + const ucl_object_t *obj); + +#endif /* LUA_UCL_H_ */ Modified: head/contrib/libucl/include/ucl.h ============================================================================== --- head/contrib/libucl/include/ucl.h Sat Nov 29 00:34:47 2014 (r275222) +++ head/contrib/libucl/include/ucl.h Sat Nov 29 00:45:09 2014 (r275223) @@ -147,7 +147,8 @@ typedef enum ucl_emitter { typedef enum ucl_parser_flags { UCL_PARSER_KEY_LOWERCASE = 0x1, /**< Convert all keys to lower case */ UCL_PARSER_ZEROCOPY = 0x2, /**< Parse input in zero-copy mode if possible */ - UCL_PARSER_NO_TIME = 0x4 /**< Do not parse time and treat time values as strings */ + UCL_PARSER_NO_TIME = 0x4, /**< Do not parse time and treat time values as strings */ + UCL_PARSER_NO_IMPLICIT_ARRAYS = 0x8 /** Create explicit arrays instead of implicit ones */ } ucl_parser_flags_t; /** @@ -171,9 +172,12 @@ typedef enum ucl_string_flags { * Basic flags for an object */ typedef enum ucl_object_flags { - UCL_OBJECT_ALLOCATED_KEY = 1, /**< An object has key allocated internally */ - UCL_OBJECT_ALLOCATED_VALUE = 2, /**< An object has a string value allocated internally */ - UCL_OBJECT_NEED_KEY_ESCAPE = 4 /**< The key of an object need to be escaped on output */ + UCL_OBJECT_ALLOCATED_KEY = 0x1, /**< An object has key allocated internally */ + UCL_OBJECT_ALLOCATED_VALUE = 0x2, /**< An object has a string value allocated internally */ + UCL_OBJECT_NEED_KEY_ESCAPE = 0x4, /**< The key of an object need to be escaped on output */ + UCL_OBJECT_EPHEMERAL = 0x8, /**< Temporary object that does not need to be freed really */ + UCL_OBJECT_MULTILINE = 0x10, /**< String should be displayed as multiline string */ + UCL_OBJECT_MULTIVALUE = 0x20 /**< Object is a key with multiple values */ } ucl_object_flags_t; /** @@ -195,14 +199,21 @@ typedef struct ucl_object_s { const char *key; /**< Key of an object */ struct ucl_object_s *next; /**< Array handle */ struct ucl_object_s *prev; /**< Array handle */ - unsigned char* trash_stack[2]; /**< Pointer to allocated chunks */ - unsigned keylen; /**< Lenght of a key */ - unsigned len; /**< Size of an object */ - enum ucl_type type; /**< Real type */ - uint16_t ref; /**< Reference count */ + uint32_t keylen; /**< Lenght of a key */ + uint32_t len; /**< Size of an object */ + uint32_t ref; /**< Reference count */ uint16_t flags; /**< Object flags */ + uint16_t type; /**< Real type */ + unsigned char* trash_stack[2]; /**< Pointer to allocated chunks */ } ucl_object_t; +/** + * Destructor type for userdata objects + * @param ud user specified data pointer + */ +typedef void (*ucl_userdata_dtor)(void *ud); +typedef const char* (*ucl_userdata_emitter)(void *ud); + /** @} */ /** @@ -239,6 +250,31 @@ UCL_EXTERN ucl_object_t* ucl_object_new UCL_EXTERN ucl_object_t* ucl_object_typed_new (ucl_type_t type) UCL_WARN_UNUSED_RESULT; /** + * Create new object with type and priority specified + * @param type type of a new object + * @param priority priority of an object + * @return new object + */ +UCL_EXTERN ucl_object_t* ucl_object_new_full (ucl_type_t type, unsigned priority) + UCL_WARN_UNUSED_RESULT; + +/** + * Create new object with userdata dtor + * @param dtor destructor function + * @return new object + */ +UCL_EXTERN ucl_object_t* ucl_object_new_userdata (ucl_userdata_dtor dtor, + ucl_userdata_emitter emitter) UCL_WARN_UNUSED_RESULT; + +/** + * Perform deep copy of an object copying everything + * @param other object to copy + * @return new object with refcount equal to 1 + */ +UCL_EXTERN ucl_object_t * ucl_object_copy (const ucl_object_t *other) + UCL_WARN_UNUSED_RESULT; + +/** * Return the type of an object * @return the object type */ @@ -293,7 +329,7 @@ UCL_EXTERN ucl_object_t* ucl_object_from /** * Insert a object 'elt' to the hash 'top' and associate it with key 'key' - * @param top destination object (will be created automatically if top is NULL) + * @param top destination object (must be of type UCL_OBJECT) * @param elt element to insert (must NOT be NULL) * @param key key to associate with this object (either const or preallocated) * @param keylen length of the key (or 0 for NULL terminated keys) @@ -306,7 +342,7 @@ UCL_EXTERN bool ucl_object_insert_key (u /** * Replace a object 'elt' to the hash 'top' and associate it with key 'key', old object will be unrefed, * if no object has been found this function works like ucl_object_insert_key() - * @param top destination object (will be created automatically if top is NULL) + * @param top destination object (must be of type UCL_OBJECT) * @param elt element to insert (must NOT be NULL) * @param key key to associate with this object (either const or preallocated) * @param keylen length of the key (or 0 for NULL terminated keys) @@ -317,6 +353,15 @@ UCL_EXTERN bool ucl_object_replace_key ( const char *key, size_t keylen, bool copy_key); /** + * Merge the keys from one object to another object. Overwrite on conflict + * @param top destination object (must be of type UCL_OBJECT) + * @param elt element to insert (must be of type UCL_OBJECT) + * @param copy copy rather than reference the elements + * @return true if all keys have been merged + */ +UCL_EXTERN bool ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy); + +/** * Delete a object associated with key 'key', old object will be unrefered, * @param top object * @param key key associated to the object to remove @@ -335,8 +380,9 @@ UCL_EXTERN bool ucl_object_delete_key (u /** - * Delete key from `top` object returning the object deleted. This object is not - * released + * Removes `key` from `top` object, returning the object that was removed. This + * object is not released, caller must unref the returned object when it is no + * longer needed. * @param top object * @param key key to remove * @param keylen length of the key (or 0 for NULL terminated keys) @@ -346,8 +392,9 @@ UCL_EXTERN ucl_object_t* ucl_object_pop_ size_t keylen) UCL_WARN_UNUSED_RESULT; /** - * Delete key from `top` object returning the object deleted. This object is not - * released + * Removes `key` from `top` object returning the object that was removed. This + * object is not released, caller must unref the returned object when it is no + * longer needed. * @param top object * @param key key to remove * @return removed object or NULL if object has not been found @@ -356,9 +403,9 @@ UCL_EXTERN ucl_object_t* ucl_object_pop_ UCL_WARN_UNUSED_RESULT; /** - * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if the specified key exist, - * try to merge its content - * @param top destination object (will be created automatically if top is NULL) + * Insert a object 'elt' to the hash 'top' and associate it with key 'key', if + * the specified key exist, try to merge its content + * @param top destination object (must be of type UCL_OBJECT) * @param elt element to insert (must NOT be NULL) * @param key key to associate with this object (either const or preallocated) * @param keylen length of the key (or 0 for NULL terminated keys) @@ -369,8 +416,8 @@ UCL_EXTERN bool ucl_object_insert_key_me const char *key, size_t keylen, bool copy_key); /** - * Append an element to the front of array object - * @param top destination object (will be created automatically if top is NULL) + * Append an element to the end of array object + * @param top destination object (must NOT be NULL) * @param elt element to append (must NOT be NULL) * @return true if value has been inserted */ @@ -379,7 +426,7 @@ UCL_EXTERN bool ucl_array_append (ucl_ob /** * Append an element to the start of array object - * @param top destination object (will be created automatically if top is NULL) + * @param top destination object (must NOT be NULL) * @param elt element to append (must NOT be NULL) * @return true if value has been inserted */ @@ -387,8 +434,19 @@ UCL_EXTERN bool ucl_array_prepend (ucl_o ucl_object_t *elt); /** - * Removes an element `elt` from the array `top`. Caller must unref the returned object when it is not - * needed. + * Merge all elements of second array into the first array + * @param top destination array (must be of type UCL_ARRAY) + * @param elt array to copy elements from (must be of type UCL_ARRAY) + * @param copy copy elements instead of referencing them + * @return true if arrays were merged + */ +UCL_EXTERN bool ucl_array_merge (ucl_object_t *top, ucl_object_t *elt, + bool copy); + +/** + * Removes an element `elt` from the array `top`, returning the object that was + * removed. This object is not released, caller must unref the returned object + * when it is no longer needed. * @param top array ucl object * @param elt element to remove * @return removed element or NULL if `top` is NULL or not an array @@ -411,35 +469,50 @@ UCL_EXTERN const ucl_object_t* ucl_array UCL_EXTERN const ucl_object_t* ucl_array_tail (const ucl_object_t *top); /** - * Removes the last element from the array `top`. Caller must unref the returned object when it is not - * needed. + * Removes the last element from the array `top`, returning the object that was + * removed. This object is not released, caller must unref the returned object + * when it is no longer needed. * @param top array ucl object * @return removed element or NULL if `top` is NULL or not an array */ UCL_EXTERN ucl_object_t* ucl_array_pop_last (ucl_object_t *top); /** - * Return object identified by an index of the array `top` - * @param obj object to get a key from (must be of type UCL_ARRAY) - * @param index index to return + * Removes the first element from the array `top`, returning the object that was + * removed. This object is not released, caller must unref the returned object + * when it is no longer needed. + * @param top array ucl object + * @return removed element or NULL if `top` is NULL or not an array + */ +UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top); + +/** + * Return object identified by index of the array `top` + * @param top object to get a key from (must be of type UCL_ARRAY) + * @param index array index to return * @return object at the specified index or NULL if index is not found */ UCL_EXTERN const ucl_object_t* ucl_array_find_index (const ucl_object_t *top, unsigned int index); /** - * Removes the first element from the array `top`. Caller must unref the returned object when it is not - * needed. - * @param top array ucl object - * @return removed element or NULL if `top` is NULL or not an array + * Replace an element in an array with a different element, returning the object + * that was replaced. This object is not released, caller must unref the + * returned object when it is no longer needed. + * @param top destination object (must be of type UCL_ARRAY) + * @param elt element to append (must NOT be NULL) + * @param index array index in destination to overwrite with elt + * @return object that was replaced or NULL if index is not found */ -UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top); +ucl_object_t * +ucl_array_replace_index (ucl_object_t *top, ucl_object_t *elt, + unsigned int index); /** * Append a element to another element forming an implicit array * @param head head to append (may be NULL) * @param elt new element - * @return true if element has been inserted + * @return the new implicit array */ UCL_EXTERN ucl_object_t * ucl_elt_append (ucl_object_t *head, ucl_object_t *elt); @@ -533,7 +606,7 @@ UCL_EXTERN const char* ucl_object_tolstr * Return object identified by a key in the specified object * @param obj object to get a key from (must be of type UCL_OBJECT) * @param key key to search - * @return object matched the specified key or NULL if key is not found + * @return object matching the specified key or NULL if key was not found */ UCL_EXTERN const ucl_object_t* ucl_object_find_key (const ucl_object_t *obj, const char *key); @@ -543,7 +616,7 @@ UCL_EXTERN const ucl_object_t* ucl_objec * @param obj object to get a key from (must be of type UCL_OBJECT) * @param key key to search * @param klen length of a key - * @return object matched the specified key or NULL if key is not found + * @return object matching the specified key or NULL if key was not found */ UCL_EXTERN const ucl_object_t* ucl_object_find_keyl (const ucl_object_t *obj, const char *key, size_t klen); @@ -575,6 +648,7 @@ UCL_EXTERN const char* ucl_object_keyl ( /** * Increase reference count for an object * @param obj object to ref + * @return the referenced object */ UCL_EXTERN ucl_object_t* ucl_object_ref (const ucl_object_t *obj); @@ -612,6 +686,21 @@ UCL_EXTERN void ucl_object_array_sort (u int (*cmp)(const ucl_object_t *o1, const ucl_object_t *o2)); /** + * Get the priority for specific UCL object + * @param obj any ucl object + * @return priority of an object + */ +UCL_EXTERN unsigned int ucl_object_get_priority (const ucl_object_t *obj); + +/** + * Set explicit priority of an object. + * @param obj any ucl object + * @param priority new priroity value (only 4 least significant bits are considred) + */ +UCL_EXTERN void ucl_object_set_priority (ucl_object_t *obj, + unsigned int priority); + +/** * Opaque iterator object */ typedef void* ucl_object_iter_t; @@ -640,11 +729,14 @@ UCL_EXTERN const ucl_object_t* ucl_itera * Macro handler for a parser * @param data the content of macro * @param len the length of content + * @param arguments arguments object * @param ud opaque user data * @param err error pointer * @return true if macro has been parsed */ -typedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len, void* ud); +typedef bool (*ucl_macro_handler) (const unsigned char *data, size_t len, + const ucl_object_t *arguments, + void* ud); /* Opaque parser */ struct ucl_parser; @@ -702,13 +794,24 @@ UCL_EXTERN void ucl_parser_set_variables * @param parser parser structure * @param data the pointer to the beginning of a chunk * @param len the length of a chunk - * @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_chunk (struct ucl_parser *parser, const unsigned char *data, size_t len); /** + * Load new chunk to a parser with the specified priority + * @param parser parser structure + * @param data the pointer to the beginning of a chunk + * @param len the length of a chunk + * @param priority the desired priority of a chunk (only 4 least significant bits + * are considered for this parameter) + * @return true if chunk has been added and false in case of error + */ +UCL_EXTERN bool ucl_parser_add_chunk_priority (struct ucl_parser *parser, + const unsigned char *data, size_t len, unsigned priority); + +/** * Load ucl object from a string * @param parser parser structure * @param data the pointer to the string @@ -835,7 +938,7 @@ struct ucl_emitter_context { /** A set of output operations */ const struct ucl_emitter_operations *ops; /** Current amount of indent tabs */ - unsigned int ident; + unsigned int indent; /** Top level object */ const ucl_object_t *top; /** The rest of context */ Modified: head/contrib/libucl/libucl.pc.in ============================================================================== --- head/contrib/libucl/libucl.pc.in Sat Nov 29 00:34:47 2014 (r275222) +++ head/contrib/libucl/libucl.pc.in Sat Nov 29 00:45:09 2014 (r275223) @@ -7,5 +7,5 @@ Name: LibUCL Description: Universal configuration library Version: @UCL_VERSION@ Libs: -L${libdir} -lucl -Libs.private: @LIBS_EXTRA@ +Libs.private: @LIBS_EXTRA@ @LUA_LIB@ Cflags: -I${includedir}/ Modified: head/contrib/libucl/src/ucl_emitter.c ============================================================================== --- head/contrib/libucl/src/ucl_emitter.c Sat Nov 29 00:34:47 2014 (r275222) +++ head/contrib/libucl/src/ucl_emitter.c Sat Nov 29 00:45:09 2014 (r275223) @@ -130,6 +130,19 @@ ucl_emitter_print_key (bool print_key, s func->ucl_emitter_append_character (' ', 1, func->ud); } } + else if (ctx->id == UCL_EMIT_YAML) { + if (obj->keylen > 0 && (obj->flags & UCL_OBJECT_NEED_KEY_ESCAPE)) { + ucl_elt_string_write_json (obj->key, obj->keylen, ctx); + } + else if (obj->keylen > 0) { + func->ucl_emitter_append_len (obj->key, obj->keylen, func->ud); + } + else { + func->ucl_emitter_append_len ("null", 4, func->ud); + } + + func->ucl_emitter_append_len (": ", 2, func->ud); + } else { if (obj->keylen > 0) { ucl_elt_string_write_json (obj->key, obj->keylen, ctx); @@ -182,7 +195,7 @@ ucl_emitter_common_end_object (struct uc const struct ucl_emitter_functions *func = ctx->func; if (UCL_EMIT_IDENT_TOP_OBJ(ctx, obj)) { - ctx->ident --; + ctx->indent --; if (compact) { func->ucl_emitter_append_character ('}', 1, func->ud); } @@ -191,7 +204,7 @@ ucl_emitter_common_end_object (struct uc /* newline is already added for this format */ func->ucl_emitter_append_character ('\n', 1, func->ud); } - ucl_add_tabs (func, ctx->ident, compact); + ucl_add_tabs (func, ctx->indent, compact); func->ucl_emitter_append_character ('}', 1, func->ud); } } @@ -210,7 +223,7 @@ ucl_emitter_common_end_array (struct ucl { const struct ucl_emitter_functions *func = ctx->func; - ctx->ident --; + ctx->indent --; if (compact) { func->ucl_emitter_append_character (']', 1, func->ud); } @@ -219,7 +232,7 @@ ucl_emitter_common_end_array (struct ucl /* newline is already added for this format */ func->ucl_emitter_append_character ('\n', 1, func->ud); } - ucl_add_tabs (func, ctx->ident, compact); + ucl_add_tabs (func, ctx->indent, compact); func->ucl_emitter_append_character (']', 1, func->ud); } @@ -249,7 +262,7 @@ ucl_emitter_common_start_array (struct u func->ucl_emitter_append_len ("[\n", 2, func->ud); } - ctx->ident ++; + ctx->indent ++; if (obj->type == UCL_ARRAY) { /* explicit array */ @@ -294,7 +307,7 @@ ucl_emitter_common_start_object (struct else { func->ucl_emitter_append_len ("{\n", 2, func->ud); } - ctx->ident ++; + ctx->indent ++; } while ((cur = ucl_hash_iterate (obj->value.ov, &it))) { @@ -315,7 +328,7 @@ ucl_emitter_common_start_object (struct func->ucl_emitter_append_len (",\n", 2, func->ud); } } - ucl_add_tabs (func, ctx->ident, compact); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411290045.sAT0jAwd031798>