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:
parent
be480fbbe3
commit
c6e013ab52
@ -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 +
|
||||
|
207
debugXML.c
207
debugXML.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ int xmlLsCountNode (xmlNodePtr node);
|
||||
|
||||
const char *xmlBoolToText (int boolval);
|
||||
long xmlGetLineNo (xmlNodePtr node);
|
||||
xmlChar *xmlGetNodePath (xmlNodePtr node);
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
|
Loading…
Reference in New Issue
Block a user