- parser.[ch]: added xmlIOParseDTD()
- xpointer.c: added support for the 2 extra parameters of
string-range, fixed a stoopid error when '0' was present
in XPointer expressions
- test/XPath/xptr/strrange2 result/XPath/xptr/strrange2: added
testsuite for the above
Daniel
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index 17051d7..ee4c808 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -407,6 +407,9 @@
xmlDtdPtr xmlSAXParseDTD (xmlSAXHandlerPtr sax,
const xmlChar *ExternalID,
const xmlChar *SystemID);
+xmlDtdPtr xmlIOParseDTD (xmlSAXHandlerPtr sax,
+ xmlParserInputBufferPtr input,
+ xmlCharEncoding enc);
int xmlParseBalancedChunkMemory(xmlDocPtr doc,
xmlSAXHandlerPtr sax,
void *user_data,
diff --git a/parser.c b/parser.c
index 7a93285..425ef57 100644
--- a/parser.c
+++ b/parser.c
@@ -8361,6 +8361,90 @@
************************************************************************/
/**
+ * xmlIOParseDTD:
+ * @sax: the SAX handler block or NULL
+ * @input: an Input Buffer
+ * @enc: the charset encoding if known
+ *
+ * Load and parse a DTD
+ *
+ * Returns the resulting xmlDtdPtr or NULL in case of error.
+ */
+
+xmlDtdPtr
+xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
+ xmlCharEncoding enc) {
+ xmlDtdPtr ret = NULL;
+ xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr pinput = NULL;
+
+ if (input == NULL)
+ return(NULL);
+
+ ctxt = xmlNewParserCtxt();
+ if (ctxt == NULL) {
+ return(NULL);
+ }
+
+ /*
+ * Set-up the SAX context
+ */
+ if (sax != NULL) {
+ if (ctxt->sax != NULL)
+ xmlFree(ctxt->sax);
+ ctxt->sax = sax;
+ ctxt->userData = NULL;
+ }
+
+ /*
+ * generate a parser input from the I/O handler
+ */
+
+ pinput = xmlNewIOInputStream(ctxt, input, enc);
+ if (pinput == NULL) {
+ if (sax != NULL) ctxt->sax = NULL;
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
+ }
+
+ /*
+ * plug some encoding conversion routines here.
+ */
+ xmlPushInput(ctxt, pinput);
+
+ pinput->filename = NULL;
+ pinput->line = 1;
+ pinput->col = 1;
+ pinput->base = ctxt->input->cur;
+ pinput->cur = ctxt->input->cur;
+ pinput->free = NULL;
+
+ /*
+ * let's parse that entity knowing it's an external subset.
+ */
+ ctxt->inSubset = 2;
+ ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
+ ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
+ BAD_CAST "none", BAD_CAST "none");
+ xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
+
+ if (ctxt->myDoc != NULL) {
+ if (ctxt->wellFormed) {
+ ret = ctxt->myDoc->extSubset;
+ ctxt->myDoc->extSubset = NULL;
+ } else {
+ ret = NULL;
+ }
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
+ if (sax != NULL) ctxt->sax = NULL;
+ xmlFreeParserCtxt(ctxt);
+
+ return(ret);
+}
+
+/**
* xmlSAXParseDTD:
* @sax: the SAX handler block
* @ExternalID: a NAME* containing the External ID of the DTD
diff --git a/parser.h b/parser.h
index 17051d7..ee4c808 100644
--- a/parser.h
+++ b/parser.h
@@ -407,6 +407,9 @@
xmlDtdPtr xmlSAXParseDTD (xmlSAXHandlerPtr sax,
const xmlChar *ExternalID,
const xmlChar *SystemID);
+xmlDtdPtr xmlIOParseDTD (xmlSAXHandlerPtr sax,
+ xmlParserInputBufferPtr input,
+ xmlCharEncoding enc);
int xmlParseBalancedChunkMemory(xmlDocPtr doc,
xmlSAXHandlerPtr sax,
void *user_data,
diff --git a/result/XPath/xptr/strrange2 b/result/XPath/xptr/strrange2
new file mode 100644
index 0000000..ea6ee45
--- /dev/null
+++ b/result/XPath/xptr/strrange2
@@ -0,0 +1,64 @@
+
+========================
+Expression: xpointer(string-range(//p, 'test', 2))
+Object is a Location Set:
+1 : Object is a range :
+ From index 11 in node
+ TEXT
+ content=a simple test
+ To index 13 in node
+ TEXT
+ content=a simple test
+
+2 : Object is a range :
+ From index 11 in node
+ TEXT
+ content=multiple tests
+ To index 13 in node
+ TEXT
+ content=multiple tests
+
+3 : Object is a range :
+ From index 8 in node
+ TEXT
+ content=anced test
+ To index 10 in node
+ TEXT
+ content=anced test
+
+
+========================
+Expression: xpointer(string-range(//p, 'test', 2, 2))
+Object is a Location Set:
+1 : Object is a range :
+ From index 11 in node
+ TEXT
+ content=a simple test
+ To index 12 in node
+ TEXT
+ content=a simple test
+
+2 : Object is a range :
+ From index 11 in node
+ TEXT
+ content=multiple tests
+ To index 12 in node
+ TEXT
+ content=multiple tests
+
+3 : Object is a range :
+ From index 8 in node
+ TEXT
+ content=anced test
+ To index 9 in node
+ TEXT
+ content=anced test
+
+
+========================
+Expression: xpointer(string-range(//p, 'difficult', 1, 0))
+Object is a Location Set:
+1 : Object is a collapsed range :
+ index 3 in node
+ TEXT
+ content=a diff
diff --git a/test/XPath/xptr/strrange2 b/test/XPath/xptr/strrange2
new file mode 100644
index 0000000..5133547
--- /dev/null
+++ b/test/XPath/xptr/strrange2
@@ -0,0 +1,3 @@
+xpointer(string-range(//p, 'test', 2))
+xpointer(string-range(//p, 'test', 2, 2))
+xpointer(string-range(//p, 'difficult', 1, 0))
diff --git a/xpointer.c b/xpointer.c
index 77cf10e..aa4b8e0 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -964,7 +964,7 @@
}
cur = buffer;
- while (CUR != '0') {
+ while (CUR != 0) {
if (CUR == ')') {
level--;
if (level == 0) {
@@ -1989,6 +1989,7 @@
pos = 0;
}
}
+
if (cur == NULL) {
*node = NULL;
*index = 0;
@@ -2020,6 +2021,11 @@
bytes -= (len - pos);
cur = xmlXPtrAdvanceNode(cur);
cur = 0;
+ } else if (pos + bytes < len) {
+ pos += bytes;
+ *node = cur;
+ *index = pos;
+ return(0);
}
}
return(-1);
@@ -2366,7 +2372,7 @@
xmlXPathObjectPtr string;
xmlXPathObjectPtr position = NULL;
xmlXPathObjectPtr number = NULL;
- int found;
+ int found, pos, num;
/*
* Grab the arguments
@@ -2377,10 +2383,14 @@
if (nargs >= 4) {
CHECK_TYPE(XPATH_NUMBER);
number = valuePop(ctxt);
+ if (number != NULL)
+ num = number->floatval;
}
if (nargs >= 3) {
CHECK_TYPE(XPATH_NUMBER);
position = valuePop(ctxt);
+ if (position != NULL)
+ pos = position->floatval;
}
CHECK_TYPE(XPATH_STRING);
string = valuePop(ctxt);
@@ -2433,8 +2443,32 @@
found = xmlXPtrSearchString(string->stringval, &start, &startindex,
&fend, &fendindex);
if (found == 1) {
- xmlXPtrLocationSetAdd(newset,
+ if (position == NULL) {
+ xmlXPtrLocationSetAdd(newset,
xmlXPtrNewRange(start, startindex, fend, fendindex));
+ } else if (xmlXPtrAdvanceChar(&start, &startindex,
+ pos - 1) == 0) {
+ if ((number != NULL) && (num > 0)) {
+ int rindex;
+ xmlNodePtr rend;
+ rend = start;
+ rindex = startindex - 1;
+ if (xmlXPtrAdvanceChar(&rend, &rindex,
+ num) == 0) {
+ xmlXPtrLocationSetAdd(newset,
+ xmlXPtrNewRange(start, startindex,
+ rend, rindex));
+ }
+ } else if (num <= 0) {
+ xmlXPtrLocationSetAdd(newset,
+ xmlXPtrNewRange(start, startindex,
+ start, startindex));
+ } else {
+ xmlXPtrLocationSetAdd(newset,
+ xmlXPtrNewRange(start, startindex,
+ fend, fendindex));
+ }
+ }
start = fend;
startindex = fendindex;
if (string->stringval[0] == 0)