From 256fa60f13d36277babc370e2fb807f302a4857c Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Tue, 2 Apr 2024 23:04:07 +0200 Subject: [PATCH] src/model.c: iteration on siblings of a given node --- src/model.c | 407 +++++----------------------------------------------- 1 file changed, 32 insertions(+), 375 deletions(-) diff --git a/src/model.c b/src/model.c index df47a08..cdbd47a 100644 --- a/src/model.c +++ b/src/model.c @@ -202,6 +202,38 @@ xmlNodePtr model_copy_node(struct model_t *self, return copiedNode; } + +/** + * Iterates over all sibling nodes of a given node, typically used to process + * each child of a specific parent node. + * + * This function takes a starting node (expected to be a parent node like ) + * and iterates through all of its child nodes. + * It calls a user-provided callback function for each child node that is an + * element node (ignores text and other types of nodes). + * + * @param node The starting node whose siblings (children) will be iterated + * over. This node is not processed by the callback, only its siblings are. + * @param processNode A callback function that will be called for each sibling + * node. This function should have a signature of + * void functionName(xmlNodePtr node, void* userData), where + * 'node' is the current sibling element node, and + * 'userData' is a pointer to user-defined data passed + * through iterateSiblings. + * @param userData A void pointer to user-defined data. This can be used to pass + * additional information to the callback function. It is passed + * directly through to the callback function as its second argument. + */ +void model_iterate_node(xmlNodePtr node, + void (*processNode)(xmlNodePtr node, void* userData), void* userData) +{ + for (xmlNodePtr curNode = node->children; curNode; curNode = curNode->next) { + if (curNode->type == XML_ELEMENT_NODE) { + processNode (curNode, userData); + } + } +} + /* -------------------------------------------------------------------------- */ char model_get_dim (struct model_t *self) @@ -242,381 +274,6 @@ char model_get_multiplicity (struct model_t *self) return 0; } -bool model_get_next_state (struct model_t *self, char *new_state_id) -{ - static xmlNodePtr cur_node = NULL; - xmlAttr *attribute; - xmlChar *value; - - if (cur_node == NULL) { - // Get first state - cur_node = model_get_node(self, (xmlChar *)"savedstates/state"); - - } else { - // Get next state - if (cur_node->next) - cur_node = cur_node->next; - else - return false; - } - - // Lookup in properties - if (model_get_node_str_attrib(cur_node, "id", new_state_id)) - return true; - - cur_node = NULL; - return false; -} - -long model_get_state_arrows_count (struct model_t *self, const char *state_id) -{ - xmlNodePtr cur_node = NULL; - xmlAttr *attribute; - long value = 0; - bool found = false; - char temp_char[25]; - uint check = 0; // bit field checker - - //printf("NEW CALL : cur_node = %p\n", cur_node); - - assert(state_id); - - // Get first state node - cur_node = model_get_node(self, (xmlChar *)"savedstates/state"); - - // Lookup in properties - while (cur_node && cur_node->properties) { - attribute = cur_node->properties; - - // Look for the id attribute - if (model_get_node_str_attrib(cur_node, "id", &temp_char)) { - if (!xmlStrcmp(temp_char, (const xmlChar *)state_id)) { - found = true; - break; - } - } - cur_node = cur_node->next; - } - - // Check if the state has been found - if (!found) { - cur_node = NULL; - return -1; - } - - - // Count arrows - if (cur_node->children) { - cur_node = cur_node->children; - while (cur_node) { - if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) - value++; - cur_node = cur_node->next; - } - } else { - return -1; - } - return value; -} - -bool model_get_next_arrow (struct model_t *self, - struct arrow_t *new_arrow, - const char *state_id, - char dimension) -{ - static xmlNodePtr cur_node = NULL; - xmlAttr *attribute; - xmlChar *value; - bool found = false; - char temp_char[25]; - uint check = 0; // bit field checker - - //printf("NEW CALL : cur_node = %p\n", cur_node); - - assert(new_arrow); - assert(state_id); - - if (cur_node == NULL) { - // Get first state node - cur_node = model_get_node(self, (xmlChar *)"savedstates/state"); - - // Lookup in properties - while (cur_node && cur_node->properties) { - attribute = cur_node->properties; - - // Look for the id attribute - if (model_get_node_str_attrib(cur_node, "id", &temp_char)) { - if (!xmlStrcmp(temp_char, (const xmlChar *)state_id)) { - found = true; - break; - } - } - cur_node = cur_node->next; - } - - // Check if the state has been found - if (!found) { - cur_node = NULL; - return false; - } - - // Get first arrow - if (cur_node->children) { - cur_node = cur_node->children; - - found = false; - while (cur_node && cur_node->name) { - if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) { - found = true; - break; - } - cur_node = cur_node->next; - } - } - - // Check if the state has been found - if (!found) { - cur_node = NULL; - return false; - } - - } else { - // Get next arrow - found = false; - while (cur_node->next) { - cur_node = cur_node->next; - if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) { - found = true; - break; - } - } - - // Check if the state has been found - if (!found) { - cur_node = NULL; - return false; - } - } - - //printf("DURING CALL : cur_node = %p\n", cur_node); - //printf("DURING CALL : cur_node->name = %s\n", cur_node->name); - - // Lookup in properties - if (cur_node && cur_node->properties) { - attribute = cur_node->properties; - - while(attribute && attribute->name && attribute->children) { - //printf("attr name : %s\n", attribute->name); - if (!xmlStrcmp(attribute->name, (const xmlChar *)"site")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_arrow->site = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_SITE; - } - if (!xmlStrcmp(attribute->name, (const xmlChar *)"weight")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_arrow->load = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_WEIGHT; - } - if (!xmlStrcmp(attribute->name, (const xmlChar *)"x")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_arrow->x = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_X; - } - if (!xmlStrcmp(attribute->name, (const xmlChar *)"y")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_arrow->y = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_Y; - } - if (!xmlStrcmp(attribute->name, (const xmlChar *)"z")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_arrow->z = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_Z; - } - attribute = attribute->next; - } - - switch(dimension) { - case 3: - return (bool)(check & SUCCESSFUL_READ_ARROW_XYZ); - case 2: - return (bool)(check & SUCCESSFUL_READ_ARROW_XY); - case 1: - return (bool)(check & SUCCESSFUL_READ_ARROW_X); - } - } - cur_node = NULL; - return false; -} - -bool model_get_next_conditions (struct model_t *self, char *new_cond_id) -{ - static xmlNodePtr cur_node = NULL; - xmlAttr *attribute; - xmlChar *value; - - printlog("NEW CALL : cur_node = %p\n", cur_node); - - if (cur_node == NULL) { - // Get first state - cur_node = model_get_node(self, (xmlChar *)"conditions"); - - } else { - // Get next state - if (cur_node->next) - cur_node = cur_node->next; - else - return false; - } - - printlog("END CALL : cur_node = %p\n", cur_node); - - // Lookup in properties - if (model_get_node_str_attrib(cur_node, "id", new_cond_id)) - return true; - - cur_node = NULL; - return false; -} - -bool model_get_next_condition (struct model_t *self, - struct condition_t *new_condition, - const char *cond_id, - char dimension) -{ - static xmlNodePtr cur_node = NULL; - xmlAttr *attribute; - xmlChar *value; - bool found = false; - char temp_char[25]; - uint check = 0; // bit field checker - - printlog("NEW CALL : cur_node = %p\n", cur_node); - - assert(new_condition); - assert(cond_id); - - if (cur_node == NULL) { - // Get first state node - cur_node = model_get_node(self, (xmlChar *)"conditions"); - - // Lookup in properties - while (cur_node && cur_node->properties) { - attribute = cur_node->properties; - - // Look for the id attribute - if (model_get_node_str_attrib(cur_node, "id", &temp_char)) { - if (!xmlStrcmp(temp_char, (const xmlChar *)cond_id)) { - found = true; - break; - } - } - cur_node = cur_node->next; - } - - // Check if the state has been found - if (!found) { - cur_node = NULL; - return false; - } - - // Get first arrow - if (cur_node->children) { - cur_node = cur_node->children; - - found = false; - while (cur_node && cur_node->name) { - if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) { - found = true; - break; - } - cur_node = cur_node->next; - } - } - - // Check if the state has been found - if (!found) { - cur_node = NULL; - return false; - } - - } else { - // Get next condition - found = false; - while (cur_node->next) { - cur_node = cur_node->next; - if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) { - found = true; - break; - } - } - - // Check if the state has been found - if (!found) { - cur_node = NULL; - return false; - } - } - - printlog("DURING CALL : cur_node = %p\n", cur_node); - printlog("DURING CALL : cur_node->name = %s\n", cur_node->name); - - // Lookup in properties - if (cur_node && cur_node->properties) { - attribute = cur_node->properties; - - while(attribute && attribute->name && attribute->children) { - //printf("attr name : %s\n", attribute->name); - if (!xmlStrcmp(attribute->name, (const xmlChar *)"site")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_condition->site = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_SITE; - } - if (!xmlStrcmp(attribute->name, (const xmlChar *)"weight")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_condition->load = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_WEIGHT; - } - if (!xmlStrcmp(attribute->name, (const xmlChar *)"x")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_condition->x = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_X; - } - if (!xmlStrcmp(attribute->name, (const xmlChar *)"y")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_condition->y = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_Y; - } - if (!xmlStrcmp(attribute->name, (const xmlChar *)"z")) { - value = xmlNodeListGetString(cur_node->doc, attribute->children, 1); - new_condition->z = strtol((char *)value, NULL, 0); - xmlFree(value); - check |= READ_Z; - } - attribute = attribute->next; - } - - switch(dimension) { - case 3: - return (bool)(check & SUCCESSFUL_READ_ARROW_XYZ); - case 2: - return (bool)(check & SUCCESSFUL_READ_ARROW_XY); - case 1: - return (bool)(check & SUCCESSFUL_READ_ARROW_X); - } - } - cur_node = NULL; - return false; -} - /* -------------------------------------------------------------------------- */ static bool model_init(struct model_t *self)