From 8b5fa9a49ac01ce604343c846d54acfd9de8802a Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Wed, 27 Oct 2010 19:22:33 +0200
Subject: Implement parts of Lua symbol registration.
The human name and area now gets resolved.
---
src/ld-lua.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 80 insertions(+), 5 deletions(-)
(limited to 'src')
diff --git a/src/ld-lua.c b/src/ld-lua.c
index 3a6a5af..0874d10 100644
--- a/src/ld-lua.c
+++ b/src/ld-lua.c
@@ -90,6 +90,8 @@ static int ld_lua_private_unregister_cb (lua_State *L);
static int ld_lua_logdiag_register (lua_State *L);
+static gchar *get_translation (lua_State *L, int index);
+static void read_symbol_area (lua_State *L, int index, LdSymbolArea *area);
static luaL_Reg ld_lua_logdiag_lib[] =
{
@@ -351,12 +353,14 @@ ld_lua_private_unregister_cb (lua_State *L)
/* ===== Application library =============================================== */
+/* XXX: This function is damn too long. */
static int
ld_lua_logdiag_register (lua_State *L)
{
LdLuaData *ud;
LdLuaSymbol *symbol;
const gchar *name;
+ gchar *human_name;
lua_getfield (L, LUA_REGISTRYINDEX, LD_LUA_DATA_INDEX);
ud = lua_touserdata (L, -1);
@@ -367,20 +371,34 @@ ld_lua_logdiag_register (lua_State *L)
name = lua_tostring (L, 1);
if (!name)
luaL_error (L, "register: bad or missing argument #%d", 1);
+ if (!lua_istable (L, 2))
+ luaL_error (L, "register: bad or missing argument #%d", 2);
+ if (!lua_istable (L, 3))
+ luaL_error (L, "register: bad or missing argument #%d", 3);
+ if (!lua_istable (L, 4))
+ luaL_error (L, "register: bad or missing argument #%d", 4);
if (!lua_isfunction (L, 5))
luaL_error (L, "register: bad or missing argument #%d", 5);
- /* TODO: Create a symbol using the given parameters:
- * 2. names (table) -> use g_get_language_names ()
- * 3. area (table)
- * 4. terminals (table)
- */
+ /* Create a symbol using the given parameters. */
+ /* XXX: If an error occurs, this object will not be freed. */
symbol = g_object_new (LD_TYPE_LUA_SYMBOL, NULL);
symbol->priv->lua = ud->self;
g_object_ref (ud->self);
symbol->priv->name = g_strdup (name);
+ human_name = get_translation (L, 2);
+ if (!human_name)
+ human_name = g_strdup (name);
+ symbol->priv->human_name = human_name;
+
+ /* TODO: Check the values. */
+ read_symbol_area (L, 3, &symbol->priv->area);
+
+ /* TODO: Read and set the terminals (they're in a table). */
+ lua_pushvalue (L, 4);
+
/* Create an entry in the symbol table. */
lua_getfield (L, LUA_REGISTRYINDEX, LD_LUA_SYMBOLS_INDEX);
lua_pushlightuserdata (L, symbol);
@@ -399,6 +417,63 @@ ld_lua_logdiag_register (lua_State *L)
return 0;
}
+/*
+ * get_translation:
+ * @L: A Lua state.
+ * @index: Stack index of the table.
+ *
+ * Select an applicable translation from a table.
+ * The return value has to be freed with g_free().
+ *
+ * Return value: The translation, if found. If none was found, returns NULL.
+ */
+static gchar *
+get_translation (lua_State *L, int index)
+{
+ const gchar *const *lang;
+ gchar *result;
+
+ for (lang = g_get_language_names (); *lang; lang++)
+ {
+ lua_getfield (L, 2, *lang);
+ if (lua_isstring (L, -1))
+ {
+ result = g_strdup (lua_tostring (L, -1));
+ lua_pop (L, 1);
+ return result;
+ }
+ lua_pop (L, 1);
+ }
+ return NULL;
+}
+
+/*
+ * read_symbol_area:
+ * @L: A Lua state.
+ * @index: Stack index of the table.
+ * @area: Where the area will be returned.
+ *
+ * Read a symbol area from a Lua table.
+ */
+static void
+read_symbol_area (lua_State *L, int index, LdSymbolArea *area)
+{
+ if (lua_objlen (L, index) != 4)
+ return;
+
+ lua_rawgeti (L, index, 1);
+ area->x1 = lua_tonumber (L, -1);
+
+ lua_rawgeti (L, index, 2);
+ area->y1 = lua_tonumber (L, -1);
+
+ lua_rawgeti (L, index, 3);
+ area->x2 = lua_tonumber (L, -1);
+
+ lua_rawgeti (L, index, 4);
+ area->y2 = lua_tonumber (L, -1);
+}
+
/* ===== Cairo ============================================================= */
static void
--
cgit v1.2.3-70-g09d2