示例#1
0
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;
}
示例#2
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;
}
示例#3
0
/* 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;
}
示例#4
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 */
}