static int hwloc_libxml_backend_init(struct hwloc_xml_backend_data_s *bdata, const char *xmlpath, const char *xmlbuffer, int xmlbuflen) { xmlDoc *doc = NULL; LIBXML_TEST_VERSION; hwloc_libxml2_disable_stderrwarnings(); errno = 0; /* set to 0 so that we know if libxml2 changed it */ if (xmlpath) doc = xmlReadFile(xmlpath, NULL, 0); else if (xmlbuffer) doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, 0); if (!doc) { if (!errno) /* libxml2 read the file fine, but it got an error during parsing */ errno = EINVAL; return -1; } bdata->look_init = hwloc_libxml_look_init; bdata->look_failed = NULL; bdata->backend_exit = hwloc_libxml_backend_exit; bdata->data = doc; return 0; }
static xmlDocPtr hwloc__libxml2_prepare_export_diff(hwloc_topology_diff_t diff, const char *refname) { struct hwloc__xml_export_state_s state; hwloc__libxml_export_state_data_t data = (void *) state.data; xmlDocPtr doc = NULL; /* document pointer */ xmlNodePtr root_node = NULL; /* root pointer */ assert(sizeof(*data) <= sizeof(state.data)); LIBXML_TEST_VERSION; hwloc_libxml2_disable_stderrwarnings(); /* Creates a new document, a node and set it as a root node. */ doc = xmlNewDoc(BAD_CAST "1.0"); root_node = xmlNewNode(NULL, BAD_CAST "topologydiff"); if (refname) xmlNewProp(root_node, BAD_CAST "refname", BAD_CAST refname); xmlDocSetRootElement(doc, root_node); /* Creates a DTD declaration. Isn't mandatory. */ (void) xmlCreateIntSubset(doc, BAD_CAST "topologydiff", NULL, BAD_CAST "hwloc.dtd"); state.new_child = hwloc__libxml_export_new_child; state.new_prop = hwloc__libxml_export_new_prop; state.add_content = hwloc__libxml_export_add_content; state.end_object = hwloc__libxml_export_end_object; data->current_node = root_node; hwloc__xml_export_diff (&state, diff); return doc; }
/* this can be the first XML call */ int hwloc_backend_xml_init(struct hwloc_topology *topology, const char *xmlpath, const char *xmlbuffer, int xmlbuflen) { #ifdef HWLOC_HAVE_LIBXML2 char *env = getenv("HWLOC_NO_LIBXML_IMPORT"); if (!env || !atoi(env)) { xmlDoc *doc = NULL; LIBXML_TEST_VERSION; hwloc_libxml2_disable_stderrwarnings(); errno = 0; /* set to 0 so that we know if libxml2 changed it */ if (xmlpath) doc = xmlReadFile(xmlpath, NULL, 0); else if (xmlbuffer) doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, 0); if (!doc) { if (!errno) /* libxml2 read the file fine, but it got an error during parsing */ errno = EINVAL; return -1; } topology->backend_params.xml.buffer = NULL; topology->backend_params.xml.doc = doc; } else #endif /* HWLOC_HAVE_LIBXML2 */ if (xmlbuffer) { topology->backend_params.xml.buffer = malloc(xmlbuflen); memcpy(topology->backend_params.xml.buffer, xmlbuffer, xmlbuflen); } else { FILE * file; size_t buflen = 4096, offset, readlen; char *buffer = malloc(buflen+1); size_t ret; if (!strcmp(xmlpath, "-")) xmlpath = "/dev/stdin"; file = fopen(xmlpath, "r"); if (!file) return -1; offset = 0; readlen = buflen; while (1) { ret = fread(buffer+offset, 1, readlen, file); offset += ret; buffer[offset] = 0; if (ret != readlen) break; buflen *= 2; buffer = realloc(buffer, buflen+1); readlen = buflen/2; } fclose(file); topology->backend_params.xml.buffer = buffer; buflen = offset+1; } topology->is_thissystem = 0; assert(topology->backend_type == HWLOC_BACKEND_NONE); topology->backend_type = HWLOC_BACKEND_XML; return 0; }
static int hwloc_libxml_import_diff(const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *firstdiffp, char **refnamep) { struct hwloc__xml_import_state_s state; hwloc__libxml_import_state_data_t lstate = (void*) state.data; char *refname = NULL; xmlDoc *doc = NULL; xmlNode* root_node; xmlDtd *dtd; int ret; assert(sizeof(*lstate) <= sizeof(state.data)); LIBXML_TEST_VERSION; hwloc_libxml2_disable_stderrwarnings(); errno = 0; /* set to 0 so that we know if libxml2 changed it */ if (xmlpath) doc = xmlReadFile(xmlpath, NULL, 0); else if (xmlbuffer) doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, 0); if (!doc) { if (!errno) /* libxml2 read the file fine, but it got an error during parsing */ errno = EINVAL; goto out; } dtd = xmlGetIntSubset(doc); if (!dtd) { if (hwloc__xml_verbose()) fprintf(stderr, "Loading XML topologydiff without DTD\n"); } else if (strcmp((char *) dtd->SystemID, "hwloc.dtd")) { if (hwloc__xml_verbose()) fprintf(stderr, "Loading XML topologydiff with wrong DTD SystemID (%s instead of %s)\n", (char *) dtd->SystemID, "hwloc.dtd"); } root_node = xmlDocGetRootElement(doc); if (strcmp((const char *) root_node->name, "topologydiff")) { /* root node should be in "topologydiff" class */ if (hwloc__xml_verbose()) fprintf(stderr, "ignoring object of class `%s' not at the top the xml hierarchy\n", (const char *) root_node->name); goto out_with_doc; } state.next_attr = hwloc__libxml_import_next_attr; state.find_child = hwloc__libxml_import_find_child; state.close_tag = hwloc__libxml_import_close_tag; state.close_child = hwloc__libxml_import_close_child; state.get_content = hwloc__libxml_import_get_content; state.close_content = hwloc__libxml_import_close_content; state.parent = NULL; lstate->node = root_node; lstate->child = root_node->children; lstate->attr = NULL; while (1) { char *attrname, *attrvalue; if (state.next_attr(&state, &attrname, &attrvalue) < 0) break; if (!strcmp(attrname, "refname")) { free(refname); refname = strdup(attrvalue); } else goto out_with_doc; } ret = hwloc__xml_import_diff(&state, firstdiffp); if (refnamep && !ret) *refnamep = refname; else free(refname); xmlFreeDoc(doc); return ret; out_with_doc: xmlFreeDoc(doc); out: return -1; /* failed */ }