1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-12-27 03:21:26 +03:00

add xmlGetNodePath() a cleaned up version of the Pwd shell string

* debugXML.c include/libxml/debugXML.h: add xmlGetNodePath()
  a cleaned up version of the Pwd shell string generation.
Daniel
This commit is contained in:
Daniel Veillard 2001-11-10 10:08:57 +00:00
parent be480fbbe3
commit c6e013ab52
3 changed files with 142 additions and 71 deletions

View File

@ -1,3 +1,8 @@
Sat Nov 10 11:07:26 CET 2001 Daniel Veillard <daniel@veillard.com>
* debugXML.c include/libxml/debugXML.h: add xmlGetNodePath()
a cleaned up version of the Pwd shell string generation.
Fri Nov 9 00:34:13 CET 2001 Daniel Veillard <daniel@veillard.com>
* valid.c include/libxml/tree.h: trying to fix namespaces +

View File

@ -28,6 +28,125 @@
#include <libxml/xmlerror.h>
#include <libxml/globals.h>
/**
* xmlGetNodePath:
* @node: a node
*
* Build a structure based Path for the given node
*
* Returns the new path or NULL in case of error. The caller must free
* the returned string
*/
xmlChar *
xmlGetNodePath(xmlNodePtr node)
{
xmlNodePtr cur, tmp, next;
xmlChar *buffer = NULL, *temp;
size_t buf_len;
xmlChar *buf;
char sep;
const char *name;
char nametemp[100];
int occur = 0;
if (node == NULL)
return (NULL);
buf_len = 500;
buffer = (xmlChar *) xmlMalloc(buf_len * sizeof(xmlChar));
if (buffer == NULL)
return (NULL);
buf = (xmlChar *) xmlMalloc(buf_len * sizeof(xmlChar));
if (buf == NULL) {
xmlFree(buffer);
return (NULL);
}
buffer[0] = 0;
cur = node;
do {
name = "";
sep = '?';
occur = 0;
if ((cur->type == XML_DOCUMENT_NODE) ||
(cur->type == XML_HTML_DOCUMENT_NODE)) {
if (buffer[0] == '/')
break;
sep = '/';
next = NULL;
} else if (cur->type == XML_ELEMENT_NODE) {
sep = '/';
name = (const char *) cur->name;
if (cur->ns) {
snprintf(nametemp, sizeof(nametemp) - 1,
"%s:%s", cur->ns->prefix, cur->name);
nametemp[sizeof(nametemp) - 1] = 0;
name = nametemp;
}
next = cur->parent;
/*
* Thumbler index computation
*/
tmp = cur->prev;
while (tmp != NULL) {
if (xmlStrEqual(cur->name, tmp->name))
occur++;
tmp = tmp->prev;
}
if (occur == 0) {
tmp = cur->next;
while (tmp != NULL) {
if (xmlStrEqual(cur->name, tmp->name))
occur++;
tmp = tmp->next;
}
if (occur != 0)
occur = 1;
} else
occur++;
} else if (cur->type == XML_ATTRIBUTE_NODE) {
sep = '@';
name = (const char *) (((xmlAttrPtr) cur)->name);
next = ((xmlAttrPtr) cur)->parent;
} else {
next = cur->parent;
}
/*
* Make sure there is enough room
*/
if (xmlStrlen(buffer) + sizeof(nametemp) + 20 > buf_len) {
buf_len =
2 * buf_len + xmlStrlen(buffer) + sizeof(nametemp) + 20;
temp = (xmlChar *) xmlRealloc(buffer, buf_len);
if (temp == NULL) {
xmlFree(buf);
xmlFree(buffer);
return (NULL);
}
buffer = temp;
temp = (xmlChar *) xmlRealloc(buf, buf_len);
if (temp == NULL) {
xmlFree(buf);
xmlFree(buffer);
return (NULL);
}
buf = temp;
}
if (occur == 0)
snprintf((char *) buf, buf_len, "%c%s%s",
sep, name, (char *) buffer);
else
snprintf((char *) buf, buf_len, "%c%s[%d]%s",
sep, name, occur, (char *) buffer);
snprintf((char *) buffer, buf_len, "%s", buf);
cur = next;
} while (cur != NULL);
xmlFree(buf);
return (buffer);
}
/**
* xmlDebugDumpString:
* @output: the FILE * for the output
@ -1801,81 +1920,27 @@ int
xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
{
xmlNodePtr cur, tmp, next;
char buf[500];
char sep;
const char *name;
char nametemp[100];
int occur = 0;
xmlChar *path;
buffer[0] = 0;
if (node == NULL)
return (-1);
cur = node;
do {
name = "";
sep = '?';
occur = 0;
if ((cur->type == XML_DOCUMENT_NODE) ||
(cur->type == XML_HTML_DOCUMENT_NODE)) {
sep = '/';
next = NULL;
} else if (cur->type == XML_ELEMENT_NODE) {
sep = '/';
name = (const char *) cur->name;
if (cur->ns) {
snprintf(nametemp, 99, "%s:%s", cur->ns->prefix,
cur->name);
name = nametemp;
}
next = cur->parent;
/*
* Thumbler index computation
*/
tmp = cur->prev;
while (tmp != NULL) {
if (xmlStrEqual(cur->name, tmp->name))
occur++;
tmp = tmp->prev;
}
if (occur == 0) {
tmp = cur->next;
while (tmp != NULL) {
if (xmlStrEqual(cur->name, tmp->name))
occur++;
tmp = tmp->next;
}
if (occur != 0)
occur = 1;
} else
occur++;
} else if (cur->type == XML_ATTRIBUTE_NODE) {
sep = '@';
name = (const char *) (((xmlAttrPtr) cur)->name);
next = ((xmlAttrPtr) cur)->parent;
} else {
next = cur->parent;
}
if (occur == 0)
snprintf(buf, sizeof(buf), "%c%s%s", sep, name, buffer);
else
snprintf(buf, sizeof(buf), "%c%s[%d]%s",
sep, name, occur, buffer);
buf[sizeof(buf) - 1] = 0;
/*
* This test prevents buffer overflow, because this routine
* is only called by xmlShell, in which the second argument is
* 500 chars long.
* It is a dirty hack before a cleaner solution is found.
* Documentation should mention that the second argument must
* be at least 500 chars long, and could be stripped if too long.
*/
if (strlen(buffer) + strlen(buf) > 499)
break;
strcpy(buffer, buf);
cur = next;
} while (cur != NULL);
path = xmlGetNodePath(node);
if (path == NULL)
return (-1);
/*
* This test prevents buffer overflow, because this routine
* is only called by xmlShell, in which the second argument is
* 500 chars long.
* It is a dirty hack before a cleaner solution is found.
* Documentation should mention that the second argument must
* be at least 500 chars long, and could be stripped if too long.
*/
snprintf(buffer, 499, "%s", path);
buffer[499] = '0';
xmlFree(path);
return (0);
}

View File

@ -52,6 +52,7 @@ int xmlLsCountNode (xmlNodePtr node);
const char *xmlBoolToText (int boolval);
long xmlGetLineNo (xmlNodePtr node);
xmlChar *xmlGetNodePath (xmlNodePtr node);
/****************************************************************
* *