aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-01-13 09:24:19 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-01-13 09:24:19 +0000
commitd9f7a74a1c97af5b878066447178135a8349d6b5 (patch)
tree7f684b1038d90f210a5a36ec88520c46247785e2
parent66da8cd82b10a94a2422b27be23bdd6c7bbebb53 (diff)
downloadrspamd-d9f7a74a1c97af5b878066447178135a8349d6b5.tar.gz
rspamd-d9f7a74a1c97af5b878066447178135a8349d6b5.zip
[Feature] Allow custom parse types in lua ucl
-rw-r--r--contrib/libucl/lua_ucl.c65
-rw-r--r--contrib/libucl/ucl.h3
-rw-r--r--contrib/libucl/ucl_internal.h2
-rw-r--r--contrib/libucl/ucl_parser.c15
-rw-r--r--contrib/libucl/ucl_sexp.c1
5 files changed, 70 insertions, 16 deletions
diff --git a/contrib/libucl/lua_ucl.c b/contrib/libucl/lua_ucl.c
index 5535ad427..fa69c72d0 100644
--- a/contrib/libucl/lua_ucl.c
+++ b/contrib/libucl/lua_ucl.c
@@ -526,6 +526,24 @@ lua_ucl_push_opaque (lua_State *L, ucl_object_t *obj)
lua_setmetatable (L, -2);
}
+static inline enum ucl_parse_type
+lua_ucl_str_to_parse_type (const char *str)
+{
+ enum ucl_parse_type type = UCL_PARSE_UCL;
+
+ if (str != NULL) {
+ if (strcasecmp (str, "msgpack") == 0) {
+ type = UCL_PARSE_MSGPACK;
+ }
+ else if (strcasecmp (str, "sexp") == 0 ||
+ strcasecmp (str, "csexp") == 0) {
+ type = UCL_PARSE_CSEXP;
+ }
+ }
+
+ return type;
+}
+
/***
* @method parser:parse_file(name)
* Parse UCL object from file.
@@ -581,13 +599,19 @@ lua_ucl_parser_parse_string (lua_State *L)
struct ucl_parser *parser;
const char *string;
size_t llen;
+ enum ucl_parse_type type = UCL_PARSE_UCL;
int ret = 2;
parser = lua_ucl_parser_get (L, 1);
string = luaL_checklstring (L, 2, &llen);
+ if (lua_type (L, 3) == LUA_TSTRING) {
+ type = lua_ucl_str_to_parse_type (lua_tostring (L, 3));
+ }
+
if (parser != NULL && string != NULL) {
- if (ucl_parser_add_chunk (parser, (const unsigned char *)string, llen)) {
+ if (ucl_parser_add_chunk_full (parser, (const unsigned char *)string,
+ llen, 0, UCL_DUPLICATE_APPEND, type)) {
lua_pushboolean (L, true);
ret = 1;
}
@@ -763,6 +787,28 @@ lua_ucl_object_unwrap (lua_State *L)
return 1;
}
+static inline enum ucl_emitter
+lua_ucl_str_to_emit_type (const char *strtype)
+{
+ enum ucl_emitter format = UCL_EMIT_JSON_COMPACT;
+
+ if (strcasecmp (strtype, "json") == 0) {
+ format = UCL_EMIT_JSON;
+ }
+ else if (strcasecmp (strtype, "json-compact") == 0) {
+ format = UCL_EMIT_JSON_COMPACT;
+ }
+ else if (strcasecmp (strtype, "yaml") == 0) {
+ format = UCL_EMIT_YAML;
+ }
+ else if (strcasecmp (strtype, "config") == 0 ||
+ strcasecmp (strtype, "ucl") == 0) {
+ format = UCL_EMIT_CONFIG;
+ }
+
+ return format;
+}
+
/***
* @method object:tostring(type)
* Unwraps opaque ucl object to string (json by default). Optionally you can
@@ -789,19 +835,7 @@ lua_ucl_object_tostring (lua_State *L)
if (lua_type (L, 2) == LUA_TSTRING) {
const char *strtype = lua_tostring (L, 2);
- if (strcasecmp (strtype, "json") == 0) {
- format = UCL_EMIT_JSON;
- }
- else if (strcasecmp (strtype, "json-compact") == 0) {
- format = UCL_EMIT_JSON_COMPACT;
- }
- else if (strcasecmp (strtype, "yaml") == 0) {
- format = UCL_EMIT_YAML;
- }
- else if (strcasecmp (strtype, "config") == 0 ||
- strcasecmp (strtype, "ucl") == 0) {
- format = UCL_EMIT_CONFIG;
- }
+ format = lua_ucl_str_to_emit_type (strtype);
}
}
@@ -1090,6 +1124,9 @@ lua_ucl_to_format (lua_State *L)
strcasecmp (strtype, "ucl") == 0) {
format = UCL_EMIT_CONFIG;
}
+ else if (strcasecmp (strtype, "msgpack") == 0) {
+ format = UCL_EMIT_MSGPACK;
+ }
}
}
diff --git a/contrib/libucl/ucl.h b/contrib/libucl/ucl.h
index ec93bd7e1..ee683b163 100644
--- a/contrib/libucl/ucl.h
+++ b/contrib/libucl/ucl.h
@@ -205,7 +205,8 @@ enum ucl_duplicate_strategy {
enum ucl_parse_type {
UCL_PARSE_UCL = 0, /**< Default ucl format */
UCL_PARSE_MSGPACK, /**< Message pack input format */
- UCL_PARSE_CSEXP /**< Canonical S-expressions */
+ UCL_PARSE_CSEXP, /**< Canonical S-expressions */
+ UCL_PARSE_AUTO /**< Try to detect parse type */
};
/**
diff --git a/contrib/libucl/ucl_internal.h b/contrib/libucl/ucl_internal.h
index db8a12c40..444a40e38 100644
--- a/contrib/libucl/ucl_internal.h
+++ b/contrib/libucl/ucl_internal.h
@@ -569,4 +569,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/contrib/libucl/ucl_parser.c b/contrib/libucl/ucl_parser.c
index fc7cea07f..82c4ca24b 100644
--- a/contrib/libucl/ucl_parser.c
+++ b/contrib/libucl/ucl_parser.c
@@ -2609,6 +2609,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;
@@ -2635,6 +2648,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/contrib/libucl/ucl_sexp.c b/contrib/libucl/ucl_sexp.c
index 1ad93d234..c4ad75a18 100644
--- a/contrib/libucl/ucl_sexp.c
+++ b/contrib/libucl/ucl_sexp.c
@@ -26,7 +26,6 @@
#include "config.h"
#endif
-#include <ucl.h>
#include "ucl.h"
#include "ucl_internal.h"
#include "utlist.h"