2 * Hic Est Leo -- Bindings for Lua
4 * (c) 2015 Martin Mares <mj@ucw.cz>
20 /*** Proxy for OSM object attributes ***/
28 static void push_proxy_tag(lua_State *L, struct proxy_tag *t)
30 SWIG_NewPointerObj(L, t, SWIGTYPE_p_proxy_tag, 0);
33 static const char *proxy_tag_index(struct proxy_tag *t, const char *key)
35 osm_key_t k = osm_key_encode(key);
36 osm_val_t v = osm_obj_find_tag(t->o, k);
37 return osm_val_decode(v);
45 const char *index(const char *key);
49 // This overrides default index function generated by SWIG.
50 // The tag proxy therefore cannot have any methods.
51 SWIG_Lua_get_class_metatable(L, "proxy_tag");
52 SWIG_Lua_add_function(L, "__index", _wrap_proxy_tag_index);
56 /*** Proxy for style properties ***/
61 struct style_results *sr;
65 static void push_proxy_style(lua_State *L, struct proxy_style *s)
67 SWIG_NewPointerObj(L, s, SWIGTYPE_p_proxy_style, 0);
70 static struct style_prop *proxy_style_index(struct proxy_style *s, const char *key)
72 prop_t k = style_prop_encode(key);
73 return style_get_by_layer(s->sr, s->layer, k);
76 static void proxy_style_newindex(struct proxy_style *s, const char *key, struct style_prop *p)
78 p->key = style_prop_encode(key);
79 style_set_by_layer(s->sr, s->layer, p);
82 static void push_style_prop(lua_State *L, struct style_prop *p)
91 case PROP_TYPE_STRING:
92 lua_pushstring(L, osm_val_decode(p->val.id));
94 case PROP_TYPE_NUMBER:
95 lua_pushnumber(L, (lua_Number) p->val.number);
98 msg(L_WARN, "Property %s has value with no LUA representation", style_prop_decode(p->key));
103 static const char *decode_style_prop(lua_State *L, int idx, struct style_prop *p)
105 if (lua_isnil(L, idx))
106 return "Cannot set property to nil. Yet."; // FIXME
108 if (lua_isnumber(L, idx)) // FIXME: numbers vs. strings
110 p->type = PROP_TYPE_NUMBER;
111 p->val.number = lua_tonumber(L, idx);
115 if (lua_isstring(L, idx))
117 p->type = PROP_TYPE_STRING;
118 p->val.id = osm_val_encode(lua_tostring(L, idx));
122 return "Invalid type of style property";
127 %typemap(out) struct style_prop * { push_style_prop(L, $1); SWIG_arg++; }
129 %typemap(in) struct style_prop * (const char *err, struct style_prop prop) {
130 err = decode_style_prop(L, $input, &prop);
133 lua_pushstring(L, err);
139 struct proxy_style { };
141 %extend proxy_style {
142 struct style_prop *index(const char *key);
143 void newindex(const char *key, struct style_prop *p);
147 // This overrides default index function generated by SWIG.
148 SWIG_Lua_get_class_metatable(L, "proxy_style");
149 SWIG_Lua_add_function(L, "__index", _wrap_proxy_style_index);
150 SWIG_Lua_add_function(L, "__newindex", _wrap_proxy_style_newindex);
154 /*** Compilation and running of expressions ***/
158 static lua_State *lua;
162 lua = luaL_newstate();
168 // SWIG init code leaves data in Lua stack. Get rid of it.
169 lua_pop(L, lua_gettop(L));
171 lua_checkstack(L, 30);
173 lua_pushliteral(L, "Leo");
175 lua_settable(L, LUA_REGISTRYINDEX);
179 // Not used at the moment (FIXME)
181 static char *current_src;
183 static const char *expr_reader(lua_State *L UNUSED, void *data UNUSED, size_t *sizep)
187 char *res = current_src;
188 *sizep = strlen(res);
201 void expr_compile(void *key, char *source)
205 lua_pushliteral(L, "Leo"); // stack: "Leo"
206 lua_gettable(L, LUA_REGISTRYINDEX); // stack: leo-table
207 ASSERT(lua_istable(L, -1));
208 lua_pushlightuserdata(L, key); // stack: leo-table, key
211 current_src = source;
212 int err = lua_load(L, expr_reader, NULL, "@(expr)", NULL);
214 int err = luaL_loadbuffer(L, source, strlen(source), "@expression");
217 css_error(lua_tostring(L, -1));
218 // stack: leo-table, key, function
220 lua_settable(L, -3); // stack: leo-table
221 lua_pop(L, 1); // stack: --
224 void expr_execute(void *key, struct style_results *r, layer_t layer)
228 struct proxy_tag pt = { .o = r->obj };
229 push_proxy_tag(L, &pt); // stack: proxy
230 lua_setglobal(L, "t"); // stack: --
232 struct proxy_style ps = { .sr = r, .layer = layer };
233 push_proxy_style(L, &ps); // stack: proxy
234 lua_setglobal(L, "s"); // stack: --
236 lua_pushliteral(L, "Leo"); // stack: "Leo"
237 lua_gettable(L, LUA_REGISTRYINDEX); // stack: leo-table
238 ASSERT(lua_istable(L, -1));
239 lua_pushlightuserdata(L, key); // stack: leo-table, key
240 lua_gettable(L, -2); // stack: leo-table, function
241 lua_remove(L, -2); // stack: function
242 ASSERT(lua_isfunction(L, -1));
244 lua_call(L, 0, 0); // stack: --