From 126f27992d541f6ff897554828c339822fafee65 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Tue, 24 Oct 2000 17:10:12 +0000 Subject: [PATCH] Bunch of fixes, finishing moving datastructures to the hash stuff: - 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 Daniel --- ChangeLog | 18 + HTMLparser.c | 26 +- debugXML.c | 114 +--- entities.c | 1 + hash.c | 289 ++++++-- hash.h | 65 +- include/Makefile.am | 2 +- include/libxml/hash.h | 65 +- include/libxml/valid.h | 48 +- include/libxml/xpath.h | 6 +- nanohttp.c | 3 - parser.c | 33 +- result/HTML/doc3.htm | 3 +- result/HTML/doc3.htm.err | 6 - result/HTML/doc3.htm.sax | 4 +- result/HTML/wired.html | 40 +- result/HTML/wired.html.sax | 28 +- tree.c | 2 + valid.c | 1298 ++++++++++++------------------------ valid.h | 48 +- xmlmemory.c | 7 +- xpath.c | 65 +- xpath.h | 6 +- 23 files changed, 935 insertions(+), 1242 deletions(-) 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

- -Taking a first look at the Abit Linux release called ?.?> +Taking a first look at the Abit Linux release called
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"> - + @@ -62,7 +64,7 @@ - + @@ -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 */