scew_list* scew_element_list_by_name (scew_element const *element, XML_Char const *name) { scew_list *list = NULL; scew_list *last = NULL; scew_list *item = NULL; assert (element != NULL); assert (name != NULL); item = element->children; while (item != NULL) { item = scew_list_find_custom (item, name, cmp_name_); if (item != NULL) { last = scew_list_append (last, scew_list_data (item)); if (NULL == list) { list = last; } item = scew_list_next (item); } } return list; }
static void print_element (scew_element *element, unsigned int indent) { XML_Char const *contents = NULL; scew_list *list = NULL; if (element == NULL) { return; } /* Prints the starting element tag with its attributes. */ print_indent (indent); scew_printf (_XT("<%s"), scew_element_name (element)); print_attributes (element); scew_printf (_XT(">")); contents = scew_element_contents (element); if (contents == NULL) { scew_printf (_XT("\n")); } /** * Call print_element function again for each child of the current * element. */ list = scew_element_children (element); while (list != NULL) { scew_element *child = scew_list_data (list); print_element (child, indent + 1); list = scew_list_next (list); } /* Prints element's content. */ if (contents != NULL) { scew_printf (_XT("%s"), contents); } else { print_indent (indent); } /* Prints the closing element tag. */ scew_printf (_XT("</%s>\n"), scew_element_name (element)); }
static void print_attributes (scew_element *element) { if (element != NULL) { /** * Iterates through the element's attribute list, printing the * pair name-value. */ scew_list *list = scew_element_attributes (element); while (list != NULL) { scew_attribute *attribute = scew_list_data (list); scew_printf (_XT(" %s=\"%s\""), scew_attribute_name (attribute), scew_attribute_value (attribute)); list = scew_list_next (list); } } }
arcus_atlas *atlas_from_xml(scew_element *element) { arcus_atlas *atlas; scew_list *list, *i; int expected_transforms, ii, jj, kk; if (!element) { set_error_string("atlas_from_xml: NULL element"); return NULL; } if (strcmp(scew_element_name(element), "atlas") != 0) { set_error_string("atlas_from_xml: element name != 'atlas'"); return NULL; } atlas = atlas_create(); if (!atlas) return NULL; list = scew_element_list_by_name(element, "system"); if (!list) { set_error_string("atlas_from_xml: no systems in atlas"); atlas_destroy(atlas); return NULL; } for (i = list ; i ; i = scew_list_next(i)) { scew_element *e; arcus_system *s; e = (scew_element *)scew_list_data(i); s = system_from_xml(e); if (!s) { atlas_destroy(atlas); return NULL; } atlas->systems = (arcus_system **)realloc(atlas->systems, (atlas->num_systems + 1) * sizeof(arcus_system *)); atlas->systems[atlas->num_systems] = s; atlas->num_systems++; } // If there's only one system, ignore the transforms if (atlas->num_systems == 1) return atlas; // Figure out how many transforms we should have (n choose k, both directions) expected_transforms = binomial(atlas->num_systems, 2) * 2; // Load transforms list = scew_element_list_by_name(element, "transform"); if (!list) { set_error_string("atlas_from_xml: no transforms in atlas when expected"); atlas_destroy(atlas); return NULL; } if (scew_list_size(list) != expected_transforms) { set_error_string("atlas_from_xml: wrong number of transforms in atlas"); atlas_destroy(atlas); return NULL; } for (i = list ; i ; i = scew_list_next(i)) { scew_element *e; arcus_transform *t; e = (scew_element *)scew_list_data(i); t = transform_from_xml(e); if (!t) { atlas_destroy(atlas); return NULL; } atlas->transforms = (arcus_transform **)realloc(atlas->transforms, (atlas->num_transforms + 1) * sizeof(arcus_transform *)); atlas->transforms[atlas->num_transforms] = t; atlas->num_transforms++; } // Load differential transforms list = scew_element_list_by_name(element, "transform_diff"); if (!list) { set_error_string("atlas_from_xml: no differential transforms in atlas when expected"); atlas_destroy(atlas); return NULL; } if (scew_list_size(list) != expected_transforms) { set_error_string("atlas_from_xml: wrong number of differential transforms in atlas"); atlas_destroy(atlas); return NULL; } for (i = list ; i ; i = scew_list_next(i)) { scew_element *e; arcus_transform *t; e = (scew_element *)scew_list_data(i); t = transform_from_xml(e); if (!t) { atlas_destroy(atlas); return NULL; } atlas->diff_transforms = (arcus_transform **)realloc(atlas->diff_transforms, (atlas->num_diff_transforms + 1) * sizeof(arcus_transform *)); atlas->diff_transforms[atlas->num_diff_transforms] = t; atlas->num_diff_transforms++; } // Check the accuracy and completeness of the transform lists for (ii = 0 ; ii < expected_transforms ; ii++) { arcus_transform *t, *dt; int found_t_from = 0, found_t_to = 0; int found_dt_from = 0, found_dt_to = 0; t = atlas->transforms[ii]; dt = atlas->diff_transforms[ii]; for (jj = 0 ; jj < atlas->num_systems ; jj++) { if (strcmp(system_id(atlas->systems[jj]), transform_from(t)) == 0) found_t_from = 1; if (strcmp(system_id(atlas->systems[jj]), transform_from(dt)) == 0) found_dt_from = 1; if (strcmp(system_id(atlas->systems[jj]), transform_to(t)) == 0) found_t_to = 1; if (strcmp(system_id(atlas->systems[jj]), transform_to(dt)) == 0) found_dt_to = 1; } if (!found_t_from || !found_t_to) { set_error_string("atlas_from_xml: transform has invalid from/to"); atlas_destroy(atlas); return NULL; } if (!found_dt_from || !found_dt_to) { set_error_string("atlas_from_xml: transform_diff has invalid from/to"); atlas_destroy(atlas); return NULL; } } for (ii = 0 ; ii < atlas->num_systems ; ii++) { for (jj = 0 ; jj < atlas->num_systems ; jj++) { int found_ij = 0, found_ji = 0, found_ij_d = 0, found_ji_d = 0; if (ii == jj) continue; arcus_system *si, *sj; si = atlas->systems[ii]; sj = atlas->systems[jj]; for (kk = 0 ; kk < expected_transforms ; kk++) { arcus_transform *t = atlas->transforms[kk]; if (strcmp(system_id(si), transform_from(t)) == 0 && strcmp(system_id(sj), transform_to(t)) == 0) found_ij = 1; else if (strcmp(system_id(sj), transform_from(t)) == 0 && strcmp(system_id(si), transform_to(t)) == 0) found_ji = 1; t = atlas->diff_transforms[kk]; if (strcmp(system_id(si), transform_from(t)) == 0 && strcmp(system_id(sj), transform_to(t)) == 0) found_ij_d = 1; else if (strcmp(system_id(sj), transform_from(t)) == 0 && strcmp(system_id(si), transform_to(t)) == 0) found_ji_d = 1; } if (!found_ij || !found_ji) { set_error_string("atlas_from_xml: no transforms found for one pair of systems"); atlas_destroy(atlas); return NULL; } if (!found_ij_d || !found_ji_d) { set_error_string("atlas_from_xml: no differential transforms found for one pair of systems"); atlas_destroy(atlas); return NULL; } } } return atlas; }