lua_ucl.c (b626f5a73a48f44a31a200291b141e1da408a2ff) | lua_ucl.c (d9f0ce31900a48d1a2bfc1c8c86f79d1e831451a) |
---|---|
1/* Copyright (c) 2014, Vsevolod Stakhov 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright --- 15 unchanged lines hidden (view full) --- 24/** 25 * @file lua ucl bindings 26 */ 27 28#include "ucl.h" 29#include "ucl_internal.h" 30#include "lua_ucl.h" 31#include <strings.h> | 1/* Copyright (c) 2014, Vsevolod Stakhov 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright --- 15 unchanged lines hidden (view full) --- 24/** 25 * @file lua ucl bindings 26 */ 27 28#include "ucl.h" 29#include "ucl_internal.h" 30#include "lua_ucl.h" 31#include <strings.h> |
32#include <zconf.h> |
|
32 33/*** 34 * @module ucl 35 * This lua module allows to parse objects from strings and to store data into 36 * ucl objects. It uses `libucl` C library to parse and manipulate with ucl objects. 37 * @example 38local ucl = require("ucl") 39 --- 104 unchanged lines hidden (view full) --- 144 int nelt = 0; 145 146 if (allow_array && obj->next != NULL) { 147 /* Actually we need to push this as an array */ 148 return ucl_object_lua_push_array (L, obj); 149 } 150 151 /* Optimize allocation by preallocation of table */ | 33 34/*** 35 * @module ucl 36 * This lua module allows to parse objects from strings and to store data into 37 * ucl objects. It uses `libucl` C library to parse and manipulate with ucl objects. 38 * @example 39local ucl = require("ucl") 40 --- 104 unchanged lines hidden (view full) --- 145 int nelt = 0; 146 147 if (allow_array && obj->next != NULL) { 148 /* Actually we need to push this as an array */ 149 return ucl_object_lua_push_array (L, obj); 150 } 151 152 /* Optimize allocation by preallocation of table */ |
152 while (ucl_iterate_object (obj, &it, true) != NULL) { | 153 while (ucl_object_iterate (obj, &it, true) != NULL) { |
153 nelt ++; 154 } 155 156 lua_createtable (L, 0, nelt); 157 it = NULL; 158 | 154 nelt ++; 155 } 156 157 lua_createtable (L, 0, nelt); 158 it = NULL; 159 |
159 while ((cur = ucl_iterate_object (obj, &it, true)) != NULL) { | 160 while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) { |
160 ucl_object_lua_push_element (L, ucl_object_key (cur), cur); 161 } 162 163 return 1; 164} 165 166/** 167 * Push an array to lua as table indexed by integers --- 248 unchanged lines hidden (view full) --- 416 fd = malloc (sizeof (*fd)); 417 if (fd != NULL) { 418 lua_pushvalue (L, idx); 419 fd->L = L; 420 fd->ret = NULL; 421 fd->idx = luaL_ref (L, LUA_REGISTRYINDEX); 422 423 obj = ucl_object_new_userdata (lua_ucl_userdata_dtor, | 161 ucl_object_lua_push_element (L, ucl_object_key (cur), cur); 162 } 163 164 return 1; 165} 166 167/** 168 * Push an array to lua as table indexed by integers --- 248 unchanged lines hidden (view full) --- 417 fd = malloc (sizeof (*fd)); 418 if (fd != NULL) { 419 lua_pushvalue (L, idx); 420 fd->L = L; 421 fd->ret = NULL; 422 fd->idx = luaL_ref (L, LUA_REGISTRYINDEX); 423 424 obj = ucl_object_new_userdata (lua_ucl_userdata_dtor, |
424 lua_ucl_userdata_emitter); 425 obj->type = UCL_USERDATA; 426 obj->value.ud = (void *)fd; | 425 lua_ucl_userdata_emitter, (void *)fd); |
427 } 428 } 429 } 430 break; 431 } 432 433 return obj; 434} --- 74 unchanged lines hidden (view full) --- 509} 510 511static ucl_object_t * 512lua_ucl_object_get (lua_State *L, int index) 513{ 514 return *((ucl_object_t **) luaL_checkudata(L, index, OBJECT_META)); 515} 516 | 426 } 427 } 428 } 429 break; 430 } 431 432 return obj; 433} --- 74 unchanged lines hidden (view full) --- 508} 509 510static ucl_object_t * 511lua_ucl_object_get (lua_State *L, int index) 512{ 513 return *((ucl_object_t **) luaL_checkudata(L, index, OBJECT_META)); 514} 515 |
516static void 517lua_ucl_push_opaque (lua_State *L, ucl_object_t *obj) 518{ 519 ucl_object_t **pobj; 520 521 pobj = lua_newuserdata (L, sizeof (*pobj)); 522 *pobj = obj; 523 luaL_getmetatable (L, OBJECT_META); 524 lua_setmetatable (L, -2); 525} 526 |
|
517/*** 518 * @method parser:parse_file(name) 519 * Parse UCL object from file. 520 * @param {string} name filename to parse 521 * @return {bool[, string]} if res is `true` then file has been parsed successfully, otherwise an error string is also returned 522@example 523local parser = ucl.parser() 524local res,err = parser:parse_file('/some/file.conf') --- 99 unchanged lines hidden (view full) --- 624 * Get top object from parser and export it to userdata object without 625 * unwrapping to lua. 626 * @return {ucl.object or nil} ucl object wrapped variable 627 */ 628static int 629lua_ucl_parser_get_object_wrapped (lua_State *L) 630{ 631 struct ucl_parser *parser; | 527/*** 528 * @method parser:parse_file(name) 529 * Parse UCL object from file. 530 * @param {string} name filename to parse 531 * @return {bool[, string]} if res is `true` then file has been parsed successfully, otherwise an error string is also returned 532@example 533local parser = ucl.parser() 534local res,err = parser:parse_file('/some/file.conf') --- 99 unchanged lines hidden (view full) --- 634 * Get top object from parser and export it to userdata object without 635 * unwrapping to lua. 636 * @return {ucl.object or nil} ucl object wrapped variable 637 */ 638static int 639lua_ucl_parser_get_object_wrapped (lua_State *L) 640{ 641 struct ucl_parser *parser; |
632 ucl_object_t *obj, **pobj; | 642 ucl_object_t *obj; |
633 int ret = 1; 634 635 parser = lua_ucl_parser_get (L, 1); 636 obj = ucl_parser_get_object (parser); 637 638 if (obj != NULL) { | 643 int ret = 1; 644 645 parser = lua_ucl_parser_get (L, 1); 646 obj = ucl_parser_get_object (parser); 647 648 if (obj != NULL) { |
639 pobj = lua_newuserdata (L, sizeof (*pobj)); 640 *pobj = obj; 641 luaL_getmetatable (L, OBJECT_META); 642 lua_setmetatable (L, -2); | 649 lua_ucl_push_opaque (L, obj); |
643 } 644 else { 645 lua_pushnil (L); 646 } 647 648 return ret; 649} 650 --- 150 unchanged lines hidden (view full) --- 801 else { 802 lua_pushnil (L); 803 } 804 805 return 1; 806} 807 808/*** | 650 } 651 else { 652 lua_pushnil (L); 653 } 654 655 return ret; 656} 657 --- 150 unchanged lines hidden (view full) --- 808 else { 809 lua_pushnil (L); 810 } 811 812 return 1; 813} 814 815/*** |
809 * @method object:validate(schema, path) | 816 * @method object:validate(schema[, path[, ext_refs]]) |
810 * Validates the given ucl object using schema object represented as another 811 * opaque ucl object. You can also specify path in the form `#/path/def` to 812 * specify the specific schema element to perform validation. 813 * 814 * @param {ucl.object} schema schema object 815 * @param {string} path optional path for validation procedure | 817 * Validates the given ucl object using schema object represented as another 818 * opaque ucl object. You can also specify path in the form `#/path/def` to 819 * specify the specific schema element to perform validation. 820 * 821 * @param {ucl.object} schema schema object 822 * @param {string} path optional path for validation procedure |
816 * @return {result,err} two values: boolean result and the corresponding error | 823 * @return {result,err} two values: boolean result and the corresponding 824 * error, if `ext_refs` are also specified, then they are returned as opaque 825 * ucl object as {result,err,ext_refs} |
817 */ 818static int 819lua_ucl_object_validate (lua_State *L) 820{ | 826 */ 827static int 828lua_ucl_object_validate (lua_State *L) 829{ |
821 ucl_object_t *obj, *schema; | 830 ucl_object_t *obj, *schema, *ext_refs = NULL; |
822 const ucl_object_t *schema_elt; 823 bool res = false; 824 struct ucl_schema_error err; 825 const char *path = NULL; 826 827 obj = lua_ucl_object_get (L, 1); 828 schema = lua_ucl_object_get (L, 2); 829 830 if (schema && obj && ucl_object_type (schema) == UCL_OBJECT) { | 831 const ucl_object_t *schema_elt; 832 bool res = false; 833 struct ucl_schema_error err; 834 const char *path = NULL; 835 836 obj = lua_ucl_object_get (L, 1); 837 schema = lua_ucl_object_get (L, 2); 838 839 if (schema && obj && ucl_object_type (schema) == UCL_OBJECT) { |
831 if (lua_gettop (L) > 2 && lua_type (L, 3) == LUA_TSTRING) { 832 path = lua_tostring (L, 3); 833 if (path[0] == '#') { 834 path ++; | 840 if (lua_gettop (L) > 2) { 841 if (lua_type (L, 3) == LUA_TSTRING) { 842 path = lua_tostring (L, 3); 843 if (path[0] == '#') { 844 path++; 845 } |
835 } | 846 } |
847 else if (lua_type (L, 3) == LUA_TUSERDATA || lua_type (L, 3) == 848 LUA_TTABLE) { 849 /* External refs */ 850 ext_refs = lua_ucl_object_get (L, 3); 851 } 852 853 if (lua_gettop (L) > 3) { 854 if (lua_type (L, 4) == LUA_TUSERDATA || lua_type (L, 4) == 855 LUA_TTABLE) { 856 /* External refs */ 857 ext_refs = lua_ucl_object_get (L, 4); 858 } 859 } |
|
836 } 837 838 if (path) { | 860 } 861 862 if (path) { |
839 schema_elt = ucl_lookup_path_char (schema, path, '/'); | 863 schema_elt = ucl_object_lookup_path_char (schema, path, '/'); |
840 } 841 else { 842 /* Use the top object */ 843 schema_elt = schema; 844 } 845 846 if (schema_elt) { | 864 } 865 else { 866 /* Use the top object */ 867 schema_elt = schema; 868 } 869 870 if (schema_elt) { |
847 res = ucl_object_validate (schema_elt, obj, &err); | 871 res = ucl_object_validate_root_ext (schema_elt, obj, schema, 872 ext_refs, &err); |
848 849 if (res) { 850 lua_pushboolean (L, res); 851 lua_pushnil (L); | 873 874 if (res) { 875 lua_pushboolean (L, res); 876 lua_pushnil (L); |
877 878 if (ext_refs) { 879 lua_ucl_push_opaque (L, ext_refs); 880 } |
|
852 } 853 else { 854 lua_pushboolean (L, res); 855 lua_pushfstring (L, "validation error: %s", err.msg); | 881 } 882 else { 883 lua_pushboolean (L, res); 884 lua_pushfstring (L, "validation error: %s", err.msg); |
885 886 if (ext_refs) { 887 lua_ucl_push_opaque (L, ext_refs); 888 } |
|
856 } 857 } 858 else { 859 lua_pushboolean (L, res); 860 | 889 } 890 } 891 else { 892 lua_pushboolean (L, res); 893 |
861 if (path) { 862 lua_pushfstring (L, "cannot find the requested path: %s", path); | 894 lua_pushfstring (L, "cannot find the requested path: %s", path); 895 896 if (ext_refs) { 897 lua_ucl_push_opaque (L, ext_refs); |
863 } | 898 } |
864 else { 865 /* Should not be reached */ 866 lua_pushstring (L, "unknown error"); 867 } | |
868 } 869 } 870 else { 871 lua_pushboolean (L, res); 872 lua_pushstring (L, "invalid object or schema"); 873 } 874 | 899 } 900 } 901 else { 902 lua_pushboolean (L, res); 903 lua_pushstring (L, "invalid object or schema"); 904 } 905 |
906 if (ext_refs) { 907 return 3; 908 } 909 |
|
875 return 2; 876} 877 878static int 879lua_ucl_object_gc (lua_State *L) 880{ 881 ucl_object_t *obj; 882 --- 256 unchanged lines hidden --- | 910 return 2; 911} 912 913static int 914lua_ucl_object_gc (lua_State *L) 915{ 916 ucl_object_t *obj; 917 --- 256 unchanged lines hidden --- |