correct tree reconstruction using a node stack
This commit is contained in:
260
cyberiadaml.c
260
cyberiadaml.c
@@ -209,7 +209,6 @@ int cyberiada_init_sm(CyberiadaSM* sm)
|
|||||||
sm->version = NULL;
|
sm->version = NULL;
|
||||||
sm->version_len = 0;
|
sm->version_len = 0;
|
||||||
sm->nodes = NULL;
|
sm->nodes = NULL;
|
||||||
sm->start = NULL;
|
|
||||||
sm->edges = NULL;
|
sm->edges = NULL;
|
||||||
}
|
}
|
||||||
return CYBERIADA_NO_ERROR;
|
return CYBERIADA_NO_ERROR;
|
||||||
@@ -336,9 +335,93 @@ const char* debug_state_names[] = {
|
|||||||
"Invalid"
|
"Invalid"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _NodeStack {
|
||||||
|
const char* xml_element;
|
||||||
|
CyberiadaNode* node;
|
||||||
|
struct _NodeStack* next;
|
||||||
|
} NodeStack;
|
||||||
|
|
||||||
|
static int node_stack_push(NodeStack** stack)
|
||||||
|
{
|
||||||
|
NodeStack* new_item = (NodeStack*)malloc(sizeof(NodeStack));
|
||||||
|
new_item->xml_element = NULL;
|
||||||
|
new_item->node = NULL;
|
||||||
|
new_item->next = (*stack);
|
||||||
|
*stack = new_item;
|
||||||
|
return CYBERIADA_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int node_stack_set_top_node(NodeStack** stack, CyberiadaNode* node)
|
||||||
|
{
|
||||||
|
NodeStack* to_pop = *stack;
|
||||||
|
if (to_pop == NULL) {
|
||||||
|
return CYBERIADA_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
to_pop->node = node;
|
||||||
|
return CYBERIADA_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int node_stack_set_top_element(NodeStack** stack, const char* element)
|
||||||
|
{
|
||||||
|
NodeStack* to_pop = *stack;
|
||||||
|
if (to_pop == NULL) {
|
||||||
|
return CYBERIADA_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
to_pop->xml_element = element;
|
||||||
|
return CYBERIADA_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CyberiadaNode* node_stack_current_node(NodeStack** stack)
|
||||||
|
{
|
||||||
|
NodeStack* s = *stack;
|
||||||
|
while (s) {
|
||||||
|
if (s->node)
|
||||||
|
return s->node;
|
||||||
|
s = s->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static CyberiadaNode* node_stack_parent_node(NodeStack** stack) */
|
||||||
|
/* { */
|
||||||
|
/* NodeStack* s = *stack; */
|
||||||
|
/* int first = 1; */
|
||||||
|
/* while (s) { */
|
||||||
|
/* if (s->node) { */
|
||||||
|
/* if (first) { */
|
||||||
|
/* first = 0; */
|
||||||
|
/* } else { */
|
||||||
|
/* return s->node; */
|
||||||
|
/* } */
|
||||||
|
/* } */
|
||||||
|
/* s = s->next; */
|
||||||
|
/* } */
|
||||||
|
/* return NULL; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
static int node_stack_pop(NodeStack** stack, CyberiadaNode** node, const char** element)
|
||||||
|
{
|
||||||
|
NodeStack* to_pop = *stack;
|
||||||
|
if (to_pop == NULL) {
|
||||||
|
return CYBERIADA_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
if (element)
|
||||||
|
*element = to_pop->xml_element;
|
||||||
|
if (node)
|
||||||
|
*node = to_pop->node;
|
||||||
|
*stack = to_pop->next;
|
||||||
|
free(to_pop);
|
||||||
|
return CYBERIADA_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static int node_stack_empty(NodeStack** stack) */
|
||||||
|
/* { */
|
||||||
|
/* return *stack == NULL; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
static GraphProcessorState handle_new_graph(xmlNode* xml_node,
|
static GraphProcessorState handle_new_graph(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
CyberiadaNode* node;
|
CyberiadaNode* node;
|
||||||
char buffer[MAX_STR_LEN];
|
char buffer[MAX_STR_LEN];
|
||||||
@@ -349,23 +432,21 @@ static GraphProcessorState handle_new_graph(xmlNode* xml_node,
|
|||||||
GRAPHML_ID_ATTRIBUTE) != CYBERIADA_NO_ERROR) {
|
GRAPHML_ID_ATTRIBUTE) != CYBERIADA_NO_ERROR) {
|
||||||
return gpsInvalid;
|
return gpsInvalid;
|
||||||
}
|
}
|
||||||
node = cyberiada_new_node(CYBERIADA_HOLLOW_NODE);
|
|
||||||
DEBUG("found graph %s \n", buffer);
|
DEBUG("found graph %s \n", buffer);
|
||||||
|
node = cyberiada_new_node(CYBERIADA_HOLLOW_NODE);
|
||||||
if (sm->nodes == NULL) {
|
if (sm->nodes == NULL) {
|
||||||
sm->nodes = node;
|
sm->nodes = node;
|
||||||
} else {
|
node_stack_set_top_node(stack, node);
|
||||||
(*current)->children = node;
|
|
||||||
node->parent = *current;
|
|
||||||
}
|
}
|
||||||
*current = node;
|
|
||||||
return gpsGraph;
|
return gpsGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GraphProcessorState handle_new_node(xmlNode* xml_node,
|
static GraphProcessorState handle_new_node(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
CyberiadaNode* node;
|
CyberiadaNode* node;
|
||||||
|
CyberiadaNode* parent;
|
||||||
char buffer[MAX_STR_LEN];
|
char buffer[MAX_STR_LEN];
|
||||||
size_t buffer_len = sizeof(buffer) - 1;
|
size_t buffer_len = sizeof(buffer) - 1;
|
||||||
if (cyberiada_get_attr_value(buffer, buffer_len,
|
if (cyberiada_get_attr_value(buffer, buffer_len,
|
||||||
@@ -374,11 +455,12 @@ static GraphProcessorState handle_new_node(xmlNode* xml_node,
|
|||||||
return gpsInvalid;
|
return gpsInvalid;
|
||||||
}
|
}
|
||||||
DEBUG("found node %s\n", buffer);
|
DEBUG("found node %s\n", buffer);
|
||||||
if (*current == NULL) {
|
parent = node_stack_current_node(stack);
|
||||||
|
if (parent == NULL) {
|
||||||
ERROR("current node invalid\n");
|
ERROR("current node invalid\n");
|
||||||
return gpsInvalid;
|
return gpsInvalid;
|
||||||
}
|
}
|
||||||
if(strcmp((*current)->id, CYBERIADA_HOLLOW_NODE) == 0) {
|
/* if(strcmp(current->id, CYBERIADA_HOLLOW_NODE) == 0) {
|
||||||
if (*current == sm->nodes) {
|
if (*current == sm->nodes) {
|
||||||
node = cyberiada_new_node(buffer);
|
node = cyberiada_new_node(buffer);
|
||||||
(*current)->children = node;
|
(*current)->children = node;
|
||||||
@@ -392,46 +474,69 @@ static GraphProcessorState handle_new_node(xmlNode* xml_node,
|
|||||||
node = cyberiada_new_node(buffer);
|
node = cyberiada_new_node(buffer);
|
||||||
cyberiada_graph_add_sibling_node(*current, node);
|
cyberiada_graph_add_sibling_node(*current, node);
|
||||||
*current = node;
|
*current = node;
|
||||||
|
}*/
|
||||||
|
node = cyberiada_new_node(buffer);
|
||||||
|
node->parent = parent;
|
||||||
|
node_stack_set_top_node(stack, node);
|
||||||
|
if (parent->children == NULL) {
|
||||||
|
parent->children = node;
|
||||||
|
} else {
|
||||||
|
cyberiada_graph_add_sibling_node(parent->children, node);
|
||||||
}
|
}
|
||||||
return gpsNode;
|
return gpsNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GraphProcessorState handle_group_node(xmlNode* xml_node,
|
static GraphProcessorState handle_group_node(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
(*current)->type = cybNodeComplex;
|
CyberiadaNode* current = node_stack_current_node(stack);
|
||||||
|
if (current == NULL) {
|
||||||
|
ERROR("current node invalid\n");
|
||||||
|
return gpsInvalid;
|
||||||
|
}
|
||||||
|
current->type = cybNodeComplex;
|
||||||
return gpsNodeGeometry;
|
return gpsNodeGeometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GraphProcessorState handle_comment_node(xmlNode* xml_node,
|
static GraphProcessorState handle_comment_node(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
(*current)->type = cybNodeComment;
|
CyberiadaNode* current = node_stack_current_node(stack);
|
||||||
cyberiada_copy_string(&((*current)->title), &((*current)->title_len), "COMMENT");
|
if (current == NULL) {
|
||||||
|
ERROR("current node invalid\n");
|
||||||
|
return gpsInvalid;
|
||||||
|
}
|
||||||
|
current->type = cybNodeComment;
|
||||||
|
cyberiada_copy_string(&(current->title), &(current->title_len), "COMMENT");
|
||||||
return gpsNodeGeometry;
|
return gpsNodeGeometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GraphProcessorState handle_generic_node(xmlNode* xml_node,
|
static GraphProcessorState handle_generic_node(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
char buffer[MAX_STR_LEN];
|
char buffer[MAX_STR_LEN];
|
||||||
size_t buffer_len = sizeof(buffer) - 1;
|
size_t buffer_len = sizeof(buffer) - 1;
|
||||||
|
CyberiadaNode* current = node_stack_current_node(stack);
|
||||||
|
if (current == NULL) {
|
||||||
|
ERROR("current node invalid\n");
|
||||||
|
return gpsInvalid;
|
||||||
|
}
|
||||||
if (cyberiada_get_attr_value(buffer, buffer_len,
|
if (cyberiada_get_attr_value(buffer, buffer_len,
|
||||||
xml_node,
|
xml_node,
|
||||||
GRAPHML_YED_NODE_CONFIG_ATTRIBUTE) == CYBERIADA_NO_ERROR &&
|
GRAPHML_YED_NODE_CONFIG_ATTRIBUTE) == CYBERIADA_NO_ERROR &&
|
||||||
(strcmp(buffer, GRAPHML_YED_NODE_CONFIG_START) == 0 ||
|
(strcmp(buffer, GRAPHML_YED_NODE_CONFIG_START) == 0 ||
|
||||||
strcmp(buffer, GRAPHML_YED_NODE_CONFIG_START2) == 0)) {
|
strcmp(buffer, GRAPHML_YED_NODE_CONFIG_START2) == 0)) {
|
||||||
(*current)->type = cybNodeInitial;
|
current->type = cybNodeInitial;
|
||||||
if ((*current)->title != NULL) {
|
if (current->title != NULL) {
|
||||||
ERROR("Trying to set start node %s label twice\n", (*current)->id);
|
ERROR("Trying to set start node %s label twice\n", current->id);
|
||||||
return gpsInvalid;
|
return gpsInvalid;
|
||||||
}
|
}
|
||||||
cyberiada_copy_string(&((*current)->title), &((*current)->title_len), "");
|
cyberiada_copy_string(&(current->title), &(current->title_len), "");
|
||||||
} else {
|
} else {
|
||||||
(*current)->type = cybNodeSimple;
|
current->type = cybNodeSimple;
|
||||||
}
|
}
|
||||||
return gpsNodeGeometry;
|
return gpsNodeGeometry;
|
||||||
}
|
}
|
||||||
@@ -473,18 +578,24 @@ static int cyberiada_xml_read_rect(xmlNode* xml_node,
|
|||||||
|
|
||||||
static GraphProcessorState handle_node_geometry(xmlNode* xml_node,
|
static GraphProcessorState handle_node_geometry(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
CyberiadaNodeType type = (*current)->type;
|
CyberiadaNodeType type;
|
||||||
|
CyberiadaNode* current = node_stack_current_node(stack);
|
||||||
|
if (current == NULL) {
|
||||||
|
ERROR("current node invalid\n");
|
||||||
|
return gpsInvalid;
|
||||||
|
}
|
||||||
|
type = current->type;
|
||||||
if (cyberiada_xml_read_rect(xml_node,
|
if (cyberiada_xml_read_rect(xml_node,
|
||||||
&((*current)->geometry_rect)) != CYBERIADA_NO_ERROR) {
|
&(current->geometry_rect)) != CYBERIADA_NO_ERROR) {
|
||||||
return gpsInvalid;
|
return gpsInvalid;
|
||||||
}
|
}
|
||||||
if (type == cybNodeInitial) {
|
if (type == cybNodeInitial) {
|
||||||
(*current)->geometry_rect.x += (*current)->geometry_rect.width / 2.0;
|
current->geometry_rect.x += current->geometry_rect.width / 2.0;
|
||||||
(*current)->geometry_rect.y += (*current)->geometry_rect.height / 2.0;
|
current->geometry_rect.y += current->geometry_rect.height / 2.0;
|
||||||
(*current)->geometry_rect.width = 0.0;
|
current->geometry_rect.width = 0.0;
|
||||||
(*current)->geometry_rect.height = 0.0;
|
current->geometry_rect.height = 0.0;
|
||||||
return gpsNodeStart;
|
return gpsNodeStart;
|
||||||
} else if (type == cybNodeComment) {
|
} else if (type == cybNodeComment) {
|
||||||
return gpsNodeAction;
|
return gpsNodeAction;
|
||||||
@@ -495,7 +606,7 @@ static GraphProcessorState handle_node_geometry(xmlNode* xml_node,
|
|||||||
|
|
||||||
static GraphProcessorState handle_property(xmlNode* xml_node,
|
static GraphProcessorState handle_property(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
char buffer[MAX_STR_LEN];
|
char buffer[MAX_STR_LEN];
|
||||||
size_t buffer_len = sizeof(buffer) - 1;
|
size_t buffer_len = sizeof(buffer) - 1;
|
||||||
@@ -512,39 +623,49 @@ static GraphProcessorState handle_property(xmlNode* xml_node,
|
|||||||
|
|
||||||
static GraphProcessorState handle_node_title(xmlNode* xml_node,
|
static GraphProcessorState handle_node_title(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
char buffer[MAX_STR_LEN];
|
char buffer[MAX_STR_LEN];
|
||||||
size_t buffer_len = sizeof(buffer) - 1;
|
size_t buffer_len = sizeof(buffer) - 1;
|
||||||
if ((*current)->title != NULL) {
|
CyberiadaNode* current = node_stack_current_node(stack);
|
||||||
ERROR("Trying to set node %s label twice\n", (*current)->id);
|
if (current == NULL) {
|
||||||
|
ERROR("current node invalid\n");
|
||||||
|
return gpsInvalid;
|
||||||
|
}
|
||||||
|
if (current->title != NULL) {
|
||||||
|
ERROR("Trying to set node %s label twice\n", current->id);
|
||||||
return gpsInvalid;
|
return gpsInvalid;
|
||||||
}
|
}
|
||||||
cyberiada_get_element_text(buffer, buffer_len, xml_node);
|
cyberiada_get_element_text(buffer, buffer_len, xml_node);
|
||||||
DEBUG("Set node %s title %s\n", (*current)->id, buffer);
|
DEBUG("Set node %s title %s\n", current->id, buffer);
|
||||||
cyberiada_copy_string(&((*current)->title), &((*current)->title_len), buffer);
|
cyberiada_copy_string(&(current->title), &(current->title_len), buffer);
|
||||||
return gpsNodeAction;
|
return gpsNodeAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GraphProcessorState handle_node_action(xmlNode* xml_node,
|
static GraphProcessorState handle_node_action(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
char buffer[MAX_STR_LEN];
|
char buffer[MAX_STR_LEN];
|
||||||
size_t buffer_len = sizeof(buffer) - 1;
|
size_t buffer_len = sizeof(buffer) - 1;
|
||||||
if ((*current)->action != NULL) {
|
CyberiadaNode* current = node_stack_current_node(stack);
|
||||||
ERROR("Trying to set node %s action twice\n", (*current)->id);
|
if (current == NULL) {
|
||||||
|
ERROR("current node invalid\n");
|
||||||
|
return gpsInvalid;
|
||||||
|
}
|
||||||
|
if (current->action != NULL) {
|
||||||
|
ERROR("Trying to set node %s action twice\n", current->id);
|
||||||
return gpsInvalid;
|
return gpsInvalid;
|
||||||
}
|
}
|
||||||
cyberiada_get_element_text(buffer, buffer_len, xml_node);
|
cyberiada_get_element_text(buffer, buffer_len, xml_node);
|
||||||
DEBUG("Set node %s action %s\n", (*current)->id, buffer);
|
DEBUG("Set node %s action %s\n", current->id, buffer);
|
||||||
cyberiada_copy_string(&((*current)->action), &((*current)->action_len), buffer);
|
cyberiada_copy_string(&(current->action), &(current->action_len), buffer);
|
||||||
return gpsGraph;
|
return gpsGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GraphProcessorState handle_new_edge(xmlNode* xml_node,
|
static GraphProcessorState handle_new_edge(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** node)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
CyberiadaNode* source = NULL;
|
CyberiadaNode* source = NULL;
|
||||||
CyberiadaNode* target = NULL;
|
CyberiadaNode* target = NULL;
|
||||||
@@ -581,7 +702,7 @@ static GraphProcessorState handle_new_edge(xmlNode* xml_node,
|
|||||||
|
|
||||||
static GraphProcessorState handle_edge_geometry(xmlNode* xml_node,
|
static GraphProcessorState handle_edge_geometry(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** node)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
CyberiadaEdge *current = cyberiada_graph_find_last_edge(sm);
|
CyberiadaEdge *current = cyberiada_graph_find_last_edge(sm);
|
||||||
if (current == NULL) {
|
if (current == NULL) {
|
||||||
@@ -607,7 +728,7 @@ static GraphProcessorState handle_edge_geometry(xmlNode* xml_node,
|
|||||||
|
|
||||||
static GraphProcessorState handle_edge_point(xmlNode* xml_node,
|
static GraphProcessorState handle_edge_point(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** node)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
CyberiadaEdge *current = cyberiada_graph_find_last_edge(sm);
|
CyberiadaEdge *current = cyberiada_graph_find_last_edge(sm);
|
||||||
double x, y;
|
double x, y;
|
||||||
@@ -640,7 +761,7 @@ static GraphProcessorState handle_edge_point(xmlNode* xml_node,
|
|||||||
|
|
||||||
static GraphProcessorState handle_edge_label(xmlNode* xml_node,
|
static GraphProcessorState handle_edge_label(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** node)
|
NodeStack** stack)
|
||||||
{
|
{
|
||||||
char buffer[MAX_STR_LEN];
|
char buffer[MAX_STR_LEN];
|
||||||
size_t buffer_len = sizeof(buffer) - 1;
|
size_t buffer_len = sizeof(buffer) - 1;
|
||||||
@@ -664,7 +785,7 @@ static GraphProcessorState handle_edge_label(xmlNode* xml_node,
|
|||||||
|
|
||||||
typedef GraphProcessorState (*Handler)(xmlNode* xml_root,
|
typedef GraphProcessorState (*Handler)(xmlNode* xml_root,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current);
|
NodeStack** stack);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GraphProcessorState state;
|
GraphProcessorState state;
|
||||||
@@ -695,14 +816,16 @@ const size_t processor_state_table_size = sizeof(processor_state_table) / sizeof
|
|||||||
|
|
||||||
static int dispatch_processor(xmlNode* xml_node,
|
static int dispatch_processor(xmlNode* xml_node,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current,
|
NodeStack** stack,
|
||||||
GraphProcessorState* gps) {
|
GraphProcessorState* gps) {
|
||||||
size_t i;
|
size_t i;
|
||||||
if (xml_node->type == XML_ELEMENT_NODE) {
|
if (xml_node->type == XML_ELEMENT_NODE) {
|
||||||
|
const char* xml_element_name = (const char*)xml_node->name;
|
||||||
|
node_stack_set_top_element(stack, xml_element_name);
|
||||||
for (i = 0; i < processor_state_table_size; i++) {
|
for (i = 0; i < processor_state_table_size; i++) {
|
||||||
if (processor_state_table[i].state == *gps &&
|
if (processor_state_table[i].state == *gps &&
|
||||||
strcmp((const char*)xml_node->name, processor_state_table[i].symbol) == 0) {
|
strcmp(xml_element_name, processor_state_table[i].symbol) == 0) {
|
||||||
*gps = (*(processor_state_table[i].handler))(xml_node, sm, current);
|
*gps = (*(processor_state_table[i].handler))(xml_node, sm, stack);
|
||||||
return CYBERIADA_NO_ERROR;
|
return CYBERIADA_NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -712,26 +835,36 @@ static int dispatch_processor(xmlNode* xml_node,
|
|||||||
|
|
||||||
static int cyberiada_build_graph(xmlNode* xml_root,
|
static int cyberiada_build_graph(xmlNode* xml_root,
|
||||||
CyberiadaSM* sm,
|
CyberiadaSM* sm,
|
||||||
CyberiadaNode** current,
|
NodeStack** stack,
|
||||||
GraphProcessorState* gps)
|
GraphProcessorState* gps)
|
||||||
{
|
{
|
||||||
xmlNode *cur_xml_node = NULL;
|
xmlNode *cur_xml_node = NULL;
|
||||||
|
/* NodeStack* s = *stack; */
|
||||||
|
/* DEBUG("\nStack:"); */
|
||||||
|
/* while (s) { */
|
||||||
|
/* DEBUG(" (%s %p)", */
|
||||||
|
/* s->xml_element ? s->xml_element : "null", */
|
||||||
|
/* s->node); */
|
||||||
|
/* s = s->next; */
|
||||||
|
/* } */
|
||||||
|
/* DEBUG("\n"); */
|
||||||
for (cur_xml_node = xml_root; cur_xml_node; cur_xml_node = cur_xml_node->next) {
|
for (cur_xml_node = xml_root; cur_xml_node; cur_xml_node = cur_xml_node->next) {
|
||||||
DEBUG("xml node %s sm root %s current %s gps %s\n",
|
DEBUG("xml node %s sm root %s gps %s\n",
|
||||||
cur_xml_node->name,
|
cur_xml_node->name,
|
||||||
sm->nodes ? sm->nodes->id : "none",
|
sm->nodes ? sm->nodes->id : "none",
|
||||||
*current ? (*current)->id : "none",
|
|
||||||
debug_state_names[*gps]);
|
debug_state_names[*gps]);
|
||||||
dispatch_processor(cur_xml_node, sm, current, gps);
|
node_stack_push(stack);
|
||||||
|
dispatch_processor(cur_xml_node, sm, stack, gps);
|
||||||
if (*gps == gpsInvalid) {
|
if (*gps == gpsInvalid) {
|
||||||
return CYBERIADA_FORMAT_ERROR;
|
return CYBERIADA_FORMAT_ERROR;
|
||||||
}
|
}
|
||||||
if (cur_xml_node->children) {
|
if (cur_xml_node->children) {
|
||||||
int res = cyberiada_build_graph(cur_xml_node->children, sm, current, gps);
|
int res = cyberiada_build_graph(cur_xml_node->children, sm, stack, gps);
|
||||||
if (res != CYBERIADA_NO_ERROR) {
|
if (res != CYBERIADA_NO_ERROR) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
node_stack_pop(stack, NULL, NULL);
|
||||||
}
|
}
|
||||||
return CYBERIADA_NO_ERROR;
|
return CYBERIADA_NO_ERROR;
|
||||||
}
|
}
|
||||||
@@ -741,12 +874,18 @@ static int cyberiada_decode_yed_xml(xmlNode* root, CyberiadaSM* sm)
|
|||||||
char buffer[MAX_STR_LEN];
|
char buffer[MAX_STR_LEN];
|
||||||
size_t buffer_len = sizeof(buffer) - 1;
|
size_t buffer_len = sizeof(buffer) - 1;
|
||||||
GraphProcessorState gps = gpsInit;
|
GraphProcessorState gps = gpsInit;
|
||||||
CyberiadaNode* current = NULL;
|
NodeStack* stack = NULL;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if ((res = cyberiada_build_graph(root, sm, ¤t, &gps)) != CYBERIADA_NO_ERROR) {
|
if ((res = cyberiada_build_graph(root, sm, &stack, &gps)) != CYBERIADA_NO_ERROR) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stack != NULL) {
|
||||||
|
fprintf(stderr, "error with node stack\n");
|
||||||
|
return CYBERIADA_FORMAT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (cyberiada_get_attr_value(buffer, buffer_len,
|
if (cyberiada_get_attr_value(buffer, buffer_len,
|
||||||
root,
|
root,
|
||||||
GRAPHML_BERLOGA_SCHEMENAME_ATTR) != CYBERIADA_NO_ERROR) {
|
GRAPHML_BERLOGA_SCHEMENAME_ATTR) != CYBERIADA_NO_ERROR) {
|
||||||
@@ -842,7 +981,7 @@ int cyberiada_read_sm(CyberiadaSM* sm, const char* filename, CyberiadaXMLFormat
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cyberiada_print_node(CyberiadaNode* node, CyberiadaNode* start, int level)
|
static int cyberiada_print_node(CyberiadaNode* node, int level)
|
||||||
{
|
{
|
||||||
CyberiadaNode* cur_node;
|
CyberiadaNode* cur_node;
|
||||||
char levelspace[16];
|
char levelspace[16];
|
||||||
@@ -856,9 +995,6 @@ static int cyberiada_print_node(CyberiadaNode* node, CyberiadaNode* start, int l
|
|||||||
|
|
||||||
printf("%sNode {id: %s, title: \"%s\", type: %d",
|
printf("%sNode {id: %s, title: \"%s\", type: %d",
|
||||||
levelspace, node->id, node->title, (int)node->type);
|
levelspace, node->id, node->title, (int)node->type);
|
||||||
if (node == start) {
|
|
||||||
printf(", S");
|
|
||||||
}
|
|
||||||
printf("}\n");
|
printf("}\n");
|
||||||
printf("%sGeometry: (%lf, %lf, %lf, %lf)\n",
|
printf("%sGeometry: (%lf, %lf, %lf, %lf)\n",
|
||||||
levelspace,
|
levelspace,
|
||||||
@@ -874,7 +1010,7 @@ static int cyberiada_print_node(CyberiadaNode* node, CyberiadaNode* start, int l
|
|||||||
|
|
||||||
printf("%sChildren:\n", levelspace);
|
printf("%sChildren:\n", levelspace);
|
||||||
for (cur_node = node->children; cur_node; cur_node = cur_node->next) {
|
for (cur_node = node->children; cur_node; cur_node = cur_node->next) {
|
||||||
cyberiada_print_node(cur_node, start, level + 1);
|
cyberiada_print_node(cur_node, level + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CYBERIADA_NO_ERROR;
|
return CYBERIADA_NO_ERROR;
|
||||||
@@ -921,7 +1057,7 @@ int cyberiada_print_sm(CyberiadaSM* sm)
|
|||||||
|
|
||||||
printf("Nodes:\n");
|
printf("Nodes:\n");
|
||||||
for (cur_node = sm->nodes; cur_node; cur_node = cur_node->next) {
|
for (cur_node = sm->nodes; cur_node; cur_node = cur_node->next) {
|
||||||
cyberiada_print_node(cur_node, sm->start, 0);
|
cyberiada_print_node(cur_node, 0);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user