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/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);
}