xml_loc
and xml_locf
. The first takes a literal locator, while
the second is a printf
-style formatted function. The only formatting directives it recognizes, however, are %s for strings
and %d for integers. Anything else will be ignored.
There are also two forms for the locator finding function: xml_getloc
and xml_getlocbuf
. The first takes an
explicit buffer for the locator to be retrieved, while the second builds the buffer using malloc
and returns it. The result
must be freed when the caller is done with it.
XMLAPI XML * xml_loc (XML * start, const char * loc) { char * mark; const char * attrval; char piece[64]; int i; int count; if (!loc) return (start); if (!*loc) return (start); if (*loc == '.') return (xml_loc (xml_first (start), loc + 1)); while (start && start->name == NULL) start = xml_next (start); if (!start) return (NULL); while (*loc == ' ') loc++; i = 0; while (*loc && *loc != '.') piece[i++] = *loc++; piece[i] = '\0'; if (*loc) loc++; while (*loc == ' ') loc++; mark = strchr (piece, ']'); if (mark) *mark = '\0'; mark = strchr (piece, '('); if (mark) { *mark++ = '\0'; count = atoi (mark); mark = NULL; } else { count = 0; mark = strchr (piece, '['); if (mark) { *mark++ = '\0'; } } while (start) { if (start->name == NULL) { start = xml_next (start); continue; } if (strcmp (start->name, piece)) { start = xml_next (start); continue; } if (count) { count --; start = xml_next (start); continue; } if (!mark) { if (*loc) return (xml_loc (xml_first (start), loc)); return (start); } attrval = xml_attrval(start, "id"); if (attrval) { if (strcmp (attrval, mark)) { start = xml_next (start); continue; } if (*loc) return (xml_loc (xml_first(start), loc)); return (start); } attrval = xml_attrval(start, "name"); if (attrval) { if (strcmp (attrval, mark)) { start = xml_next (start); continue; } if (*loc) return (xml_loc (xml_first(start), loc)); return (start); } } return (NULL); } XMLAPI XML * xml_locf (XML *start, const char * loc, ...) { va_list args; char * locator; XML * found; va_start (args, loc); locator = _xml_string_format (loc, args); va_end (args); found = xml_loc (start, locator); FREE (locator); return (found); } |
_xml_string_tackon
XMLAPI void xml_getloc (XML * xml, char *loc, int len) { int s; int count; XML * sib; if (xml->parent != NULL) { xml_getloc (xml->parent, loc, len); } else { *loc = '\0'; } s = strlen (loc); if (s > 0 && s < len-1) { strcat (loc, "."); s++; } len -= s; loc += s; if (strlen(xml->name) < len) { strcpy (loc, xml->name); } else { strncpy (loc, xml->name, len-1); loc[len-1] = '\0'; } if (xml->parent == NULL) return; sib = xml_first(xml->parent); count = 0; while (sib != xml && sib != NULL) { if (sib->name != NULL) { if (!strcmp (sib->name, xml->name)) count ++; } sib = xml_next(sib); } if (count > 0 && s > 4) { strcat (loc, "("); sprintf (loc + strlen(loc), "%d", count); strcat (loc, ")"); } } |
char * _xml_getlocbuf_buf (XML * xml, char *buffer, int *cursize, int *curptr) { int s; int count; XML * sib; char countbuf[sizeof(int) * 3 + 1]; if (xml->parent != NULL) { _xml_getlocbuf_buf (xml->parent, buffer, cursize, curptr); buffer = _xml_string_tackon (buffer, cursize, curptr, "."); } buffer = _xml_string_tackon (buffer, cursize, curptr, xml->name); if (xml->parent == NULL) return (buffer); sib = xml_first(xml->parent); count = 0; while (sib != xml && sib != NULL) { if (sib->name != NULL) { if (!strcmp (sib->name, xml->name)) count ++; } sib = xml_next(sib); } if (count > 0) { buffer = _xml_string_tackon (buffer, cursize, curptr, "("); sprintf (countbuf, "%d", count); buffer = _xml_string_tackon (buffer, cursize, curptr, countbuf); buffer = _xml_string_tackon (buffer, cursize, curptr, ")"); } return (buffer); } XMLAPI char * xml_getlocbuf (XML * xml) { char * buf = (char *) MALLOC (256); int cursize = 256; int curptr = 0; *buf = '\0'; return (_xml_getlocbuf_buf (xml, buf, &cursize, &curptr)); } |
This code and documentation are released under the terms of the GNU license. They are additionally copyright (c) 2000, Vivtek. All rights reserved except those explicitly granted under the terms of the GNU license. This presentation was created using LPML. |