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; }
scew_element* scew_element_by_index (scew_element const *element, unsigned int index) { scew_list *item = NULL; assert (element != NULL); assert (index < element->n_children); item = scew_list_index (element->children, index); return (NULL == item) ? NULL : (scew_element *) scew_list_data (item); }
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)); }
scew_element* scew_element_by_name (scew_element const *element, XML_Char const *name) { scew_list *item = NULL; assert (element != NULL); assert (name != NULL); if (element->children != NULL) { item = scew_list_find_custom (element->children, name, cmp_name_); } return (NULL == item) ? NULL : (scew_element *) scew_list_data (item); }
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; }
arcus_system *system_from_xml(scew_element *element) { arcus_system *sys; scew_attribute *attr; const char *attr_val; scew_list *list; scew_element *e; const char *contents; if (!element) { set_error_string("system_from_xml: NULL element"); return NULL; } if (strcmp(scew_element_name(element), "system") != 0) { set_error_string("system_from_xml: element name != 'system'"); return NULL; } sys = system_create(); if (!sys) return NULL; // Get system id attr = scew_element_attribute_by_name(element, "id"); if (!attr) { set_error_string("system_from_xml: system without id"); system_destroy(sys); return NULL; } attr_val = scew_attribute_value(attr); if (!attr_val) { set_error_string("system_from_xml: attribute without value (scew bug?)"); system_destroy(sys); return NULL; } sys->id = strdup(attr_val); // Load metric list = scew_element_list_by_name(element, "metric"); if (!list) { set_error_string("system_create: no metric in system"); system_destroy(sys); return NULL; } if (scew_list_size(list) != 1) { set_error_string("system_create: more than one metric in system"); system_destroy(sys); return NULL; } sys->metric = metric_from_xml((scew_element *)scew_list_data(list)); if (!sys->metric) { system_destroy(sys); return NULL; } // Load christoffel symbols sys->cs = christoffel_from_xml(element); if (!sys->cs) { system_destroy(sys); return NULL; } // Load range list = scew_element_list_by_name(element, "range"); if (!list) { set_error_string("system_create: no range in system"); system_destroy(sys); return NULL; } if (scew_list_size(list) != 1) { set_error_string("system_create: more than one range in system"); system_destroy(sys); return NULL; } e = (scew_element *)scew_list_data(list); if (!e || strcmp(scew_element_name(e), "range") != 0) { set_error_string("system_create: no/wrong range element in list (SCEW bug?)"); system_destroy(sys); return NULL; } contents = scew_element_contents(e); if (!contents || !contents[0]) { set_error_string("system_create: no contents in range element"); system_destroy(sys); return NULL; } if (!af_formula_setexpr(sys->range, contents)) { set_error_string("system_create: cannot set range function expression"); system_destroy(sys); return NULL; } return sys; }