Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
Update libucl to newest version
Baptiste Daroussin committed 11 years ago
commit a4bf99dab4dc51b730f7088d919e94353f277b1f
parent f77d261af25baab39d2840654eb89da5da1e66a8
17 files changed +1074 -17
modified external/libucl/Makefile.am
@@ -4,4 +4,8 @@ EXTRA_DIST = uthash README.md
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libucl.pc

-
SUBDIRS = src tests utils doc

\ No newline at end of file
+
if LUA_SUB
+
  LUA_SUBDIR = lua
+
endif
+

+
SUBDIRS = src tests utils doc $(LUA_SUBDIR)

\ No newline at end of file
modified external/libucl/cmake/CMakeLists.txt
@@ -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_SOURCE_DIR}/../uthash")
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 external/libucl/configure.ac
@@ -6,7 +6,8 @@ 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([--enable-regex],
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
added external/libucl/include/lua_ucl.h
@@ -0,0 +1,57 @@
+
/* 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"
+

+
/**
+
 * 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);
+

+
#endif /* LUA_UCL_H_ */
modified external/libucl/include/ucl.h
@@ -195,12 +195,12 @@ 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;

/** @} */
modified external/libucl/libucl.pc.in
@@ -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}/
added external/libucl/lua/Makefile.am
@@ -0,0 +1,26 @@
+
ucl_common_cflags=	-I$(top_srcdir)/src \
+
			-I$(top_srcdir)/include \
+
			-I$(top_srcdir)/uthash \
+
			-Wall -W -Wno-unused-parameter -Wno-pointer-sign
+
luaexec_LTLIBRARIES=	ucl.la
+
ucl_la_SOURCES=	lua_ucl.c
+
ucl_la_CFLAGS=	$(ucl_common_cflags) \
+
					@LUA_INCLUDE@
+
ucl_la_LDFLAGS = -module -export-dynamic -avoid-version
+
ucl_la_LIBADD=	$(top_srcdir)/src/libucl.la \
+
					@LIBFETCH_LIBS@ \
+
					@LIBCRYPTO_LIB@ \
+
					@LIBREGEX_LIB@ \
+
					@CURL_LIBS@ \
+
					@LUA_LIB@
+

+
include_HEADERS=	$(top_srcdir)/include/lua_ucl.h
+

+
ROCKSPEC = $(PACKAGE)-$(VERSION)-1.rockspec
+
EXTRA_DIST = $(PACKAGE).rockspec.in \
+
			test.lua
+
DISTCLEANFILES = $(PACKAGE).rockspec
+

+
$(ROCKSPEC): $(PACKAGE).rockspec dist
+
	sed -e 's/@MD5@/'`$(MD5SUM) $(distdir).tar.gz | \
+
	cut -d " " -f 1`'/g' < $(PACKAGE).rockspec > $@

\ No newline at end of file
added external/libucl/lua/libucl.rockspec
@@ -0,0 +1,26 @@
+
package="libucl"
+
version="0.5.0-1"
+
source = {
+
  url = "https://github.com/downloads/vstakhov/libucl/libucl-0.5.0.tar.gz",
+
  md5 = "@MD5@",
+
  dir = "libucl-0.5.0"
+
}
+
description = {
+
  summary = "UCL - json like configuration language",
+
  detailed = [[
+
      UCL is heavily infused by nginx configuration as the example 
+
      of a convenient configuration system. 
+
      However, UCL is fully compatible with JSON format and is able 
+
      to parse json files. 
+
   ]],
+
  homepage = "http://github.com/vstakhov/libucl/",
+
  license = ""
+
}
+
dependencies = {
+
  "lua >= 5.1"
+
}
+
build = {
+
  type = "command",
+
  build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make",
+
  install_command = "make install"
+
}
added external/libucl/lua/libucl.rockspec.in
@@ -0,0 +1,26 @@
+
package="@PACKAGE@"
+
version="@VERSION@-1"
+
source = {
+
  url = "https://github.com/downloads/vstakhov/@PACKAGE@/@PACKAGE@-@VERSION@.tar.gz",
+
  md5 = "@MD5@",
+
  dir = "@PACKAGE@-@VERSION@"
+
}
+
description = {
+
  summary = "UCL - json like configuration language",
+
  detailed = [[
+
      UCL is heavily infused by nginx configuration as the example 
+
      of a convenient configuration system. 
+
      However, UCL is fully compatible with JSON format and is able 
+
      to parse json files. 
+
   ]],
+
  homepage = "http://github.com/vstakhov/@PACKAGE@/",
+
  license = ""
+
}
+
dependencies = {
+
  "lua >= 5.1"
+
}
+
build = {
+
  type = "command",
+
  build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make",
+
  install_command = "make install"
+
}
added external/libucl/lua/lua_ucl.c
@@ -0,0 +1,627 @@
+
/* 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.
+
 */
+

+
/**
+
 * @file lua ucl bindings
+
 */
+

+
#include "ucl.h"
+
#include "ucl_internal.h"
+
#include "lua_ucl.h"
+

+
#define PARSER_META "ucl.parser.meta"
+
#define EMITTER_META "ucl.emitter.meta"
+
#define NULL_META "null.emitter.meta"
+

+
static int ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj);
+
static int ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj, bool allow_array);
+
static ucl_object_t* ucl_object_lua_fromtable (lua_State *L, int idx);
+
static ucl_object_t* ucl_object_lua_fromelt (lua_State *L, int idx);
+

+
static void *ucl_null;
+

+
/**
+
 * Push a single element of an object to lua
+
 * @param L
+
 * @param key
+
 * @param obj
+
 */
+
static void
+
ucl_object_lua_push_element (lua_State *L, const char *key,
+
		const ucl_object_t *obj)
+
{
+
	lua_pushstring (L, key);
+
	ucl_object_push_lua (L, obj, true);
+
	lua_settable (L, -3);
+
}
+

+
/**
+
 * Push a single object to lua
+
 * @param L
+
 * @param obj
+
 * @return
+
 */
+
static int
+
ucl_object_lua_push_object (lua_State *L, const ucl_object_t *obj,
+
		bool allow_array)
+
{
+
	const ucl_object_t *cur;
+
	ucl_object_iter_t it = NULL;
+
	int nelt = 0;
+

+
	if (allow_array && obj->next != NULL) {
+
		/* Actually we need to push this as an array */
+
		return ucl_object_lua_push_array (L, obj);
+
	}
+

+
	/* Optimize allocation by preallocation of table */
+
	while (ucl_iterate_object (obj, &it, true) != NULL) {
+
		nelt ++;
+
	}
+

+
	lua_createtable (L, 0, nelt);
+
	it = NULL;
+

+
	while ((cur = ucl_iterate_object (obj, &it, true)) != NULL) {
+
		ucl_object_lua_push_element (L, ucl_object_key (cur), cur);
+
	}
+

+
	return 1;
+
}
+

+
/**
+
 * Push an array to lua as table indexed by integers
+
 * @param L
+
 * @param obj
+
 * @return
+
 */
+
static int
+
ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj)
+
{
+
	const ucl_object_t *cur;
+
	int i = 1, nelt = 0;
+

+
	/* Optimize allocation by preallocation of table */
+
	LL_FOREACH (obj, cur) {
+
		nelt ++;
+
	}
+

+
	lua_createtable (L, nelt, 0);
+

+
	LL_FOREACH (obj, cur) {
+
		ucl_object_push_lua (L, cur, false);
+
		lua_rawseti (L, -2, i);
+
		i ++;
+
	}
+

+
	return 1;
+
}
+

+
/**
+
 * Push a simple object to lua depending on its actual type
+
 */
+
static int
+
ucl_object_lua_push_scalar (lua_State *L, const ucl_object_t *obj,
+
		bool allow_array)
+
{
+
	if (allow_array && obj->next != NULL) {
+
		/* Actually we need to push this as an array */
+
		return ucl_object_lua_push_array (L, obj);
+
	}
+

+
	switch (obj->type) {
+
	case UCL_BOOLEAN:
+
		lua_pushboolean (L, ucl_obj_toboolean (obj));
+
		break;
+
	case UCL_STRING:
+
		lua_pushstring (L, ucl_obj_tostring (obj));
+
		break;
+
	case UCL_INT:
+
#if LUA_VERSION_NUM >= 501
+
		lua_pushinteger (L, ucl_obj_toint (obj));
+
#else
+
		lua_pushnumber (L, ucl_obj_toint (obj));
+
#endif
+
		break;
+
	case UCL_FLOAT:
+
	case UCL_TIME:
+
		lua_pushnumber (L, ucl_obj_todouble (obj));
+
		break;
+
	case UCL_NULL:
+
		lua_getfield (L, LUA_REGISTRYINDEX, "ucl.null");
+
		break;
+
	default:
+
		lua_pushnil (L);
+
		break;
+
	}
+

+
	return 1;
+
}
+

+
/**
+
 * Push an object to lua
+
 * @param L lua state
+
 * @param obj object to push
+
 */
+
int
+
ucl_object_push_lua (lua_State *L, const ucl_object_t *obj, bool allow_array)
+
{
+
	switch (obj->type) {
+
	case UCL_OBJECT:
+
		return ucl_object_lua_push_object (L, obj, allow_array);
+
	case UCL_ARRAY:
+
		return ucl_object_lua_push_array (L, obj->value.av);
+
	default:
+
		return ucl_object_lua_push_scalar (L, obj, allow_array);
+
	}
+
}
+

+
/**
+
 * Parse lua table into object top
+
 * @param L
+
 * @param top
+
 * @param idx
+
 */
+
static ucl_object_t *
+
ucl_object_lua_fromtable (lua_State *L, int idx)
+
{
+
	ucl_object_t *obj, *top = NULL;
+
	size_t keylen;
+
	const char *k;
+
	bool is_array = true;
+
	int max = INT_MIN;
+

+
	if (idx < 0) {
+
		/* For negative indicies we want to invert them */
+
		idx = lua_gettop (L) + idx + 1;
+
	}
+
	/* Check for array */
+
	lua_pushnil (L);
+
	while (lua_next (L, idx) != 0) {
+
		if (lua_type (L, -2) == LUA_TNUMBER) {
+
			double num = lua_tonumber (L, -2);
+
			if (num == (int)num) {
+
				if (num > max) {
+
					max = num;
+
				}
+
			}
+
			else {
+
				/* Keys are not integer */
+
				lua_pop (L, 2);
+
				is_array = false;
+
				break;
+
			}
+
		}
+
		else {
+
			/* Keys are not numeric */
+
			lua_pop (L, 2);
+
			is_array = false;
+
			break;
+
		}
+
		lua_pop (L, 1);
+
	}
+

+
	/* Table iterate */
+
	if (is_array) {
+
		int i;
+

+
		top = ucl_object_typed_new (UCL_ARRAY);
+
		for (i = 1; i <= max; i ++) {
+
			lua_pushinteger (L, i);
+
			lua_gettable (L, idx);
+
			obj = ucl_object_lua_fromelt (L, lua_gettop (L));
+
			if (obj != NULL) {
+
				ucl_array_append (top, obj);
+
			}
+
		}
+
	}
+
	else {
+
		lua_pushnil (L);
+
		top = ucl_object_typed_new (UCL_OBJECT);
+
		while (lua_next (L, idx) != 0) {
+
			/* copy key to avoid modifications */
+
			k = lua_tolstring (L, -2, &keylen);
+
			obj = ucl_object_lua_fromelt (L, lua_gettop (L));
+

+
			if (obj != NULL) {
+
				ucl_object_insert_key (top, obj, k, keylen, true);
+
			}
+
			lua_pop (L, 1);
+
		}
+
	}
+

+
	return top;
+
}
+

+
/**
+
 * Get a single element from lua to object obj
+
 * @param L
+
 * @param obj
+
 * @param idx
+
 */
+
static ucl_object_t *
+
ucl_object_lua_fromelt (lua_State *L, int idx)
+
{
+
	int type;
+
	double num;
+
	ucl_object_t *obj = NULL;
+

+
	type = lua_type (L, idx);
+

+
	switch (type) {
+
	case LUA_TSTRING:
+
		obj = ucl_object_fromstring_common (lua_tostring (L, idx), 0, 0);
+
		break;
+
	case LUA_TNUMBER:
+
		num = lua_tonumber (L, idx);
+
		if (num == (int64_t)num) {
+
			obj = ucl_object_fromint (num);
+
		}
+
		else {
+
			obj = ucl_object_fromdouble (num);
+
		}
+
		break;
+
	case LUA_TBOOLEAN:
+
		obj = ucl_object_frombool (lua_toboolean (L, idx));
+
		break;
+
	case LUA_TUSERDATA:
+
		if (lua_topointer (L, idx) == ucl_null) {
+
			obj = ucl_object_typed_new (UCL_NULL);
+
		}
+
		break;
+
	case LUA_TTABLE:
+
	case LUA_TFUNCTION:
+
	case LUA_TTHREAD:
+
		if (luaL_getmetafield (L, idx, "__gen_ucl")) {
+
			if (lua_isfunction (L, -1)) {
+
				lua_settop (L, 3); /* gen, obj, func */
+
				lua_insert (L, 1); /* func, gen, obj */
+
				lua_insert (L, 2); /* func, obj, gen */
+
				lua_call(L, 2, 1);
+
				obj = ucl_object_lua_fromelt (L, 1);
+
			}
+
			lua_pop (L, 2);
+
		}
+
		if (type == LUA_TTABLE) {
+
			obj = ucl_object_lua_fromtable (L, idx);
+
		}
+
		else if (type == LUA_TFUNCTION) {
+
			lua_pushvalue (L, idx);
+
			obj = ucl_object_new ();
+
			obj->type = UCL_USERDATA;
+
			obj->value.ud = (void *)(uintptr_t)(int)(luaL_ref (L, LUA_REGISTRYINDEX));
+
		}
+
		break;
+
	}
+

+
	return obj;
+
}
+

+
/**
+
 * Extract rcl object from lua object
+
 * @param L
+
 * @return
+
 */
+
ucl_object_t *
+
ucl_object_lua_import (lua_State *L, int idx)
+
{
+
	ucl_object_t *obj;
+
	int t;
+

+
	t = lua_type (L, idx);
+
	switch (t) {
+
	case LUA_TTABLE:
+
		obj = ucl_object_lua_fromtable (L, idx);
+
		break;
+
	default:
+
		obj = ucl_object_lua_fromelt (L, idx);
+
		break;
+
	}
+

+
	return obj;
+
}
+

+
static int
+
lua_ucl_parser_init (lua_State *L)
+
{
+
	struct ucl_parser *parser, **pparser;
+
	int flags = 0;
+

+
	if (lua_gettop (L) >= 1) {
+
		flags = lua_tonumber (L, 1);
+
	}
+

+
	parser = ucl_parser_new (flags);
+
	if (parser == NULL) {
+
		lua_pushnil (L);
+
	}
+

+
	pparser = lua_newuserdata (L, sizeof (parser));
+
	*pparser = parser;
+
	luaL_getmetatable (L, PARSER_META);
+
	lua_setmetatable (L, -2);
+

+
	return 1;
+
}
+

+
static struct ucl_parser *
+
lua_ucl_parser_get (lua_State *L, int index)
+
{
+
	return *((struct ucl_parser **) luaL_checkudata(L, index, PARSER_META));
+
}
+

+
static int
+
lua_ucl_parser_parse_file (lua_State *L)
+
{
+
	struct ucl_parser *parser;
+
	const char *file;
+
	int ret = 2;
+

+
	parser = lua_ucl_parser_get (L, 1);
+
	file = luaL_checkstring (L, 2);
+

+
	if (parser != NULL && file != NULL) {
+
		if (ucl_parser_add_file (parser, file)) {
+
			lua_pushboolean (L, true);
+
			ret = 1;
+
		}
+
		else {
+
			lua_pushboolean (L, false);
+
			lua_pushstring (L, ucl_parser_get_error (parser));
+
		}
+
	}
+
	else {
+
		lua_pushboolean (L, false);
+
		lua_pushstring (L, "invalid arguments");
+
	}
+

+
	return ret;
+
}
+

+
static int
+
lua_ucl_parser_parse_string (lua_State *L)
+
{
+
	struct ucl_parser *parser;
+
	const char *string;
+
	size_t llen;
+
	int ret = 2;
+

+
	parser = lua_ucl_parser_get (L, 1);
+
	string = luaL_checklstring (L, 2, &llen);
+

+
	if (parser != NULL && string != NULL) {
+
		if (ucl_parser_add_chunk (parser, (const unsigned char *)string, llen)) {
+
			lua_pushboolean (L, true);
+
			ret = 1;
+
		}
+
		else {
+
			lua_pushboolean (L, false);
+
			lua_pushstring (L, ucl_parser_get_error (parser));
+
		}
+
	}
+
	else {
+
		lua_pushboolean (L, false);
+
		lua_pushstring (L, "invalid arguments");
+
	}
+

+
	return ret;
+
}
+

+
static int
+
lua_ucl_parser_get_object (lua_State *L)
+
{
+
	struct ucl_parser *parser;
+
	ucl_object_t *obj;
+
	int ret = 1;
+

+
	parser = lua_ucl_parser_get (L, 1);
+
	obj = ucl_parser_get_object (parser);
+

+
	if (obj != NULL) {
+
		ret = ucl_object_push_lua (L, obj, false);
+
		/* no need to keep reference */
+
		ucl_object_unref (obj);
+
	}
+
	else {
+
		lua_pushnil (L);
+
	}
+

+
	return ret;
+
}
+

+
static int
+
lua_ucl_parser_gc (lua_State *L)
+
{
+
	struct ucl_parser *parser;
+

+
	parser = lua_ucl_parser_get (L, 1);
+
	ucl_parser_free (parser);
+

+
	return 0;
+
}
+

+
static void
+
lua_ucl_parser_mt (lua_State *L)
+
{
+
	luaL_newmetatable (L, PARSER_META);
+

+
	lua_pushvalue(L, -1);
+
	lua_setfield(L, -2, "__index");
+

+
	lua_pushcfunction (L, lua_ucl_parser_gc);
+
	lua_setfield (L, -2, "__gc");
+

+
	lua_pushcfunction (L, lua_ucl_parser_parse_file);
+
	lua_setfield (L, -2, "parse_file");
+

+
	lua_pushcfunction (L, lua_ucl_parser_parse_string);
+
	lua_setfield (L, -2, "parse_string");
+

+
	lua_pushcfunction (L, lua_ucl_parser_get_object);
+
	lua_setfield (L, -2, "get_object");
+

+
	lua_pop (L, 1);
+
}
+

+
static int
+
lua_ucl_to_string (lua_State *L, const ucl_object_t *obj, enum ucl_emitter type)
+
{
+
	unsigned char *result;
+

+
	result = ucl_object_emit (obj, type);
+

+
	if (result != NULL) {
+
		lua_pushstring (L, (const char *)result);
+
		free (result);
+
	}
+
	else {
+
		lua_pushnil (L);
+
	}
+

+
	return 1;
+
}
+

+
static int
+
lua_ucl_to_json (lua_State *L)
+
{
+
	ucl_object_t *obj;
+
	int format = UCL_EMIT_JSON;
+

+
	if (lua_gettop (L) > 1) {
+
		if (lua_toboolean (L, 2)) {
+
			format = UCL_EMIT_JSON_COMPACT;
+
		}
+
	}
+

+
	obj = ucl_object_lua_import (L, 1);
+
	if (obj != NULL) {
+
		lua_ucl_to_string (L, obj, format);
+
		ucl_object_unref (obj);
+
	}
+
	else {
+
		lua_pushnil (L);
+
	}
+

+
	return 1;
+
}
+

+
static int
+
lua_ucl_to_config (lua_State *L)
+
{
+
	ucl_object_t *obj;
+

+
	obj = ucl_object_lua_import (L, 1);
+
	if (obj != NULL) {
+
		lua_ucl_to_string (L, obj, UCL_EMIT_CONFIG);
+
		ucl_object_unref (obj);
+
	}
+
	else {
+
		lua_pushnil (L);
+
	}
+

+
	return 1;
+
}
+

+
static int
+
lua_ucl_to_format (lua_State *L)
+
{
+
	ucl_object_t *obj;
+
	int format = UCL_EMIT_JSON;
+

+
	if (lua_gettop (L) > 1) {
+
		format = lua_tonumber (L, 2);
+
		if (format < 0 || format >= UCL_EMIT_YAML) {
+
			lua_pushnil (L);
+
			return 1;
+
		}
+
	}
+

+
	obj = ucl_object_lua_import (L, 1);
+
	if (obj != NULL) {
+
		lua_ucl_to_string (L, obj, format);
+
		ucl_object_unref (obj);
+
	}
+
	else {
+
		lua_pushnil (L);
+
	}
+

+
	return 1;
+
}
+

+
static int
+
lua_ucl_null_tostring (lua_State* L)
+
{
+
	lua_pushstring (L, "null");
+
	return 1;
+
}
+

+
static void
+
lua_ucl_null_mt (lua_State *L)
+
{
+
	luaL_newmetatable (L, NULL_META);
+

+
	lua_pushcfunction (L, lua_ucl_null_tostring);
+
	lua_setfield (L, -2, "__tostring");
+

+
	lua_pop (L, 1);
+
}
+

+
int
+
luaopen_ucl (lua_State *L)
+
{
+
	lua_ucl_parser_mt (L);
+
	lua_ucl_null_mt (L);
+

+
	/* Create the refs weak table: */
+
	lua_createtable (L, 0, 2);
+
	lua_pushliteral (L, "v"); /* tbl, "v" */
+
	lua_setfield (L, -2, "__mode");
+
	lua_pushvalue (L, -1); /* tbl, tbl */
+
	lua_setmetatable (L, -2); /* tbl */
+
	lua_setfield (L, LUA_REGISTRYINDEX, "ucl.refs");
+

+
	lua_newtable (L);
+

+
	lua_pushcfunction (L, lua_ucl_parser_init);
+
	lua_setfield (L, -2, "parser");
+

+
	lua_pushcfunction (L, lua_ucl_to_json);
+
	lua_setfield (L, -2, "to_json");
+

+
	lua_pushcfunction (L, lua_ucl_to_config);
+
	lua_setfield (L, -2, "to_config");
+

+
	lua_pushcfunction (L, lua_ucl_to_format);
+
	lua_setfield (L, -2, "to_format");
+

+
	ucl_null = lua_newuserdata (L, 0);
+
	luaL_getmetatable (L, NULL_META);
+
	lua_setmetatable (L, -2);
+

+
	lua_pushvalue (L, -1);
+
	lua_setfield (L, LUA_REGISTRYINDEX, "ucl.null");
+

+
	lua_setfield (L, -2, "null");
+

+
	return 1;
+
}
added external/libucl/lua/test.lua
@@ -0,0 +1,34 @@
+
local ucl = require("ucl")
+

+
function test_simple()
+
  local expect =
+
    '['..
+
    '"float",1.5,'..
+
    '"integer",5,'..
+
    '"true",true,'..
+
    '"false",false,'..
+
    '"null",null,'..
+
    '"string","hello",'..
+
    '"array",[1,2],'..
+
    '"object",{"key":"value"}'..
+
    ']'
+

+
  -- Input to to_value matches the output of to_string:
+
  local parser = ucl.parser()
+
  local res,err = parser:parse_string(expect)
+
  if not res then
+
    print('parser error: ' .. err)
+
    return 1
+
  end
+
  
+
  local obj = parser:get_object()
+
  local got = ucl.to_json(obj, true)
+
  if expect == got then
+
    return 0
+
  else
+
   print(expect .. " == " .. tostring(got))
+
   return 1
+
  end
+
end
+

+
test_simple()
modified external/libucl/src/ucl_emitter.c
@@ -425,10 +425,10 @@ ucl_emitter_common_elt (struct ucl_emitter_context *ctx,
		ucl_emitter_common_end_array (ctx, obj, (compact));	\
	}

-
UCL_EMIT_TYPE_IMPL(json, false);
-
UCL_EMIT_TYPE_IMPL(json_compact, true);
-
UCL_EMIT_TYPE_IMPL(config, false);
-
UCL_EMIT_TYPE_IMPL(yaml, false);
+
UCL_EMIT_TYPE_IMPL(json, false)
+
UCL_EMIT_TYPE_IMPL(json_compact, true)
+
UCL_EMIT_TYPE_IMPL(config, false)
+
UCL_EMIT_TYPE_IMPL(yaml, false)

unsigned char *
ucl_object_emit (const ucl_object_t *obj, enum ucl_emitter emit_type)
modified external/libucl/src/ucl_parser.c
@@ -676,8 +676,7 @@ ucl_maybe_parse_number (ucl_object_t *obj,
	}

	/* Now check endptr */
-
	if (endptr == NULL || ucl_lex_is_atom_end (*endptr) || *endptr == '\0' ||
-
			ucl_test_character (*endptr, UCL_CHARACTER_WHITESPACE_UNSAFE)) {
+
	if (endptr == NULL || ucl_lex_is_atom_end (*endptr) || *endptr == '\0') {
		p = endptr;
		goto set_obj;
	}
@@ -788,6 +787,14 @@ ucl_maybe_parse_number (ucl_object_t *obj,
				goto set_obj;
			}
			break;
+
		case '\t':
+
		case ' ':
+
			while (p < end && ucl_test_character(*p, UCL_CHARACTER_WHITESPACE)) {
+
				p++;
+
			}
+
			if (ucl_lex_is_atom_end(*p))
+
				goto set_obj;
+
			break;
		}
	}

modified external/libucl/tests/Makefile.am
@@ -1,4 +1,4 @@
-
EXTRA_DIST = $(TESTS) basic schema generate.res rcl_test.json.xz
+
EXTRA_DIST = $(TESTS) basic schema generate.res streamline.res rcl_test.json.xz

TESTS = basic.test \
		generate.test \
added external/libucl/tests/basic/12.in
@@ -0,0 +1,2 @@
+
key1: 12   ,
+
key2: 12 value
added external/libucl/tests/basic/12.res
@@ -0,0 +1,3 @@
+
key1 = 12;
+
key2 = "12 value";
+

added external/libucl/tests/test_streamline
@@ -0,0 +1,210 @@
+
#! /bin/sh
+

+
# test_streamline - temporary wrapper script for .libs/test_streamline
+
# Generated by libtool (GNU libtool) 2.4.2
+
#
+
# The test_streamline program cannot be directly executed until all the libtool
+
# libraries that it depends on are installed.
+
#
+
# This wrapper script should never be moved out of the build directory.
+
# If it is, it will not operate correctly.
+

+
# Sed substitution that helps us do robust quoting.  It backslashifies
+
# metacharacters that are still active within double-quoted strings.
+
sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+

+
# Be Bourne compatible
+
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+
  emulate sh
+
  NULLCMD=:
+
  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+
  # is contrary to our usage.  Disable this feature.
+
  alias -g '${1+"$@"}'='"$@"'
+
  setopt NO_GLOB_SUBST
+
else
+
  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+
fi
+
BIN_SH=xpg4; export BIN_SH # for Tru64
+
DUALCASE=1; export DUALCASE # for MKS sh
+

+
# The HP-UX ksh and POSIX shell print the target directory to stdout
+
# if CDPATH is set.
+
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+

+
relink_command=""
+

+
# This environment variable determines our operation mode.
+
if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+
  # install mode needs the following variables:
+
  generated_by_libtool_version='2.4.2'
+
  notinst_deplibs=' ../src/libucl.la'
+
else
+
  # When we are sourced in execute mode, $file and $ECHO are already set.
+
  if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+
    file="$0"
+

+
# A function that is used when there is no print builtin or printf.
+
func_fallback_echo ()
+
{
+
  eval 'cat <<_LTECHO_EOF
+
$1
+
_LTECHO_EOF'
+
}
+
    ECHO="printf %s\\n"
+
  fi
+

+
# Very basic option parsing. These options are (a) specific to
+
# the libtool wrapper, (b) are identical between the wrapper
+
# /script/ and the wrapper /executable/ which is used only on
+
# windows platforms, and (c) all begin with the string --lt-
+
# (application programs are unlikely to have options which match
+
# this pattern).
+
#
+
# There are only two supported options: --lt-debug and
+
# --lt-dump-script. There is, deliberately, no --lt-help.
+
#
+
# The first argument to this parsing function should be the
+
# script's ../libtool value, followed by no.
+
lt_option_debug=
+
func_parse_lt_options ()
+
{
+
  lt_script_arg0=$0
+
  shift
+
  for lt_opt
+
  do
+
    case "$lt_opt" in
+
    --lt-debug) lt_option_debug=1 ;;
+
    --lt-dump-script)
+
        lt_dump_D=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+
        test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+
        lt_dump_F=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%^.*/%%'`
+
        cat "$lt_dump_D/$lt_dump_F"
+
        exit 0
+
      ;;
+
    --lt-*)
+
        $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+
        exit 1
+
      ;;
+
    esac
+
  done
+

+
  # Print the debug banner immediately:
+
  if test -n "$lt_option_debug"; then
+
    echo "test_streamline:test_streamline:${LINENO}: libtool wrapper (GNU libtool) 2.4.2" 1>&2
+
  fi
+
}
+

+
# Used when --lt-debug. Prints its arguments to stdout
+
# (redirection is the responsibility of the caller)
+
func_lt_dump_args ()
+
{
+
  lt_dump_args_N=1;
+
  for lt_arg
+
  do
+
    $ECHO "test_streamline:test_streamline:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+
    lt_dump_args_N=`expr $lt_dump_args_N + 1`
+
  done
+
}
+

+
# Core function for launching the target application
+
func_exec_program_core ()
+
{
+

+
      if test -n "$lt_option_debug"; then
+
        $ECHO "test_streamline:test_streamline:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+
        func_lt_dump_args ${1+"$@"} 1>&2
+
      fi
+
      exec "$progdir/$program" ${1+"$@"}
+

+
      $ECHO "$0: cannot exec $program $*" 1>&2
+
      exit 1
+
}
+

+
# A function to encapsulate launching the target application
+
# Strips options in the --lt-* namespace from $@ and
+
# launches target application with the remaining arguments.
+
func_exec_program ()
+
{
+
  case " $* " in
+
  *\ --lt-*)
+
    for lt_wr_arg
+
    do
+
      case $lt_wr_arg in
+
      --lt-*) ;;
+
      *) set x "$@" "$lt_wr_arg"; shift;;
+
      esac
+
      shift
+
    done ;;
+
  esac
+
  func_exec_program_core ${1+"$@"}
+
}
+

+
  # Parse options
+
  func_parse_lt_options "$0" ${1+"$@"}
+

+
  # Find the directory that this script lives in.
+
  thisdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'`
+
  test "x$thisdir" = "x$file" && thisdir=.
+

+
  # Follow symbolic links until we get to the real thisdir.
+
  file=`ls -ld "$file" | /usr/bin/sed -n 's/.*-> //p'`
+
  while test -n "$file"; do
+
    destdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'`
+

+
    # If there was a directory component, then change thisdir.
+
    if test "x$destdir" != "x$file"; then
+
      case "$destdir" in
+
      [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+
      *) thisdir="$thisdir/$destdir" ;;
+
      esac
+
    fi
+

+
    file=`$ECHO "$file" | /usr/bin/sed 's%^.*/%%'`
+
    file=`ls -ld "$thisdir/$file" | /usr/bin/sed -n 's/.*-> //p'`
+
  done
+

+
  # Usually 'no', except on cygwin/mingw when embedded into
+
  # the cwrapper.
+
  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+
  if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+
    # special case for '.'
+
    if test "$thisdir" = "."; then
+
      thisdir=`pwd`
+
    fi
+
    # remove .libs from thisdir
+
    case "$thisdir" in
+
    *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /usr/bin/sed 's%[\\/][^\\/]*$%%'` ;;
+
    .libs )   thisdir=. ;;
+
    esac
+
  fi
+

+
  # Try to get the absolute directory name.
+
  absdir=`cd "$thisdir" && pwd`
+
  test -n "$absdir" && thisdir="$absdir"
+

+
  program='test_streamline'
+
  progdir="$thisdir/.libs"
+

+

+
  if test -f "$progdir/$program"; then
+
    # Add our own library path to LD_LIBRARY_PATH
+
    LD_LIBRARY_PATH="/home/bapt/dev/libucl/src/.libs:$LD_LIBRARY_PATH"
+

+
    # Some systems cannot cope with colon-terminated LD_LIBRARY_PATH
+
    # The second colon is a workaround for a bug in BeOS R4 sed
+
    LD_LIBRARY_PATH=`$ECHO "$LD_LIBRARY_PATH" | /usr/bin/sed 's/::*$//'`
+

+
    export LD_LIBRARY_PATH
+

+
    if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+
      # Run the actual program with our arguments.
+
      func_exec_program ${1+"$@"}
+
    fi
+
  else
+
    # The program doesn't exist.
+
    $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+
    $ECHO "This script is just a wrapper for $program." 1>&2
+
    $ECHO "See the libtool documentation for more information." 1>&2
+
    exit 1
+
  fi
+
fi