Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
HardenedBSD
HardenedBSD
Commits
94f2b741
Commit
94f2b741
authored
Apr 17, 2016
by
Baptiste Daroussin
Browse files
Import libucl 0.8.0
parent
4e2fa78e
Changes
40
Expand all
Hide whitespace changes
Inline
Side-by-side
ChangeLog.md
View file @
94f2b741
...
...
@@ -37,3 +37,31 @@
-
Fixed a bug with macroes that come after an empty object
-
Fixed a bug in include processing when an incorrect variable has been destroyed (use-after-free)
### Libucl 0.8.0
-
Allow to save comments and macros when parsing UCL documents
-
C++ API
-
Python bindings (by Eitan Adler)
-
Add msgpack support for parser and emitter
-
Add Canonical S-expressions parser for libucl
-
CLI interface for parsing and validation (by Maxim Ignatenko)
-
Implement include with priority
-
Add 'nested' functionality to .include macro (by Allan Jude)
-
Allow searching an array of paths for includes (by Allan Jude)
-
Add new .load macro (by Allan Jude)
-
Implement .inherit macro (#100)
-
Add merge strategies
-
Add schema validation to lua API
-
Add support for external references to schema validation
-
Add coveralls integration to libucl
-
Implement tests for 80% of libucl code lines
-
Fix tonns of minor and major bugs
-
Improve documentation
-
Rework function names to the common conventions (old names are preserved for backwards compatibility)
-
Add Coverity scan integration
-
Add fuzz tests
**Incompatible changes**
:
-
`ucl_object_emit_full`
now accepts additional argument
`comments`
that could be used to emit comments with UCL output
\ No newline at end of file
Makefile.am
View file @
94f2b741
...
...
@@ -8,4 +8,74 @@ if LUA_SUB
LUA_SUBDIR
=
lua
endif
SUBDIRS
=
src tests utils doc
$(LUA_SUBDIR)
\ No newline at end of file
COVERAGE_INFO_FILE
=
$(top_builddir)
/coverage.info
COVERAGE_REPORT_DIR
=
$(top_builddir)
/coverage
.PHONY
=
coverage-requirement-check clean-coverage-report
coverage-requirement-check
:
@
if
test
!
-e
$(GCOV)
;
then
\
echo
"Cannot find
$(GCOV)
. Please install gcov."
;
\
exit
1
;
\
fi
coverage
:
coverage-requirement-check clean-coverage coverage-build coverage-check coverage-report
@
echo
"Please execute 'make clean' before 'make' or 'make check' to remove instrumented object files(compiled with -O0 etc.). Note that 'make clean' also remove coverage data."
coverage-build
:
coverage-requirement-check
@
if
test
`
find
$(top_builddir)
-name
"*.gcno"
|
wc
-l
`
-eq
0
;
then
\
echo
"Start to remove old non-instrumented object files..."
;
\
$(MAKE)
$(AM_MAKEFLAGS)
clean
;
\
echo
"Successfully removed old non-instrumented object files."
;
\
fi
@
echo
"Start to build libraries with coverage options..."
$(MAKE)
$(AM_MAKEFLAGS)
\
CFLAGS
=
"
$(CFLAGS)
$(COVERAGE_CFLAGS)
$(COVERAGE_OPTFLAGS)
"
\
CXXFLAGS
=
"
$(CXXFLAGS)
$(COVERAGE_CXXFLAGS)
$(COVERAGE_OPTFLAGS)
"
\
LDFLAGS
=
"
$(LDFLAGS)
$(COVERAGE_LDFLAGS)
"
\
LIBS
=
"
$(LIBS)
$(COVERAGE_LIBS)
"
@
echo
"Successfully built libraries with coverage options."
coverage-check
:
coverage-requirement-check
@
echo
"Start to run tests with instrumented libraries..."
$(MAKE)
$(AM_MAKEFLAGS)
check
\
CFLAGS
=
"
$(CFLAGS)
$(COVERAGE_CFLAGS)
$(COVERAGE_OPTFLAGS)
"
\
CXXFLAGS
=
"
$(CXXFLAGS)
$(COVERAGE_CXXFLAGS)
$(COVERAGE_OPTFLAGS)
"
\
LDFLAGS
=
"
$(LDFLAGS)
$(COVERAGE_LDFLAGS)
"
\
LIBS
=
"
$(LIBS)
$(COVERAGE_LIBS)
"
@
echo
"Successfully run tests with instrumented libraries."
coverage-lcov
:
coverage-check coverage-requirement-check
$(LCOV)
--capture
\
--directory
"
$(top_builddir)
/"
\
--output-file
$(COVERAGE_INFO_FILE)
\
--gcov-tool
$(GCOV)
\
--compat-libtool
--checksum
$(LCOV)
--extract
$(COVERAGE_INFO_FILE)
`
pwd
`
/src/ucl_
\*
\
--output-file
$(COVERAGE_INFO_FILE)
coverage-report
:
coverage-lcov
@
echo
"Start to create coverage reports..."
$(GENHTML)
--prefix
"
$(top_srcdir)
"
\
--output-directory
$(COVERAGE_REPORT_DIR)
\
--title
$(PACKAGE_NAME)
\
--legend
--show-details
\
$(GENHTML_OPTIONS)
\
$(COVERAGE_INFO_FILE)
@
echo
"Successfully created coverage reports into
$(COVERAGE_REPORT_DIR)
directory."
clean-coverage-report
:
-
rm
-rf
$(COVERAGE_INFO_FILE)
-
rm
-rf
$(COVERAGE_REPORT_DIR)
clean-coverage
:
clean-coverage-report
-
$(LCOV)
--gcov-tool
$(GCOV)
--zerocounters
--directory
$(top_builddir)
@
if
xargs
--version
2>/dev/null
;
then
\
find
$(top_builddir)
-name
"*.gcno"
| xargs
--no-run-if-empty
rm
;
\
else
\
find
$(top_builddir)
-name
"*.gcno"
| xargs
rm
;
\
fi
clean-local
:
clean-coverage
SUBDIRS
=
src tests utils doc
$(LUA_SUBDIR)
README.md
View file @
94f2b741
# LIBUCL
[

](https://travis-ci.org/vstakhov/libucl)
[

](https://scan.coverity.com/projects/4138)
[

](https://travis-ci.org/vstakhov/libucl)
[

](https://scan.coverity.com/projects/4138)
[

](https://coveralls.io/github/vstakhov/libucl?branch=master)
**Table of Contents**
*generated with [DocToc](http://doctoc.herokuapp.com/)*
...
...
configure.ac
View file @
94f2b741
m4_define([maj_ver], [0])
m4_define([med_ver], [
7
])
m4_define([min_ver], [
3
])
m4_define([so_version], [
5
:0:
2
])
m4_define([med_ver], [
8
])
m4_define([min_ver], [
0
])
m4_define([so_version], [
6
:0:
0
])
m4_define([ucl_version], [maj_ver.med_ver.min_ver])
AC_INIT([libucl],[ucl_version],[https://github.com/vstakhov/libucl],[libucl])
...
...
@@ -173,6 +173,8 @@ AC_LINK_IFELSE([
AC_MSG_WARN([Libucl references could be thread-unsafe because atomic builtins are missing])
])
AX_CODE_COVERAGE
AC_CONFIG_FILES(Makefile \
src/Makefile \
lua/Makefile
...
...
include/ucl++.h
View file @
94f2b741
...
...
@@ -26,7 +26,6 @@
#include
<string>
#include
<memory>
#include
<iostream>
#include
<strstream>
#include
"ucl.h"
...
...
@@ -120,18 +119,19 @@ class Ucl final {
it
=
std
::
shared_ptr
<
void
>
(
ucl_object_iterate_new
(
obj
.
obj
.
get
()),
ucl_iter_deleter
());
cur
.
reset
(
new
Ucl
(
ucl_object_iterate_safe
(
it
.
get
(),
true
)));
if
(
!*
cur
)
{
it
.
reset
();
cur
.
reset
();
}
}
const_iterator
()
{}
const_iterator
(
const
const_iterator
&
other
)
{
it
=
other
.
it
;
}
const_iterator
(
const
const_iterator
&
other
)
=
delete
;
const_iterator
(
const_iterator
&&
other
)
=
default
;
~
const_iterator
()
{}
const_iterator
&
operator
=
(
const
const_iterator
&
other
)
{
it
=
other
.
it
;
return
*
this
;
}
const_iterator
&
operator
=
(
const
const_iterator
&
other
)
=
delete
;
const_iterator
&
operator
=
(
const_iterator
&&
other
)
=
default
;
bool
operator
==
(
const
const_iterator
&
other
)
const
{
...
...
@@ -264,45 +264,51 @@ class Ucl final {
return
res
;
}
double
number_value
()
const
double
number_value
(
const
double
default_val
=
0.0
)
const
{
if
(
obj
)
{
return
ucl_object_todouble
(
obj
.
get
());
double
res
;
if
(
ucl_object_todouble_safe
(
obj
.
get
(),
&
res
))
{
return
res
;
}
return
0.0
;
return
default_val
;
}
int64_t
int_value
()
const
int64_t
int_value
(
const
int64_t
default_val
=
0
)
const
{
if
(
obj
)
{
return
ucl_object_toint
(
obj
.
get
());
int64_t
res
;
if
(
ucl_object_toint_safe
(
obj
.
get
(),
&
res
))
{
return
res
;
}
return
0
;
return
default_val
;
}
bool
bool_value
()
const
bool
bool_value
(
const
bool
default_val
=
false
)
const
{
if
(
obj
)
{
return
ucl_object_toboolean
(
obj
.
get
());
bool
res
;
if
(
ucl_object_toboolean_safe
(
obj
.
get
(),
&
res
))
{
return
res
;
}
return
false
;
return
default_val
;
}
const
std
::
string
string_value
()
const
const
std
::
string
string_value
(
const
std
::
string
&
default_val
=
""
)
const
{
std
::
string
res
;
const
char
*
res
=
nullptr
;
if
(
obj
)
{
re
s
.
assign
(
ucl_object_tostring
(
obj
.
get
()))
;
if
(
ucl_object_tostring_safe
(
obj
.
get
(),
&
res
)
)
{
re
turn
res
;
}
return
res
;
return
default_val
;
}
const
Ucl
operator
[]
(
size_t
i
)
const
const
Ucl
at
(
size_t
i
)
const
{
if
(
type
()
==
UCL_ARRAY
)
{
return
Ucl
(
ucl_array_find_index
(
obj
.
get
(),
i
));
...
...
@@ -311,15 +317,25 @@ class Ucl final {
return
Ucl
(
nullptr
);
}
const
Ucl
operator
[]
(
const
std
::
string
&
key
)
const
const
Ucl
lookup
(
const
std
::
string
&
key
)
const
{
if
(
type
()
==
UCL_OBJECT
)
{
return
Ucl
(
ucl_object_
find_keyl
(
obj
.
get
(),
return
Ucl
(
ucl_object_
lookup_len
(
obj
.
get
(),
key
.
data
(),
key
.
size
()));
}
return
Ucl
(
nullptr
);
}
inline
const
Ucl
operator
[]
(
size_t
i
)
const
{
return
at
(
i
);
}
inline
const
Ucl
operator
[](
const
std
::
string
&
key
)
const
{
return
lookup
(
key
);
}
// Serialize.
void
dump
(
std
::
string
&
out
,
ucl_emitter_t
type
=
UCL_EMIT_JSON
)
const
{
...
...
@@ -328,7 +344,7 @@ class Ucl final {
cbdata
=
Ucl
::
default_emit_funcs
();
cbdata
.
ud
=
reinterpret_cast
<
void
*>
(
&
out
);
ucl_object_emit_full
(
obj
.
get
(),
type
,
&
cbdata
);
ucl_object_emit_full
(
obj
.
get
(),
type
,
&
cbdata
,
nullptr
);
}
std
::
string
dump
(
ucl_emitter_t
type
=
UCL_EMIT_JSON
)
const
...
...
@@ -375,6 +391,12 @@ class Ucl final {
std
::
istreambuf_iterator
<
char
>
()),
err
);
}
Ucl
&
operator
=
(
Ucl
rhs
)
{
obj
.
swap
(
rhs
.
obj
);
return
*
this
;
}
bool
operator
==
(
const
Ucl
&
rhs
)
const
{
return
ucl_object_compare
(
obj
.
get
(),
rhs
.
obj
.
get
())
==
0
;
...
...
@@ -388,7 +410,7 @@ class Ucl final {
bool
operator
>
(
const
Ucl
&
rhs
)
const
{
return
(
rhs
<
*
this
);
}
bool
operator
>=
(
const
Ucl
&
rhs
)
const
{
return
!
(
*
this
<
rhs
);
}
operator
bool
()
const
explicit
operator
bool
()
const
{
if
(
!
obj
||
type
()
==
UCL_NULL
)
{
return
false
;
...
...
include/ucl.h
View file @
94f2b741
...
...
@@ -107,7 +107,8 @@ typedef enum ucl_error {
UCL_ENESTED
,
/**< Input has too many recursion levels */
UCL_EMACRO
,
/**< Error processing a macro */
UCL_EINTERNAL
,
/**< Internal unclassified error */
UCL_ESSL
/**< SSL error */
UCL_ESSL
,
/**< SSL error */
UCL_EMERGE
/**< A merge error occured */
}
ucl_error_t
;
/**
...
...
@@ -147,11 +148,13 @@ typedef enum ucl_emitter {
* UCL still has to perform copying implicitly.
*/
typedef
enum
ucl_parser_flags
{
UCL_PARSER_DEFAULT
=
0x0
,
/**< No special 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_IMPLICIT_ARRAYS
=
0x8
/** Create explicit arrays instead of implicit ones */
UCL_PARSER_DEFAULT
=
0
,
/**< No special flags */
UCL_PARSER_KEY_LOWERCASE
=
(
1
<<
0
),
/**< Convert all keys to lower case */
UCL_PARSER_ZEROCOPY
=
(
1
<<
1
),
/**< Parse input in zero-copy mode if possible */
UCL_PARSER_NO_TIME
=
(
1
<<
2
),
/**< Do not parse time and treat time values as strings */
UCL_PARSER_NO_IMPLICIT_ARRAYS
=
(
1
<<
3
),
/** Create explicit arrays instead of implicit ones */
UCL_PARSER_SAVE_COMMENTS
=
(
1
<<
4
),
/** Save comments in the parser context */
UCL_PARSER_DISABLE_MACRO
=
(
1
<<
5
)
/** Treat macros as comments */
}
ucl_parser_flags_t
;
/**
...
...
@@ -159,17 +162,17 @@ typedef enum ucl_parser_flags {
*/
typedef
enum
ucl_string_flags
{
UCL_STRING_RAW
=
0x0
,
/**< Treat string as is */
UCL_STRING_ESCAPE
=
0x1
,
/**< Perform JSON escape */
UCL_STRING_TRIM
=
0x2
,
/**< Trim leading and trailing whitespaces */
UCL_STRING_PARSE_BOOLEAN
=
0x4
,
/**< Parse passed string and detect boolean */
UCL_STRING_PARSE_INT
=
0x8
,
/**< Parse passed string and detect integer number */
UCL_STRING_PARSE_DOUBLE
=
0x10
,
/**< Parse passed string and detect integer or float number */
UCL_STRING_PARSE_TIME
=
0x20
,
/**< Parse time strings */
UCL_STRING_ESCAPE
=
(
1
<<
0
)
,
/**< Perform JSON escape */
UCL_STRING_TRIM
=
(
1
<<
1
)
,
/**< Trim leading and trailing whitespaces */
UCL_STRING_PARSE_BOOLEAN
=
(
1
<<
2
)
,
/**< Parse passed string and detect boolean */
UCL_STRING_PARSE_INT
=
(
1
<<
3
)
,
/**< Parse passed string and detect integer number */
UCL_STRING_PARSE_DOUBLE
=
(
1
<<
4
)
,
/**< Parse passed string and detect integer or float number */
UCL_STRING_PARSE_TIME
=
(
1
<<
5
)
,
/**< Parse time strings */
UCL_STRING_PARSE_NUMBER
=
UCL_STRING_PARSE_INT
|
UCL_STRING_PARSE_DOUBLE
|
UCL_STRING_PARSE_TIME
,
/**<
Parse passed string and detect number */
UCL_STRING_PARSE
=
UCL_STRING_PARSE_BOOLEAN
|
UCL_STRING_PARSE_NUMBER
,
/**<
Parse passed string (and detect booleans and numbers) */
UCL_STRING_PARSE_BYTES
=
0x40
/**< Treat numbers as bytes */
UCL_STRING_PARSE_BYTES
=
(
1
<<
6
)
/**< Treat numbers as bytes */
}
ucl_string_flags_t
;
/**
...
...
@@ -286,10 +289,12 @@ UCL_EXTERN ucl_object_t* ucl_object_new_full (ucl_type_t type, unsigned priority
/**
* Create new object with userdata dtor
* @param dtor destructor function
* @param emitter emitter for userdata
* @param ptr opaque pointer
* @return new object
*/
UCL_EXTERN
ucl_object_t
*
ucl_object_new_userdata
(
ucl_userdata_dtor
dtor
,
ucl_userdata_emitter
emitter
)
UCL_WARN_UNUSED_RESULT
;
ucl_userdata_emitter
emitter
,
void
*
ptr
)
UCL_WARN_UNUSED_RESULT
;
/**
* Perform deep copy of an object copying everything
...
...
@@ -305,6 +310,21 @@ UCL_EXTERN ucl_object_t * ucl_object_copy (const ucl_object_t *other)
*/
UCL_EXTERN
ucl_type_t
ucl_object_type
(
const
ucl_object_t
*
obj
);
/**
* Converts ucl object type to its string representation
* @param type type of object
* @return constant string describing type
*/
UCL_EXTERN
const
char
*
ucl_object_type_to_string
(
ucl_type_t
type
);
/**
* Converts string that represents ucl type to real ucl type enum
* @param input C string with name of type
* @param res resulting target
* @return true if `input` is a name of type stored in `res`
*/
UCL_EXTERN
bool
ucl_object_string_to_type
(
const
char
*
input
,
ucl_type_t
*
res
);
/**
* Convert any string to an ucl object making the specified transformations
* @param str fixed size or NULL terminated string
...
...
@@ -642,8 +662,9 @@ UCL_EXTERN const char* ucl_object_tolstring (const ucl_object_t *obj, size_t *tl
* @param key key to search
* @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
,
UCL_EXTERN
const
ucl_object_t
*
ucl_object_
lookup
(
const
ucl_object_t
*
obj
,
const
char
*
key
);
#define ucl_object_find_key ucl_object_lookup
/**
* Return object identified by a key in the specified object, if the first key is
...
...
@@ -655,8 +676,9 @@ UCL_EXTERN const ucl_object_t* ucl_object_find_key (const ucl_object_t *obj,
* @param ... list of alternative keys to search (NULL terminated)
* @return object matching the specified key or NULL if key was not found
*/
UCL_EXTERN
const
ucl_object_t
*
ucl_object_
find_any_ke
y
(
const
ucl_object_t
*
obj
,
UCL_EXTERN
const
ucl_object_t
*
ucl_object_
lookup_an
y
(
const
ucl_object_t
*
obj
,
const
char
*
key
,
...);
#define ucl_object_find_any_key ucl_object_lookup_any
/**
* Return object identified by a fixed size key in the specified object
...
...
@@ -665,8 +687,9 @@ UCL_EXTERN const ucl_object_t* ucl_object_find_any_key (const ucl_object_t *obj,
* @param klen length of a key
* @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
,
UCL_EXTERN
const
ucl_object_t
*
ucl_object_
lookup_len
(
const
ucl_object_t
*
obj
,
const
char
*
key
,
size_t
klen
);
#define ucl_object_find_keyl ucl_object_lookup_len
/**
* Return object identified by dot notation string
...
...
@@ -674,8 +697,9 @@ UCL_EXTERN const ucl_object_t* ucl_object_find_keyl (const ucl_object_t *obj,
* @param path dot.notation.path to the path to lookup. May use numeric .index on arrays
* @return object matched the specified path or NULL if path is not found
*/
UCL_EXTERN
const
ucl_object_t
*
ucl_lookup_path
(
const
ucl_object_t
*
obj
,
UCL_EXTERN
const
ucl_object_t
*
ucl_
object_
lookup_path
(
const
ucl_object_t
*
obj
,
const
char
*
path
);
#define ucl_lookup_path ucl_object_lookup_path
/**
* Return object identified by object notation string using arbitrary delimiter
...
...
@@ -684,8 +708,9 @@ UCL_EXTERN const ucl_object_t *ucl_lookup_path (const ucl_object_t *obj,
* @param sep the sepatorator to use in place of . (incase keys have . in them)
* @return object matched the specified path or NULL if path is not found
*/
UCL_EXTERN
const
ucl_object_t
*
ucl_lookup_path_char
(
const
ucl_object_t
*
obj
,
UCL_EXTERN
const
ucl_object_t
*
ucl_
object_
lookup_path_char
(
const
ucl_object_t
*
obj
,
const
char
*
path
,
char
sep
);
#define ucl_lookup_path_char ucl_object_lookup_path_char
/**
* Returns a key of an object as a NULL terminated string
...
...
@@ -734,6 +759,19 @@ UCL_EXTERN void ucl_object_unref (ucl_object_t *obj);
UCL_EXTERN
int
ucl_object_compare
(
const
ucl_object_t
*
o1
,
const
ucl_object_t
*
o2
);
/**
* Compare objects `o1` and `o2` useful for sorting
* @param o1 the first object
* @param o2 the second object
* @return values >0, 0 and <0 if `o1` is more than, equal and less than `o2`.
* The order of comparison:
* 1) Type of objects
* 2) Size of objects
* 3) Content of objects
*/
UCL_EXTERN
int
ucl_object_compare_qsort
(
const
ucl_object_t
**
o1
,
const
ucl_object_t
**
o2
);
/**
* Sort UCL array using `cmp` compare function
* @param ar
...
...
@@ -770,8 +808,9 @@ typedef void* ucl_object_iter_t;
* while ((cur = ucl_iterate_object (obj, &it)) != NULL) ...
* @return the next object or NULL
*/
UCL_EXTERN
const
ucl_object_t
*
ucl_iterate
_object
(
const
ucl_object_t
*
obj
,
UCL_EXTERN
const
ucl_object_t
*
ucl_
object_
iterate
(
const
ucl_object_t
*
obj
,
ucl_object_iter_t
*
iter
,
bool
expand_values
);
#define ucl_iterate_object ucl_object_iterate
/**
* Create new safe iterator for the specified object
...
...
@@ -1040,34 +1079,34 @@ UCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser);
* @param parser parser object
* @return error description
*/
UCL_EXTERN
const
char
*
ucl_parser_get_error
(
struct
ucl_parser
*
parser
);
UCL_EXTERN
const
char
*
ucl_parser_get_error
(
struct
ucl_parser
*
parser
);
/**
* Get the code of the last error
* @param parser parser object
* @return error code
*/
UCL_EXTERN
int
ucl_parser_get_error_code
(
struct
ucl_parser
*
parser
);
UCL_EXTERN
int
ucl_parser_get_error_code
(
struct
ucl_parser
*
parser
);
/**
* Get the current column number within parser
* @param parser parser object
* @return current column number
*/
UCL_EXTERN
unsigned
ucl_parser_get_column
(
struct
ucl_parser
*
parser
);
UCL_EXTERN
unsigned
ucl_parser_get_column
(
struct
ucl_parser
*
parser
);
/**
* Get the current line number within parser
* @param parser parser object
* @return current line number
*/
UCL_EXTERN
unsigned
ucl_parser_get_linenum
(
struct
ucl_parser
*
parser
);
UCL_EXTERN
unsigned
ucl_parser_get_linenum
(
struct
ucl_parser
*
parser
);
/**
* Clear the error in the parser
* @param parser parser object
*/
UCL_EXTERN
void
ucl_parser_clear_error
(
struct
ucl_parser
*
parser
);
UCL_EXTERN
void
ucl_parser_clear_error
(
struct
ucl_parser
*
parser
);
/**
* Free ucl parser object
...
...
@@ -1075,6 +1114,42 @@ UCL_EXTERN void ucl_parser_clear_error(struct ucl_parser *parser);
*/
UCL_EXTERN
void
ucl_parser_free
(
struct
ucl_parser
*
parser
);
/**
* Get constant opaque pointer to comments structure for this parser. Increase
* refcount to prevent this object to be destroyed on parser's destruction
* @param parser parser structure
* @return ucl comments pointer or NULL
*/
UCL_EXTERN
const
ucl_object_t
*
ucl_parser_get_comments
(
struct
ucl_parser
*
parser
);
/**
* Utility function to find a comment object for the specified object in the input
* @param comments comments object
* @param srch search object
* @return string comment enclosed in ucl_object_t
*/
UCL_EXTERN
const
ucl_object_t
*
ucl_comments_find
(
const
ucl_object_t
*
comments
,
const
ucl_object_t
*
srch
);
/**
* Move comment from `from` object to `to` object
* @param comments comments object
* @param what source object
* @param whith destination object
* @return `true` if `from` has comment and it has been moved to `to`
*/
UCL_EXTERN
bool
ucl_comments_move
(
ucl_object_t
*
comments
,
const
ucl_object_t
*
from
,
const
ucl_object_t
*
to
);
/**
* Adds a new comment for an object
* @param comments comments object
* @param obj object to add comment to
* @param comment string representation of a comment
*/
UCL_EXTERN
void
ucl_comments_add
(
ucl_object_t
*
comments
,
const
ucl_object_t
*
obj
,
const
char
*
comment
);
/**
* Add new public key to parser for signatures check
* @param parser parser object
...
...
@@ -1083,7 +1158,8 @@ UCL_EXTERN void ucl_parser_free (struct ucl_parser *parser);
* @param err if *err is NULL it is set to parser error
* @return true if a key has been successfully added
*/
UCL_EXTERN
bool
ucl_pubkey_add
(
struct
ucl_parser
*
parser
,
const
unsigned
char
*
key
,
size_t
len
);
UCL_EXTERN
bool
ucl_parser_pubkey_add
(
struct
ucl_parser
*
parser
,
const
unsigned
char
*
key
,
size_t
len
);
/**
* Set FILENAME and CURDIR variables in parser
...
...
@@ -1156,8 +1232,8 @@ struct ucl_emitter_context {
unsigned
int
indent
;
/** Top level object */
const
ucl_object_t
*
top
;
/**
The rest of context
*/
unsigned
char
data
[
1
]
;
/**
Optional comments
*/
const
ucl_object_t
*
comments
;
};
/**
...
...
@@ -1187,11 +1263,13 @@ UCL_EXTERN unsigned char *ucl_object_emit_len (const ucl_object_t *obj,
* @param emit_type if type is #UCL_EMIT_JSON then emit json, if type is
* #UCL_EMIT_CONFIG then emit config like object
* @param emitter a set of emitter functions
* @param comments optional comments for the parser
* @return dump of an object (must be freed after using) or NULL in case of error
*/
UCL_EXTERN
bool
ucl_object_emit_full
(
const
ucl_object_t
*
obj
,
enum
ucl_emitter
emit_type
,
struct
ucl_emitter_functions
*
emitter
);
struct
ucl_emitter_functions
*
emitter
,
const
ucl_object_t
*
comments
);
/**
* Start streamlined UCL object emitter
...
...
@@ -1280,6 +1358,9 @@ enum ucl_schema_error_code {
UCL_SCHEMA_MISSING_PROPERTY
,
/**< one or more missing properties */
UCL_SCHEMA_CONSTRAINT
,
/**< constraint found */
UCL_SCHEMA_MISSING_DEPENDENCY
,
/**< missing dependency */
UCL_SCHEMA_EXTERNAL_REF_MISSING
,
/**< cannot fetch external ref */
UCL_SCHEMA_EXTERNAL_REF_INVALID
,
/**< invalid external ref */
UCL_SCHEMA_INTERNAL_ERROR
,
/**< something bad happened */
UCL_SCHEMA_UNKNOWN
/**< generic error */
};
...
...
@@ -1303,6 +1384,37 @@ struct ucl_schema_error {
UCL_EXTERN
bool
ucl_object_validate
(
const
ucl_object_t
*
schema
,
const
ucl_object_t
*
obj
,
struct
ucl_schema_error
*
err
);
/**
* Validate object `obj` using schema object `schema` and root schema at `root`.
* @param schema schema object
* @param obj object to validate
* @param root root schema object
* @param err error pointer, if this parameter is not NULL and error has been
* occured, then `err` is filled with the exact error definition.
* @return true if `obj` is valid using `schema`
*/
UCL_EXTERN
bool
ucl_object_validate_root
(
const
ucl_object_t
*
schema
,
const
ucl_object_t
*
obj
,
const
ucl_object_t
*
root
,
struct
ucl_schema_error
*
err
);
/**
* Validate object `obj` using schema object `schema` and root schema at `root`
* using some external references provided.
* @param schema schema object
* @param obj object to validate
* @param root root schema object
* @param ext_refs external references (might be modified during validation)
* @param err error pointer, if this parameter is not NULL and error has been
* occured, then `err` is filled with the exact error definition.
* @return true if `obj` is valid using `schema`
*/
UCL_EXTERN
bool
ucl_object_validate_root_ext
(
const
ucl_object_t
*
schema
,
const
ucl_object_t
*
obj
,
const
ucl_object_t
*
root
,
ucl_object_t
*
ext_refs
,
struct
ucl_schema_error
*
err
);