Line data Source code
1 : /*
2 : Minetest
3 : Copyright (C) 2013 PilzAdam <pilzadam@minetest.net>
4 :
5 : This program is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU Lesser General Public License as published by
7 : the Free Software Foundation; either version 2.1 of the License, or
8 : (at your option) any later version.
9 :
10 : This program is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU Lesser General Public License for more details.
14 :
15 : You should have received a copy of the GNU Lesser General Public License along
16 : with this program; if not, write to the Free Software Foundation, Inc.,
17 : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "lua_api/l_settings.h"
21 : #include "lua_api/l_internal.h"
22 : #include "cpp_api/s_security.h"
23 : #include "settings.h"
24 : #include "log.h"
25 :
26 : // garbage collector
27 0 : int LuaSettings::gc_object(lua_State* L)
28 : {
29 0 : LuaSettings* o = *(LuaSettings **)(lua_touserdata(L, 1));
30 0 : delete o;
31 0 : return 0;
32 : }
33 :
34 : // get(self, key) -> value
35 0 : int LuaSettings::l_get(lua_State* L)
36 : {
37 0 : NO_MAP_LOCK_REQUIRED;
38 0 : LuaSettings* o = checkobject(L, 1);
39 :
40 0 : std::string key = std::string(luaL_checkstring(L, 2));
41 0 : if (o->m_settings->exists(key)) {
42 0 : std::string value = o->m_settings->get(key);
43 0 : lua_pushstring(L, value.c_str());
44 : } else {
45 0 : lua_pushnil(L);
46 : }
47 :
48 0 : return 1;
49 : }
50 :
51 : // get_bool(self, key) -> boolean
52 0 : int LuaSettings::l_get_bool(lua_State* L)
53 : {
54 0 : NO_MAP_LOCK_REQUIRED;
55 0 : LuaSettings* o = checkobject(L, 1);
56 :
57 0 : std::string key = std::string(luaL_checkstring(L, 2));
58 0 : if (o->m_settings->exists(key)) {
59 0 : bool value = o->m_settings->getBool(key);
60 0 : lua_pushboolean(L, value);
61 : } else {
62 0 : lua_pushnil(L);
63 : }
64 :
65 0 : return 1;
66 : }
67 :
68 : // set(self, key, value)
69 0 : int LuaSettings::l_set(lua_State* L)
70 : {
71 0 : NO_MAP_LOCK_REQUIRED;
72 0 : LuaSettings* o = checkobject(L, 1);
73 :
74 0 : std::string key = std::string(luaL_checkstring(L, 2));
75 0 : const char* value = luaL_checkstring(L, 3);
76 :
77 0 : if (!o->m_settings->set(key, value))
78 0 : throw LuaError("Invalid sequence found in setting parameters");
79 :
80 0 : return 0;
81 : }
82 :
83 : // remove(self, key) -> success
84 0 : int LuaSettings::l_remove(lua_State* L)
85 : {
86 0 : NO_MAP_LOCK_REQUIRED;
87 0 : LuaSettings* o = checkobject(L, 1);
88 :
89 0 : std::string key = std::string(luaL_checkstring(L, 2));
90 :
91 0 : bool success = o->m_settings->remove(key);
92 0 : lua_pushboolean(L, success);
93 :
94 0 : return 1;
95 : }
96 :
97 : // get_names(self) -> {key1, ...}
98 0 : int LuaSettings::l_get_names(lua_State* L)
99 : {
100 0 : NO_MAP_LOCK_REQUIRED;
101 0 : LuaSettings* o = checkobject(L, 1);
102 :
103 0 : std::vector<std::string> keys = o->m_settings->getNames();
104 :
105 0 : lua_newtable(L);
106 0 : for (unsigned int i=0; i < keys.size(); i++)
107 : {
108 0 : lua_pushstring(L, keys[i].c_str());
109 0 : lua_rawseti(L, -2, i + 1);
110 : }
111 :
112 0 : return 1;
113 : }
114 :
115 : // write(self) -> success
116 0 : int LuaSettings::l_write(lua_State* L)
117 : {
118 0 : NO_MAP_LOCK_REQUIRED;
119 0 : LuaSettings* o = checkobject(L, 1);
120 :
121 0 : bool success = o->m_settings->updateConfigFile(o->m_filename.c_str());
122 0 : lua_pushboolean(L, success);
123 :
124 0 : return 1;
125 : }
126 :
127 : // to_table(self) -> {[key1]=value1,...}
128 0 : int LuaSettings::l_to_table(lua_State* L)
129 : {
130 0 : NO_MAP_LOCK_REQUIRED;
131 0 : LuaSettings* o = checkobject(L, 1);
132 :
133 0 : std::vector<std::string> keys = o->m_settings->getNames();
134 :
135 0 : lua_newtable(L);
136 0 : for (unsigned int i=0; i < keys.size(); i++)
137 : {
138 0 : lua_pushstring(L, o->m_settings->get(keys[i]).c_str());
139 0 : lua_setfield(L, -2, keys[i].c_str());
140 : }
141 :
142 0 : return 1;
143 : }
144 :
145 0 : LuaSettings::LuaSettings(const char* filename)
146 : {
147 0 : m_filename = std::string(filename);
148 :
149 0 : m_settings = new Settings();
150 0 : m_settings->readConfigFile(m_filename.c_str());
151 0 : }
152 :
153 0 : LuaSettings::~LuaSettings()
154 : {
155 0 : delete m_settings;
156 0 : }
157 :
158 1 : void LuaSettings::Register(lua_State* L)
159 : {
160 1 : lua_newtable(L);
161 1 : int methodtable = lua_gettop(L);
162 1 : luaL_newmetatable(L, className);
163 1 : int metatable = lua_gettop(L);
164 :
165 1 : lua_pushliteral(L, "__metatable");
166 1 : lua_pushvalue(L, methodtable);
167 1 : lua_settable(L, metatable); // hide metatable from Lua getmetatable()
168 :
169 1 : lua_pushliteral(L, "__index");
170 1 : lua_pushvalue(L, methodtable);
171 1 : lua_settable(L, metatable);
172 :
173 1 : lua_pushliteral(L, "__gc");
174 1 : lua_pushcfunction(L, gc_object);
175 1 : lua_settable(L, metatable);
176 :
177 1 : lua_pop(L, 1); // drop metatable
178 :
179 1 : luaL_openlib(L, 0, methods, 0); // fill methodtable
180 1 : lua_pop(L, 1); // drop methodtable
181 :
182 : // Can be created from Lua (Settings(filename))
183 1 : lua_register(L, className, create_object);
184 1 : }
185 :
186 : // LuaSettings(filename)
187 : // Creates an LuaSettings and leaves it on top of stack
188 0 : int LuaSettings::create_object(lua_State* L)
189 : {
190 0 : NO_MAP_LOCK_REQUIRED;
191 0 : const char* filename = luaL_checkstring(L, 1);
192 0 : CHECK_SECURE_PATH_OPTIONAL(L, filename);
193 0 : LuaSettings* o = new LuaSettings(filename);
194 0 : *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
195 0 : luaL_getmetatable(L, className);
196 0 : lua_setmetatable(L, -2);
197 0 : return 1;
198 : }
199 :
200 0 : LuaSettings* LuaSettings::checkobject(lua_State* L, int narg)
201 : {
202 0 : NO_MAP_LOCK_REQUIRED;
203 0 : luaL_checktype(L, narg, LUA_TUSERDATA);
204 0 : void *ud = luaL_checkudata(L, narg, className);
205 0 : if(!ud) luaL_typerror(L, narg, className);
206 0 : return *(LuaSettings**)ud; // unbox pointer
207 : }
208 :
209 : const char LuaSettings::className[] = "Settings";
210 : const luaL_reg LuaSettings::methods[] = {
211 : luamethod(LuaSettings, get),
212 : luamethod(LuaSettings, get_bool),
213 : luamethod(LuaSettings, set),
214 : luamethod(LuaSettings, remove),
215 : luamethod(LuaSettings, get_names),
216 : luamethod(LuaSettings, write),
217 : luamethod(LuaSettings, to_table),
218 : {0,0}
219 3 : };
|