diff --git a/ChangeLog b/ChangeLog
index 004eacbc..c9709b9a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Tue Oct 24 18:49:34 CEST 2000 Daniel Veillard
+
+ * hash.[ch] debugXML.c: expanded/enhanced the API, added
+ multikey tuples, made hash structure opaque
+ * valid.[ch]: moved elements, attributes, notations decalarations
+ as well as ID and refs to hash tables.
+ * entities.c: hash cleanup
+ * xmlmemory.c: fixed a dump problem in debug mode
+ * include/Makefile.am: problem passing in DESTDIR= values patch
+ from Marc Christensen
+ * nanohttp.c: removed debugging remains
+ * HTMLparser.c: the bogus tag should be ignored (Wayne)
+ * HTMLparser.c parser.c: fixing a number of problems with the
+ macros in the *parser.c files (Wayne).
+ * HTMLparser.c: close the previous option when opening a new one
+ (Marc Sanfacon).
+ * result/HTML/*: updated the HTML results accordingly
+
Sun Oct 22 18:39:19 CEST 2000 Daniel Veillard
* entities.[ch] xpath.[ch] hash.[ch] debugXML.c tree.h: added/hacked
diff --git a/HTMLparser.c b/HTMLparser.c
index 5750bf42..4ded5441 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -139,24 +139,25 @@ PUSH_AND_POP(extern, xmlChar*, name)
#define CURRENT ((int) (*ctxt->input->cur))
-#define SKIP_BLANKS htmlSkipBlankChars(ctxt);
+#define SKIP_BLANKS htmlSkipBlankChars(ctxt)
/* Inported from XML */
/* #define CUR (ctxt->token ? ctxt->token : (int) (*ctxt->input->cur)) */
#define CUR ((int) (*ctxt->input->cur))
-#define NEXT xmlNextChar(ctxt);ctxt->nbChars++;
+#define NEXT xmlNextChar(ctxt),ctxt->nbChars++
#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
#define NXT(val) ctxt->input->cur[(val)]
#define CUR_PTR ctxt->input->cur
-#define NEXTL(l) \
+#define NEXTL(l) do { \
if (*(ctxt->input->cur) == '\n') { \
ctxt->input->line++; ctxt->input->col = 1; \
} else ctxt->input->col++; \
- ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++;
+ ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++; \
+ } while (0)
/************
\
@@ -164,12 +165,12 @@ PUSH_AND_POP(extern, xmlChar*, name)
if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
************/
-#define CUR_CHAR(l) htmlCurrentChar(ctxt, &l);
-#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l);
+#define CUR_CHAR(l) htmlCurrentChar(ctxt, &l)
+#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
#define COPY_BUF(l,b,i,v) \
if (l == 1) b[i++] = (xmlChar) v; \
- else i += xmlCopyChar(l,&b[i],v);
+ else i += xmlCopyChar(l,&b[i],v)
/**
* htmlCurrentChar:
@@ -540,6 +541,7 @@ char *htmlStartClose[] = {
"tbody", "th", "td", "tr", "caption", "col", "colgroup", "thead",
"tfoot", "tbody", "p", NULL,
"optgroup", "option", NULL,
+"option", "option", NULL,
"fieldset", "legend", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6",
"pre", "listing", "xmp", "a", NULL,
NULL
@@ -2894,6 +2896,9 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
ctxt->sax->error(ctxt->userData,
"htmlParseStartTag: invalid element name\n");
ctxt->wellFormed = 0;
+ /* Dump the bogus tag like browsers do */
+ while ((IS_CHAR(CUR)) && (CUR != '>'))
+ NEXT;
return;
}
if (xmlStrEqual(name, BAD_CAST"meta"))
@@ -2969,6 +2974,13 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
atts[nbatts] = NULL;
atts[nbatts + 1] = NULL;
}
+ else {
+ /* Dump the bogus attribute string up to the next blank or
+ * the end of the tag. */
+ while ((IS_CHAR(CUR)) && !(IS_BLANK(CUR)) && (CUR != '>')
+ && ((CUR != '/') || (NXT(1) != '>')))
+ NEXT;
+ }
failed:
SKIP_BLANKS;
diff --git a/debugXML.c b/debugXML.c
index 2ebb57e2..22172edb 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -771,11 +771,41 @@ void xmlDebugDumpDTD(FILE *output, xmlDtdPtr dtd) {
xmlDebugDumpNodeList(output, dtd->children, 1);
}
-void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) {
- int i;
- xmlHashEntryPtr ent;
- xmlEntityPtr cur;
+void xmlDebugDumpEntityCallback(xmlEntityPtr cur, FILE *output,
+ const xmlChar *name) {
+ fprintf(output, "%s : ", cur->name);
+ switch (cur->etype) {
+ case XML_INTERNAL_GENERAL_ENTITY:
+ fprintf(output, "INTERNAL GENERAL, ");
+ break;
+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+ fprintf(output, "EXTERNAL PARSED, ");
+ break;
+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+ fprintf(output, "EXTERNAL UNPARSED, ");
+ break;
+ case XML_INTERNAL_PARAMETER_ENTITY:
+ fprintf(output, "INTERNAL PARAMETER, ");
+ break;
+ case XML_EXTERNAL_PARAMETER_ENTITY:
+ fprintf(output, "EXTERNAL PARAMETER, ");
+ break;
+ default:
+ fprintf(output, "UNKNOWN TYPE %d",
+ cur->etype);
+ }
+ if (cur->ExternalID != NULL)
+ fprintf(output, "ID \"%s\"", cur->ExternalID);
+ if (cur->SystemID != NULL)
+ fprintf(output, "SYSTEM \"%s\"", cur->SystemID);
+ if (cur->orig != NULL)
+ fprintf(output, "\n orig \"%s\"", cur->orig);
+ if (cur->content != NULL)
+ fprintf(output, "\n content \"%s\"", cur->content);
+ fprintf(output, "\n");
+}
+void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) {
if (output == NULL) output = stdout;
if (doc == NULL) {
fprintf(output, "DOCUMENT == NULL !\n");
@@ -829,86 +859,14 @@ void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) {
xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
doc->intSubset->entities;
fprintf(output, "Entities in internal subset\n");
- for (i = 0;i < table->size;i++) {
- ent = table->table[i];
- while (ent != NULL) {
- cur = (xmlEntityPtr) ent->payload;
- fprintf(output, "%d : %s : ", i, cur->name);
- switch (cur->etype) {
- case XML_INTERNAL_GENERAL_ENTITY:
- fprintf(output, "INTERNAL GENERAL, ");
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- fprintf(output, "EXTERNAL PARSED, ");
- break;
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- fprintf(output, "EXTERNAL UNPARSED, ");
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- fprintf(output, "INTERNAL PARAMETER, ");
- break;
- case XML_EXTERNAL_PARAMETER_ENTITY:
- fprintf(output, "EXTERNAL PARAMETER, ");
- break;
- default:
- fprintf(output, "UNKNOWN TYPE %d",
- cur->etype);
- }
- if (cur->ExternalID != NULL)
- fprintf(output, "ID \"%s\"", cur->ExternalID);
- if (cur->SystemID != NULL)
- fprintf(output, "SYSTEM \"%s\"", cur->SystemID);
- if (cur->orig != NULL)
- fprintf(output, "\n orig \"%s\"", cur->orig);
- if (cur->content != NULL)
- fprintf(output, "\n content \"%s\"", cur->content);
- fprintf(output, "\n");
- ent = ent->next;
- }
- }
+ xmlHashScan(table, (xmlHashScanner)xmlDebugDumpEntityCallback, output);
} else
fprintf(output, "No entities in internal subset\n");
if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
doc->extSubset->entities;
fprintf(output, "Entities in external subset\n");
- for (i = 0;i < table->size;i++) {
- ent = table->table[i];
- while (ent != NULL) {
- cur = (xmlEntityPtr) ent->payload;
- fprintf(output, "%d : %s : ", i, cur->name);
- switch (cur->etype) {
- case XML_INTERNAL_GENERAL_ENTITY:
- fprintf(output, "INTERNAL GENERAL, ");
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- fprintf(output, "EXTERNAL PARSED, ");
- break;
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- fprintf(output, "EXTERNAL UNPARSED, ");
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- fprintf(output, "INTERNAL PARAMETER, ");
- break;
- case XML_EXTERNAL_PARAMETER_ENTITY:
- fprintf(output, "EXTERNAL PARAMETER, ");
- break;
- default:
- fprintf(output, "UNKNOWN TYPE %d",
- cur->etype);
- }
- if (cur->ExternalID != NULL)
- fprintf(output, "ID \"%s\"", cur->ExternalID);
- if (cur->SystemID != NULL)
- fprintf(output, "SYSTEM \"%s\"", cur->SystemID);
- if (cur->orig != NULL)
- fprintf(output, "\n orig \"%s\"", cur->orig);
- if (cur->content != NULL)
- fprintf(output, "\n content \"%s\"", cur->content);
- fprintf(output, "\n");
- ent = ent->next;
- }
- }
+ xmlHashScan(table, (xmlHashScanner)xmlDebugDumpEntityCallback, output);
} else
fprintf(output, "No entities in external subset\n");
}
diff --git a/entities.c b/entities.c
index d609fd34..f855f062 100644
--- a/entities.c
+++ b/entities.c
@@ -153,6 +153,7 @@ xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
* entity was already defined at another level.
*/
xmlFreeEntity(ret);
+ return(NULL);
}
return(ret);
}
diff --git a/hash.c b/hash.c
index bb190c45..a5c2770e 100644
--- a/hash.c
+++ b/hash.c
@@ -21,6 +21,27 @@
#include
#include
+/*
+ * A single entry in the hash table
+ */
+typedef struct _xmlHashEntry xmlHashEntry;
+typedef xmlHashEntry *xmlHashEntryPtr;
+struct _xmlHashEntry {
+ struct _xmlHashEntry *next;
+ xmlChar *name;
+ xmlChar *name2;
+ xmlChar *name3;
+ void *payload;
+};
+
+/*
+ * The entire hash table
+ */
+struct _xmlHashTable {
+ struct _xmlHashEntry **table;
+ int size;
+};
+
/*
* xmlHashComputeKey:
* Calculate the hash key
@@ -88,8 +109,12 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
next = iter->next;
if (iter->name)
xmlFree(iter->name);
+ if (iter->name2)
+ xmlFree(iter->name2);
+ if (iter->name3)
+ xmlFree(iter->name3);
if (f)
- f(iter->payload);
+ f(iter->payload, iter->name);
iter->payload = NULL;
xmlFree(iter);
iter = next;
@@ -114,43 +139,25 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
*/
int
xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
- unsigned long key;
- xmlHashEntryPtr entry;
- xmlHashEntryPtr insert;
+ return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
+}
- if ((table == NULL) || name == NULL)
- return(-1);
-
- /*
- * Check for duplicate and insertion location.
- */
- key = xmlHashComputeKey(table, name);
- if (table->table[key] == NULL) {
- insert = NULL;
- } else {
- for (insert = table->table[key]; insert->next != NULL;
- insert = insert->next) {
- if (xmlStrEqual(insert->name, name))
- return(-1);
- }
- if (xmlStrEqual(insert->name, name))
- return(-1);
- }
-
- entry = xmlMalloc(sizeof(xmlHashEntry));
- if (entry == NULL)
- return(-1);
- entry->name = xmlStrdup(name);
- entry->payload = userdata;
- entry->next = NULL;
-
-
- if (insert == NULL) {
- table->table[key] = entry;
- } else {
- insert->next = entry;
- }
- return(0);
+/**
+ * xmlHashAddEntry2:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @userdata: a pointer to the userdata
+ *
+ * Add the userdata to the hash table. This can later be retrieved
+ * by using the (name, name2) tuple. Duplicate tuples generate errors.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name,
+ const xmlChar *name2, void *userdata) {
+ return(xmlHashAddEntry3(table, name, name2, NULL, userdata));
}
/**
@@ -169,6 +176,78 @@ xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
int
xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
void *userdata, xmlHashDeallocator f) {
+ return(xmlHashUpdateEntry3(table, name, NULL, NULL, userdata, f));
+}
+
+/**
+ * xmlHashUpdateEntry2:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @userdata: a pointer to the userdata
+ * @f: the deallocator function for replaced item (if any)
+ *
+ * Add the userdata to the hash table. This can later be retrieved
+ * by using the (name, name2) tuple. Existing entry for this tuple will
+ * be removed and freed with @f if found.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name,
+ const xmlChar *name2, void *userdata,
+ xmlHashDeallocator f) {
+ return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f));
+}
+
+/**
+ * xmlHashLookup:
+ * @table: the hash table
+ * @name: the name of the userdata
+ *
+ * Find the userdata specified by the name.
+ *
+ * Returns the a pointer to the userdata
+ */
+void *
+xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
+ return(xmlHashLookup3(table, name, NULL, NULL));
+}
+
+/**
+ * xmlHashLookup2:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ *
+ * Find the userdata specified by the (name, name2) tuple.
+ *
+ * Returns the a pointer to the userdata
+ */
+void *
+xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name,
+ const xmlChar *name2) {
+ return(xmlHashLookup3(table, name, name2, NULL));
+}
+
+/**
+ * xmlHashAddEntry3:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @name3: a third name of the userdata
+ * @userdata: a pointer to the userdata
+ *
+ * Add the userdata to the hash table. This can later be retrieved
+ * by using the tuple (name, name2, name3). Duplicate entries generate
+ * errors.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
+ const xmlChar *name2, const xmlChar *name3,
+ void *userdata) {
unsigned long key;
xmlHashEntryPtr entry;
xmlHashEntryPtr insert;
@@ -185,16 +264,84 @@ xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
} else {
for (insert = table->table[key]; insert->next != NULL;
insert = insert->next) {
- if (xmlStrEqual(insert->name, name)) {
+ if ((xmlStrEqual(insert->name, name)) &&
+ (xmlStrEqual(insert->name2, name2)) &&
+ (xmlStrEqual(insert->name3, name3)))
+ return(-1);
+ }
+ if ((xmlStrEqual(insert->name, name)) &&
+ (xmlStrEqual(insert->name2, name2)) &&
+ (xmlStrEqual(insert->name3, name3)))
+ return(-1);
+ }
+
+ 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;
+
+
+ if (insert == NULL) {
+ table->table[key] = entry;
+ } else {
+ insert->next = entry;
+ }
+ return(0);
+}
+
+/**
+ * xmlHashUpdateEntry3:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @name3: a third name of the userdata
+ * @userdata: a pointer to the userdata
+ * @f: the deallocator function for replaced item (if any)
+ *
+ * Add the userdata to the hash table. This can later be retrieved
+ * by using the tuple (name, name2, name3). Existing entry for this tuple
+ * will be removed and freed with @f if found.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
+ const xmlChar *name2, const xmlChar *name3,
+ void *userdata, xmlHashDeallocator f) {
+ unsigned long key;
+ xmlHashEntryPtr entry;
+ xmlHashEntryPtr insert;
+
+ if ((table == NULL) || name == NULL)
+ return(-1);
+
+ /*
+ * Check for duplicate and insertion location.
+ */
+ key = xmlHashComputeKey(table, name);
+ if (table->table[key] == NULL) {
+ insert = NULL;
+ } else {
+ for (insert = table->table[key]; insert->next != NULL;
+ insert = insert->next) {
+ if ((xmlStrEqual(insert->name, name)) &&
+ (xmlStrEqual(insert->name2, name2)) &&
+ (xmlStrEqual(insert->name3, name3))) {
if (f)
- f(insert->payload);
+ f(insert->payload, insert->name);
insert->payload = userdata;
return(0);
}
}
- if (xmlStrEqual(insert->name, name)) {
+ if ((xmlStrEqual(insert->name, name)) &&
+ (xmlStrEqual(insert->name2, name2)) &&
+ (xmlStrEqual(insert->name3, name3))) {
if (f)
- f(insert->payload);
+ f(insert->payload, insert->name);
insert->payload = userdata;
return(0);
}
@@ -204,6 +351,8 @@ xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
if (entry == NULL)
return(-1);
entry->name = xmlStrdup(name);
+ entry->name2 = xmlStrdup(name2);
+ entry->name3 = xmlStrdup(name3);
entry->payload = userdata;
entry->next = NULL;
@@ -220,13 +369,16 @@ xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
* xmlHashLookup:
* @table: the hash table
* @name: the name of the userdata
+ * @name2: a second name of the userdata
+ * @name3: a third name of the userdata
*
- * Find the userdata specified by the name.
+ * Find the userdata specified by the (name, name2, name3) tuple.
*
* Returns the a pointer to the userdata
*/
void *
-xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
+xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
+ const xmlChar *name2, const xmlChar *name3) {
unsigned long key;
xmlHashEntryPtr entry;
@@ -236,7 +388,9 @@ xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
return(NULL);
key = xmlHashComputeKey(table, name);
for (entry = table->table[key]; entry != NULL; entry = entry->next) {
- if (xmlStrEqual(name, entry->name))
+ if ((xmlStrEqual(entry->name, name)) &&
+ (xmlStrEqual(entry->name2, name2)) &&
+ (xmlStrEqual(entry->name3, name3)))
return(entry->payload);
}
return(NULL);
@@ -267,7 +421,49 @@ xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
while (iter) {
next = iter->next;
if (f)
- f(iter->payload, data);
+ f(iter->payload, data, iter->name);
+ iter = next;
+ }
+ }
+ }
+}
+
+/**
+ * xmlHashScan3:
+ * @table: the hash table
+ * @name: the name of the userdata or NULL
+ * @name2: a second name of the userdata or NULL
+ * @name3: a third name of the userdata or NULL
+ * @f: the scanner function for items in the hash
+ * @data: extra data passed to f
+ *
+ * Scan the hash table and applied f to each value matching
+ * (name, name2, name3) tuple. If one of the names is null,
+ * the comparison is considered to match.
+ */
+void
+xmlHashScan3(xmlHashTablePtr table, const xmlChar *name,
+ const xmlChar *name2, const xmlChar *name3,
+ xmlHashScanner f, void *data) {
+ int i;
+ xmlHashEntryPtr iter;
+ xmlHashEntryPtr next;
+
+ if (table == NULL)
+ return;
+ if (f == NULL)
+ return;
+
+ if (table->table) {
+ for(i = 0; i < table->size; i++) {
+ iter = table->table[i];
+ while (iter) {
+ next = iter->next;
+ if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
+ ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) &&
+ ((name3 == NULL) || (xmlStrEqual(name3, iter->name3)))) {
+ f(iter->payload, data, iter->name);
+ }
iter = next;
}
}
@@ -301,7 +497,8 @@ xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
iter = table->table[i];
while (iter) {
next = iter->next;
- xmlHashAddEntry(ret, iter->name, f(iter));
+ xmlHashAddEntry3(ret, iter->name, iter->name2,
+ iter->name3, f(iter->payload, iter->name));
iter = next;
}
}
diff --git a/hash.h b/hash.h
index 399e40aa..e0453136 100644
--- a/hash.h
+++ b/hash.h
@@ -25,32 +25,17 @@ extern "C" {
#endif
/*
- * A single entry in the hash table
- */
-typedef struct _xmlHashEntry xmlHashEntry;
-typedef xmlHashEntry *xmlHashEntryPtr;
-struct _xmlHashEntry {
- struct _xmlHashEntry *next;
- xmlChar *name;
- void *payload;
-};
-
-/*
- * The entire hash table
+ * The hash table
*/
typedef struct _xmlHashTable xmlHashTable;
typedef xmlHashTable *xmlHashTablePtr;
-struct _xmlHashTable {
- struct _xmlHashEntry **table;
- int size;
-};
/*
* function types:
*/
-typedef void (*xmlHashDeallocator)(void *payload);
-typedef void *(*xmlHashCopier)(void *payload);
-typedef void *(*xmlHashScanner)(void *payload, void *data);
+typedef void (*xmlHashDeallocator)(void *payload, xmlChar *name);
+typedef void *(*xmlHashCopier)(void *payload, xmlChar *name);
+typedef void *(*xmlHashScanner)(void *payload, void *data, xmlChar *name);
/*
* Constructor and destructor
@@ -69,11 +54,38 @@ int xmlHashUpdateEntry(xmlHashTablePtr table,
const xmlChar *name,
void *userdata,
xmlHashDeallocator f);
+int xmlHashAddEntry2(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ void *userdata);
+int xmlHashUpdateEntry2(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ void *userdata,
+ xmlHashDeallocator f);
+int xmlHashAddEntry3(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ void *userdata);
+int xmlHashUpdateEntry3(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ void *userdata,
+ xmlHashDeallocator f);
/*
* Retrieve the userdata
*/
void * xmlHashLookup (xmlHashTablePtr table,
const xmlChar *name);
+void * xmlHashLookup2 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2);
+void * xmlHashLookup3 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3);
/*
* Helpers
@@ -83,6 +95,21 @@ xmlHashTablePtr xmlHashCopy (xmlHashTablePtr table,
void xmlHashScan (xmlHashTablePtr table,
xmlHashScanner f,
void *data);
+void xmlHashScan1 (xmlHashTablePtr table,
+ const xmlChar *name,
+ xmlHashScanner f,
+ void *data);
+void xmlHashScan2 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ xmlHashScanner f,
+ void *data);
+void xmlHashScan3 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ xmlHashScanner f,
+ void *data);
#ifdef __cplusplus
}
#endif
diff --git a/include/Makefile.am b/include/Makefile.am
index 18d7cfaa..6c11a310 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -27,6 +27,6 @@ xmlinc_HEADERS = \
libxml/xmlversion.h
install-exec-hook:
- $(mkinstalldirs) $(xmlincdir) $(xmlincdir)/libxml
+ $(mkinstalldirs) $(DESTDIR)$(xmlincdir) $(DESTDIR)$(xmlincdir)/libxml
EXTRA_DIST = win32config.h
diff --git a/include/libxml/hash.h b/include/libxml/hash.h
index 399e40aa..e0453136 100644
--- a/include/libxml/hash.h
+++ b/include/libxml/hash.h
@@ -25,32 +25,17 @@ extern "C" {
#endif
/*
- * A single entry in the hash table
- */
-typedef struct _xmlHashEntry xmlHashEntry;
-typedef xmlHashEntry *xmlHashEntryPtr;
-struct _xmlHashEntry {
- struct _xmlHashEntry *next;
- xmlChar *name;
- void *payload;
-};
-
-/*
- * The entire hash table
+ * The hash table
*/
typedef struct _xmlHashTable xmlHashTable;
typedef xmlHashTable *xmlHashTablePtr;
-struct _xmlHashTable {
- struct _xmlHashEntry **table;
- int size;
-};
/*
* function types:
*/
-typedef void (*xmlHashDeallocator)(void *payload);
-typedef void *(*xmlHashCopier)(void *payload);
-typedef void *(*xmlHashScanner)(void *payload, void *data);
+typedef void (*xmlHashDeallocator)(void *payload, xmlChar *name);
+typedef void *(*xmlHashCopier)(void *payload, xmlChar *name);
+typedef void *(*xmlHashScanner)(void *payload, void *data, xmlChar *name);
/*
* Constructor and destructor
@@ -69,11 +54,38 @@ int xmlHashUpdateEntry(xmlHashTablePtr table,
const xmlChar *name,
void *userdata,
xmlHashDeallocator f);
+int xmlHashAddEntry2(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ void *userdata);
+int xmlHashUpdateEntry2(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ void *userdata,
+ xmlHashDeallocator f);
+int xmlHashAddEntry3(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ void *userdata);
+int xmlHashUpdateEntry3(xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ void *userdata,
+ xmlHashDeallocator f);
/*
* Retrieve the userdata
*/
void * xmlHashLookup (xmlHashTablePtr table,
const xmlChar *name);
+void * xmlHashLookup2 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2);
+void * xmlHashLookup3 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3);
/*
* Helpers
@@ -83,6 +95,21 @@ xmlHashTablePtr xmlHashCopy (xmlHashTablePtr table,
void xmlHashScan (xmlHashTablePtr table,
xmlHashScanner f,
void *data);
+void xmlHashScan1 (xmlHashTablePtr table,
+ const xmlChar *name,
+ xmlHashScanner f,
+ void *data);
+void xmlHashScan2 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ xmlHashScanner f,
+ void *data);
+void xmlHashScan3 (xmlHashTablePtr table,
+ const xmlChar *name,
+ const xmlChar *name2,
+ const xmlChar *name3,
+ xmlHashScanner f,
+ void *data);
#ifdef __cplusplus
}
#endif
diff --git a/include/libxml/valid.h b/include/libxml/valid.h
index ff7a9af1..54babdde 100644
--- a/include/libxml/valid.h
+++ b/include/libxml/valid.h
@@ -37,6 +37,8 @@ struct _xmlValidCtxt {
xmlNodePtr *nodeTab; /* array of nodes */
int finishDtd; /* finished validating the Dtd ? */
+ xmlDocPtr doc; /* the document */
+ int valid; /* temporary validity check result */
};
/*
@@ -44,76 +46,40 @@ struct _xmlValidCtxt {
* there is one table per DTD
*/
-#define XML_MIN_NOTATION_TABLE 32
-
-typedef struct _xmlNotationTable xmlNotationTable;
+typedef struct _xmlHashTable xmlNotationTable;
typedef xmlNotationTable *xmlNotationTablePtr;
-struct _xmlNotationTable {
- int nb_notations; /* number of notations stored */
- int max_notations; /* maximum number of notations */
- xmlNotationPtr *table; /* the table of attributes */
-};
/*
* ALl element declarations are stored in a table
* there is one table per DTD
*/
-#define XML_MIN_ELEMENT_TABLE 32
-
-typedef struct _xmlElementTable xmlElementTable;
+typedef struct _xmlHashTable xmlElementTable;
typedef xmlElementTable *xmlElementTablePtr;
-struct _xmlElementTable {
- int nb_elements; /* number of elements stored */
- int max_elements; /* maximum number of elements */
- xmlElementPtr *table; /* the table of elements */
- int last; /* last element accessed */
-};
/*
* ALl attribute declarations are stored in a table
* there is one table per DTD
*/
-#define XML_MIN_ATTRIBUTE_TABLE 32
-
-typedef struct _xmlAttributeTable xmlAttributeTable;
+typedef struct _xmlHashTable xmlAttributeTable;
typedef xmlAttributeTable *xmlAttributeTablePtr;
-struct _xmlAttributeTable {
- int nb_attributes; /* number of attributes stored */
- int max_attributes; /* maximum number of attributes */
- xmlAttributePtr *table; /* the table of attributes */
-};
/*
* ALl IDs attributes are stored in a table
* there is one table per document
*/
-#define XML_MIN_ID_TABLE 32
-
-typedef struct _xmlIDTable xmlIDTable;
+typedef struct _xmlHashTable xmlIDTable;
typedef xmlIDTable *xmlIDTablePtr;
-struct _xmlIDTable {
- int nb_ids; /* number of ids stored */
- int max_ids; /* maximum number of ids */
- xmlIDPtr *table; /* the table of ids */
-};
/*
* ALl Refs attributes are stored in a table
* there is one table per document
*/
-#define XML_MIN_REF_TABLE 32
-
-typedef struct _xmlRefTable xmlRefTable;
+typedef struct _xmlHashTable xmlRefTable;
typedef xmlRefTable *xmlRefTablePtr;
-struct _xmlRefTable {
- int nb_refs; /* number of refs stored */
- int max_refs; /* maximum number of refs */
- xmlRefPtr *table; /* the table of refs */
-};
/* Notation */
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h
index add4edda..0d2fa168 100644
--- a/include/libxml/xpath.h
+++ b/include/libxml/xpath.h
@@ -177,9 +177,9 @@ struct _xmlXPathContext {
xmlDocPtr doc; /* The current document */
xmlNodePtr node; /* The current node */
- int nb_variables; /* number of defined variables */
- int max_variables; /* max number of variables */
- xmlXPathVariablePtr variables; /* Array of defined variables */
+ int nb_variables_unused; /* unused (hash table) */
+ int max_variables_unused; /* unused (hash table) */
+ xmlHashTablePtr varHash; /* Hash table of defined variables */
int nb_types; /* number of defined types */
int max_types; /* max number of types */
diff --git a/nanohttp.c b/nanohttp.c
index a1cadd61..302988cc 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -966,9 +966,6 @@ xmlNanoHTTPClose(void *ctx) {
xmlNanoHTTPFreeCtxt(ctxt);
}
-#ifndef DEBUG_HTTP
-#define DEBUG_HTTP
-#endif
/**
* xmlNanoHTTPMethod:
* @URL: The URL to load
diff --git a/parser.c b/parser.c
index 675c82a8..9d21fecb 100644
--- a/parser.c
+++ b/parser.c
@@ -215,41 +215,48 @@ int spacePop(xmlParserCtxtPtr ctxt) {
#define NXT(val) ctxt->input->cur[(val)]
#define CUR_PTR ctxt->input->cur
-#define SKIP(val) ctxt->nbChars += (val),ctxt->input->cur += (val); \
+#define SKIP(val) do { \
+ ctxt->nbChars += (val),ctxt->input->cur += (val); \
if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
/* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */\
if ((*ctxt->input->cur == 0) && \
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
- xmlPopInput(ctxt)
+ xmlPopInput(ctxt); \
+ } while (0)
-#define SHRINK xmlParserInputShrink(ctxt->input); \
+#define SHRINK do { \
+ xmlParserInputShrink(ctxt->input); \
if ((*ctxt->input->cur == 0) && \
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
- xmlPopInput(ctxt)
+ xmlPopInput(ctxt); \
+ } while (0)
-#define GROW xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \
+#define GROW do { \
+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \
if ((*ctxt->input->cur == 0) && \
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
- xmlPopInput(ctxt)
+ xmlPopInput(ctxt); \
+ } while (0)
-#define SKIP_BLANKS xmlSkipBlankChars(ctxt);
+#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
-#define NEXT xmlNextChar(ctxt);
+#define NEXT xmlNextChar(ctxt)
-#define NEXTL(l) \
+#define NEXTL(l) do { \
if (*(ctxt->input->cur) == '\n') { \
ctxt->input->line++; ctxt->input->col = 1; \
} else ctxt->input->col++; \
ctxt->token = 0; ctxt->input->cur += l; \
if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
- /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */
+ /* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */\
+ } while (0)
-#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l);
-#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l);
+#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
+#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
#define COPY_BUF(l,b,i,v) \
if (l == 1) b[i++] = (xmlChar) v; \
- else i += xmlCopyChar(l,&b[i],v);
+ else i += xmlCopyChar(l,&b[i],v)
/**
* xmlSkipBlankChars:
diff --git a/result/HTML/doc3.htm b/result/HTML/doc3.htm
index 65ab90db..7fd1db6f 100644
--- a/result/HTML/doc3.htm
+++ b/result/HTML/doc3.htm
@@ -89,8 +89,7 @@ eval("page" + id + " = window.open(URL, '" + id + "', 'toolbars=0, scrollbars=0,
Win2k Install
-
- ?.?>
+
Gentus
|
diff --git a/result/HTML/doc3.htm.err b/result/HTML/doc3.htm.err
index 5a57449d..73860c8c 100644
--- a/result/HTML/doc3.htm.err
+++ b/result/HTML/doc3.htm.err
@@ -13,12 +13,6 @@ _top">
-
+
|
@@ -166,22 +168,36 @@
|
diff --git a/result/HTML/wired.html.sax b/result/HTML/wired.html.sax
index 1c64b08e..b94358ca 100644
--- a/result/HTML/wired.html.sax
+++ b/result/HTML/wired.html.sax
@@ -52,6 +52,7 @@ SAX.characters(
SAX.startElement(option, value='WA', selected)
SAX.characters(WA
, 4)
+SAX.endElement(option)
SAX.startElement(option, value='AL')
SAX.characters(AL, 2)
SAX.endElement(option)
@@ -282,7 +283,6 @@ SAX.characters(WY, 2)
SAX.endElement(option)
SAX.characters(
, 2)
-SAX.endElement(option)
SAX.endElement(select)
SAX.startElement(input, type='hidden', name='source', value='2hb8bhc059')
SAX.endElement(input)
@@ -1014,44 +1014,57 @@ SAX.characters(
SAX.startElement(option, value='301')
SAX.characters(Business Top 20
, 16)
+SAX.endElement(option)
SAX.startElement(option, value='500')
SAX.characters(Computers
, 10)
+SAX.endElement(option)
SAX.startElement(option, value='503')
SAX.characters(Computer Games
, 15)
+SAX.endElement(option)
SAX.startElement(option, value='1604')
SAX.characters(Current Affairs
, 16)
+SAX.endElement(option)
SAX.startElement(option, value='511')
SAX.characters(Cyberculture
, 13)
+SAX.endElement(option)
SAX.startElement(option, value='510')
SAX.characters(Internet/Web
, 13)
+SAX.endElement(option)
SAX.startElement(option, value='303')
SAX.characters(Investing
, 10)
+SAX.endElement(option)
SAX.startElement(option, value='1606')
SAX.characters(Law
, 4)
+SAX.endElement(option)
SAX.startElement(option, value='513')
SAX.characters(Multimedia
, 12)
+SAX.endElement(option)
SAX.startElement(option, value='1605')
SAX.characters(Newsmakers
, 11)
+SAX.endElement(option)
SAX.startElement(option, value='1607')
SAX.characters(Politics/Govt.
, 17)
+SAX.endElement(option)
SAX.startElement(option, value='315')
SAX.characters( Web Business
, 16)
+SAX.endElement(option)
SAX.startElement(option, value='2800')
SAX.characters( Bargain Books
, 40)
+SAX.endElement(option)
SAX.startElement(option, value='4')
SAX.characters(Other
@@ -1061,19 +1074,6 @@ SAX.characters(Other
, 14)
SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
-SAX.endElement(option)
SAX.endElement(select)
SAX.endElement(font)
SAX.error: Opening and ending tag mismatch: td and form
diff --git a/tree.c b/tree.c
index 497de9dc..20d2b820 100644
--- a/tree.c
+++ b/tree.c
@@ -480,6 +480,8 @@ xmlFreeDtd(xmlDtdPtr cur) {
xmlFreeAttributeTable((xmlAttributeTablePtr) cur->attributes);
if (cur->entities != NULL)
xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
+ if (cur->pentities != NULL)
+ xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->pentities);
memset(cur, -1, sizeof(xmlDtd));
xmlFree(cur);
diff --git a/valid.c b/valid.c
index 2e4240a0..fe64bc06 100644
--- a/valid.c
+++ b/valid.c
@@ -21,6 +21,7 @@
#endif
#include
+#include
#include
#include
#include
@@ -453,27 +454,26 @@ xmlSprintfElementContent(char *buf, xmlElementContentPtr content, int glob) {
*/
xmlElementTablePtr
xmlCreateElementTable(void) {
- xmlElementTablePtr ret;
+ return(xmlHashCreate(0));
+}
- ret = (xmlElementTablePtr)
- xmlMalloc(sizeof(xmlElementTable));
- if (ret == NULL) {
- fprintf(stderr, "xmlCreateElementTable : xmlMalloc(%ld) failed\n",
- (long)sizeof(xmlElementTable));
- return(NULL);
- }
- ret->max_elements = XML_MIN_ELEMENT_TABLE;
- ret->nb_elements = 0;
- ret->last = 0;
- ret->table = (xmlElementPtr *)
- xmlMalloc(ret->max_elements * sizeof(xmlElementPtr));
- if (ret->table == NULL) {
- fprintf(stderr, "xmlCreateElementTable : xmlMalloc(%ld) failed\n",
- ret->max_elements * (long)sizeof(xmlElement));
- xmlFree(ret);
- return(NULL);
- }
- return(ret);
+/**
+ * xmlFreeElement:
+ * @elem: An element
+ *
+ * Deallocate the memory used by an element definition
+ */
+void
+xmlFreeElement(xmlElementPtr elem) {
+ if (elem == NULL) return;
+ xmlUnlinkNode((xmlNodePtr) elem);
+ xmlFreeElementContent(elem->content);
+ if (elem->name != NULL)
+ xmlFree((xmlChar *) elem->name);
+ if (elem->prefix != NULL)
+ xmlFree((xmlChar *) elem->prefix);
+ memset(elem, -1, sizeof(xmlElement));
+ xmlFree(elem);
}
@@ -493,10 +493,9 @@ xmlElementPtr
xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
xmlElementTypeVal type,
xmlElementContentPtr content) {
- xmlElementPtr ret, cur;
+ xmlElementPtr ret;
xmlElementTablePtr table;
xmlChar *ns, *uqname;
- int i;
if (dtd == NULL) {
fprintf(stderr, "xmlAddElementDecl: dtd == NULL\n");
@@ -560,39 +559,6 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
return(NULL);
}
- /*
- * Validity Check:
- * Search the DTD for previous declarations of the ELEMENT
- */
- for (i = 0;i < table->nb_elements;i++) {
- cur = table->table[i];
- if ((ns != NULL) && (cur->prefix == NULL)) continue;
- if ((ns == NULL) && (cur->prefix != NULL)) continue;
- if ((xmlStrEqual(cur->name, name)) &&
- ((ns == NULL) || (xmlStrEqual(cur->prefix, ns)))) {
- /*
- * The element is already defined in this Dtd.
- */
- VERROR(ctxt->userData, "Redefinition of element %s\n", name);
- return(NULL);
- }
- }
-
- /*
- * Grow the table, if needed.
- */
- if (table->nb_elements >= table->max_elements) {
- /*
- * need more elements.
- */
- table->max_elements *= 2;
- table->table = (xmlElementPtr *)
- xmlRealloc(table->table, table->max_elements * sizeof(xmlElementPtr));
- if (table->table == NULL) {
- fprintf(stderr, "xmlAddElementDecl: out of memory\n");
- return(NULL);
- }
- }
ret = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
if (ret == NULL) {
fprintf(stderr, "xmlAddElementDecl: out of memory\n");
@@ -600,7 +566,6 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
}
memset(ret, 0, sizeof(xmlElement));
ret->type = XML_ELEMENT_DECL;
- table->table[table->nb_elements] = ret;
/*
* fill the structure.
@@ -610,7 +575,21 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
ret->prefix = ns;
ret->content = xmlCopyElementContent(content);
ret->attributes = xmlScanAttributeDecl(dtd, name);
- table->nb_elements++;
+
+ /*
+ * Validity Check:
+ * Insertion must not fail
+ */
+ if (xmlHashAddEntry2(table, name, ns, ret)) {
+ /*
+ * The element is already defined in this Dtd.
+ */
+ VERROR(ctxt->userData, "Redefinition of element %s\n", name);
+ xmlFreeElement(ret);
+ if (uqname != NULL)
+ xmlFree(uqname);
+ return(NULL);
+ }
/*
* Link it to the Dtd
@@ -629,25 +608,6 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
return(ret);
}
-/**
- * xmlFreeElement:
- * @elem: An element
- *
- * Deallocate the memory used by an element definition
- */
-void
-xmlFreeElement(xmlElementPtr elem) {
- if (elem == NULL) return;
- xmlUnlinkNode((xmlNodePtr) elem);
- xmlFreeElementContent(elem->content);
- if (elem->name != NULL)
- xmlFree((xmlChar *) elem->name);
- if (elem->prefix != NULL)
- xmlFree((xmlChar *) elem->prefix);
- memset(elem, -1, sizeof(xmlElement));
- xmlFree(elem);
-}
-
/**
* xmlFreeElementTable:
* @table: An element table
@@ -656,15 +616,41 @@ xmlFreeElement(xmlElementPtr elem) {
*/
void
xmlFreeElementTable(xmlElementTablePtr table) {
- int i;
+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeElement);
+}
- if (table == NULL) return;
+/**
+ * xmlCopyElement:
+ * @elem: An element
+ *
+ * Build a copy of an element.
+ *
+ * Returns the new xmlElementPtr or NULL in case of error.
+ */
+xmlElementPtr
+xmlCopyElement(xmlElementPtr elem) {
+ xmlElementPtr cur;
- for (i = 0;i < table->nb_elements;i++) {
- xmlFreeElement(table->table[i]);
+ cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlCopyElement: out of memory !\n");
+ return(NULL);
}
- xmlFree(table->table);
- xmlFree(table);
+ memset(cur, 0, sizeof(xmlElement));
+ cur->type = XML_ELEMENT_DECL;
+ cur->etype = elem->etype;
+ if (elem->name != NULL)
+ cur->name = xmlStrdup(elem->name);
+ else
+ cur->name = NULL;
+ if (elem->prefix != NULL)
+ cur->prefix = xmlStrdup(elem->prefix);
+ else
+ cur->prefix = NULL;
+ cur->content = xmlCopyElementContent(elem->content);
+ /* TODO : rebuild the attribute list on the copy */
+ cur->attributes = NULL;
+ return(cur);
}
/**
@@ -677,46 +663,8 @@ xmlFreeElementTable(xmlElementTablePtr table) {
*/
xmlElementTablePtr
xmlCopyElementTable(xmlElementTablePtr table) {
- xmlElementTablePtr ret;
- xmlElementPtr cur, ent;
- int i;
-
- ret = (xmlElementTablePtr) xmlMalloc(sizeof(xmlElementTable));
- if (ret == NULL) {
- fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
- return(NULL);
- }
- ret->table = (xmlElementPtr *) xmlMalloc(table->max_elements *
- sizeof(xmlElementPtr));
- if (ret->table == NULL) {
- fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
- xmlFree(ret);
- return(NULL);
- }
- ret->max_elements = table->max_elements;
- ret->nb_elements = table->nb_elements;
- for (i = 0;i < ret->nb_elements;i++) {
- cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
- if (cur == NULL) {
- fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
- xmlFree(ret);
- xmlFree(ret->table);
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlElement));
- cur->type = XML_ELEMENT_DECL;
- ret->table[i] = cur;
- ent = table->table[i];
- cur->etype = ent->etype;
- if (ent->name != NULL)
- cur->name = xmlStrdup(ent->name);
- else
- cur->name = NULL;
- cur->content = xmlCopyElementContent(ent->content);
- /* TODO : rebuild the attribute list on the copy */
- cur->attributes = NULL;
- }
- return(ret);
+ return((xmlElementTablePtr) xmlHashCopy(table,
+ (xmlHashCopier) xmlCopyElement));
}
/**
@@ -770,15 +718,7 @@ xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
*/
void
xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
- int i;
- xmlElementPtr cur;
-
- if (table == NULL) return;
-
- for (i = 0;i < table->nb_elements;i++) {
- cur = table->table[i];
- xmlDumpElementDecl(buf, cur);
- }
+ xmlHashScan(table, (xmlHashScanner) xmlDumpElementDecl, buf);
}
/**
@@ -876,26 +816,22 @@ xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
*/
xmlAttributeTablePtr
xmlCreateAttributeTable(void) {
- xmlAttributeTablePtr ret;
+ return(xmlHashCreate(0));
+}
- ret = (xmlAttributeTablePtr)
- xmlMalloc(sizeof(xmlAttributeTable));
- if (ret == NULL) {
- fprintf(stderr, "xmlCreateAttributeTable : xmlMalloc(%ld) failed\n",
- (long)sizeof(xmlAttributeTable));
- return(NULL);
- }
- ret->max_attributes = XML_MIN_ATTRIBUTE_TABLE;
- ret->nb_attributes = 0;
- ret->table = (xmlAttributePtr *)
- xmlMalloc(ret->max_attributes * sizeof(xmlAttributePtr));
- if (ret->table == NULL) {
- fprintf(stderr, "xmlCreateAttributeTable : xmlMalloc(%ld) failed\n",
- ret->max_attributes * (long)sizeof(xmlAttributePtr));
- xmlFree(ret);
- return(NULL);
- }
- return(ret);
+/**
+ * xmlScanAttributeDeclCallback:
+ * @attr: the attribute decl
+ * @list: the list to update
+ *
+ * Callback called by xmlScanAttributeDecl when a new attribute
+ * has to be entered in the list.
+ */
+void
+xmlScanAttributeDeclCallback(xmlAttributePtr attr, xmlAttributePtr *list,
+ const xmlChar* name) {
+ attr->nexth = *list;
+ *list = attr;
}
/**
@@ -913,7 +849,6 @@ xmlAttributePtr
xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem) {
xmlAttributePtr ret = NULL;
xmlAttributeTablePtr table;
- int i;
if (dtd == NULL) {
fprintf(stderr, "xmlScanAttributeDecl: dtd == NULL\n");
@@ -927,12 +862,9 @@ xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem) {
if (table == NULL)
return(NULL);
- for (i = 0;i < table->nb_attributes;i++) {
- if (xmlStrEqual(table->table[i]->elem, elem)) {
- table->table[i]->nexth = ret;
- ret = table->table[i];
- }
- }
+ /* WRONG !!! */
+ xmlHashScan3(table, NULL, NULL, elem,
+ (xmlHashScanner) xmlScanAttributeDeclCallback, &ret);
return(ret);
}
@@ -966,6 +898,30 @@ xmlScanIDAttributeDecl(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
return(ret);
}
+/**
+ * xmlFreeAttribute:
+ * @elem: An attribute
+ *
+ * Deallocate the memory used by an attribute definition
+ */
+void
+xmlFreeAttribute(xmlAttributePtr attr) {
+ if (attr == NULL) return;
+ xmlUnlinkNode((xmlNodePtr) attr);
+ if (attr->tree != NULL)
+ xmlFreeEnumeration(attr->tree);
+ if (attr->elem != NULL)
+ xmlFree((xmlChar *) attr->elem);
+ if (attr->name != NULL)
+ xmlFree((xmlChar *) attr->name);
+ if (attr->defaultValue != NULL)
+ xmlFree((xmlChar *) attr->defaultValue);
+ if (attr->prefix != NULL)
+ xmlFree((xmlChar *) attr->prefix);
+ memset(attr, -1, sizeof(xmlAttribute));
+ xmlFree(attr);
+}
+
/**
* xmlAddAttributeDecl:
@@ -989,10 +945,9 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
const xmlChar *name, const xmlChar *ns,
xmlAttributeType type, xmlAttributeDefault def,
const xmlChar *defaultValue, xmlEnumerationPtr tree) {
- xmlAttributePtr ret, cur;
+ xmlAttributePtr ret;
xmlAttributeTablePtr table;
xmlElementPtr elemDef;
- int i;
if (dtd == NULL) {
fprintf(stderr, "xmlAddAttributeDecl: dtd == NULL\n");
@@ -1058,81 +1013,7 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
return(NULL);
}
- /*
- * Validity Check:
- * Search the DTD for previous declarations of the ATTLIST
- * The initial code used to walk the attribute table comparing
- * all pairs of element/attribute names, and was far too slow
- * for large DtDs, we now walk the attribute list associated to
- * the element declaration instead if this declaration is found.
- */
- elemDef = xmlGetDtdElementDesc(dtd, elem);
- if (elemDef != NULL) {
- /*
- * follow the attribute list.
- */
- cur = elemDef->attributes;
- while (cur != NULL) {
- if ((ns != NULL) && (cur->prefix == NULL)) {
- cur = cur->nexth;
- continue;
- }
- if ((ns == NULL) && (cur->prefix != NULL)) {
- cur = cur->nexth;
- continue;
- }
- if ((xmlStrEqual(cur->name, name)) &&
- ((ns == NULL) || (xmlStrEqual(cur->prefix, ns)))) {
- /*
- * The attribute is already defined in this Dtd.
- */
- VWARNING(ctxt->userData,
- "Attribute %s on %s: already defined\n",
- name, elem);
- xmlFreeEnumeration(tree);
- return(NULL);
- }
- cur = cur->nexth;
- }
- } else {
- /*
- * Walk down the attribute table.
- */
- for (i = 0;i < table->nb_attributes;i++) {
- cur = table->table[i];
- if ((ns != NULL) && (cur->prefix == NULL)) continue;
- if ((ns == NULL) && (cur->prefix != NULL)) continue;
- if ((xmlStrEqual(cur->name, name)) &&
- (xmlStrEqual(cur->elem, elem)) &&
- ((ns == NULL) || (xmlStrEqual(cur->prefix, ns)))) {
- /*
- * The attribute is already defined in this Dtd.
- */
- VWARNING(ctxt->userData,
- "Attribute %s on %s: already defined\n",
- elem, name);
- xmlFreeEnumeration(tree);
- return(NULL);
- }
- }
- }
- /*
- * Grow the table, if needed.
- */
- if (table->nb_attributes >= table->max_attributes) {
- /*
- * need more attributes.
- */
- table->max_attributes *= 2;
- table->table = (xmlAttributePtr *)
- xmlRealloc(table->table, table->max_attributes *
- sizeof(xmlAttributePtr));
- if (table->table == NULL) {
- fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
- return(NULL);
- }
- }
ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
if (ret == NULL) {
fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
@@ -1140,7 +1021,6 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
}
memset(ret, 0, sizeof(xmlAttribute));
ret->type = XML_ATTRIBUTE_DECL;
- table->table[table->nb_attributes] = ret;
/*
* fill the structure.
@@ -1153,6 +1033,27 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
ret->tree = tree;
if (defaultValue != NULL)
ret->defaultValue = xmlStrdup(defaultValue);
+
+ /*
+ * Validity Check:
+ * Search the DTD for previous declarations of the ATTLIST
+ */
+ if (xmlHashAddEntry3(table, name, ns, elem, ret) < 0) {
+ /*
+ * The attribute is already defined in this Dtd.
+ */
+ VWARNING(ctxt->userData,
+ "Attribute %s on %s: already defined\n",
+ name, elem);
+ xmlFreeAttribute(ret);
+ return(NULL);
+ }
+
+ /*
+ * Validity Check:
+ * Multiple ID per element
+ */
+ elemDef = xmlGetDtdElementDesc(dtd, elem);
if (elemDef != NULL) {
if ((type == XML_ATTRIBUTE_ID) &&
(xmlScanIDAttributeDecl(NULL, elemDef) != 0))
@@ -1162,7 +1063,6 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
ret->nexth = elemDef->attributes;
elemDef->attributes = ret;
}
- table->nb_attributes++;
/*
* Link it to the Dtd
@@ -1179,30 +1079,6 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
return(ret);
}
-/**
- * xmlFreeAttribute:
- * @elem: An attribute
- *
- * Deallocate the memory used by an attribute definition
- */
-void
-xmlFreeAttribute(xmlAttributePtr attr) {
- if (attr == NULL) return;
- xmlUnlinkNode((xmlNodePtr) attr);
- if (attr->tree != NULL)
- xmlFreeEnumeration(attr->tree);
- if (attr->elem != NULL)
- xmlFree((xmlChar *) attr->elem);
- if (attr->name != NULL)
- xmlFree((xmlChar *) attr->name);
- if (attr->defaultValue != NULL)
- xmlFree((xmlChar *) attr->defaultValue);
- if (attr->prefix != NULL)
- xmlFree((xmlChar *) attr->prefix);
- memset(attr, -1, sizeof(xmlAttribute));
- xmlFree(attr);
-}
-
/**
* xmlFreeAttributeTable:
* @table: An attribute table
@@ -1211,15 +1087,37 @@ xmlFreeAttribute(xmlAttributePtr attr) {
*/
void
xmlFreeAttributeTable(xmlAttributeTablePtr table) {
- int i;
+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeAttribute);
+}
- if (table == NULL) return;
+/**
+ * xmlCopyAttribute:
+ * @attr: An attribute
+ *
+ * Build a copy of an attribute.
+ *
+ * Returns the new xmlAttributePtr or NULL in case of error.
+ */
+xmlAttributePtr
+xmlCopyAttribute(xmlAttributePtr attr) {
+ xmlAttributePtr cur;
- for (i = 0;i < table->nb_attributes;i++) {
- xmlFreeAttribute(table->table[i]);
+ cur = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlCopyAttribute: out of memory !\n");
+ return(NULL);
}
- xmlFree(table->table);
- xmlFree(table);
+ memset(cur, 0, sizeof(xmlAttribute));
+ cur->atype = attr->atype;
+ cur->def = attr->def;
+ cur->tree = xmlCopyEnumeration(attr->tree);
+ if (attr->elem != NULL)
+ cur->elem = xmlStrdup(attr->elem);
+ if (attr->name != NULL)
+ cur->name = xmlStrdup(attr->name);
+ if (attr->defaultValue != NULL)
+ cur->defaultValue = xmlStrdup(attr->defaultValue);
+ return(cur);
}
/**
@@ -1232,48 +1130,8 @@ xmlFreeAttributeTable(xmlAttributeTablePtr table) {
*/
xmlAttributeTablePtr
xmlCopyAttributeTable(xmlAttributeTablePtr table) {
- xmlAttributeTablePtr ret;
- xmlAttributePtr cur, attr;
- int i;
-
- ret = (xmlAttributeTablePtr) xmlMalloc(sizeof(xmlAttributeTable));
- if (ret == NULL) {
- fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
- return(NULL);
- }
- ret->table = (xmlAttributePtr *) xmlMalloc(table->max_attributes *
- sizeof(xmlAttributePtr));
- if (ret->table == NULL) {
- fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
- xmlFree(ret);
- return(NULL);
- }
- ret->max_attributes = table->max_attributes;
- ret->nb_attributes = table->nb_attributes;
- for (i = 0;i < ret->nb_attributes;i++) {
- attr = table->table[i];
- cur = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
- if (cur == NULL) {
- fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
- xmlFree(ret);
- xmlFree(ret->table);
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlAttribute));
- /* !!! cur->type = XML_ATTRIBUTE_DECL; */
- ret->table[i] = cur;
- cur->atype = attr->atype;
- cur->def = attr->def;
- cur->tree = xmlCopyEnumeration(attr->tree);
- if (attr->elem != NULL)
- cur->elem = xmlStrdup(attr->elem);
- if (attr->name != NULL)
- cur->name = xmlStrdup(attr->name);
- if (attr->defaultValue != NULL)
- cur->defaultValue = xmlStrdup(attr->defaultValue);
- /* NEED to rebuild the next chain !!!!!! */
- }
- return(ret);
+ return((xmlAttributeTablePtr) xmlHashCopy(table,
+ (xmlHashCopier) xmlCopyAttribute));
}
/**
@@ -1365,15 +1223,7 @@ xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
*/
void
xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
- int i;
- xmlAttributePtr cur;
-
- if (table == NULL) return;
-
- for (i = 0;i < table->nb_attributes;i++) {
- cur = table->table[i];
- xmlDumpAttributeDecl(buf, cur);
- }
+ xmlHashScan(table, (xmlHashScanner) xmlDumpAttributeDecl, buf);
}
/************************************************************************
@@ -1391,26 +1241,26 @@ xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
*/
xmlNotationTablePtr
xmlCreateNotationTable(void) {
- xmlNotationTablePtr ret;
+ return(xmlHashCreate(0));
+}
- ret = (xmlNotationTablePtr)
- xmlMalloc(sizeof(xmlNotationTable));
- if (ret == NULL) {
- fprintf(stderr, "xmlCreateNotationTable : xmlMalloc(%ld) failed\n",
- (long)sizeof(xmlNotationTable));
- return(NULL);
- }
- ret->max_notations = XML_MIN_NOTATION_TABLE;
- ret->nb_notations = 0;
- ret->table = (xmlNotationPtr *)
- xmlMalloc(ret->max_notations * sizeof(xmlNotationPtr));
- if (ret->table == NULL) {
- fprintf(stderr, "xmlCreateNotationTable : xmlMalloc(%ld) failed\n",
- ret->max_notations * (long)sizeof(xmlNotation));
- xmlFree(ret);
- return(NULL);
- }
- return(ret);
+/**
+ * xmlFreeNotation:
+ * @not: A notation
+ *
+ * Deallocate the memory used by an notation definition
+ */
+void
+xmlFreeNotation(xmlNotationPtr nota) {
+ if (nota == NULL) return;
+ if (nota->name != NULL)
+ xmlFree((xmlChar *) nota->name);
+ if (nota->PublicID != NULL)
+ xmlFree((xmlChar *) nota->PublicID);
+ if (nota->SystemID != NULL)
+ xmlFree((xmlChar *) nota->SystemID);
+ memset(nota, -1, sizeof(xmlNotation));
+ xmlFree(nota);
}
@@ -1429,9 +1279,8 @@ xmlCreateNotationTable(void) {
xmlNotationPtr
xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
const xmlChar *PublicID, const xmlChar *SystemID) {
- xmlNotationPtr ret, cur;
+ xmlNotationPtr ret;
xmlNotationTablePtr table;
- int i;
if (dtd == NULL) {
fprintf(stderr, "xmlAddNotationDecl: dtd == NULL\n");
@@ -1456,44 +1305,12 @@ xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
return(NULL);
}
- /*
- * Validity Check:
- * Search the DTD for previous declarations of the ATTLIST
- */
- for (i = 0;i < table->nb_notations;i++) {
- cur = table->table[i];
- if (xmlStrEqual(cur->name, name)) {
- /*
- * The notation is already defined in this Dtd.
- */
- fprintf(stderr,
- "xmlAddNotationDecl: %s already defined\n", name);
- }
- }
-
- /*
- * Grow the table, if needed.
- */
- if (table->nb_notations >= table->max_notations) {
- /*
- * need more notations.
- */
- table->max_notations *= 2;
- table->table = (xmlNotationPtr *)
- xmlRealloc(table->table, table->max_notations *
- sizeof(xmlNotationPtr));
- if (table->table == NULL) {
- fprintf(stderr, "xmlAddNotationDecl: out of memory\n");
- return(NULL);
- }
- }
ret = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
if (ret == NULL) {
fprintf(stderr, "xmlAddNotationDecl: out of memory\n");
return(NULL);
}
memset(ret, 0, sizeof(xmlNotation));
- table->table[table->nb_notations] = ret;
/*
* fill the structure.
@@ -1503,30 +1320,20 @@ xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
ret->SystemID = xmlStrdup(SystemID);
if (PublicID != NULL)
ret->PublicID = xmlStrdup(PublicID);
- table->nb_notations++;
+ /*
+ * Validity Check:
+ * Check the DTD for previous declarations of the ATTLIST
+ */
+ if (xmlHashAddEntry(table, name, ret)) {
+ fprintf(stderr,
+ "xmlAddNotationDecl: %s already defined\n", name);
+ xmlFreeNotation(ret);
+ return(NULL);
+ }
return(ret);
}
-/**
- * xmlFreeNotation:
- * @not: A notation
- *
- * Deallocate the memory used by an notation definition
- */
-void
-xmlFreeNotation(xmlNotationPtr nota) {
- if (nota == NULL) return;
- if (nota->name != NULL)
- xmlFree((xmlChar *) nota->name);
- if (nota->PublicID != NULL)
- xmlFree((xmlChar *) nota->PublicID);
- if (nota->SystemID != NULL)
- xmlFree((xmlChar *) nota->SystemID);
- memset(nota, -1, sizeof(xmlNotation));
- xmlFree(nota);
-}
-
/**
* xmlFreeNotationTable:
* @table: An notation table
@@ -1535,15 +1342,39 @@ xmlFreeNotation(xmlNotationPtr nota) {
*/
void
xmlFreeNotationTable(xmlNotationTablePtr table) {
- int i;
+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeNotation);
+}
- if (table == NULL) return;
+/**
+ * xmlCopyNotation:
+ * @nota: A notation
+ *
+ * Build a copy of a notation.
+ *
+ * Returns the new xmlNotationPtr or NULL in case of error.
+ */
+xmlNotationPtr
+xmlCopyNotation(xmlNotationPtr nota) {
+ xmlNotationPtr cur;
- for (i = 0;i < table->nb_notations;i++) {
- xmlFreeNotation(table->table[i]);
+ cur = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlCopyNotation: out of memory !\n");
+ return(NULL);
}
- xmlFree(table->table);
- xmlFree(table);
+ if (nota->name != NULL)
+ cur->name = xmlStrdup(nota->name);
+ else
+ cur->name = NULL;
+ if (nota->PublicID != NULL)
+ cur->PublicID = xmlStrdup(nota->PublicID);
+ else
+ cur->PublicID = NULL;
+ if (nota->SystemID != NULL)
+ cur->SystemID = xmlStrdup(nota->SystemID);
+ else
+ cur->SystemID = NULL;
+ return(cur);
}
/**
@@ -1556,48 +1387,8 @@ xmlFreeNotationTable(xmlNotationTablePtr table) {
*/
xmlNotationTablePtr
xmlCopyNotationTable(xmlNotationTablePtr table) {
- xmlNotationTablePtr ret;
- xmlNotationPtr cur, nota;
- int i;
-
- ret = (xmlNotationTablePtr) xmlMalloc(sizeof(xmlNotationTable));
- if (ret == NULL) {
- fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
- return(NULL);
- }
- ret->table = (xmlNotationPtr *) xmlMalloc(table->max_notations *
- sizeof(xmlNotationPtr));
- if (ret->table == NULL) {
- fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
- xmlFree(ret);
- return(NULL);
- }
- ret->max_notations = table->max_notations;
- ret->nb_notations = table->nb_notations;
- for (i = 0;i < ret->nb_notations;i++) {
- cur = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
- if (cur == NULL) {
- fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
- xmlFree(ret);
- xmlFree(ret->table);
- return(NULL);
- }
- ret->table[i] = cur;
- nota = table->table[i];
- if (nota->name != NULL)
- cur->name = xmlStrdup(nota->name);
- else
- cur->name = NULL;
- if (nota->PublicID != NULL)
- cur->PublicID = xmlStrdup(nota->PublicID);
- else
- cur->PublicID = NULL;
- if (nota->SystemID != NULL)
- cur->SystemID = xmlStrdup(nota->SystemID);
- else
- cur->SystemID = NULL;
- }
- return(ret);
+ return((xmlNotationTablePtr) xmlHashCopy(table,
+ (xmlHashCopier) xmlCopyNotation));
}
/**
@@ -1634,15 +1425,7 @@ xmlDumpNotationDecl(xmlBufferPtr buf, xmlNotationPtr nota) {
*/
void
xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
- int i;
- xmlNotationPtr cur;
-
- if (table == NULL) return;
-
- for (i = 0;i < table->nb_notations;i++) {
- cur = table->table[i];
- xmlDumpNotationDecl(buf, cur);
- }
+ xmlHashScan(table, (xmlHashScanner) xmlDumpNotationDecl, buf);
}
/************************************************************************
@@ -1660,28 +1443,23 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
*/
xmlIDTablePtr
xmlCreateIDTable(void) {
- xmlIDTablePtr ret;
-
- ret = (xmlIDTablePtr)
- xmlMalloc(sizeof(xmlIDTable));
- if (ret == NULL) {
- fprintf(stderr, "xmlCreateIDTable : xmlMalloc(%ld) failed\n",
- (long)sizeof(xmlIDTable));
- return(NULL);
- }
- ret->max_ids = XML_MIN_NOTATION_TABLE;
- ret->nb_ids = 0;
- ret->table = (xmlIDPtr *)
- xmlMalloc(ret->max_ids * sizeof(xmlIDPtr));
- if (ret->table == NULL) {
- fprintf(stderr, "xmlCreateIDTable : xmlMalloc(%ld) failed\n",
- ret->max_ids * (long)sizeof(xmlID));
- xmlFree(ret);
- return(NULL);
- }
- return(ret);
+ return(xmlHashCreate(0));
}
+/**
+ * xmlFreeID:
+ * @not: A id
+ *
+ * Deallocate the memory used by an id definition
+ */
+void
+xmlFreeID(xmlIDPtr id) {
+ if (id == NULL) return;
+ if (id->value != NULL)
+ xmlFree((xmlChar *) id->value);
+ memset(id, -1, sizeof(xmlID));
+ xmlFree(id);
+}
/**
* xmlAddID:
@@ -1697,9 +1475,8 @@ xmlCreateIDTable(void) {
xmlIDPtr
xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
xmlAttrPtr attr) {
- xmlIDPtr ret, cur;
+ xmlIDPtr ret;
xmlIDTablePtr table;
- int i;
if (doc == NULL) {
fprintf(stderr, "xmlAddIDDecl: doc == NULL\n");
@@ -1725,69 +1502,29 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
return(NULL);
}
- /*
- * Validity Check:
- * Search the DTD for previous declarations of the ATTLIST
- */
- for (i = 0;i < table->nb_ids;i++) {
- cur = table->table[i];
- if (xmlStrEqual(cur->value, value)) {
- /*
- * The id is already defined in this Dtd.
- */
- VERROR(ctxt->userData, "ID %s already defined\n", value);
- return(NULL);
- }
- }
-
- /*
- * Grow the table, if needed.
- */
- if (table->nb_ids >= table->max_ids) {
- /*
- * need more ids.
- */
- table->max_ids *= 2;
- table->table = (xmlIDPtr *)
- xmlRealloc(table->table, table->max_ids *
- sizeof(xmlIDPtr));
- if (table->table == NULL) {
- fprintf(stderr, "xmlAddID: out of memory\n");
- return(NULL);
- }
- }
ret = (xmlIDPtr) xmlMalloc(sizeof(xmlID));
if (ret == NULL) {
fprintf(stderr, "xmlAddID: out of memory\n");
return(NULL);
}
- table->table[table->nb_ids] = ret;
/*
* fill the structure.
*/
ret->value = xmlStrdup(value);
ret->attr = attr;
- table->nb_ids++;
+ if (xmlHashAddEntry(table, value, ret) < 0) {
+ /*
+ * The id is already defined in this Dtd.
+ */
+ VERROR(ctxt->userData, "ID %s already defined\n", value);
+ xmlFreeID(ret);
+ return(NULL);
+ }
return(ret);
}
-/**
- * xmlFreeID:
- * @not: A id
- *
- * Deallocate the memory used by an id definition
- */
-void
-xmlFreeID(xmlIDPtr id) {
- if (id == NULL) return;
- if (id->value != NULL)
- xmlFree((xmlChar *) id->value);
- memset(id, -1, sizeof(xmlID));
- xmlFree(id);
-}
-
/**
* xmlFreeIDTable:
* @table: An id table
@@ -1796,15 +1533,7 @@ xmlFreeID(xmlIDPtr id) {
*/
void
xmlFreeIDTable(xmlIDTablePtr table) {
- int i;
-
- if (table == NULL) return;
-
- for (i = 0;i < table->nb_ids;i++) {
- xmlFreeID(table->table[i]);
- }
- xmlFree(table->table);
- xmlFree(table);
+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);
}
/**
@@ -1856,9 +1585,9 @@ xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
*/
int
xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
- xmlIDPtr cur;
+ xmlAttrPtr cur;
xmlIDTablePtr table;
- int i;
+ xmlChar *ID;
if (doc == NULL) return(-1);
if (attr == NULL) return(-1);
@@ -1866,19 +1595,19 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
if (table == NULL)
return(-1);
- /*
- * Search the ID list.
- */
- for (i = 0;i < table->nb_ids;i++) {
- cur = table->table[i];
- if (cur->attr == attr) {
- table->nb_ids--;
- memmove(&table->table[i], &table->table[i+1],
- (table->nb_ids - i) * sizeof(xmlIDPtr));
- return(0);
- }
+ if (attr == NULL)
+ return(-1);
+ ID = xmlNodeListGetString(doc, attr->children, 1);
+ if (ID == NULL)
+ return(-1);
+ cur = xmlHashLookup(table, ID);
+ if (cur != attr) {
+ xmlFree(ID);
+ return(-1);
}
- return(-1);
+ xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator) xmlFreeID);
+ xmlFree(ID);
+ return(0);
}
/**
@@ -1892,9 +1621,8 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
*/
xmlAttrPtr
xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
- xmlIDPtr cur;
xmlIDTablePtr table;
- int i;
+ xmlIDPtr id;
if (doc == NULL) {
fprintf(stderr, "xmlGetID: doc == NULL\n");
@@ -1910,16 +1638,10 @@ xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
if (table == NULL)
return(NULL);
- /*
- * Search the ID list.
- */
- for (i = 0;i < table->nb_ids;i++) {
- cur = table->table[i];
- if (xmlStrEqual(cur->value, ID)) {
- return(cur->attr);
- }
- }
- return(NULL);
+ id = xmlHashLookup(table, ID);
+ if (id == NULL)
+ return(NULL);
+ return(id->attr);
}
/************************************************************************
@@ -1937,28 +1659,23 @@ xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
*/
xmlRefTablePtr
xmlCreateRefTable(void) {
- xmlRefTablePtr ret;
-
- ret = (xmlRefTablePtr)
- xmlMalloc(sizeof(xmlRefTable));
- if (ret == NULL) {
- fprintf(stderr, "xmlCreateRefTable : xmlMalloc(%ld) failed\n",
- (long)sizeof(xmlRefTable));
- return(NULL);
- }
- ret->max_refs = XML_MIN_NOTATION_TABLE;
- ret->nb_refs = 0;
- ret->table = (xmlRefPtr *)
- xmlMalloc(ret->max_refs * sizeof(xmlRefPtr));
- if (ret->table == NULL) {
- fprintf(stderr, "xmlCreateRefTable : xmlMalloc(%ld) failed\n",
- ret->max_refs * (long)sizeof(xmlRef));
- xmlFree(ret);
- return(NULL);
- }
- return(ret);
+ return(xmlHashCreate(0));
}
+/**
+ * xmlFreeRef:
+ * @ref: A ref
+ *
+ * Deallocate the memory used by an ref definition
+ */
+void
+xmlFreeRef(xmlRefPtr ref) {
+ if (ref == NULL) return;
+ if (ref->value != NULL)
+ xmlFree((xmlChar *) ref->value);
+ memset(ref, -1, sizeof(xmlRef));
+ xmlFree(ref);
+}
/**
* xmlAddRef:
@@ -2001,54 +1718,28 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
return(NULL);
}
- /*
- * Grow the table, if needed.
- */
- if (table->nb_refs >= table->max_refs) {
- /*
- * need more refs.
- */
- table->max_refs *= 2;
- table->table = (xmlRefPtr *)
- xmlRealloc(table->table, table->max_refs *
- sizeof(xmlRefPtr));
- if (table->table == NULL) {
- fprintf(stderr, "xmlAddRef: out of memory\n");
- return(NULL);
- }
- }
ret = (xmlRefPtr) xmlMalloc(sizeof(xmlRef));
if (ret == NULL) {
fprintf(stderr, "xmlAddRef: out of memory\n");
return(NULL);
}
- table->table[table->nb_refs] = ret;
/*
* fill the structure.
*/
ret->value = xmlStrdup(value);
ret->attr = attr;
- table->nb_refs++;
+ /*
+ * !!! Should we keep track of all refs ? and use xmlHashAddEntry2 ?
+ */
+ if (xmlHashAddEntry(table, value, ret) < 0) {
+ xmlFreeRef(ret);
+ return(NULL);
+ }
return(ret);
}
-/**
- * xmlFreeRef:
- * @not: A ref
- *
- * Deallocate the memory used by an ref definition
- */
-void
-xmlFreeRef(xmlRefPtr ref) {
- if (ref == NULL) return;
- if (ref->value != NULL)
- xmlFree((xmlChar *) ref->value);
- memset(ref, -1, sizeof(xmlRef));
- xmlFree(ref);
-}
-
/**
* xmlFreeRefTable:
* @table: An ref table
@@ -2057,15 +1748,7 @@ xmlFreeRef(xmlRefPtr ref) {
*/
void
xmlFreeRefTable(xmlRefTablePtr table) {
- int i;
-
- if (table == NULL) return;
-
- for (i = 0;i < table->nb_refs;i++) {
- xmlFreeRef(table->table[i]);
- }
- xmlFree(table->table);
- xmlFree(table);
+ xmlHashFree(table, (xmlHashDeallocator) xmlFreeRef);
}
/**
@@ -2084,11 +1767,6 @@ int
xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
return(0);
- /*******************
- if (((attr->name[0] == 'I') || (attr->name[0] == 'i')) &&
- ((attr->name[1] == 'D') || (attr->name[1] == 'd')) &&
- (attr->name[2] == 0)) return(1);
- *******************/
} else if (doc->type == XML_HTML_DOCUMENT_NODE) {
/* TODO @@@ */
return(0);
@@ -2117,9 +1795,9 @@ xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
*/
int
xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
- xmlRefPtr cur;
+ xmlAttrPtr cur;
xmlRefTablePtr table;
- int i;
+ xmlChar *ID;
if (doc == NULL) return(-1);
if (attr == NULL) return(-1);
@@ -2127,19 +1805,19 @@ xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
if (table == NULL)
return(-1);
- /*
- * Search the Ref list.
- */
- for (i = 0;i < table->nb_refs;i++) {
- cur = table->table[i];
- if (cur->attr == attr) {
- table->nb_refs--;
- memmove(&table->table[i], &table->table[i+1],
- (table->nb_refs - i) * sizeof(xmlRefPtr));
- return(0);
- }
+ if (attr == NULL)
+ return(-1);
+ ID = xmlNodeListGetString(doc, attr->children, 1);
+ if (ID == NULL)
+ return(-1);
+ cur = xmlHashLookup(table, ID);
+ if (cur != attr) {
+ xmlFree(ID);
+ return(-1);
}
- return(-1);
+ xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator) xmlFreeRef);
+ xmlFree(ID);
+ return(0);
}
/**
@@ -2153,9 +1831,7 @@ xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
*/
xmlAttrPtr
xmlGetRef(xmlDocPtr doc, const xmlChar *Ref) {
- xmlRefPtr cur;
xmlRefTablePtr table;
- int i;
if (doc == NULL) {
fprintf(stderr, "xmlGetRef: doc == NULL\n");
@@ -2171,16 +1847,7 @@ xmlGetRef(xmlDocPtr doc, const xmlChar *Ref) {
if (table == NULL)
return(NULL);
- /*
- * Search the Ref list.
- */
- for (i = 0;i < table->nb_refs;i++) {
- cur = table->table[i];
- if (xmlStrEqual(cur->value, Ref)) {
- return(cur->attr);
- }
- }
- return(NULL);
+ return(xmlHashLookup(table, Ref));
}
/************************************************************************
@@ -2204,45 +1871,19 @@ xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) {
xmlElementTablePtr table;
xmlElementPtr cur;
xmlChar *uqname = NULL, *prefix = NULL;
- int i;
if (dtd == NULL) return(NULL);
if (dtd->elements == NULL) return(NULL);
table = (xmlElementTablePtr) dtd->elements;
- if ((table->last >= 0) && (table->last < table->nb_elements)) {
- cur = table->table[table->last];
- if (xmlStrEqual(cur->name, name))
- return(cur);
- }
- for (i = 0;i < table->nb_elements;i++) {
- cur = table->table[i];
- if (xmlStrEqual(cur->name, name)) {
- table->last = i;
- return(cur);
- }
- }
-
- /*
- * Specific case if name is a QName.
- */
uqname = xmlSplitQName2(name, &prefix);
- if (uqname == NULL) return(NULL);
-
- for (i = 0;i < table->nb_elements;i++) {
- cur = table->table[i];
- if ((xmlStrEqual(cur->name, uqname)) &&
- ((prefix == cur->prefix) ||
- ((prefix != NULL) && (cur->prefix != NULL) &&
- (xmlStrEqual(cur->prefix, prefix))))) {
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
- return(cur);
- }
- }
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
- return(NULL);
+ if (uqname != NULL) {
+ cur = xmlHashLookup2(table, uqname, prefix);
+ if (prefix != NULL) xmlFree(prefix);
+ if (uqname != NULL) xmlFree(uqname);
+ } else
+ cur = xmlHashLookup2(table, name, NULL);
+ return(cur);
}
/**
@@ -2260,22 +1901,12 @@ xmlElementPtr
xmlGetDtdQElementDesc(xmlDtdPtr dtd, const xmlChar *name,
const xmlChar *prefix) {
xmlElementTablePtr table;
- xmlElementPtr cur;
- int i;
if (dtd == NULL) return(NULL);
if (dtd->elements == NULL) return(NULL);
table = (xmlElementTablePtr) dtd->elements;
- for (i = 0;i < table->nb_elements;i++) {
- cur = table->table[i];
- if (xmlStrEqual(cur->name, name) &&
- ((prefix == cur->prefix) ||
- ((prefix != NULL) && (cur->prefix != NULL) &&
- (xmlStrEqual(cur->prefix, prefix)))))
- return(cur);
- }
- return(NULL);
+ return(xmlHashLookup2(table, name, prefix));
}
/**
@@ -2293,69 +1924,25 @@ xmlGetDtdQElementDesc(xmlDtdPtr dtd, const xmlChar *name,
xmlAttributePtr
xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) {
xmlAttributeTablePtr table;
- xmlElementTablePtr etable;
xmlAttributePtr cur;
- xmlElementPtr ecur;
xmlChar *uqname = NULL, *prefix = NULL;
- int i;
if (dtd == NULL) return(NULL);
if (dtd->attributes == NULL) return(NULL);
- /*
- * Faster lookup through the element table
- */
- etable = (xmlElementTablePtr) dtd->elements;
- if (etable != NULL) {
- for (i = 0;i < etable->nb_elements;i++) {
- ecur = etable->table[i];
- if (xmlStrEqual(ecur->name, elem)) {
- cur = ecur->attributes;
- while (cur != NULL) {
- if (xmlStrEqual(cur->name, name))
- return(cur);
- cur = cur->nexth;
- }
- /* TODO: same accelerator for QNames !!! */
- break;
- }
- }
- }
- /*
- * Miss on the element table, retry on the attribute one
- */
-
table = (xmlAttributeTablePtr) dtd->attributes;
if (table == NULL)
return(NULL);
- for (i = 0;i < table->nb_attributes;i++) {
- cur = table->table[i];
- if ((xmlStrEqual(cur->name, name)) &&
- (xmlStrEqual(cur->elem, elem)))
- return(cur);
- }
- /*
- * Specific case if name is a QName.
- */
uqname = xmlSplitQName2(name, &prefix);
- if (uqname == NULL) return(NULL);
- for (i = 0;i < table->nb_attributes;i++) {
- cur = table->table[i];
- if ((xmlStrEqual(cur->name, uqname)) &&
- (xmlStrEqual(cur->elem, elem)) &&
- ((prefix == cur->prefix) ||
- ((prefix != NULL) && (cur->prefix != NULL) &&
- (xmlStrEqual(cur->prefix, prefix))))) {
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
- return(cur);
- }
- }
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
- return(NULL);
+ if (uqname != NULL) {
+ cur = xmlHashLookup3(table, uqname, prefix, elem);
+ if (prefix != NULL) xmlFree(prefix);
+ if (uqname != NULL) xmlFree(uqname);
+ } else
+ cur = xmlHashLookup3(table, name, NULL, elem);
+ return(cur);
}
/**
@@ -2375,23 +1962,12 @@ xmlAttributePtr
xmlGetDtdQAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name,
const xmlChar *prefix) {
xmlAttributeTablePtr table;
- xmlAttributePtr cur;
- int i;
if (dtd == NULL) return(NULL);
if (dtd->attributes == NULL) return(NULL);
table = (xmlAttributeTablePtr) dtd->attributes;
- for (i = 0;i < table->nb_attributes;i++) {
- cur = table->table[i];
- if ((xmlStrEqual(cur->name, name)) &&
- (xmlStrEqual(cur->elem, elem)) &&
- ((prefix == cur->prefix) ||
- ((prefix != NULL) && (cur->prefix != NULL) &&
- (xmlStrEqual(cur->prefix, prefix)))))
- return(cur);
- }
- return(NULL);
+ return(xmlHashLookup3(table, name, prefix, elem));
}
/**
@@ -2407,19 +1983,12 @@ xmlGetDtdQAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name,
xmlNotationPtr
xmlGetDtdNotationDesc(xmlDtdPtr dtd, const xmlChar *name) {
xmlNotationTablePtr table;
- xmlNotationPtr cur;
- int i;
if (dtd == NULL) return(NULL);
if (dtd->notations == NULL) return(NULL);
table = (xmlNotationTablePtr) dtd->notations;
- for (i = 0;i < table->nb_notations;i++) {
- cur = table->table[i];
- if (xmlStrEqual(cur->name, name))
- return(cur);
- }
- return(NULL);
+ return(xmlHashLookup(table, name));
}
/**
@@ -2917,6 +2486,12 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
return(ret);
}
+void
+xmlValidateAttributeIdCallback(xmlAttributePtr attr, int *count,
+ const xmlChar* name) {
+ if (attr->atype == XML_ATTRIBUTE_ID) (*count)++;
+}
+
/**
* xmlValidateAttributeDecl:
* @ctxt: the validation context
@@ -2976,7 +2551,6 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
nbId = xmlScanIDAttributeDecl(NULL, elem);
} else {
xmlAttributeTablePtr table;
- int i;
/*
* The attribute may be declared in the internal subset and the
@@ -2984,14 +2558,8 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
*/
nbId = 0;
table = (xmlAttributeTablePtr) doc->intSubset->attributes;
- if (table != NULL) {
- for (i = 0;i < table->nb_attributes;i++) {
- if ((table->table[i]->atype == XML_ATTRIBUTE_ID) &&
- (xmlStrEqual(table->table[i]->elem, attr->elem))) {
- nbId++;
- }
- }
- }
+ xmlHashScan3(table, NULL, NULL, attr->elem, (xmlHashScanner)
+ xmlValidateAttributeIdCallback, &nbId);
}
if (nbId > 1) {
VERROR(ctxt->userData,
@@ -4011,6 +3579,56 @@ xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
return(ret);
}
+
+void
+xmlValidateCheckRefCallback(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
+ const xmlChar *name) {
+ xmlAttrPtr id;
+ xmlAttrPtr attr;
+
+ if (ref == NULL)
+ return;
+ attr = ref->attr;
+ if (attr == NULL)
+ return;
+ if (attr->atype == XML_ATTRIBUTE_IDREF) {
+ id = xmlGetID(ctxt->doc, name);
+ if (id == NULL) {
+ VERROR(ctxt->userData,
+ "IDREF attribute %s reference an unknown ID \"%s\"\n",
+ attr->name, name);
+ ctxt->valid = 0;
+ }
+ } else if (attr->atype == XML_ATTRIBUTE_IDREFS) {
+ xmlChar *dup, *str = NULL, *cur, save;
+
+ dup = xmlStrdup(name);
+ if (dup == NULL) {
+ ctxt->valid = 0;
+ return;
+ }
+ cur = dup;
+ while (*cur != 0) {
+ str = cur;
+ while ((*cur != 0) && (!IS_BLANK(*cur))) cur++;
+ save = *cur;
+ *cur = 0;
+ id = xmlGetID(ctxt->doc, str);
+ if (id == NULL) {
+ VERROR(ctxt->userData,
+ "IDREFS attribute %s reference an unknown ID \"%s\"\n",
+ attr->name, str);
+ ctxt->valid = 0;
+ }
+ if (save == 0)
+ break;
+ *cur = save;
+ while (IS_BLANK(*cur)) cur++;
+ }
+ xmlFree(dup);
+ }
+}
+
/**
* xmlValidateDocumentFinal:
* @ctxt: the validation context
@@ -4027,9 +3645,7 @@ xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
int
xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
- int ret = 1, i;
xmlRefTablePtr table;
- xmlAttrPtr id;
if (doc == NULL) {
fprintf(stderr, "xmlValidateDocumentFinal: doc == NULL\n");
@@ -4046,45 +3662,10 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
* Check all the IDREF/IDREFS attributes definition for validity
*/
table = (xmlRefTablePtr) doc->refs;
- if (table != NULL) {
- for (i = 0; i < table->nb_refs; i++) {
- if (table->table[i]->attr->atype == XML_ATTRIBUTE_IDREF) {
- id = xmlGetID(doc, table->table[i]->value);
- if (id == NULL) {
- VERROR(ctxt->userData,
- "IDREF attribute %s reference an unknown ID \"%s\"\n",
- table->table[i]->attr->name, table->table[i]->value);
- ret = 0;
- }
- } else if (table->table[i]->attr->atype == XML_ATTRIBUTE_IDREFS) {
- xmlChar *dup, *name = NULL, *cur, save;
-
- dup = xmlStrdup(table->table[i]->value);
- if (dup == NULL)
- return(0);
- cur = dup;
- while (*cur != 0) {
- name = cur;
- while ((*cur != 0) && (!IS_BLANK(*cur))) cur++;
- save = *cur;
- *cur = 0;
- id = xmlGetID(doc, name);
- if (id == NULL) {
- VERROR(ctxt->userData,
- "IDREFS attribute %s reference an unknown ID \"%s\"\n",
- table->table[i]->attr->name, name);
- ret = 0;
- }
- if (save == 0)
- break;
- *cur = save;
- while (IS_BLANK(*cur)) cur++;
- }
- xmlFree(dup);
- }
- }
- }
- return(ret);
+ ctxt->doc = doc;
+ ctxt->valid = 1;
+ xmlHashScan(table, (xmlHashScanner) xmlValidateCheckRefCallback, ctxt);
+ return(ctxt->valid);
}
/**
@@ -4122,6 +3703,38 @@ xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
return(ret);
}
+void
+xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
+ const xmlChar *name) {
+ if (cur == NULL)
+ return;
+ switch (cur->atype) {
+ case XML_ATTRIBUTE_CDATA:
+ case XML_ATTRIBUTE_ID:
+ case XML_ATTRIBUTE_IDREF :
+ case XML_ATTRIBUTE_IDREFS:
+ case XML_ATTRIBUTE_NMTOKEN:
+ case XML_ATTRIBUTE_NMTOKENS:
+ case XML_ATTRIBUTE_ENUMERATION:
+ break;
+ case XML_ATTRIBUTE_ENTITY:
+ case XML_ATTRIBUTE_ENTITIES:
+ case XML_ATTRIBUTE_NOTATION:
+ if (cur->defaultValue != NULL) {
+ ctxt->valid &= xmlValidateAttributeValue2(ctxt, ctxt->doc,
+ cur->name, cur->atype, cur->defaultValue);
+ }
+ if (cur->tree != NULL) {
+ xmlEnumerationPtr tree = cur->tree;
+ while (tree != NULL) {
+ ctxt->valid &= xmlValidateAttributeValue2(ctxt, ctxt->doc,
+ cur->name, cur->atype, tree->name);
+ tree = tree->next;
+ }
+ }
+ }
+}
+
/**
* xmlValidateDtdFinal:
* @ctxt: the validation context
@@ -4141,81 +3754,26 @@ xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
int
xmlValidateDtdFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
- int ret = 1, i;
+ int ret = 1;
xmlDtdPtr dtd;
xmlAttributeTablePtr table;
- xmlAttributePtr cur;
if (doc == NULL) return(0);
if ((doc->intSubset == NULL) && (doc->extSubset == NULL))
return(0);
+ ctxt->doc = doc;
+ ctxt->valid = ret;
dtd = doc->intSubset;
if ((dtd != NULL) && (dtd->attributes != NULL)) {
table = (xmlAttributeTablePtr) dtd->attributes;
-
- for (i = 0;i < table->nb_attributes;i++) {
- cur = table->table[i];
- switch (cur->atype) {
- case XML_ATTRIBUTE_CDATA:
- case XML_ATTRIBUTE_ID:
- case XML_ATTRIBUTE_IDREF :
- case XML_ATTRIBUTE_IDREFS:
- case XML_ATTRIBUTE_NMTOKEN:
- case XML_ATTRIBUTE_NMTOKENS:
- case XML_ATTRIBUTE_ENUMERATION:
- break;
- case XML_ATTRIBUTE_ENTITY:
- case XML_ATTRIBUTE_ENTITIES:
- case XML_ATTRIBUTE_NOTATION:
- if (cur->defaultValue != NULL) {
- ret &= xmlValidateAttributeValue2(ctxt, doc, cur->name,
- cur->atype, cur->defaultValue);
- }
- if (cur->tree != NULL) {
- xmlEnumerationPtr tree = cur->tree;
- while (tree != NULL) {
- ret &= xmlValidateAttributeValue2(ctxt, doc,
- cur->name, cur->atype, tree->name);
- tree = tree->next;
- }
- }
- }
- }
+ xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
}
dtd = doc->extSubset;
if ((dtd != NULL) && (dtd->attributes != NULL)) {
table = (xmlAttributeTablePtr) dtd->attributes;
-
- for (i = 0;i < table->nb_attributes;i++) {
- cur = table->table[i];
- switch (cur->atype) {
- case XML_ATTRIBUTE_CDATA:
- case XML_ATTRIBUTE_ID:
- case XML_ATTRIBUTE_IDREF :
- case XML_ATTRIBUTE_IDREFS:
- case XML_ATTRIBUTE_NMTOKEN:
- case XML_ATTRIBUTE_NMTOKENS:
- case XML_ATTRIBUTE_ENUMERATION:
- break;
- case XML_ATTRIBUTE_ENTITY:
- case XML_ATTRIBUTE_ENTITIES:
- case XML_ATTRIBUTE_NOTATION:
- if (cur->defaultValue != NULL) {
- ret &= xmlValidateAttributeValue2(ctxt, doc, cur->name,
- cur->atype, cur->defaultValue);
- }
- if (cur->tree != NULL) {
- xmlEnumerationPtr tree = cur->tree;
- while (tree != NULL) {
- ret &= xmlValidateAttributeValue2(ctxt, doc,
- cur->name, cur->atype, tree->name);
- tree = tree->next;
- }
- }
- }
- }
+ xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
}
- return(ret);
+ return(ctxt->valid);
}
/**
diff --git a/valid.h b/valid.h
index ff7a9af1..54babdde 100644
--- a/valid.h
+++ b/valid.h
@@ -37,6 +37,8 @@ struct _xmlValidCtxt {
xmlNodePtr *nodeTab; /* array of nodes */
int finishDtd; /* finished validating the Dtd ? */
+ xmlDocPtr doc; /* the document */
+ int valid; /* temporary validity check result */
};
/*
@@ -44,76 +46,40 @@ struct _xmlValidCtxt {
* there is one table per DTD
*/
-#define XML_MIN_NOTATION_TABLE 32
-
-typedef struct _xmlNotationTable xmlNotationTable;
+typedef struct _xmlHashTable xmlNotationTable;
typedef xmlNotationTable *xmlNotationTablePtr;
-struct _xmlNotationTable {
- int nb_notations; /* number of notations stored */
- int max_notations; /* maximum number of notations */
- xmlNotationPtr *table; /* the table of attributes */
-};
/*
* ALl element declarations are stored in a table
* there is one table per DTD
*/
-#define XML_MIN_ELEMENT_TABLE 32
-
-typedef struct _xmlElementTable xmlElementTable;
+typedef struct _xmlHashTable xmlElementTable;
typedef xmlElementTable *xmlElementTablePtr;
-struct _xmlElementTable {
- int nb_elements; /* number of elements stored */
- int max_elements; /* maximum number of elements */
- xmlElementPtr *table; /* the table of elements */
- int last; /* last element accessed */
-};
/*
* ALl attribute declarations are stored in a table
* there is one table per DTD
*/
-#define XML_MIN_ATTRIBUTE_TABLE 32
-
-typedef struct _xmlAttributeTable xmlAttributeTable;
+typedef struct _xmlHashTable xmlAttributeTable;
typedef xmlAttributeTable *xmlAttributeTablePtr;
-struct _xmlAttributeTable {
- int nb_attributes; /* number of attributes stored */
- int max_attributes; /* maximum number of attributes */
- xmlAttributePtr *table; /* the table of attributes */
-};
/*
* ALl IDs attributes are stored in a table
* there is one table per document
*/
-#define XML_MIN_ID_TABLE 32
-
-typedef struct _xmlIDTable xmlIDTable;
+typedef struct _xmlHashTable xmlIDTable;
typedef xmlIDTable *xmlIDTablePtr;
-struct _xmlIDTable {
- int nb_ids; /* number of ids stored */
- int max_ids; /* maximum number of ids */
- xmlIDPtr *table; /* the table of ids */
-};
/*
* ALl Refs attributes are stored in a table
* there is one table per document
*/
-#define XML_MIN_REF_TABLE 32
-
-typedef struct _xmlRefTable xmlRefTable;
+typedef struct _xmlHashTable xmlRefTable;
typedef xmlRefTable *xmlRefTablePtr;
-struct _xmlRefTable {
- int nb_refs; /* number of refs stored */
- int max_refs; /* maximum number of refs */
- xmlRefPtr *table; /* the table of refs */
-};
/* Notation */
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
diff --git a/xmlmemory.c b/xmlmemory.c
index 1595a2a1..a9b25112 100644
--- a/xmlmemory.c
+++ b/xmlmemory.c
@@ -384,6 +384,11 @@ xmlMemContentShow(FILE *fp, MEMHDR *p)
int i,j,len = p->mh_size;
const char *buf = (const char *) HDR_2_CLIENT(p);
+ if (p == NULL) {
+ fprintf(fp, " NULL");
+ return;
+ }
+
for (i = 0;i < len;i++) {
if (buf[i] == 0) break;
if (!isprint(buf[i])) break;
@@ -401,7 +406,7 @@ xmlMemContentShow(FILE *fp, MEMHDR *p)
if (p == q) break;
p = p->mh_next;
}
- if (p == q) {
+ if ((p != NULL) && (p == q)) {
fprintf(fp, " pointer to #%lu at index %d",
p->mh_number, j);
return;
diff --git a/xpath.c b/xpath.c
index cd2533bb..545dd07a 100644
--- a/xpath.c
+++ b/xpath.c
@@ -903,44 +903,17 @@ xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
int
xmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
xmlXPathObjectPtr value) {
- int i;
-
if (ctxt == NULL)
return(-1);
if (name == NULL)
return(-1);
- for (i = 0;i < ctxt->nb_variables;i++) {
- if (xmlStrEqual(ctxt->variables[i].name, name)) {
- /*
- * It's just an update or a removal
- */
- if (ctxt->variables[i].value != NULL) {
- xmlXPathFreeObject(ctxt->variables[i].value);
- }
- ctxt->variables[i].value = xmlXPathObjectCopy(value);
- return(0);
- }
- }
- if (ctxt->max_variables <= 0) {
- ctxt->max_variables = 10;
- ctxt->nb_variables = 0;
- ctxt->variables = (xmlXPathVariablePtr)
- xmlMalloc(ctxt->max_variables * sizeof(xmlXPathVariable));
- } else if (ctxt->max_variables <= ctxt->nb_variables) {
- ctxt->max_variables *= 2;
- ctxt->variables = (xmlXPathVariablePtr)
- xmlRealloc(ctxt->variables,
- ctxt->max_variables * sizeof(xmlXPathVariable));
- }
- if (ctxt->variables == NULL) {
- fprintf(xmlXPathDebug, "xmlXPathRegisterVariable: out of memory\n");
+ if (ctxt->varHash == NULL)
+ ctxt->varHash = xmlHashCreate(0);
+ if (ctxt->varHash == NULL)
return(-1);
- }
- ctxt->variables[ctxt->nb_variables].name = xmlStrdup(name);
- ctxt->variables[ctxt->nb_variables].value = xmlXPathObjectCopy(value);
- ctxt->nb_variables++;
- return(0);
+ return(xmlHashUpdateEntry(ctxt->varHash, name, (void *) value,
+ (xmlHashDeallocator)xmlXPathFreeObject));
}
/**
@@ -955,19 +928,14 @@ xmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
*/
xmlXPathObjectPtr
xmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
- int i;
-
if (ctxt == NULL)
return(NULL);
+ if (ctxt->varHash == NULL)
+ return(NULL);
if (name == NULL)
return(NULL);
- for (i = 0;i < ctxt->nb_variables;i++) {
- if (xmlStrEqual(ctxt->variables[i].name, name)) {
- return(xmlXPathObjectCopy(ctxt->variables[i].value));
- }
- }
- return(NULL);
+ return((xmlXPathObjectPtr) xmlHashLookup(ctxt->varHash, name));
}
/**
@@ -978,20 +946,11 @@ xmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
*/
void
xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
- int i;
-
if (ctxt == NULL)
return;
- for (i = 0;i < ctxt->nb_variables;i++) {
- xmlFree((xmlChar *) ctxt->variables[i].name);
- xmlXPathFreeObject(ctxt->variables[i].value);
- }
- ctxt->nb_variables = -1;
- ctxt->max_variables = -1;
- if (ctxt->variables != NULL)
- xmlFree(ctxt->variables);
- ctxt->variables = NULL;
+ xmlHashFree(ctxt->varHash, NULL);
+ ctxt->varHash = NULL;
}
/************************************************************************
@@ -1196,9 +1155,7 @@ xmlXPathNewContext(xmlDocPtr doc) {
ret->doc = doc;
ret->node = NULL;
- ret->nb_variables = 0;
- ret->max_variables = 0;
- ret->variables = NULL;
+ ret->varHash = NULL;
ret->nb_types = 0;
ret->max_types = 0;
diff --git a/xpath.h b/xpath.h
index add4edda..0d2fa168 100644
--- a/xpath.h
+++ b/xpath.h
@@ -177,9 +177,9 @@ struct _xmlXPathContext {
xmlDocPtr doc; /* The current document */
xmlNodePtr node; /* The current node */
- int nb_variables; /* number of defined variables */
- int max_variables; /* max number of variables */
- xmlXPathVariablePtr variables; /* Array of defined variables */
+ int nb_variables_unused; /* unused (hash table) */
+ int max_variables_unused; /* unused (hash table) */
+ xmlHashTablePtr varHash; /* Hash table of defined variables */
int nb_types; /* number of defined types */
int max_types; /* max number of types */
|