aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/libucl/ucl_parser.c116
-rw-r--r--contrib/libucl/ucl_util.c307
2 files changed, 309 insertions, 114 deletions
diff --git a/contrib/libucl/ucl_parser.c b/contrib/libucl/ucl_parser.c
index 088813918..e82b5da51 100644
--- a/contrib/libucl/ucl_parser.c
+++ b/contrib/libucl/ucl_parser.c
@@ -44,16 +44,17 @@ struct ucl_parser_saved_state {
* @param len
* @return new position in chunk
*/
-#define ucl_chunk_skipc(chunk, p) do{ \
- if (*(p) == '\n') { \
- (chunk)->line ++; \
- (chunk)->column = 0; \
- } \
- else (chunk)->column ++; \
- (p++); \
- (chunk)->pos ++; \
- (chunk)->remain --; \
- } while (0)
+#define ucl_chunk_skipc(chunk, p) \
+do { \
+ if (*(p) == '\n') { \
+ (chunk)->line ++; \
+ (chunk)->column = 0; \
+ } \
+ else (chunk)->column ++; \
+ (p++); \
+ (chunk)->pos ++; \
+ (chunk)->remain --; \
+} while (0)
static inline void
ucl_set_err (struct ucl_parser *parser, int code, const char *str, UT_string **err)
@@ -1706,6 +1707,7 @@ ucl_parse_value (struct ucl_parser *parser, struct ucl_chunk *chunk)
}
}
/* Fallback to ordinary strings */
+ /* FALLTHRU */
default:
parse_string:
if (obj == NULL) {
@@ -2506,6 +2508,16 @@ ucl_parser_set_default_priority (struct ucl_parser *parser, unsigned prio)
return true;
}
+int
+ucl_parser_get_default_priority (struct ucl_parser *parser)
+{
+ if (parser == NULL) {
+ return -1;
+ }
+
+ return parser->default_priority;
+}
+
void
ucl_parser_register_macro (struct ucl_parser *parser, const char *macro,
ucl_macro_handler handler, void* ud)
@@ -2724,6 +2736,39 @@ ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data,
}
bool
+ucl_parser_insert_chunk (struct ucl_parser *parser, const unsigned char *data,
+ size_t len)
+{
+ if (parser == NULL || parser->top_obj == NULL) {
+ return false;
+ }
+
+ bool res;
+ struct ucl_chunk *chunk;
+
+ int state = parser->state;
+ parser->state = UCL_STATE_INIT;
+
+ /* Prevent inserted chunks from unintentionally closing the current object */
+ if (parser->stack != NULL && parser->stack->next != NULL) parser->stack->level = parser->stack->next->level;
+
+ res = ucl_parser_add_chunk_full (parser, data, len, parser->chunks->priority,
+ parser->chunks->strategy, parser->chunks->parse_type);
+
+ /* Remove chunk from the stack */
+ chunk = parser->chunks;
+ if (chunk != NULL) {
+ parser->chunks = chunk->next;
+ UCL_FREE (sizeof (struct ucl_chunk), chunk);
+ parser->recursion --;
+ }
+
+ parser->state = state;
+
+ return res;
+}
+
+bool
ucl_parser_add_string_priority (struct ucl_parser *parser, const char *data,
size_t len, unsigned priority)
{
@@ -2772,3 +2817,54 @@ ucl_set_include_path (struct ucl_parser *parser, ucl_object_t *paths)
return true;
}
+
+unsigned char ucl_parser_chunk_peek (struct ucl_parser *parser)
+{
+ if (parser == NULL || parser->chunks == NULL || parser->chunks->pos == NULL || parser->chunks->end == NULL ||
+ parser->chunks->pos == parser->chunks->end) {
+ return 0;
+ }
+
+ return( *parser->chunks->pos );
+}
+
+bool ucl_parser_chunk_skip (struct ucl_parser *parser)
+{
+ if (parser == NULL || parser->chunks == NULL || parser->chunks->pos == NULL || parser->chunks->end == NULL ||
+ parser->chunks->pos == parser->chunks->end) {
+ return false;
+ }
+
+ const unsigned char *p = parser->chunks->pos;
+ ucl_chunk_skipc( parser->chunks, p );
+ if( parser->chunks->pos != NULL ) return true;
+ return false;
+}
+
+ucl_object_t* ucl_parser_get_current_stack_object (struct ucl_parser *parser, unsigned int depth)
+{
+ ucl_object_t *obj;
+
+ if (parser == NULL || parser->stack == NULL) {
+ return NULL;
+ }
+
+ struct ucl_stack *stack = parser->stack;
+ if(stack == NULL || stack->obj == NULL || ucl_object_type (stack->obj) != UCL_OBJECT)
+ {
+ return NULL;
+ }
+
+ for( unsigned int i = 0; i < depth; ++i )
+ {
+ stack = stack->next;
+ if(stack == NULL || stack->obj == NULL || ucl_object_type (stack->obj) != UCL_OBJECT)
+ {
+ return NULL;
+ }
+ }
+
+ obj = ucl_object_ref (stack->obj);
+ return obj;
+}
+
diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c
index 8f5231e2f..fba3df920 100644
--- a/contrib/libucl/ucl_util.c
+++ b/contrib/libucl/ucl_util.c
@@ -26,15 +26,23 @@
#include "ucl_internal.h"
#include "ucl_chartable.h"
#include "kvec.h"
+#include <limits.h>
#include <stdarg.h>
#include <stdio.h> /* for snprintf */
#ifndef _WIN32
#include <glob.h>
+#include <sys/param.h>
+#else
+#ifndef NBBY
+#define NBBY 8
+#endif
#endif
#ifdef HAVE_LIBGEN_H
-#include <libgen.h> /* For dirname */
+#ifndef _WIN32
+# include <libgen.h> /* For dirname */
+#endif
#endif
typedef kvec_t(ucl_object_t *) ucl_array_t;
@@ -59,8 +67,10 @@ typedef kvec_t(ucl_object_t *) ucl_array_t;
#include <fetch.h>
#endif
-#ifdef _WIN32
+#if defined(_MSC_VER)
#include <windows.h>
+#include <io.h>
+#include <direct.h>
#ifndef PROT_READ
#define PROT_READ 1
@@ -81,10 +91,9 @@ typedef kvec_t(ucl_object_t *) ucl_array_t;
#define MAP_FAILED ((void *) -1)
#endif
-#ifdef _WIN32
-#include <limits.h>
-#define NBBY CHAR_BIT
-#endif
+#define getcwd _getcwd
+#define open _open
+#define close _close
static void *ucl_mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset)
{
@@ -132,16 +141,46 @@ static int ucl_munmap(void *map,size_t length)
return(0);
}
-static char* ucl_realpath(const char *path, char *resolved_path) {
- char *p;
- char tmp[MAX_PATH + 1];
- strncpy(tmp, path, sizeof(tmp)-1);
- p = tmp;
- while(*p) {
- if (*p == '/') *p = '\\';
- p++;
- }
- return _fullpath(resolved_path, tmp, MAX_PATH);
+static char* ucl_realpath(const char *path, char *resolved_path)
+{
+ char *p;
+ char tmp[MAX_PATH + 1];
+ strncpy(tmp, path, sizeof(tmp)-1);
+ p = tmp;
+ while(*p) {
+ if (*p == '/') *p = '\\';
+ p++;
+ }
+ return _fullpath(resolved_path, tmp, MAX_PATH);
+}
+
+
+char *dirname(char *path)
+{
+ static char path_buffer[_MAX_PATH];
+ char drive[_MAX_DRIVE];
+ char dir[_MAX_DIR];
+ char fname[_MAX_FNAME];
+ char ext[_MAX_EXT];
+
+ _splitpath (path, drive, dir, fname, ext);
+ _makepath(path_buffer, drive, dir, NULL, NULL);
+
+ return path_buffer;
+}
+
+char *basename(char *path)
+{
+ static char path_buffer[_MAX_PATH];
+ char drive[_MAX_DRIVE];
+ char dir[_MAX_DIR];
+ char fname[_MAX_FNAME];
+ char ext[_MAX_EXT];
+
+ _splitpath(path, drive, dir, fname, ext);
+ _makepath(path_buffer, NULL, NULL, fname, ext);
+
+ return path_buffer;
}
#else
#define ucl_mmap mmap
@@ -1052,53 +1091,89 @@ ucl_include_file_single (const unsigned char *data, size_t len,
old_obj = __DECONST (ucl_object_t *, ucl_hash_search (container,
params->prefix, strlen (params->prefix)));
- if (strcasecmp (params->target, "array") == 0 && old_obj == NULL) {
- /* Create an array with key: prefix */
- old_obj = ucl_object_new_full (UCL_ARRAY, params->priority);
- old_obj->key = params->prefix;
- old_obj->keylen = strlen (params->prefix);
- ucl_copy_key_trash(old_obj);
- old_obj->prev = old_obj;
- old_obj->next = NULL;
+ if (strcasecmp (params->target, "array") == 0) {
+ if (old_obj == NULL) {
+ /* Create an array with key: prefix */
+ old_obj = ucl_object_new_full (UCL_ARRAY, params->priority);
+ old_obj->key = params->prefix;
+ old_obj->keylen = strlen (params->prefix);
+ ucl_copy_key_trash (old_obj);
+ old_obj->prev = old_obj;
+ old_obj->next = NULL;
- container = ucl_hash_insert_object (container, old_obj,
- parser->flags & UCL_PARSER_KEY_LOWERCASE);
- parser->stack->obj->len ++;
+ container = ucl_hash_insert_object (container, old_obj,
+ parser->flags & UCL_PARSER_KEY_LOWERCASE);
+ parser->stack->obj->len++;
- nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
- nest_obj->prev = nest_obj;
- nest_obj->next = NULL;
+ nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
+ nest_obj->prev = nest_obj;
+ nest_obj->next = NULL;
- ucl_array_append (old_obj, nest_obj);
- }
- else if (old_obj == NULL) {
- /* Create an object with key: prefix */
- nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
+ ucl_array_append (old_obj, nest_obj);
+ }
+ else {
+ if (ucl_object_type (old_obj) == UCL_ARRAY) {
+ /* Append to the existing array */
+ nest_obj = ucl_object_new_full (UCL_OBJECT,
+ params->priority);
+ if (nest_obj == NULL) {
+ ucl_create_err (&parser->err,
+ "cannot allocate memory for an object");
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
- if (nest_obj == NULL) {
- ucl_create_err (&parser->err, "cannot allocate memory for an object");
- if (buf) {
- ucl_munmap (buf, buflen);
+ return false;
+ }
+ nest_obj->prev = nest_obj;
+ nest_obj->next = NULL;
+
+ ucl_array_append (old_obj, nest_obj);
}
+ else {
+ /* Convert the object to an array */
+ new_obj = ucl_object_typed_new (UCL_ARRAY);
+ if (new_obj == NULL) {
+ ucl_create_err (&parser->err,
+ "cannot allocate memory for an object");
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
- return false;
- }
+ return false;
+ }
+ new_obj->key = old_obj->key;
+ new_obj->keylen = old_obj->keylen;
+ new_obj->flags |= UCL_OBJECT_MULTIVALUE;
+ new_obj->prev = new_obj;
+ new_obj->next = NULL;
+
+ nest_obj = ucl_object_new_full (UCL_OBJECT,
+ params->priority);
+ if (nest_obj == NULL) {
+ ucl_create_err (&parser->err,
+ "cannot allocate memory for an object");
+ if (buf) {
+ ucl_munmap (buf, buflen);
+ }
- nest_obj->key = params->prefix;
- nest_obj->keylen = strlen (params->prefix);
- ucl_copy_key_trash(nest_obj);
- nest_obj->prev = nest_obj;
- nest_obj->next = NULL;
+ return false;
+ }
+ nest_obj->prev = nest_obj;
+ nest_obj->next = NULL;
- container = ucl_hash_insert_object (container, nest_obj,
- parser->flags & UCL_PARSER_KEY_LOWERCASE);
- parser->stack->obj->len ++;
+ ucl_array_append (new_obj, old_obj);
+ ucl_array_append (new_obj, nest_obj);
+ ucl_hash_replace (container, old_obj, new_obj);
+ }
+ }
}
- else if (strcasecmp (params->target, "array") == 0 ||
- ucl_object_type(old_obj) == UCL_ARRAY) {
- if (ucl_object_type(old_obj) == UCL_ARRAY) {
- /* Append to the existing array */
+ else {
+ /* Case of object */
+ if (old_obj == NULL) {
+ /* Create an object with key: prefix */
nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
+
if (nest_obj == NULL) {
ucl_create_err (&parser->err, "cannot allocate memory for an object");
if (buf) {
@@ -1107,64 +1182,39 @@ ucl_include_file_single (const unsigned char *data, size_t len,
return false;
}
+
+ nest_obj->key = params->prefix;
+ nest_obj->keylen = strlen (params->prefix);
+ ucl_copy_key_trash(nest_obj);
nest_obj->prev = nest_obj;
nest_obj->next = NULL;
- ucl_array_append (old_obj, nest_obj);
+ container = ucl_hash_insert_object (container, nest_obj,
+ parser->flags & UCL_PARSER_KEY_LOWERCASE);
+ parser->stack->obj->len ++;
}
else {
- /* Convert the object to an array */
- new_obj = ucl_object_typed_new (UCL_ARRAY);
- if (new_obj == NULL) {
- ucl_create_err (&parser->err, "cannot allocate memory for an object");
- if (buf) {
- ucl_munmap (buf, buflen);
- }
-
- return false;
+ if (ucl_object_type (old_obj) == UCL_OBJECT) {
+ /* Append to existing Object*/
+ nest_obj = old_obj;
}
- new_obj->key = old_obj->key;
- new_obj->keylen = old_obj->keylen;
- new_obj->flags |= UCL_OBJECT_MULTIVALUE;
- new_obj->prev = new_obj;
- new_obj->next = NULL;
-
- nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
- if (nest_obj == NULL) {
- ucl_create_err (&parser->err, "cannot allocate memory for an object");
+ else {
+ /* The key is not an object */
+ ucl_create_err (&parser->err,
+ "Conflicting type for key: %s, asked %s, has %s",
+ params->prefix, params->target,
+ ucl_object_type_to_string (ucl_object_type (old_obj)));
if (buf) {
ucl_munmap (buf, buflen);
}
return false;
}
- nest_obj->prev = nest_obj;
- nest_obj->next = NULL;
-
- ucl_array_append (new_obj, old_obj);
- ucl_array_append (new_obj, nest_obj);
- ucl_hash_replace (container, old_obj, new_obj);
}
}
- else {
- if (ucl_object_type (old_obj) == UCL_OBJECT) {
- /* Append to existing Object*/
- nest_obj = old_obj;
- }
- else {
- /* The key is not an object */
- ucl_create_err (&parser->err,
- "Conflicting type for key: %s",
- params->prefix);
- if (buf) {
- ucl_munmap (buf, buflen);
- }
- return false;
- }
- }
- /* Put all of the content of the include inside that object */
+ /* Put all of the content of the include inside that object */
parser->stack->obj->value.ov = container;
st = UCL_ALLOC (sizeof (struct ucl_stack));
@@ -1808,8 +1858,9 @@ ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, bool n
}
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;
@@ -1832,7 +1883,8 @@ ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename,
}
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);
@@ -1842,19 +1894,34 @@ ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename,
}
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);
+}
+
+bool
ucl_parser_add_file (struct ucl_parser *parser, const char *filename)
{
if (parser == NULL) {
return false;
}
- return ucl_parser_add_file_priority(parser, filename,
- parser->default_priority);
+ return ucl_parser_add_file_full(parser, filename,
+ parser->default_priority, UCL_DUPLICATE_APPEND,
+ UCL_PARSE_UCL);
}
+
bool
-ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
- unsigned priority)
+ucl_parser_add_fd_full (struct ucl_parser *parser, int fd,
+ unsigned priority, enum ucl_duplicate_strategy strat,
+ enum ucl_parse_type parse_type)
{
unsigned char *buf;
size_t len;
@@ -1866,6 +1933,9 @@ ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
fd, strerror (errno));
return false;
}
+ if (st.st_size == 0) {
+ return true;
+ }
if ((buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
ucl_create_err (&parser->err, "cannot mmap fd %d: %s",
fd, strerror (errno));
@@ -1877,7 +1947,8 @@ ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
}
parser->cur_file = NULL;
len = st.st_size;
- 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);
@@ -1887,6 +1958,18 @@ ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
}
bool
+ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd,
+ unsigned priority)
+{
+ if (parser == NULL) {
+ return false;
+ }
+
+ return ucl_parser_add_fd_full(parser, fd, parser->default_priority,
+ UCL_DUPLICATE_APPEND, UCL_PARSE_UCL);
+}
+
+bool
ucl_parser_add_fd (struct ucl_parser *parser, int fd)
{
if (parser == NULL) {
@@ -3025,6 +3108,22 @@ ucl_array_pop_first (ucl_object_t *top)
return ret;
}
+unsigned int
+ucl_array_size (const ucl_object_t *top)
+{
+ if (top == NULL || top->type != UCL_ARRAY) {
+ return 0;
+ }
+
+ UCL_ARRAY_GET (vec, top);
+
+ if (vec != NULL) {
+ return kv_size(*vec);
+ }
+
+ return 0;
+}
+
const ucl_object_t *
ucl_array_find_index (const ucl_object_t *top, unsigned int index)
{
@@ -3132,7 +3231,7 @@ ucl_object_toint_safe (const ucl_object_t *obj, int64_t *target)
break;
case UCL_FLOAT:
case UCL_TIME:
- *target = obj->value.dv; /* Loosing of decimal points */
+ *target = obj->value.dv; /* Losing of decimal points */
break;
default:
return false;