]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Allow custom parse types in lua ucl
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 13 Jan 2017 09:24:19 +0000 (09:24 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 13 Jan 2017 09:24:19 +0000 (09:24 +0000)
contrib/libucl/lua_ucl.c
contrib/libucl/ucl.h
contrib/libucl/ucl_internal.h
contrib/libucl/ucl_parser.c
contrib/libucl/ucl_sexp.c

index 5535ad42763834cd2d142e4c74599eeecd137196..fa69c72d0dc5de54ec563fa455c993441689d36e 100644 (file)
@@ -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;
+                       }
                }
        }
 
index ec93bd7e1dfd04fc6f688764c60981e5282dbef9..ee683b163afce1c8cf57372210c1a7616e48ed94 100644 (file)
@@ -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 */
 };
 
 /**
index db8a12c408b1f0c347437f738c68c0c4e1a24cd6..444a40e3820320205b696d61f4ea38d59ddeb35f 100644 (file)
@@ -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_ */
index fc7cea07febab39b1dacb0a9e36a294c2059b2bc..82c4ca24b2e64a8fcbcfd5ec8ab996e36e1c7aaa 100644 (file)
@@ -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 {
index 1ad93d23458e8a841e85503309d134b2e8598c01..c4ad75a1804a83d900b6e8a58ca777cfb7ed6418 100644 (file)
@@ -26,7 +26,6 @@
 #include "config.h"
 #endif
 
-#include <ucl.h>
 #include "ucl.h"
 #include "ucl_internal.h"
 #include "utlist.h"