summaryrefslogtreecommitdiff
path: root/graphics/pgf/base/source/InterfaceFromC.c
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/base/source/InterfaceFromC.c')
-rw-r--r--graphics/pgf/base/source/InterfaceFromC.c1189
1 files changed, 0 insertions, 1189 deletions
diff --git a/graphics/pgf/base/source/InterfaceFromC.c b/graphics/pgf/base/source/InterfaceFromC.c
deleted file mode 100644
index b5606f2f39..0000000000
--- a/graphics/pgf/base/source/InterfaceFromC.c
+++ /dev/null
@@ -1,1189 +0,0 @@
-
-// Own header:
-#include <pgf/gd/interface/c/InterfaceFromC.h>
-
-// Lua stuff:
-#include <lauxlib.h>
-
-// C stuff:
-#include <stdlib.h>
-#include <string.h>
-
-
-// Remove once Lua Link Bug is fixed:
-//
-// The following is a hack to avoid a problem with the Lua lib being linked twice.
-// When this happens, two version of "dummynode" exist in Lua and we must ensure that
-// we never create a table using such a dummynode while using a second lib.
-// The following should later be set to 0 and replaced everywhere, once this is fixed.
-#define MIN_HASH_SIZE_FIX 1
-
-
-
-// Help functions
-
-static void set_field (lua_State* L, const char* what, const char* where)
-{
- if (what) {
- lua_pushstring(L, what);
- lua_setfield(L, -2, where);
- }
-}
-
-
-static void init_vertex_array(pgfgd_Vertex_array* a, int count)
-{
- a->length = count;
- a->array = (pgfgd_Vertex**) calloc(count, sizeof(pgfgd_Vertex*));
-}
-
-static void init_edge_array(pgfgd_Edge_array* a, int count)
-{
- a->length = count;
- a->array = (pgfgd_Edge**) calloc(count, sizeof(pgfgd_Edge*));
-}
-
-static void init_arcs_array(pgfgd_Arc_array* arcs, int length)
-{
- arcs->length = length;
- arcs->tails = (int*) calloc(length, sizeof(int));
- arcs->heads = (int*) calloc(length, sizeof(int));
-}
-
-static void init_path(pgfgd_Path* a, int count)
-{
- a->length = count;
- a->coordinates = (pgfgd_Coordinate*) calloc(count, sizeof(pgfgd_Coordinate));
- a->strings = (char**) calloc(count, sizeof(char*));
-}
-
-static void clear_path(pgfgd_Path* p)
-{
- int i;
- for (i=0; i < p->length; i++)
- free(p->strings[i]);
-
- free(p->strings);
- free(p->coordinates);
-
- p->length = 0;
- p->strings = 0;
- p->coordinates = 0;
-}
-
-
-
-// Option handling
-
-struct pgfgd_OptionTable {
- lua_State* state;
-
- int kind;
- int index;
-};
-
-// These are the indices of the parameters during a run of the main
-// algorithm:
-#define GRAPH_INDEX 1
-#define VERTICES_INDEX 2
-#define EDGES_INDEX 3
-#define ALGORITHM_INDEX 4
-
-// This is the index of a special table mapping vertices back to the
-// index they have. It is created in the C code, but stays on the
-// stack during the computations.
-#define BACKINDEX_STORAGE_INDEX 5
-
-// These are the positions of different upvalues for the C closure of
-// a C algorithm.
-#define FUNCTION_UPVALUE 1
-#define USER_UPVALUE 2
-#define DIGRAPH_OBJECT_UPVALUE 3
-
-
-static pgfgd_OptionTable* make_option_table(lua_State* L, int kind, int index)
-{
- pgfgd_OptionTable* t = (pgfgd_OptionTable*) malloc(sizeof(pgfgd_OptionTable));
-
- t->state = L;
- t->kind = kind;
- t->index = index;
-
- return t;
-}
-
-static void push_option_table(pgfgd_OptionTable* t)
-{
- switch (t->kind) {
- case GRAPH_INDEX:
- lua_getfield(t->state, GRAPH_INDEX, "options");
- break;
- case VERTICES_INDEX:
- lua_rawgeti(t->state, VERTICES_INDEX, t->index);
- lua_getfield(t->state, -1, "options");
- lua_replace(t->state, -2);
- break;
- case EDGES_INDEX:
- lua_rawgeti(t->state, EDGES_INDEX, t->index);
- lua_getfield(t->state, -1, "options");
- lua_replace(t->state, -2);
- break;
- }
-}
-
-int pgfgd_isset(pgfgd_OptionTable* t, const char* key)
-{
- push_option_table(t);
- lua_getfield(t->state, -1, key);
- int is_nil = lua_isnil(t->state, -1);
- lua_pop(t->state, 2);
- return !is_nil;
-}
-
-int pgfgd_isnumber(pgfgd_OptionTable* t, const char* key)
-{
- push_option_table(t);
- lua_getfield(t->state, -1, key);
- int is_number = lua_isnumber(t->state, -1);
- lua_pop(t->state, 2);
- return is_number;
-}
-
-int pgfgd_isboolean(pgfgd_OptionTable* t, const char* key)
-{
- push_option_table(t);
- lua_getfield(t->state, -1, key);
- int is_bool = lua_isboolean(t->state, -1);
- lua_pop(t->state, 2);
- return is_bool;
-}
-
-int pgfgd_isstring(pgfgd_OptionTable* t, const char* key)
-{
- push_option_table(t);
- lua_getfield(t->state, -1, key);
- int is_string = lua_isstring(t->state, -1);
- lua_pop(t->state, 2);
- return is_string;
-}
-
-int pgfgd_isuser(pgfgd_OptionTable* t, const char* key)
-{
- push_option_table(t);
- lua_getfield(t->state, -1, key);
- int is_user = lua_isuserdata(t->state, -1);
- lua_pop(t->state, 2);
- return is_user;
-}
-
-
-double pgfgd_tonumber(pgfgd_OptionTable* t, const char* key)
-{
- push_option_table(t);
- lua_getfield(t->state, -1, key);
- double d = lua_tonumber(t->state, -1);
- lua_pop(t->state, 2);
- return d;
-}
-
-int pgfgd_toboolean(pgfgd_OptionTable* t, const char* key)
-{
- push_option_table(t);
- lua_getfield(t->state, -1, key);
- int d = lua_toboolean(t->state, -1);
- lua_pop(t->state, 2);
- return d;
-}
-
-char* pgfgd_tostring(pgfgd_OptionTable* t, const char* key)
-{
- push_option_table(t);
- lua_getfield(t->state, -1, key);
- const char* s = lua_tostring(t->state, -1);
- char* copy = strcpy((char*) malloc(strlen(s)+1), s);
- lua_pop(t->state, 2);
- return copy;
-}
-
-void* pgfgd_touser(pgfgd_OptionTable* t, const char* key)
-{
- push_option_table(t);
- lua_getfield(t->state, -1, key);
- void* d = lua_touserdata(t->state, -1);
- lua_pop(t->state, 2);
- return d;
-}
-
-
-// Handling algorithms
-
-struct pgfgd_SyntacticDigraph_internals {
- lua_State* state;
-};
-
-static char* make_string_from(lua_State* L, const char* name)
-{
- lua_getfield(L, -1, name);
- if (lua_isnil(L, -1)) {
- // Field not set; return emtpy string.
- lua_pop(L, 1);
- return (char*) calloc(1, sizeof(char));
- }
- else {
- const char* s = lua_tostring(L, -1);
- char* copy = strcpy((char*) malloc(strlen(s)+1), s);
- lua_pop(L, 1);
- return copy;
- }
-}
-
-static void make_coordinate(lua_State* L, pgfgd_Coordinate* c)
-{
- lua_getfield(L, -1, "x");
- c->x = lua_tonumber(L, -1);
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "y");
- c->y = lua_tonumber(L, -1);
- lua_pop(L, 1);
-}
-
-static pgfgd_Path* make_empty_path(lua_State* L)
-{
- return (pgfgd_Path*) calloc(1, sizeof(pgfgd_Path));
-}
-
-static pgfgd_Path* make_path(lua_State* L)
-{
- /* Path object must be on top of stack. */
- pgfgd_Path* p = make_empty_path(L);
-
- // Fill path:
- int path_length = lua_rawlen(L, -1);
- if (path_length > 0) {
- init_path(p, path_length);
- int i;
- for (i = 0; i < path_length; i++) {
- lua_rawgeti(L, -1, i+1);
- if (lua_isstring(L, -1)) {
- const char* s = lua_tostring(L, -1);
- p->strings[i] = strcpy((char*) malloc(strlen(s)+1), s);
- } else {
- lua_getfield(L, -1, "x");
- p->coordinates[i].x = lua_tonumber(L, -1);
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "y");
- p->coordinates[i].y = lua_tonumber(L, -1);
- lua_pop(L, 1);
- }
- lua_pop(L, 1);
- }
- }
-
- return p;
-}
-
-static void construct_digraph(lua_State* L, pgfgd_SyntacticDigraph* d)
-{
- d->internals = (pgfgd_SyntacticDigraph_internals*) calloc(1, sizeof(pgfgd_SyntacticDigraph_internals));
- d->internals->state = L;
-
- // Create the options table:
- d->options = make_option_table(L, GRAPH_INDEX, 0);
-
- // Create the vertex table
- init_vertex_array(&d->vertices, lua_rawlen(L, VERTICES_INDEX));
-
- // Create the vertices
- int i;
- for (i=0; i<d->vertices.length; i++) {
- pgfgd_Vertex* v = (pgfgd_Vertex*) calloc(1, sizeof(pgfgd_Vertex));
-
- // Push the vertex onto the Lua stack:
- lua_rawgeti(L, VERTICES_INDEX, i+1);
-
- // Fill v with information:
- v->name = make_string_from(L, "name");
- v->shape = make_string_from(L, "shape");
- v->kind = make_string_from(L, "kind");
-
- // Options:
- v->options = make_option_table(L, VERTICES_INDEX, i+1);
-
- // Index:
- v->array_index = i;
-
- // Setup pos field
- lua_getfield(L, -1, "pos");
- make_coordinate(L, &v->pos);
- lua_pop(L, 1);
-
- // Setup path array:
- lua_getfield(L, -1, "path");
- v->path = make_path(L);
- lua_pop(L, 1);
-
- // Pop the vertex
- lua_pop(L, 1);
-
- d->vertices.array[i] = v;
- }
-
- // Construct the edges:
- init_edge_array(&d->syntactic_edges, lua_rawlen(L, EDGES_INDEX));
-
- int edge_index;
- for (edge_index = 0; edge_index < d->syntactic_edges.length; edge_index++) {
- pgfgd_Edge* e = (pgfgd_Edge*) calloc(1, sizeof(pgfgd_Edge));
-
- lua_rawgeti(L, EDGES_INDEX, edge_index+1);
-
- e->direction = make_string_from(L, "direction");
- e->options = make_option_table(L, EDGES_INDEX, edge_index+1);
-
- // Index:
- e->array_index = edge_index;
-
- // Compute the tail vertex index:
- lua_getfield(L, -1, "tail");
- lua_gettable(L, VERTICES_INDEX);
- e->tail = d->vertices.array[lua_tointeger(L, -1) - 1];
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "head");
- lua_gettable(L, VERTICES_INDEX);
- e->head = d->vertices.array[lua_tointeger(L, -1) - 1];
- lua_pop(L, 1);
-
- // Fill path:
- e->path = make_empty_path(L);
- e->path->length = -1; // Means that a default path should be created.
-
- // Pop the edge form the Lua stack:
- lua_pop(L, 1);
-
- d->syntactic_edges.array[edge_index] = e;
- }
-}
-
-
-static void sync_digraph(lua_State* L, pgfgd_SyntacticDigraph* d)
-{
- // Writes back the computed position information to the digraph:
- int i;
- for (i=0; i<d->vertices.length; i++) {
-
- // Push pos field of vertex:
- lua_rawgeti(L, VERTICES_INDEX, i+1);
- lua_getfield(L, -1, "pos");
-
- // Set x and y coordinates:
- pgfgd_Vertex* v = d->vertices.array[i];
- lua_pushnumber(L, v->pos.x);
- lua_setfield(L, -2, "x");
- lua_pushnumber(L, v->pos.y);
- lua_setfield(L, -2, "y");
-
- // pop pos and vertex
- lua_pop(L, 2);
- }
-
- // Write back the paths
-
- int tos = lua_gettop(L);
-
- // First, get "Coordinate.new" as a "local"
- lua_getglobal(L, "require");
- lua_pushstring(L, "pgf.gd.model.Path");
- lua_call(L, 1, 1);
- int Path_index = lua_gettop(L);
-
- lua_getglobal(L, "require");
- lua_pushstring(L, "pgf.gd.model.Coordinate");
- lua_call(L, 1, 1);
- lua_getfield(L, -1, "new");
-
- int Coordinate_new_index = lua_gettop(L);
-
- for (i=0; i < d->syntactic_edges.length; i++) {
- pgfgd_Edge* e = d->syntactic_edges.array[i];
-
- lua_rawgeti(L, EDGES_INDEX, i+1);
-
- if (e->path->length == -1) {
- // Create default path
- pgfgd_path_append_moveto_tail(e);
- pgfgd_path_append_lineto_head(e);
- }
-
- lua_createtable(L, e->path->length ? e->path->length : 1, MIN_HASH_SIZE_FIX);
- lua_pushvalue(L, Path_index);
- lua_setmetatable(L, -2);
-
- int j;
- for (j=0; j<e->path->length; j++) {
- if (e->path->strings[j]) {
- lua_pushstring(L, e->path->strings[j]);
- lua_rawseti(L, -2, j+1);
- } else {
- lua_pushvalue(L, Coordinate_new_index);
- lua_pushnumber(L, e->path->coordinates[j].x);
- lua_pushnumber(L, e->path->coordinates[j].y);
- lua_call(L, 2, 1);
-
- lua_rawseti(L, -2, j+1);
- }
- }
-
- lua_setfield(L, -2, "path");
- lua_pop(L, 1); // The edge object
- }
-
- lua_settop(L, tos); // Cleanup
-}
-
-
-static void free_digraph(pgfgd_SyntacticDigraph* digraph)
-{
- int i;
- for (i=0; i < digraph->vertices.length; i++) {
- pgfgd_Vertex* v = digraph->vertices.array[i];
-
- clear_path(v->path);
- free(v->path);
- free(v->name);
- free(v->shape);
- free(v->kind);
- free(v->options);
- free(v->incoming.array);
- free(v->outgoing.array);
- free(v);
- }
-
- for (i=0; i < digraph->syntactic_edges.length; i++) {
- pgfgd_Edge* e = digraph->syntactic_edges.array[i];
-
- clear_path(e->path);
- free(e->path);
- free(e->direction);
- free(e->options);
- free(e);
- }
-
- free(digraph->vertices.array);
- free(digraph->syntactic_edges.array);
- free(digraph->options);
- free(digraph->internals);
- free(digraph);
-}
-
-static int algorithm_dispatcher(lua_State* L)
-{
- // Create the back index table. It will be at index BACKINDEX_STORAGE_INDEX
- lua_createtable(L, 0, MIN_HASH_SIZE_FIX);
-
- // The actual function is stored in an upvalue.
- pgfgd_SyntacticDigraph* digraph = (pgfgd_SyntacticDigraph*) calloc(1, sizeof(pgfgd_SyntacticDigraph));
-
- construct_digraph(L, digraph);
-
- pgfgd_algorithm_fun fun = lua_touserdata(L, lua_upvalueindex(FUNCTION_UPVALUE));
- fun(digraph, lua_touserdata(L, lua_upvalueindex(USER_UPVALUE)));
-
- sync_digraph(L, digraph);
-
- free_digraph(digraph);
-
- return 0;
-}
-
-
-int pgfgd_vertex_anchor(pgfgd_Vertex* v, const char* anchor, double* x, double* y)
-{
- lua_State* L = v->options->state;
-
- // Ok, first, find the vertex:
- lua_rawgeti(L, VERTICES_INDEX, v->array_index+1);
-
- // Find the anchor function:
- lua_getfield(L, -1, "anchor");
- lua_pushvalue(L, -2);
- lua_pushstring(L, anchor);
-
- // Find the anchor:
- lua_call(L, 2, 1);
-
- if (lua_isnil(L, -1)) {
- // Failed. Cleanup!
- lua_pop(L, 2);
- *x = 0;
- *y = 0;
- return 0;
- } else {
- lua_getfield(L, -1, "x");
- *x = lua_tonumber(L, -1);
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "y");
- *y = lua_tonumber(L, -1);
- lua_pop(L, 1);
-
- lua_pop(L, 2);
- return 1;
- }
- return 0;
-}
-
-
-
-void pgfgd_path_clear(pgfgd_Edge* e)
-{
- clear_path (e->path);
-}
-
-static void path_add_segment(pgfgd_Edge* edge, const char* s, int num, double a, double b, double c, double d, double e, double f)
-{
- if (edge->path->length == -1)
- pgfgd_path_clear(edge);
-
- int start = edge->path->length;
-
- edge->path->length += num + 1;
- edge->path->strings = (char **)
- realloc(edge->path->strings, edge->path->length*sizeof(char*));
- edge->path->coordinates = (pgfgd_Coordinate*)
- realloc(edge->path->coordinates, edge->path->length*sizeof(pgfgd_Coordinate));
-
- edge->path->coordinates[start].x = 0;
- edge->path->coordinates[start].y = 0;
- edge->path->strings[start] = strcpy((char*) malloc(strlen(s)+1), s);
-
- if (num > 0) {
- edge->path->coordinates[start+1].x = a;
- edge->path->coordinates[start+1].y = b;
- edge->path->strings[start+1] = 0;
- }
-
- if (num > 1) {
- edge->path->coordinates[start+2].x = c;
- edge->path->coordinates[start+2].y = d;
- edge->path->strings[start+2] = 0;
- }
-
- if (num > 2) {
- edge->path->coordinates[start+3].x = e;
- edge->path->coordinates[start+3].y = f;
- edge->path->strings[start+3] = 0;
- }
-}
-
-
-void pgfgd_path_append_moveto(pgfgd_Edge* e, double x, double y)
-{
- path_add_segment(e, "moveto", 1, x, y, 0, 0, 0, 0);
-}
-
-void pgfgd_path_append_moveto_tail (pgfgd_Edge* e)
-{
- double x, y;
- char* tail_anchor = pgfgd_tostring(e->tail->options, "tail anchor");
-
- pgfgd_vertex_anchor(e->tail, tail_anchor, &x, &y);
- x += e->tail->pos.x;
- y += e->tail->pos.y;
-
- pgfgd_path_append_moveto(e, x, y);
- free(tail_anchor);
-}
-
-void pgfgd_path_append_lineto(pgfgd_Edge* e, double x, double y)
-{
- path_add_segment(e, "lineto", 1, x, y, 0, 0, 0, 0);
-}
-
-void pgfgd_path_append_lineto_head (pgfgd_Edge* e)
-{
- double x, y;
- char* head_anchor = pgfgd_tostring(e->head->options, "head anchor");
-
- pgfgd_vertex_anchor(e->head, head_anchor, &x, &y);
- x += e->head->pos.x;
- y += e->head->pos.y;
-
- pgfgd_path_append_lineto(e, x, y);
- free(head_anchor);
-}
-
-void pgfgd_path_append_curveto(pgfgd_Edge* edge, double a, double b, double c, double d, double e, double f)
-{
- path_add_segment(edge, "curveto", 3, a, b, c, d, e, f);
-}
-
-void pgfgd_path_append_closepath(pgfgd_Edge* e)
-{
- path_add_segment(e, "closepath", 0, 0, 0, 0, 0, 0, 0);
-}
-
-
-
-// Handling digraphs
-
-struct pgfgd_Digraph {
- lua_State* state;
- const char* name;
- pgfgd_SyntacticDigraph* syntactic_digraph;
-};
-
-
-pgfgd_Digraph* pgfgd_get_digraph (pgfgd_SyntacticDigraph* g, const char* graph_name)
-{
- lua_State* L = g->internals->state;
-
- lua_getfield(L, ALGORITHM_INDEX, graph_name);
- if (lua_isnil(L, -1))
- luaL_error(L, "digraph named %s not found in algorithm class", graph_name);
- lua_pop(L, 1);
-
- pgfgd_Digraph* new = (pgfgd_Digraph*) calloc(1, sizeof(pgfgd_Digraph));
-
- new->state = L;
- new->name = graph_name;
- new->syntactic_digraph = g;
-
- return new;
-}
-
-int pgfgd_digraph_num_vertices (pgfgd_Digraph* g)
-{
- lua_getfield(g->state, ALGORITHM_INDEX, g->name);
- lua_getfield(g->state, -1, "vertices");
- int num = lua_rawlen(g->state, -1);
- lua_pop(g->state, 2);
-
- return num;
-}
-
-static void push_digraph_and_backindex(pgfgd_Digraph* g)
-{
- lua_State* L = g->state;
-
- // Get digraph
- lua_getfield(L, ALGORITHM_INDEX, g->name);
- int digraph_pos = lua_gettop(L);
-
- // Get entry in back index table
- lua_pushvalue(L, digraph_pos);
- lua_gettable(L, BACKINDEX_STORAGE_INDEX);
- int backtable_pos = lua_gettop(L);
- if (lua_isnil(L, backtable_pos)) {
- // Aha. We need to install a new table:
- lua_pop(L, 1); // Get rid of nil
-
- lua_createtable(L, 0, MIN_HASH_SIZE_FIX);
-
- lua_pushvalue(L, digraph_pos); // The digraph object
- lua_pushvalue(L, backtable_pos); // The new table
- lua_settable(L, BACKINDEX_STORAGE_INDEX);
-
- // Fill the table:
- lua_getfield(L, digraph_pos, "vertices");
- int vertex_pos = lua_gettop(L);
- int i;
- int n = lua_rawlen(L, -1);
- for (i = 1; i <= n; i++) {
- lua_rawgeti(L, vertex_pos, i);
- lua_pushinteger(L, i);
- lua_settable(L, backtable_pos);
- }
- lua_pop(L, 1);
- }
-}
-
-static pgfgd_Arc_array* build_c_array_of_arcs_from_lua_array_of_arcs(pgfgd_Digraph* g)
-{
- lua_State* L = g->state;
-
- pgfgd_Arc_array* arcs = (pgfgd_Arc_array*) calloc(1, sizeof(pgfgd_Arc_array));
-
- int array_pos = lua_gettop(L);
-
- push_digraph_and_backindex(g);
- int backtable_pos = lua_gettop(L);
-
- // Get number of arcs:
- init_arcs_array(arcs, lua_rawlen(L, array_pos));
- int i;
- for (i = 1; i<=arcs->length; i++) {
- lua_rawgeti(L, array_pos, i); // Get arcs[i]
-
- // The tail field:
- lua_getfield(L, -1, "tail");
- lua_gettable(L, backtable_pos);
-
- arcs->tails[i-1] = lua_tointeger(L, -1);
- lua_pop(L, 1); // The number
-
- // The head field:
- lua_getfield(L, -1, "head");
- lua_gettable(L, backtable_pos);
- arcs->heads[i-1] = lua_tointeger(L, -1);
- lua_pop(L, 1); // The number
-
- lua_pop(L, 1); // Pop arcs[i]
- }
-
- lua_settop(L, array_pos);
-
- return arcs;
-}
-
-
-pgfgd_Arc_array* pgfgd_digraph_arcs (pgfgd_Digraph* g)
-{
- lua_getfield(g->state, ALGORITHM_INDEX, g->name);
- lua_getfield(g->state, -1, "arcs");
-
- pgfgd_Arc_array* a = build_c_array_of_arcs_from_lua_array_of_arcs(g);
-
- lua_pop(g->state, 2);
-
- return a;
-}
-
-
-pgfgd_Vertex* pgfgd_digraph_syntactic_vertex (pgfgd_Digraph* g, int v)
-{
- int tos = lua_gettop(g->state);
- pgfgd_Vertex* return_me = 0;
-
- lua_getfield(g->state, ALGORITHM_INDEX, g->name);
- lua_getfield(g->state, -1, "vertices");
- lua_rawgeti(g->state, -1, v);
-
- lua_gettable(g->state, VERTICES_INDEX);
- if (lua_isnumber(g->state, -1)) {
- return_me = g->syntactic_digraph->vertices.array[lua_tointeger(g->state, -1)-1];
- }
-
- lua_settop(g->state, tos);
- return return_me;
-}
-
-
-int pgfgd_digraph_isarc (pgfgd_Digraph* g, int tail, int head)
-{
- lua_State* L = g->state;
- int is_arc = 0;
-
- lua_getfield(L, ALGORITHM_INDEX, g->name);
- int digraph_pos = lua_gettop(L);
-
- lua_getfield(L, digraph_pos, "vertices");
- int vertices_pos = lua_gettop(L);
-
- // Call digraph:connected(tail, head)
- lua_pushvalue(L, lua_upvalueindex(DIGRAPH_OBJECT_UPVALUE));
- lua_getfield(L, -1, "arc");
- lua_pushvalue(L, digraph_pos);
- lua_rawgeti(L, vertices_pos, tail);
- lua_rawgeti(L, vertices_pos, head);
- lua_call(L, 3, 1);
-
- is_arc = !lua_isnil(L, -1);
-
- lua_settop(L, digraph_pos-1);
-
- return is_arc;
-}
-
-pgfgd_Arc_array* pgfgd_digraph_incoming (pgfgd_Digraph* g, int v)
-{
- lua_State* L = g->state;
-
- lua_getfield(L, ALGORITHM_INDEX, g->name);
- int digraph_pos = lua_gettop(L);
-
- lua_getfield(L, digraph_pos, "vertices");
- int vertices_pos = lua_gettop(L);
-
- // Call digraph:connected(tail, head)
- lua_pushvalue(L, lua_upvalueindex(DIGRAPH_OBJECT_UPVALUE));
- lua_getfield(L, -1, "incoming");
- lua_pushvalue(L, digraph_pos);
- lua_rawgeti(L, vertices_pos, v);
- lua_call(L, 2, 1);
-
- pgfgd_Arc_array* a = build_c_array_of_arcs_from_lua_array_of_arcs(g);
-
- lua_settop(L, digraph_pos-1);
-
- return a;
-}
-
-pgfgd_Arc_array* pgfgd_digraph_outgoing (pgfgd_Digraph* g, int v)
-{
- lua_State* L = g->state;
-
- lua_getfield(L, ALGORITHM_INDEX, g->name);
- int digraph_pos = lua_gettop(L);
-
- lua_getfield(L, digraph_pos, "vertices");
- int vertices_pos = lua_gettop(L);
-
- // Call digraph:connected(tail, head)
- lua_pushvalue(L, lua_upvalueindex(DIGRAPH_OBJECT_UPVALUE));
- lua_getfield(L, -1, "outgoing");
- lua_pushvalue(L, digraph_pos);
- lua_rawgeti(L, vertices_pos, v);
- lua_call(L, 2, 1);
-
- pgfgd_Arc_array* a = build_c_array_of_arcs_from_lua_array_of_arcs(g);
-
- lua_settop(L, digraph_pos-1);
-
- return a;
-}
-
-pgfgd_Edge_array* pgfgd_digraph_syntactic_edges (pgfgd_Digraph* g, int tail, int head)
-{
- pgfgd_Edge_array* edges = (pgfgd_Edge_array*) calloc(1, sizeof(pgfgd_Edge_array));
-
- // First, get the arc in the syntatic digraph.
- lua_State* L = g->state;
- int tos = lua_gettop(L);
-
- lua_getfield(L, ALGORITHM_INDEX, g->name);
- int digraph_pos = lua_gettop(L);
-
- lua_getfield(L, digraph_pos, "vertices");
- int vertices_pos = lua_gettop(L);
-
- // Call digraph:arc(tail, head)
- lua_pushvalue(L, lua_upvalueindex(DIGRAPH_OBJECT_UPVALUE));
- int digraph_class_index = lua_gettop(L);
-
- lua_getfield(L, digraph_class_index, "arc");
- lua_pushvalue(L, digraph_pos);
- lua_rawgeti(L, vertices_pos, tail);
- lua_rawgeti(L, vertices_pos, head);
- lua_call(L, 3, 1);
-
- if (!lua_isnil(L, -1)) {
- // Get syntactic_digraph of the arc:
- lua_getfield(L, -1, "syntactic_digraph");
-
- // Call syntactic_digraph:arc(tail, head)
- lua_getfield(L, digraph_class_index, "arc");
- lua_pushvalue(L, -2);
- lua_rawgeti(L, vertices_pos, tail);
- lua_rawgeti(L, vertices_pos, head);
- lua_call(L, 3, 1);
-
- if (!lua_isnil(L, -1)) {
- lua_getfield(L, -1, "syntactic_edges");
- int syntactic_edges_index = lua_gettop(L);
-
- int n = lua_rawlen(L, syntactic_edges_index);
- init_edge_array(edges, n);
- int i;
- for (i=1; i<=n; i++) {
- lua_rawgeti(L, syntactic_edges_index, i);
- lua_gettable(L, EDGES_INDEX);
- if (!lua_isnumber(L, -1)) {
- pgfgd_digraph_free_edge_array(edges);
- luaL_error(L, "syntactic edge index not found");
- }
- int p = lua_tonumber(L, -1);
- edges->array[i-1] = g->syntactic_digraph->syntactic_edges.array[p-1];
- }
- }
- }
-
- lua_settop(L, tos);
-
- return edges;
-}
-
-
-
-void pgfgd_digraph_free (pgfgd_Digraph* g)
-{
- free(g);
-}
-
-void pgfgd_digraph_free_arc_array (pgfgd_Arc_array* arcs)
-{
- free (arcs->tails);
- free (arcs->heads);
- free (arcs);
-}
-
-void pgfgd_digraph_free_edge_array (pgfgd_Edge_array* edges)
-{
- free (edges->array);
- free (edges);
-}
-
-
-
-// Handling declarations
-
-
-struct pgfgd_Declaration {
- const char* key;
- const char* summary;
- const char* type;
- const char* initial;
- void* initial_user;
- const char* default_value;
- const char* alias;
- const char* alias_function_string;
- const char* documentation;
- const char* documentation_in;
- pgfgd_algorithm_fun algorithm;
- void* algorithm_user;
- const char* phase;
-
- int use_length;
- const char** use_keys;
- const char** use_values_strings;
- void** use_values_user;
-
- int examples_length;
- const char** examples;
-
- int pre_length;
- const char** pre;
-
- int post_length;
- const char** post;
-};
-
-
-pgfgd_Declaration* pgfgd_new_key (const char* key)
-{
- pgfgd_Declaration* d = (pgfgd_Declaration*) calloc(1, sizeof(pgfgd_Declaration));
-
- d->key = key;
-
- return d;
-}
-
-void pgfgd_declare(struct lua_State* state, pgfgd_Declaration* d)
-{
- if (d && d->key) {
- int tos = lua_gettop(state);
-
- lua_gc(state, LUA_GCSTOP, 0); // Remove once Lua Link Bug is fixed
-
- // Find declare function:
- lua_getglobal(state, "require");
- lua_pushstring(state, "pgf.gd.interface.InterfaceToAlgorithms");
- lua_call(state, 1, 1);
- lua_getfield(state, -1, "declare");
-
- // Build a Lua table:
- lua_createtable(state, 0, 11);
-
- set_field (state, d->key, "key");
- set_field (state, d->summary, "summary");
- set_field (state, d->type, "type");
- set_field (state, d->initial, "initial");
- set_field (state, d->documentation, "documentation");
- set_field (state, d->documentation_in, "documentation_in");
- set_field (state, d->default_value, "default");
- set_field (state, d->alias, "alias");
- set_field (state, d->alias_function_string, "alias_function_string");
- set_field (state, d->phase, "phase");
-
- if (d->initial_user) {
- lua_pushlightuserdata(state, d->initial_user);
- lua_setfield(state, -2, "initial");
- }
-
- if (d->use_length > 0) {
- lua_createtable(state, d->use_length, MIN_HASH_SIZE_FIX);
- int i;
- for (i=0; i < d->use_length; i++) {
- lua_createtable(state, 0, 2);
- set_field(state, d->use_keys[i], "key");
- if (d->use_values_strings[i])
- set_field(state, d->use_values_strings[i], "value");
- if (d->use_values_user[i]) {
- lua_pushlightuserdata(state, d->use_values_user[i]);
- lua_setfield(state, -2, "value");
- }
- lua_rawseti(state, -2, i+1);
- }
- lua_setfield(state, -2, "use");
- }
-
- if (d->pre) {
- lua_createtable(state, 0, d->pre_length);
- int i;
- for (i=0; i < d->pre_length; i++) {
- lua_pushboolean(state, 1);
- lua_setfield(state, -2, d->pre[i]);
- }
- lua_setfield(state, -2, "preconditions");
- }
-
- if (d->post) {
- lua_createtable(state, 0, d->post_length);
- int i;
- for (i=0; i < d->post_length; i++) {
- lua_pushboolean(state, 1);
- lua_setfield(state, -2, d->post[i]);
- }
- lua_setfield(state, -2, "postconditions");
- }
-
- if (d->examples) {
- lua_createtable(state, d->examples_length, MIN_HASH_SIZE_FIX);
- int i;
- for (i=0; i < d->examples_length; i++) {
- lua_pushstring(state, d->examples[i]);
- lua_rawseti(state, -2, i+1);
- }
- lua_setfield(state, -2, "examples");
- }
-
- if (d->algorithm) {
- // The algorithm function and the user data is stored as lightuserdate upvalue
- lua_pushlightuserdata(state, (void *) d->algorithm);
- lua_pushlightuserdata(state, (void *) d->algorithm_user);
-
- // Find the Digraph.arc function and store it as the second upvalue:
- lua_getglobal(state, "require");
- lua_pushstring(state, "pgf.gd.model.Digraph");
- lua_call(state, 1, 1);
-
- lua_pushcclosure(state, algorithm_dispatcher, 3);
- lua_setfield(state, -2, "algorithm_written_in_c");
- }
-
- // Call the declare function:
- lua_call(state, 1, 0);
-
- // Cleanup:
- lua_settop(state, tos);
-
- lua_gc(state, LUA_GCRESTART, 0); // Remove once Lua Link Bug is fixed
- }
-}
-
-void pgfgd_key_add_use(pgfgd_Declaration* d, const char* key, const char* value)
-{
- d->use_length++;
- d->use_keys = (const char **) realloc(d->use_keys, d->use_length*sizeof(const char*));
- d->use_values_strings = (const char **) realloc(d->use_values_strings, d->use_length*sizeof(const char*));
- d->use_values_user = (void **) realloc(d->use_values_user, d->use_length*sizeof(void*));
-
- d->use_keys [d->use_length-1] = key;
- d->use_values_strings[d->use_length-1] = value;
- d->use_values_user [d->use_length-1] = 0;
-}
-
-void pgfgd_key_add_use_user(pgfgd_Declaration* d, const char* key, void* value)
-{
- d->use_length++;
- d->use_keys = (const char **) realloc(d->use_keys, d->use_length*sizeof(const char*));
- d->use_values_strings = (const char **) realloc(d->use_values_strings, d->use_length*sizeof(const char*));
- d->use_values_user = (void **) realloc(d->use_values_user, d->use_length*sizeof(void*));
-
- d->use_keys [d->use_length-1] = key;
- d->use_values_strings[d->use_length-1] = 0;
- d->use_values_user [d->use_length-1] = value;
-}
-
-void pgfgd_key_add_example(pgfgd_Declaration* d, const char* s)
-{
- d->examples_length++;
- d->examples = (const char **) realloc(d->examples, d->examples_length*sizeof(const char*));
-
- d->examples[d->examples_length-1] = s;
-}
-
-void pgfgd_key_add_precondition(pgfgd_Declaration* d, const char* s)
-{
- d->pre_length++;
- d->pre = (const char **) realloc(d->pre, d->pre_length*sizeof(const char*));
-
- d->pre[d->pre_length-1] = s;
-}
-
-void pgfgd_key_add_postcondition(pgfgd_Declaration* d, const char* s)
-{
- d->post_length++;
- d->post = (const char **) realloc(d->post, d->post_length*sizeof(const char*));
-
- d->post[d->post_length-1] = s;
-}
-
-void pgfgd_key_summary(pgfgd_Declaration* d, const char* s)
-{
- d->summary = s;
-}
-
-void pgfgd_key_type(pgfgd_Declaration* d, const char* s)
-{
- d->type = s;
-}
-
-void pgfgd_key_initial(pgfgd_Declaration* d, const char* s)
-{
- d->initial = s;
-}
-
-void pgfgd_key_initial_user(pgfgd_Declaration* d, void* s)
-{
- d->initial_user = s;
-}
-
-void pgfgd_key_default(pgfgd_Declaration* d, const char* s)
-{
- d->default_value = s;
-}
-
-void pgfgd_key_alias(pgfgd_Declaration* d, const char* s)
-{
- d->alias = s;
-}
-
-void pgfgd_key_alias_function(pgfgd_Declaration* d, const char* s)
-{
- d->alias_function_string = s;
-}
-
-void pgfgd_key_documentation(pgfgd_Declaration* d, const char* s)
-{
- d->documentation = s;
-}
-
-void pgfgd_key_documentation_in(pgfgd_Declaration* d, const char* s)
-{
- d->documentation_in = s;
-}
-
-void pgfgd_key_phase(pgfgd_Declaration* d, const char* s)
-{
- d->phase = s;
-}
-
-void pgfgd_key_algorithm(pgfgd_Declaration* d, pgfgd_algorithm_fun f, void* user_data)
-{
- d->algorithm = f;
- d->algorithm_user = user_data;
-}
-
-void pgfgd_free_key(pgfgd_Declaration* d)
-{
- if (d) {
- free(d->examples);
- free(d->use_keys);
- free(d->use_values_user);
- free(d->use_values_strings);
- free(d);
- }
-}