|
@@ -166,7 +166,7 @@ static int l_graph_add (lua_State *L)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static int l_graph_iter_next (lua_State *L)
|
|
|
+static int graph_iter_next (lua_State *L)
|
|
|
{
|
|
|
LSUP_GraphIterator *it =
|
|
|
*(LSUP_GraphIterator **)lua_touserdata (L, lua_upvalueindex (1));
|
|
@@ -178,7 +178,6 @@ static int l_graph_iter_next (lua_State *L)
|
|
|
LSUP_rc rc = LSUP_graph_iter_next (it, spo_p);
|
|
|
|
|
|
if (rc == LSUP_END) {
|
|
|
- LSUP_graph_iter_free (it);
|
|
|
lua_pushnil (L);
|
|
|
lua_pushstring (L, "End of lookup results.");
|
|
|
return 2;
|
|
@@ -211,20 +210,116 @@ static int l_graph_lookup (lua_State *L)
|
|
|
LUA_NLCHECK (*it_p, "Error creating graph iterator.");
|
|
|
LOG_DEBUG ("Found triples: %d", ct);
|
|
|
|
|
|
- lua_pushcclosure (L, l_graph_iter_next, 1);
|
|
|
+ lua_pushcclosure (L, graph_iter_next, 1);
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
|
|
|
+static int graph_iter_gc (lua_State *L)
|
|
|
+{
|
|
|
+ LSUP_GraphIterator *it = *(LSUP_GraphIterator **)lua_touserdata (L, 1);
|
|
|
+ LSUP_graph_iter_free (it);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int conn_iter_done (lua_State *L)
|
|
|
+{
|
|
|
+ LSUP_LinkMapIterator *it =
|
|
|
+ *(LSUP_LinkMapIterator **)lua_touserdata (L, lua_upvalueindex (1));
|
|
|
+ LSUP_link_map_iter_free (it);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int lmap_iter_next (lua_State *L)
|
|
|
+{
|
|
|
+ LSUP_LinkMapIterator *it =
|
|
|
+ *(LSUP_LinkMapIterator **)lua_touserdata (L, lua_upvalueindex (1));
|
|
|
+
|
|
|
+ LSUP_Term **link_p = (LSUP_Term **)lua_newuserdata (L, sizeof *link_p);
|
|
|
+ *link_p = NULL;
|
|
|
+ LSUP_TermSet *ts = NULL;
|
|
|
+ LSUP_rc rc = LSUP_link_map_next (it, link_p, &ts);
|
|
|
+
|
|
|
+ if (rc != LSUP_OK) {
|
|
|
+ if (rc == LSUP_END) {
|
|
|
+ LSUP_link_map_iter_free (it);
|
|
|
+ lua_pushnil (L);
|
|
|
+ lua_pushstring (L, "End of the loop.");
|
|
|
+ return 2;
|
|
|
+ }
|
|
|
+ else LUA_PCHECK (rc, "Error iterating through link map");
|
|
|
+ }
|
|
|
+
|
|
|
+ size_t i = 0;
|
|
|
+ LSUP_Term *conn = NULL;
|
|
|
+ lua_newtable (L);
|
|
|
+ while (LSUP_term_set_next (ts, &i, &conn)) {
|
|
|
+ LSUP_Term **conn_p = (LSUP_Term **)lua_newuserdata (L, sizeof *conn_p);
|
|
|
+ *conn_p = conn;
|
|
|
+ lua_pushboolean (L, true);
|
|
|
+ lua_rawset (L, -3);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 2;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int l_lmap_iter_init (lua_State *L)
|
|
|
+{
|
|
|
+ LSUP_LinkMap *lm = *(LSUP_LinkMap **)luaL_checkudata(L, 1, "LSUP.LinkMap");
|
|
|
+
|
|
|
+ LSUP_LinkMapIterator **lmit_p =
|
|
|
+ (LSUP_LinkMapIterator **)lua_newuserdata (L, sizeof *lmit_p);
|
|
|
+ *lmit_p = LSUP_link_map_iter_new (lm);
|
|
|
+ luaL_getmetatable (L, "LSUP.LMapIterator");
|
|
|
+ lua_setmetatable (L, -2);
|
|
|
+ stackDump (L, "After allocating LMIter");
|
|
|
+
|
|
|
+ lua_pushcclosure (L, lmap_iter_next, 1);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/** Returns a LinkMap that can be iterated over with iter().
|
|
|
+ */
|
|
|
static int l_graph_connections (lua_State *L)
|
|
|
{
|
|
|
const LSUP_Graph *gr = check_graph (L);
|
|
|
+ LSUP_Term *t = *(LSUP_Term **)luaL_checkudata (L, 2, "LSUP.Term");
|
|
|
+ const LSUP_LinkType type = luaL_checkinteger (L, 3);
|
|
|
+
|
|
|
+ LSUP_LinkMap **lm_p =
|
|
|
+ (LSUP_LinkMap **)lua_newuserdata (L, sizeof *lm_p);
|
|
|
+ *lm_p = LSUP_graph_connections (gr, t, type);
|
|
|
+ luaL_getmetatable (L, "LSUP.LinkMap");
|
|
|
+ lua_setmetatable (L, -2);
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
|
|
|
+static int link_map_gc (lua_State *L)
|
|
|
+{
|
|
|
+ LSUP_LinkMap *lm = *(LSUP_LinkMap **)lua_touserdata (L, 1);
|
|
|
+ LSUP_link_map_free (lm);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int lmap_iter_gc (lua_State *L)
|
|
|
+{
|
|
|
+ LSUP_LinkMapIterator *it = *(LSUP_LinkMapIterator **)lua_touserdata (L, 1);
|
|
|
+ LSUP_link_map_iter_free (it);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static int l_graph_term_set (lua_State *L)
|
|
|
{
|
|
|
const LSUP_Graph *gr = check_graph (L);
|
|
@@ -293,6 +388,15 @@ static const luaL_Reg graph_lib_meth [] = {
|
|
|
};
|
|
|
|
|
|
|
|
|
+static const LEnumConst graph_enums[] = {
|
|
|
+ {"LINK_INBOUND", LSUP_LINK_INBOUND},
|
|
|
+ {"LINK_OUTBOUND", LSUP_LINK_OUTBOUND},
|
|
|
+ {"LINK_EDGE", LSUP_LINK_EDGE},
|
|
|
+
|
|
|
+ {NULL, 0}
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
int luaopen_lsup_graph (lua_State *L)
|
|
|
{
|
|
|
LSUP_init(); // This is idempotent: no problem calling it multiple times.
|
|
@@ -301,7 +405,18 @@ int luaopen_lsup_graph (lua_State *L)
|
|
|
lua_setfield (L, -2, "__index");
|
|
|
luaL_setfuncs (L, graph_lib_meth, 0);
|
|
|
|
|
|
+ // Metatables for ancillary types.
|
|
|
luaL_newmetatable (L, "LSUP.GraphIterator");
|
|
|
+ lua_pushcfunction (L, graph_iter_gc);
|
|
|
+ lua_setfield (L, -2, "__gc");
|
|
|
+
|
|
|
+ luaL_newmetatable (L, "LSUP.LinkMap");
|
|
|
+ lua_pushcfunction (L, link_map_gc);
|
|
|
+ lua_setfield (L, -2, "__gc");
|
|
|
+
|
|
|
+ luaL_newmetatable (L, "LSUP.LMapIterator");
|
|
|
+ lua_pushcfunction (L, lmap_iter_gc);
|
|
|
+ lua_setfield (L, -2, "__gc");
|
|
|
|
|
|
/*
|
|
|
// Getters table.
|
|
@@ -315,5 +430,8 @@ int luaopen_lsup_graph (lua_State *L)
|
|
|
*/
|
|
|
luaL_newlib (L, graph_lib_fn);
|
|
|
|
|
|
+ // Module-level constants.
|
|
|
+ push_int_const (L, graph_enums);
|
|
|
+
|
|
|
return 1;
|
|
|
}
|