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; }