applied patch from Richard Jinks for the namespace axis + fixed a memory
* xpath.c: applied patch from Richard Jinks for the namespace
axis + fixed a memory error.
* parser.c parserInternals.c: applied patches from Peter Jacobi
removing ctxt->token for good.
* xmlschemas.c xmlschemastypes.c: fixed a few memory leaks
popped out by the regression tests.
* Makefile.am: patch for threads makefile from Gary Pennington
Daniel
diff --git a/ChangeLog b/ChangeLog
index ae121b8..f5d21b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,16 @@
+Mon Jul 1 23:23:41 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+ * xpath.c: applied patch from Richard Jinks for the namespace
+ axis + fixed a memory error.
+ * parser.c parserInternals.c: applied patches from Peter Jacobi
+ removing ctxt->token for good.
+ * xmlschemas.c xmlschemastypes.c: fixed a few memory leaks
+ popped out by the regression tests.
+ * Makefile.am: patch for threads makefile from Gary Pennington
+
Fri Jun 28 19:38:00 HKT 2002 William Brack <wbrack@mmm.com.hk>
- * xpath.c enhanced behaviour of position() after usage of
+ * xpath.c: enhanced behaviour of position() after usage of
expressions involving preceding-sibling (et al).
Tue Jun 18 09:58:48 CEST 2002 Daniel Veillard <daniel@veillard.com>
diff --git a/Makefile.am b/Makefile.am
index 9643396..0d3162f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,7 +13,7 @@
bin_SCRIPTS=xml2-config
lib_LTLIBRARIES = libxml2.la
-libxml2_la_LIBADD = @Z_LIBS@ $(ICONV_LIBS) -lm
+libxml2_la_LIBADD = @THREAD_LIBS@ @Z_LIBS@ $(ICONV_LIBS) -lm
libxml2_la_LDFLAGS = -version-info @LIBXML_VERSION_INFO@
diff --git a/hash.c b/hash.c
index f1bfb92..28bf014 100644
--- a/hash.c
+++ b/hash.c
@@ -42,13 +42,14 @@
xmlChar *name2;
xmlChar *name3;
void *payload;
+ int valid;
};
/*
* The entire hash table
*/
struct _xmlHashTable {
- struct _xmlHashEntry **table;
+ struct _xmlHashEntry *table;
int size;
int nbElems;
};
@@ -101,9 +102,9 @@
if (table) {
table->size = size;
table->nbElems = 0;
- table->table = xmlMalloc(size * sizeof(xmlHashEntryPtr));
+ table->table = xmlMalloc(size * sizeof(xmlHashEntry));
if (table->table) {
- memset(table->table, 0, size * sizeof(xmlHashEntryPtr));
+ memset(table->table, 0, size * sizeof(xmlHashEntry));
return(table);
}
xmlFree(table);
@@ -125,7 +126,7 @@
unsigned long key;
int oldsize, i;
xmlHashEntryPtr iter, next;
- struct _xmlHashEntry **oldtable;
+ struct _xmlHashEntry *oldtable;
#ifdef DEBUG_GROW
unsigned long nbElem = 0;
#endif
@@ -142,16 +143,31 @@
if (oldtable == NULL)
return(-1);
- table->table = xmlMalloc(size * sizeof(xmlHashEntryPtr));
+ table->table = xmlMalloc(size * sizeof(xmlHashEntry));
if (table->table == NULL) {
table->table = oldtable;
return(-1);
}
- memset(table->table, 0, size * sizeof(xmlHashEntryPtr));
+ memset(table->table, 0, size * sizeof(xmlHashEntry));
table->size = size;
+ /* If the two loops are merged, there would be situations where
+ a new entry needs to allocated and data copied into it from
+ the main table. So instead, we run through the array twice, first
+ copying all the elements in the main array (where we can't get
+ conflicts) and then the rest, so we only free (and don't allocate)
+ */
for (i = 0; i < oldsize; i++) {
- iter = oldtable[i];
+ if (oldtable[i].valid == 0)
+ continue;
+ key = xmlHashComputeKey(table, oldtable[i].name, oldtable[i].name2,
+ oldtable[i].name3);
+ memcpy(&(table->table[key]), &(oldtable[i]), sizeof(xmlHashEntry));
+ table->table[key].next = NULL;
+ }
+
+ for (i = 0; i < oldsize; i++) {
+ iter = oldtable[i].next;
while (iter) {
next = iter->next;
@@ -161,8 +177,14 @@
key = xmlHashComputeKey(table, iter->name, iter->name2,
iter->name3);
- iter->next = table->table[key];
- table->table[key] = iter;
+ if (table->table[key].valid == 0) {
+ memcpy(&(table->table[key]), iter, sizeof(xmlHashEntry));
+ table->table[key].next = NULL;
+ xmlFree(iter);
+ } else {
+ iter->next = table->table[key].next;
+ table->table[key].next = iter;
+ }
#ifdef DEBUG_GROW
nbElem++;
@@ -195,12 +217,16 @@
int i;
xmlHashEntryPtr iter;
xmlHashEntryPtr next;
+ int inside_table = 0;
if (table == NULL)
return;
if (table->table) {
for(i = 0; i < table->size; i++) {
- iter = table->table[i];
+ iter = &(table->table[i]);
+ if (iter->valid == 0)
+ continue;
+ inside_table = 1;
while (iter) {
next = iter->next;
if (f)
@@ -212,10 +238,12 @@
if (iter->name3)
xmlFree(iter->name3);
iter->payload = NULL;
- xmlFree(iter);
+ if (!inside_table)
+ xmlFree(iter);
+ inside_table = 0;
iter = next;
}
- table->table[i] = NULL;
+ inside_table = 0;
}
xmlFree(table->table);
}
@@ -355,10 +383,10 @@
* Check for duplicate and insertion location.
*/
key = xmlHashComputeKey(table, name, name2, name3);
- if (table->table[key] == NULL) {
+ if (table->table[key].valid == 0) {
insert = NULL;
} else {
- for (insert = table->table[key]; insert->next != NULL;
+ for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
@@ -372,21 +400,25 @@
return(-1);
}
- entry = xmlMalloc(sizeof(xmlHashEntry));
- if (entry == NULL)
- return(-1);
+ if (insert == NULL) {
+ entry = &(table->table[key]);
+ } else {
+ entry = xmlMalloc(sizeof(xmlHashEntry));
+ if (entry == NULL)
+ return(-1);
+ }
+
entry->name = xmlStrdup(name);
entry->name2 = xmlStrdup(name2);
entry->name3 = xmlStrdup(name3);
entry->payload = userdata;
entry->next = NULL;
+ entry->valid = 1;
- if (insert == NULL) {
- table->table[key] = entry;
- } else {
+ if (insert != NULL)
insert->next = entry;
- }
+
table->nbElems++;
if (len > MAX_HASH_LEN)
@@ -425,10 +457,10 @@
* Check for duplicate and insertion location.
*/
key = xmlHashComputeKey(table, name, name2, name3);
- if (table->table[key] == NULL) {
+ if (table->table[key].valid == 0) {
insert = NULL;
} else {
- for (insert = table->table[key]; insert->next != NULL;
+ for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
@@ -449,20 +481,24 @@
}
}
- entry = xmlMalloc(sizeof(xmlHashEntry));
- if (entry == NULL)
- return(-1);
+ if (insert == NULL) {
+ entry = &(table->table[key]);
+ } else {
+ entry = xmlMalloc(sizeof(xmlHashEntry));
+ if (entry == NULL)
+ return(-1);
+ }
+
entry->name = xmlStrdup(name);
entry->name2 = xmlStrdup(name2);
entry->name3 = xmlStrdup(name3);
entry->payload = userdata;
entry->next = NULL;
+ entry->valid = 1;
table->nbElems++;
- if (insert == NULL) {
- table->table[key] = entry;
- } else {
+ if (insert != NULL) {
insert->next = entry;
}
return(0);
@@ -490,7 +526,9 @@
if (name == NULL)
return(NULL);
key = xmlHashComputeKey(table, name, name2, name3);
- for (entry = table->table[key]; entry != NULL; entry = entry->next) {
+ if (table->table[key].valid == 0)
+ return(NULL);
+ for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
if ((xmlStrEqual(entry->name, name)) &&
(xmlStrEqual(entry->name2, name2)) &&
(xmlStrEqual(entry->name3, name3)))
@@ -549,7 +587,9 @@
if (table->table) {
for(i = 0; i < table->size; i++) {
- iter = table->table[i];
+ if (table->table[i].valid == 0)
+ continue;
+ iter = &(table->table[i]);
while (iter) {
next = iter->next;
if (f)
@@ -610,7 +650,9 @@
if (table->table) {
for(i = 0; i < table->size; i++) {
- iter = table->table[i];
+ if (table->table[i].valid == 0)
+ continue;
+ iter = &(table->table[i]);
while (iter) {
next = iter->next;
if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
@@ -649,7 +691,9 @@
ret = xmlHashCreate(table->size);
if (table->table) {
for(i = 0; i < table->size; i++) {
- iter = table->table[i];
+ if (table->table[i].valid == 0)
+ continue;
+ iter = &(table->table[i]);
while (iter) {
next = iter->next;
xmlHashAddEntry3(ret, iter->name, iter->name2,
@@ -737,10 +781,10 @@
return(-1);
key = xmlHashComputeKey(table, name, name2, name3);
- if (table->table[key] == NULL) {
+ if (table->table[key].valid == 0) {
return(-1);
} else {
- for (entry = table->table[key]; entry != NULL; entry = entry->next) {
+ for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
if (xmlStrEqual(entry->name, name) &&
xmlStrEqual(entry->name2, name2) &&
xmlStrEqual(entry->name3, name3)) {
@@ -753,11 +797,18 @@
xmlFree(entry->name2);
if(entry->name3)
xmlFree(entry->name3);
- if(prev)
+ if(prev) {
prev->next = entry->next;
- else
- table->table[key] = entry->next;
- xmlFree(entry);
+ xmlFree(entry);
+ } else {
+ if (entry->next == NULL) {
+ entry->valid = 0;
+ } else {
+ entry = entry->next;
+ memcpy(&(table->table[key]), entry, sizeof(xmlHashEntry));
+ xmlFree(entry);
+ }
+ }
table->nbElems--;
return(0);
}
diff --git a/parser.c b/parser.c
index 2d08673..2338100 100644
--- a/parser.c
+++ b/parser.c
@@ -268,8 +268,8 @@
* GROW, SHRINK handling of input buffers
*/
-#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
-#define CUR (ctxt->token ? ctxt->token : (*ctxt->input->cur))
+#define RAW (*ctxt->input->cur)
+#define CUR (*ctxt->input->cur)
#define NXT(val) ctxt->input->cur[(val)]
#define CUR_PTR ctxt->input->cur
@@ -316,7 +316,7 @@
if (*(ctxt->input->cur) == '\n') { \
ctxt->input->line++; ctxt->input->col = 1; \
} else ctxt->input->col++; \
- ctxt->token = 0; ctxt->input->cur += l; \
+ ctxt->input->cur += l; \
if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
} while (0)
@@ -341,12 +341,6 @@
xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
int res = 0;
- if (ctxt->token != 0) {
- if (!IS_BLANK(ctxt->token))
- return(0);
- ctxt->token = 0;
- res++;
- }
/*
* It's Okay to use CUR/NEXT here since all the blanks are on
* the ASCII range.
@@ -465,11 +459,6 @@
unsigned int val = 0;
int count = 0;
- if (ctxt->token != 0) {
- val = ctxt->token;
- ctxt->token = 0;
- return(val);
- }
/*
* Using RAW/CUR/NEXT is okay since we are working on ASCII range here
*/
@@ -754,9 +743,6 @@
xmlEntityPtr entity = NULL;
xmlParserInputPtr input;
- if (ctxt->token != 0) {
- return;
- }
if (RAW != '%') return;
switch(ctxt->instate) {
case XML_PARSER_CDATA_SECTION:
@@ -2363,32 +2349,10 @@
* OK loop until we reach one of the ending char or a size limit.
*/
c = CUR_CHAR(l);
- while (((NXT(0) != limit) && /* checked */
- (c != '<')) || (ctxt->token != 0)) {
+ while ((NXT(0) != limit) && /* checked */
+ (c != '<')) {
if (c == 0) break;
- if (ctxt->token == '&') {
- if (ctxt->replaceEntities) {
- if (len > buf_size - 10) {
- growBuffer(buf);
- }
- buf[len++] = '&';
- } else {
- /*
- * The reparsing will be done in xmlStringGetNodeList()
- * called by the attribute() function in SAX.c
- */
- static xmlChar buffer[6] = "&";
-
- if (len > buf_size - 10) {
- growBuffer(buf);
- }
- current = &buffer[0];
- while (*current != 0) { /* non input consuming */
- buf[len++] = *current++;
- }
- ctxt->token = 0;
- }
- } else if (c == '&') {
+ if (c == '&') {
if (NXT(1) == '#') {
int val = xmlParseCharRef(ctxt);
if (val == '&') {
@@ -2707,7 +2671,7 @@
* Accelerated common case where input don't need to be
* modified before passing it to the handler.
*/
- if ((ctxt->token == 0) && (!cdata)) {
+ if (!cdata) {
in = ctxt->input->cur;
do {
get_more:
@@ -2799,9 +2763,9 @@
SHRINK;
GROW;
cur = CUR_CHAR(l);
- while (((cur != '<') || (ctxt->token == '<')) && /* checked */
- ((cur != '&') || (ctxt->token == '&')) &&
- (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
+ while ((cur != '<') && /* checked */
+ (cur != '&') &&
+ (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
if ((cur == ']') && (NXT(1) == ']') &&
(NXT(2) == '>')) {
if (cdata) break;
@@ -4960,7 +4924,6 @@
(NXT(2) != '>'))) {
const xmlChar *check = CUR_PTR;
int cons = ctxt->input->consumed;
- int tok = ctxt->token;
if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
xmlParseConditionalSections(ctxt);
@@ -4977,8 +4940,7 @@
while ((RAW == 0) && (ctxt->inputNr > 1))
xmlPopInput(ctxt);
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
- (tok == ctxt->token)) {
+ if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@@ -5270,7 +5232,6 @@
(RAW == '%') || IS_BLANK(CUR)) {
const xmlChar *check = CUR_PTR;
int cons = ctxt->input->consumed;
- int tok = ctxt->token;
GROW;
if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
@@ -5288,8 +5249,7 @@
while ((RAW == 0) && (ctxt->inputNr > 1))
xmlPopInput(ctxt);
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
- (tok == ctxt->token)) {
+ if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@@ -6884,23 +6844,16 @@
void
xmlParseContent(xmlParserCtxtPtr ctxt) {
GROW;
- while (((RAW != 0) || (ctxt->token != 0)) &&
+ while ((RAW != 0) &&
((RAW != '<') || (NXT(1) != '/'))) {
const xmlChar *test = CUR_PTR;
int cons = ctxt->input->consumed;
- int tok = ctxt->token;
const xmlChar *cur = ctxt->input->cur;
/*
- * Handle possible processed charrefs.
- */
- if (ctxt->token != 0) {
- xmlParseCharData(ctxt, 0);
- }
- /*
* First case : a Processing Instruction.
*/
- else if ((*cur == '<') && (cur[1] == '?')) {
+ if ((*cur == '<') && (cur[1] == '?')) {
xmlParsePI(ctxt);
}
@@ -6955,8 +6908,7 @@
xmlPopInput(ctxt);
SHRINK;
- if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
- (tok == ctxt->token)) {
+ if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
ctxt->errNo = XML_ERR_INTERNAL_ERROR;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@@ -8573,20 +8525,6 @@
case XML_PARSER_CONTENT: {
const xmlChar *test;
int cons;
- int tok;
-
- /*
- * Handle preparsed entities and charRef
- */
- if (ctxt->token != 0) {
- xmlChar current[2] = { 0 , 0 } ;
-
- current[0] = (xmlChar) ctxt->token;
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, current, 1);
- ctxt->token = 0;
- }
if ((avail < 2) && (ctxt->inputNr == 1))
goto done;
cur = ctxt->input->cur[0];
@@ -8594,7 +8532,6 @@
test = CUR_PTR;
cons = ctxt->input->consumed;
- tok = ctxt->token;
if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
(xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
@@ -8684,8 +8621,7 @@
*/
while ((RAW == 0) && (ctxt->inputNr > 1))
xmlPopInput(ctxt);
- if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
- (tok == ctxt->token)) {
+ if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
ctxt->errNo = XML_ERR_INTERNAL_ERROR;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
diff --git a/parserInternals.c b/parserInternals.c
index 68ac538..8d4e680 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -1110,8 +1110,7 @@
* literal #xD, an XML processor must pass to the application
* the single character #xA.
*/
- if (ctxt->token != 0) ctxt->token = 0;
- else if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
+ if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
if ((*ctxt->input->cur == 0) &&
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
(ctxt->instate != XML_PARSER_COMMENT)) {
@@ -1260,10 +1259,6 @@
if (ctxt->instate == XML_PARSER_EOF)
return(0);
- if (ctxt->token != 0) {
- *len = 0;
- return(ctxt->token);
- }
if ((*ctxt->input->cur >= 0x20) && (*ctxt->input->cur <= 0x7F)) {
*len = 1;
return((int) *ctxt->input->cur);
@@ -2785,11 +2780,11 @@
(c != end2) && (c != end3)) {
GROW;
if (c == 0) break;
- if (((c == '&') && (ctxt->token != '&')) && (NXT(1) == '#')) {
+ if ((c == '&') && (NXT(1) == '#')) {
int val = xmlParseCharRef(ctxt);
COPY_BUF(0,buffer,nbchars,val);
NEXTL(l);
- } else if ((c == '&') && (ctxt->token != '&') &&
+ } else if (c == '&') &&
(what & XML_SUBSTITUTE_REF)) {
if (xmlParserDebugEntities)
xmlGenericError(xmlGenericErrorContext,
@@ -3321,229 +3316,6 @@
deprecated = 1;
}
-#if 0
- xmlParserInputPtr input;
- xmlChar *name;
- xmlEntityPtr ent = NULL;
-
- if (ctxt->token != 0) {
- return;
- }
- if (RAW != '&') return;
- GROW;
- if ((RAW == '&') && (NXT(1) == '#')) {
- switch(ctxt->instate) {
- case XML_PARSER_ENTITY_DECL:
- case XML_PARSER_PI:
- case XML_PARSER_CDATA_SECTION:
- case XML_PARSER_COMMENT:
- case XML_PARSER_SYSTEM_LITERAL:
- /* we just ignore it there */
- return;
- case XML_PARSER_START_TAG:
- return;
- case XML_PARSER_END_TAG:
- return;
- case XML_PARSER_EOF:
- ctxt->errNo = XML_ERR_CHARREF_AT_EOF;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "CharRef at EOF\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- case XML_PARSER_PROLOG:
- case XML_PARSER_START:
- case XML_PARSER_MISC:
- ctxt->errNo = XML_ERR_CHARREF_IN_PROLOG;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "CharRef in prolog!\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- case XML_PARSER_EPILOG:
- ctxt->errNo = XML_ERR_CHARREF_IN_EPILOG;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "CharRef in epilog!\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- case XML_PARSER_DTD:
- ctxt->errNo = XML_ERR_CHARREF_IN_DTD;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "CharRef are forbidden in DTDs!\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- case XML_PARSER_ENTITY_VALUE:
- /*
- * NOTE: in the case of entity values, we don't do the
- * substitution here since we need the literal
- * entity value to be able to save the internal
- * subset of the document.
- * This will be handled by xmlStringDecodeEntities
- */
- return;
- case XML_PARSER_CONTENT:
- return;
- case XML_PARSER_ATTRIBUTE_VALUE:
- /* ctxt->token = xmlParseCharRef(ctxt); */
- return;
- case XML_PARSER_IGNORE:
- return;
- }
- return;
- }
-
- switch(ctxt->instate) {
- case XML_PARSER_CDATA_SECTION:
- return;
- case XML_PARSER_PI:
- case XML_PARSER_COMMENT:
- case XML_PARSER_SYSTEM_LITERAL:
- case XML_PARSER_CONTENT:
- return;
- case XML_PARSER_START_TAG:
- return;
- case XML_PARSER_END_TAG:
- return;
- case XML_PARSER_EOF:
- ctxt->errNo = XML_ERR_ENTITYREF_AT_EOF;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Reference at EOF\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- case XML_PARSER_PROLOG:
- case XML_PARSER_START:
- case XML_PARSER_MISC:
- ctxt->errNo = XML_ERR_ENTITYREF_IN_PROLOG;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Reference in prolog!\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- case XML_PARSER_EPILOG:
- ctxt->errNo = XML_ERR_ENTITYREF_IN_EPILOG;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Reference in epilog!\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- case XML_PARSER_ENTITY_VALUE:
- /*
- * NOTE: in the case of entity values, we don't do the
- * substitution here since we need the literal
- * entity value to be able to save the internal
- * subset of the document.
- * This will be handled by xmlStringDecodeEntities
- */
- return;
- case XML_PARSER_ATTRIBUTE_VALUE:
- /*
- * NOTE: in the case of attributes values, we don't do the
- * substitution here unless we are in a mode where
- * the parser is explicitly asked to substitute
- * entities. The SAX callback is called with values
- * without entity substitution.
- * This will then be handled by xmlStringDecodeEntities
- */
- return;
- case XML_PARSER_ENTITY_DECL:
- /*
- * we just ignore it there
- * the substitution will be done once the entity is referenced
- */
- return;
- case XML_PARSER_DTD:
- ctxt->errNo = XML_ERR_ENTITYREF_IN_DTD;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity references are forbidden in DTDs!\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- return;
- case XML_PARSER_IGNORE:
- return;
- }
-
-/* TODO: this seems not reached anymore .... Verify ... */
-xmlGenericError(xmlGenericErrorContext,
- "Reached deprecated section in xmlParserHandleReference()\n");
-xmlGenericError(xmlGenericErrorContext,
- "Please forward the document to daniel@veillard.com\n");
-xmlGenericError(xmlGenericErrorContext,
- "indicating the version: %s, thanks !\n", xmlParserVersion);
- NEXT;
- name = xmlScanName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_ENTITYREF_NO_NAME;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Entity reference: no name\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->token = '&';
- return;
- }
- if (NXT(xmlStrlen(name)) != ';') {
- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity reference: ';' expected\n");
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- ctxt->token = '&';
- xmlFree(name);
- return;
- }
- SKIP(xmlStrlen(name) + 1);
- if (ctxt->sax != NULL) {
- if (ctxt->sax->getEntity != NULL)
- ent = ctxt->sax->getEntity(ctxt->userData, name);
- }
-
- /*
- * [ WFC: Entity Declared ]
- * the Name given in the entity reference must match that in an entity
- * declaration, except that well-formed documents need not declare any
- * of the following entities: amp, lt, gt, apos, quot.
- */
- if (ent == NULL)
- ent = xmlGetPredefinedEntity(name);
- if (ent == NULL) {
- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity reference: entity %s not declared\n",
- name);
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- xmlFree(name);
- return;
- }
-
- /*
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an unparsed entity
- */
- if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity reference to unparsed entity %s\n", name);
- ctxt->wellFormed = 0;
- ctxt->disableSAX = 1;
- }
-
- if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
- ctxt->token = ent->content[0];
- xmlFree(name);
- return;
- }
- input = xmlNewEntityInputStream(ctxt, ent);
- xmlPushInput(ctxt, input);
- xmlFree(name);
-#endif
return;
}
diff --git a/result/XPath/expr/floats b/result/XPath/expr/floats
index bc3801d..b6255ce 100644
--- a/result/XPath/expr/floats
+++ b/result/XPath/expr/floats
@@ -222,3 +222,23 @@
========================
Expression: -(1 div 0) div 1
Object is a number : -Infinity
+
+========================
+Expression: 5 mod 2
+Object is a number : 1
+
+========================
+Expression: 5 mod -2
+Object is a number : 1
+
+========================
+Expression: -5 mod 2
+Object is a number : -1
+
+========================
+Expression: -5 mod -2
+Object is a number : -1
+
+========================
+Expression: 8 mod 3 = 2
+Object is a Boolean : true
diff --git a/test/XPath/expr/floats b/test/XPath/expr/floats
index 2453186..96c10d1 100644
--- a/test/XPath/expr/floats
+++ b/test/XPath/expr/floats
@@ -54,3 +54,8 @@
1 div (1 div 0)
(1 div 0) div 1
-(1 div 0) div 1
+5 mod 2
+5 mod -2
+-5 mod 2
+-5 mod -2
+8 mod 3 = 2
diff --git a/xmlschemas.c b/xmlschemas.c
index bae2c7a..99956d4 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -210,6 +210,20 @@
}
/**
+ * xmlSchemaFreeAnnot:
+ * @annot: a schema type structure
+ *
+ * Deallocate a annotation structure
+ */
+static void
+xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
+{
+ if (annot == NULL)
+ return;
+ xmlFree(annot);
+}
+
+/**
* xmlSchemaFreeNotation:
* @schema: a schema notation structure
*
@@ -310,6 +324,8 @@
xmlSchemaFreeValue(facet->val);
if (facet->regexp != NULL)
xmlRegFreeRegexp(facet->regexp);
+ if (facet->annot != NULL)
+ xmlSchemaFreeAnnot(facet->annot);
xmlFree(facet);
}
@@ -346,20 +362,6 @@
}
/**
- * xmlSchemaFreeAnnot:
- * @annot: a schema type structure
- *
- * Deallocate a annotation structure
- */
-static void
-xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
-{
- if (annot == NULL)
- return;
- xmlFree(annot);
-}
-
-/**
* xmlSchemaFree:
* @schema: a schema structure
*
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index 4d63224..0615025 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -1463,18 +1463,25 @@
q1 = xmlSchemaDateNormalize(y, (14 * SECS_PER_HOUR));
q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
- if (p1d < q1d)
+ if (p1d < q1d) {
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
return -1;
- else if (p1d == q1d) {
+ } else if (p1d == q1d) {
double sec;
sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
- if (sec < 0.0)
+ if (sec < 0.0) {
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
return -1;
- else {
+ } else {
/* normalize y - 14:00 */
q2 = xmlSchemaDateNormalize(y, -(14 * SECS_PER_HOUR));
q2d = _xmlSchemaDateCastYMToDays(q2) + q2->value.date.day;
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
+ xmlSchemaFreeValue(q2);
if (p1d > q2d)
return 1;
else if (p1d == q2d) {
@@ -1485,7 +1492,10 @@
return 2; /* indeterminate */
}
}
- }
+ } else {
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
+ }
}
} else if (y->value.date.tz_flag) {
q1 = xmlSchemaDateNormalize(y, 0);
@@ -1495,19 +1505,26 @@
p1 = xmlSchemaDateNormalize(x, -(14 * SECS_PER_HOUR));
p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
- if (p1d < q1d)
+ if (p1d < q1d) {
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
return -1;
- else if (p1d == q1d) {
+ } else if (p1d == q1d) {
double sec;
sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
- if (sec < 0.0)
+ if (sec < 0.0) {
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
return -1;
- else {
+ } else {
/* normalize x + 14:00 */
p2 = xmlSchemaDateNormalize(x, (14 * SECS_PER_HOUR));
p2d = _xmlSchemaDateCastYMToDays(p2) + p2->value.date.day;
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
+ xmlSchemaFreeValue(p2);
if (p2d > q1d)
return 1;
else if (p2d == q1d) {
@@ -1518,6 +1535,9 @@
return 2; /* indeterminate */
}
}
+ } else {
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
}
}
@@ -1531,14 +1551,20 @@
p1 = xmlSchemaDateNormalize(x, 0);
p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
- if (p1d < q1d)
+ if (p1d < q1d) {
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
return -1;
- else if (p1d > q1d)
+ } else if (p1d > q1d) {
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
return 1;
- else {
+ } else {
double sec;
sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
+ xmlSchemaFreeValue(p1);
+ xmlSchemaFreeValue(q1);
if (sec < 0.0)
return -1;
else if (sec > 0.0)
diff --git a/xpath.c b/xpath.c
index 4d2fcd7..f824989 100644
--- a/xpath.c
+++ b/xpath.c
@@ -4873,7 +4873,7 @@
void
xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
xmlXPathObjectPtr arg;
- double arg1, arg2, tmp;
+ double arg1, arg2;
arg = valuePop(ctxt);
if (arg == NULL)
@@ -4887,8 +4887,7 @@
if (arg2 == 0)
ctxt->value->floatval = xmlXPathNAN;
else {
- tmp=arg1/arg2;
- ctxt->value->floatval = arg2 * (tmp - (double)((int)tmp));
+ ctxt->value->floatval = fmod(arg1, arg2);
}
}
@@ -5443,26 +5442,28 @@
*/
xmlNodePtr
xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- xmlNodePtr ret;
-
if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
- if (cur == (xmlNodePtr) xmlXPathXMLNamespace)
- return(NULL);
- if ((cur == NULL) || (ctxt->context->tmpNsList == NULL)) {
+ if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) {
if (ctxt->context->tmpNsList != NULL)
xmlFree(ctxt->context->tmpNsList);
ctxt->context->tmpNsList =
xmlGetNsList(ctxt->context->doc, ctxt->context->node);
- if (ctxt->context->tmpNsList == NULL) return(NULL);
ctxt->context->tmpNsNr = 0;
- }
- ret = (xmlNodePtr)ctxt->context->tmpNsList[ctxt->context->tmpNsNr++];
- if (ret == NULL) {
- xmlFree(ctxt->context->tmpNsList);
- ctxt->context->tmpNsList = NULL;
+ if (ctxt->context->tmpNsList != NULL) {
+ while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) {
+ ctxt->context->tmpNsNr++;
+ }
+ }
return((xmlNodePtr) xmlXPathXMLNamespace);
}
- return(ret);
+ if (ctxt->context->tmpNsNr > 0) {
+ return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr];
+ } else {
+ if (ctxt->context->tmpNsList != NULL)
+ xmlFree(ctxt->context->tmpNsList);
+ ctxt->context->tmpNsList = NULL;
+ return(NULL);
+ }
}
/**