moved xmlGetLineNo() and xmlGetNodePath() into the main tree module, they
* tree.c debugXML.c include/libxml/tree.h include/libxml/debugXML.h:
moved xmlGetLineNo() and xmlGetNodePath() into the main tree module,
they are not really tied to debugging
Daniel
diff --git a/tree.c b/tree.c
index 17a63e9..56a11a1 100644
--- a/tree.c
+++ b/tree.c
@@ -2999,6 +2999,155 @@
************************************************************************/
/**
+ * xmlGetLineNo:
+ * @node : valid node
+ *
+ * Get line number of node. this requires activation of this option
+ * before inoking the parser by calling xmlLineNumbersDefault(1)
+ *
+ * Returns the line number if sucessfull, -1 otherwise
+ */
+long
+xmlGetLineNo(xmlNodePtr node)
+{
+ long result = -1;
+
+ if (!node)
+ return result;
+ if (node->type == XML_ELEMENT_NODE)
+ result = (long) node->content;
+ else if ((node->prev != NULL) &&
+ ((node->prev->type == XML_ELEMENT_NODE) ||
+ (node->prev->type == XML_TEXT_NODE)))
+ result = xmlGetLineNo(node->prev);
+ else if ((node->parent != NULL) &&
+ ((node->parent->type == XML_ELEMENT_NODE) ||
+ (node->parent->type == XML_TEXT_NODE)))
+ result = xmlGetLineNo(node->parent);
+
+ return result;
+}
+
+/**
+ * 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);
+}
+
+/**
* xmlDocGetRootElement:
* @doc: the document
*