From 97a25eff3d980efc93379d112e0f258f2de2d3fa Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 21 Mar 2018 13:08:45 +0000 Subject: [PATCH] [Minor] Sync from libucl --- contrib/libucl/ucl_parser.c | 116 ++++++++++++-- contrib/libucl/ucl_util.c | 307 ++++++++++++++++++++++++------------ 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) @@ -2723,6 +2735,39 @@ ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data, parser->default_priority, UCL_DUPLICATE_APPEND, UCL_PARSE_UCL); } +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 #include #include /* for snprintf */ #ifndef _WIN32 #include +#include +#else +#ifndef NBBY +#define NBBY 8 +#endif #endif #ifdef HAVE_LIBGEN_H -#include /* For dirname */ +#ifndef _WIN32 +# include /* 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 #endif -#ifdef _WIN32 +#if defined(_MSC_VER) #include +#include +#include #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 -#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); @@ -1841,6 +1893,18 @@ ucl_parser_add_file_priority (struct ucl_parser *parser, const char *filename, return ret; } +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) { @@ -1848,13 +1912,16 @@ ucl_parser_add_file (struct ucl_parser *parser, const char *filename) 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); @@ -1886,6 +1957,18 @@ ucl_parser_add_fd_priority (struct ucl_parser *parser, int fd, return ret; } +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) { @@ -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; -- 2.39.5