diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ucl_emitter_utils.c | 8 | ||||
-rw-r--r-- | src/ucl_internal.h | 31 | ||||
-rw-r--r-- | src/ucl_parser.c | 21 | ||||
-rw-r--r-- | src/ucl_util.c | 57 |
4 files changed, 89 insertions, 28 deletions
diff --git a/src/ucl_emitter_utils.c b/src/ucl_emitter_utils.c index 95ac9a5d5776..3559eb63df92 100644 --- a/src/ucl_emitter_utils.c +++ b/src/ucl_emitter_utils.c @@ -102,7 +102,7 @@ ucl_elt_string_write_json (const char *str, size_t size, func->ucl_emitter_append_character ('"', 1, func->ud); while (size) { - if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE)) { + if (ucl_test_character (*p, UCL_CHARACTER_JSON_UNSAFE|UCL_CHARACTER_DENIED)) { if (len > 0) { func->ucl_emitter_append_len (c, len, func->ud); } @@ -128,6 +128,10 @@ ucl_elt_string_write_json (const char *str, size_t size, case '"': func->ucl_emitter_append_len ("\\\"", 2, func->ud); break; + default: + /* Emit unicode unknown character */ + func->ucl_emitter_append_len ("\\uFFFD", 5, func->ud); + break; } len = 0; c = ++p; @@ -138,9 +142,11 @@ ucl_elt_string_write_json (const char *str, size_t size, } size --; } + if (len > 0) { func->ucl_emitter_append_len (c, len, func->ud); } + func->ucl_emitter_append_character ('"', 1, func->ud); } diff --git a/src/ucl_internal.h b/src/ucl_internal.h index 37871eb666df..9ae5250cc92e 100644 --- a/src/ucl_internal.h +++ b/src/ucl_internal.h @@ -87,6 +87,9 @@ #ifdef HAVE_STRING_H #include <string.h> #endif +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif #include "utlist.h" #include "utstring.h" @@ -127,19 +130,19 @@ enum ucl_parser_state { }; enum ucl_character_type { - UCL_CHARACTER_DENIED = 0, - UCL_CHARACTER_KEY = 1, - UCL_CHARACTER_KEY_START = 1 << 1, - UCL_CHARACTER_WHITESPACE = 1 << 2, - UCL_CHARACTER_WHITESPACE_UNSAFE = 1 << 3, - UCL_CHARACTER_VALUE_END = 1 << 4, - UCL_CHARACTER_VALUE_STR = 1 << 5, - UCL_CHARACTER_VALUE_DIGIT = 1 << 6, - UCL_CHARACTER_VALUE_DIGIT_START = 1 << 7, - UCL_CHARACTER_ESCAPE = 1 << 8, - UCL_CHARACTER_KEY_SEP = 1 << 9, - UCL_CHARACTER_JSON_UNSAFE = 1 << 10, - UCL_CHARACTER_UCL_UNSAFE = 1 << 11 + UCL_CHARACTER_DENIED = (1 << 0), + UCL_CHARACTER_KEY = (1 << 1), + UCL_CHARACTER_KEY_START = (1 << 2), + UCL_CHARACTER_WHITESPACE = (1 << 3), + UCL_CHARACTER_WHITESPACE_UNSAFE = (1 << 4), + UCL_CHARACTER_VALUE_END = (1 << 5), + UCL_CHARACTER_VALUE_STR = (1 << 6), + UCL_CHARACTER_VALUE_DIGIT = (1 << 7), + UCL_CHARACTER_VALUE_DIGIT_START = (1 << 8), + UCL_CHARACTER_ESCAPE = (1 << 9), + UCL_CHARACTER_KEY_SEP = (1 << 10), + UCL_CHARACTER_JSON_UNSAFE = (1 << 11), + UCL_CHARACTER_UCL_UNSAFE = (1 << 12) }; struct ucl_macro { @@ -568,4 +571,6 @@ bool ucl_parser_process_object_element (struct ucl_parser *parser, */ bool ucl_parse_msgpack (struct ucl_parser *parser); +bool ucl_parse_csexp (struct ucl_parser *parser); + #endif /* UCL_INTERNAL_H_ */ diff --git a/src/ucl_parser.c b/src/ucl_parser.c index 0f029ea6210f..9f44de10a6fc 100644 --- a/src/ucl_parser.c +++ b/src/ucl_parser.c @@ -2469,8 +2469,10 @@ ucl_parser_new (int flags) parser->comments = ucl_object_typed_new (UCL_OBJECT); } - /* Initial assumption about filevars */ - ucl_parser_set_filevars (parser, NULL, false); + if (!(flags & UCL_PARSER_NO_FILEVARS)) { + /* Initial assumption about filevars */ + ucl_parser_set_filevars (parser, NULL, false); + } return parser; } @@ -2617,6 +2619,19 @@ ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data, return false; } + if (parse_type == UCL_PARSE_AUTO && len > 0) { + /* We need to detect parse type by the first symbol */ + if ((*data & 0x80) == 0x80 && (*data >= 0xdc && *data <= 0xdf)) { + parse_type = UCL_PARSE_MSGPACK; + } + else if (*data == '(') { + parse_type = UCL_PARSE_CSEXP; + } + else { + parse_type = UCL_PARSE_UCL; + } + } + chunk->begin = data; chunk->remain = len; chunk->pos = chunk->begin; @@ -2643,6 +2658,8 @@ ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data, return ucl_state_machine (parser); case UCL_PARSE_MSGPACK: return ucl_parse_msgpack (parser); + case UCL_PARSE_CSEXP: + return ucl_parse_csexp (parser); } } else { diff --git a/src/ucl_util.c b/src/ucl_util.c index ccc437384ae2..299e0bca2357 100644 --- a/src/ucl_util.c +++ b/src/ucl_util.c @@ -26,11 +26,17 @@ #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 @@ -81,11 +87,6 @@ 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 - static void *ucl_mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset) { void *map = NULL; @@ -1854,9 +1855,11 @@ ucl_parser_add_file (struct ucl_parser *parser, const char *filename) 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; @@ -1882,7 +1885,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); @@ -1892,6 +1896,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) { @@ -2488,6 +2504,10 @@ ucl_object_iterate_reset (ucl_object_iter_t it, const ucl_object_t *obj) UCL_SAFE_ITER_CHECK (rit); + if (rit->expl_it != NULL) { + UCL_FREE (sizeof (*rit->expl_it), rit->expl_it); + } + rit->impl_it = obj; rit->expl_it = NULL; @@ -2497,6 +2517,13 @@ ucl_object_iterate_reset (ucl_object_iter_t it, const ucl_object_t *obj) const ucl_object_t* ucl_object_iterate_safe (ucl_object_iter_t it, bool expand_values) { + return ucl_object_iterate_full (it, expand_values ? UCL_ITERATE_BOTH : + UCL_ITERATE_IMPLICIT); +} + +const ucl_object_t* +ucl_object_iterate_full (ucl_object_iter_t it, enum ucl_iterate_type type) +{ struct ucl_object_safe_iter *rit = UCL_SAFE_ITER (it); const ucl_object_t *ret = NULL; @@ -2509,21 +2536,23 @@ ucl_object_iterate_safe (ucl_object_iter_t it, bool expand_values) if (rit->impl_it->type == UCL_OBJECT || rit->impl_it->type == UCL_ARRAY) { ret = ucl_object_iterate (rit->impl_it, &rit->expl_it, true); - if (ret == NULL) { + if (ret == NULL && (type & UCL_ITERATE_IMPLICIT)) { /* Need to switch to another implicit object in chain */ rit->impl_it = rit->impl_it->next; rit->expl_it = NULL; - return ucl_object_iterate_safe (it, expand_values); + + return ucl_object_iterate_safe (it, type); } } else { /* Just iterate over the implicit array */ ret = rit->impl_it; rit->impl_it = rit->impl_it->next; - if (expand_values) { + + if (type & UCL_ITERATE_EXPLICIT) { /* We flatten objects if need to expand values */ if (ret->type == UCL_OBJECT || ret->type == UCL_ARRAY) { - return ucl_object_iterate_safe (it, expand_values); + return ucl_object_iterate_safe (it, type); } } } @@ -2538,6 +2567,10 @@ ucl_object_iterate_free (ucl_object_iter_t it) UCL_SAFE_ITER_CHECK (rit); + if (rit->expl_it != NULL) { + UCL_FREE (sizeof (*rit->expl_it), rit->expl_it); + } + UCL_FREE (sizeof (*rit), it); } |