示例#1
0
static int
hwloc__nolibxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, char **valuep)
{
  hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
  int namelen;
  size_t len, escaped;
  char *buffer, *value, *end;

  /* find the beginning of an attribute */
  buffer = hwloc__nolibxml_import_ignore_spaces(nstate->attrbuffer);
  namelen = strspn(buffer, "abcdefghijklmnopqrstuvwxyz_");
  if (buffer[namelen] != '=' || buffer[namelen+1] != '\"')
    return -1;
  buffer[namelen] = '\0';
  *namep = buffer;

  /* find the beginning of its value, and unescape it */
  *valuep = value = buffer+namelen+2;
  len = 0; escaped = 0;
  while (value[len+escaped] != '\"') {
    if (value[len+escaped] == '&') {
      if (!strncmp(&value[1+len+escaped], "#10;", 4)) {
	escaped += 4;
	value[len] = '\n';
      } else if (!strncmp(&value[1+len+escaped], "#13;", 4)) {
	escaped += 4;
	value[len] = '\r';
      } else if (!strncmp(&value[1+len+escaped], "#9;", 3)) {
	escaped += 3;
	value[len] = '\t';
      } else if (!strncmp(&value[1+len+escaped], "quot;", 5)) {
	escaped += 5;
	value[len] = '\"';
      } else if (!strncmp(&value[1+len+escaped], "lt;", 3)) {
	escaped += 3;
	value[len] = '<';
      } else if (!strncmp(&value[1+len+escaped], "gt;", 3)) {
	escaped += 3;
	value[len] = '>';
      } else if (!strncmp(&value[1+len+escaped], "amp;", 4)) {
	escaped += 4;
	value[len] = '&';
      } else {
	return -1;
      }
    } else {
      value[len] = value[len+escaped];
    }
    len++;
    if (value[len+escaped] == '\0')
      return -1;
  }
  value[len] = '\0';

  /* find next attribute */
  end = &value[len+escaped+1]; /* skip the ending " */
  nstate->attrbuffer = hwloc__nolibxml_import_ignore_spaces(end);
  return 0;
}
static int
hwloc__nolibxml_import_close_tag(hwloc__xml_import_state_t state)
{
  hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
  char *buffer = nstate->tagbuffer;
  char *end;

  /* auto-closed tags need nothing */
  if (nstate->closed)
    return 0;

  /* find the beginning of the tag */
  buffer = hwloc__nolibxml_import_ignore_spaces(buffer);
  if (buffer[0] != '<')
    return -1;
  buffer++;

  /* find the end, mark it and return it to the parent */
  end = strchr(buffer, '>');
  if (!end)
    return -1;
  end[0] = '\0';
  nstate->tagbuffer = end+1;

  /* if closing tag, return nothing */
  if (buffer[0] != '/' || strcmp(buffer+1, nstate->tagname) )
    return -1;
  return 0;
}
static int
hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
				  hwloc__xml_import_state_t childstate,
				  char **tagp)
{
  hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
  hwloc__nolibxml_import_state_data_t nchildstate = (void*) childstate->data;
  char *buffer = nstate->tagbuffer;
  char *end;
  int namelen;

  childstate->parent = state;
  childstate->next_attr = state->next_attr;
  childstate->find_child = state->find_child;
  childstate->close_tag = state->close_tag;
  childstate->close_child = state->close_child;
  childstate->get_content = state->get_content;
  childstate->close_content = state->close_content;

  /* auto-closed tags have no children */
  if (nstate->closed)
    return 0;

  /* find the beginning of the tag */
  buffer = hwloc__nolibxml_import_ignore_spaces(buffer);
  if (buffer[0] != '<')
    return -1;
  buffer++;

  /* if closing tag, return nothing and do not advance */
  if (buffer[0] == '/')
    return 0;

  /* normal tag */
  *tagp = nchildstate->tagname = buffer;

  /* find the end, mark it and return it */
  end = strchr(buffer, '>');
  if (!end)
    return -1;
  end[0] = '\0';
  nchildstate->tagbuffer = end+1;

  /* handle auto-closing tags */
  if (end[-1] == '/') {
    nchildstate->closed = 1;
    end[-1] = '\0';
  } else
    nchildstate->closed = 0;

  /* find attributes */
  namelen = strspn(buffer, "abcdefghijklmnopqrstuvwxyz_");

  if (buffer[namelen] == '\0') {
    /* no attributes */
    nchildstate->attrbuffer = NULL;
    return 1;
  }

  if (buffer[namelen] != ' ')
    return -1;

  /* found a space, likely starting attributes */
  buffer[namelen] = '\0';
  nchildstate->attrbuffer = buffer+namelen+1;
  return 1;
}