diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2000-10-22 16:56:02 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2000-10-22 16:56:02 +0000 |
commit | 52afe800ace426d98ef98f742cabbbf08c7d83e3 (patch) | |
tree | 8124d4cf20521252920384e4af5e9923d2d54dff | |
parent | 683cb026362f6f41000bda3a541b19c17e81ae48 (diff) | |
download | libxml2-52afe800ace426d98ef98f742cabbbf08c7d83e3.tar.gz |
Started working on the hash table module integration, fixed a bug:
- entities.[ch] xpath.[ch] hash.[ch] debugXML.c tree.h: added/hacked
hash tables from Bjorn Reese <breese@mail1.stofanet.dk>. Switched
XPath functions and XML entities table to them. More to come...
- xmlIO.c: fixed libxml closing FILEs it didn't open.
Daniel
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | debugXML.c | 19 | ||||
-rw-r--r-- | entities.c | 468 | ||||
-rw-r--r-- | entities.h | 28 | ||||
-rw-r--r-- | include/Makefile.am | 1 | ||||
-rw-r--r-- | include/libxml/entities.h | 28 | ||||
-rw-r--r-- | include/libxml/tree.h | 1 | ||||
-rw-r--r-- | include/libxml/xpath.h | 7 | ||||
-rw-r--r-- | tree.h | 1 | ||||
-rw-r--r-- | xmlIO.c | 15 | ||||
-rw-r--r-- | xpath.c | 208 | ||||
-rw-r--r-- | xpath.h | 7 |
14 files changed, 180 insertions, 612 deletions
@@ -1,3 +1,10 @@ +Sun Oct 22 18:39:19 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org> + + * entities.[ch] xpath.[ch] hash.[ch] debugXML.c tree.h: added/hacked + hash tables from Bjorn Reese <breese@mail1.stofanet.dk>. Switched + XPath functions and XML entities table to them. More to come... + * xmlIO.c: fixed libxml closing FILEs it didn't open. + Sun Oct 22 13:59:50 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org> * tree.c: coalesce adjacent text nodes diff --git a/Makefile.am b/Makefile.am index e837a143..713ecd27 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,6 +23,7 @@ libxml_la_SOURCES = \ parserInternals.c \ parser.c \ tree.c \ + hash.c \ xmlIO.c \ xmlmemory.c \ uri.c \ diff --git a/configure.in b/configure.in index 032d8f24..1fd2ea3b 100644 --- a/configure.in +++ b/configure.in @@ -264,6 +264,7 @@ AC_SUBST(HTML_OBJ) AC_ARG_WITH(xpath, [ --with-xpath Add the XPATH support (on)]) if test "$with_xpath" = "no" ; then echo Disabling XPATH support + with_xptr="no" WITH_XPATH=0 XPATH_OBJ= else @@ -773,6 +773,7 @@ void xmlDebugDumpDTD(FILE *output, xmlDtdPtr dtd) { void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) { int i; + xmlHashEntryPtr ent; xmlEntityPtr cur; if (output == NULL) output = stdout; @@ -828,9 +829,10 @@ void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) { xmlEntitiesTablePtr table = (xmlEntitiesTablePtr) doc->intSubset->entities; fprintf(output, "Entities in internal subset\n"); - for (i = 0;i < table->max_entities;i++) { - cur = table->table[i]; - while (cur != NULL) { + 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: @@ -861,7 +863,7 @@ void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) { if (cur->content != NULL) fprintf(output, "\n content \"%s\"", cur->content); fprintf(output, "\n"); - cur = cur->nexte; + ent = ent->next; } } } else @@ -870,9 +872,10 @@ void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) { xmlEntitiesTablePtr table = (xmlEntitiesTablePtr) doc->extSubset->entities; fprintf(output, "Entities in external subset\n"); - for (i = 0;i < table->max_entities;i++) { - cur = table->table[i]; - while (cur != NULL) { + 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: @@ -903,7 +906,7 @@ void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) { if (cur->content != NULL) fprintf(output, "\n content \"%s\"", cur->content); fprintf(output, "\n"); - cur = cur->nexte; + ent = ent->next; } } } else @@ -18,6 +18,7 @@ #include <stdlib.h> #endif #include <libxml/xmlmemory.h> +#include <libxml/hash.h> #include <libxml/entities.h> #include <libxml/parser.h> @@ -60,7 +61,7 @@ struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = { * TODO: !!!!!!! This is GROSS, allocation of a 256 entry hash for * a fixed number of 4 elements ! */ -xmlEntitiesTablePtr xmlPredefinedEntities = NULL; +xmlHashTablePtr xmlPredefinedEntities = NULL; /* * xmlFreeEntity : clean-up an entity record. @@ -82,15 +83,6 @@ void xmlFreeEntity(xmlEntityPtr entity) { xmlFree((char *) entity->content); if (entity->orig != NULL) xmlFree((char *) entity->orig); -#ifdef WITH_EXTRA_ENT_DETECT - if (entity->entTab != NULL) { - int i; - - for (i = 0; i < entity->entNr; i++) - xmlFree(entity->entTab[i]); - xmlFree(entity->entTab); - } -#endif memset(entity, -1, sizeof(xmlEntity)); xmlFree(entity); } @@ -99,77 +91,35 @@ void xmlFreeEntity(xmlEntityPtr entity) { * xmlAddEntity : register a new entity for an entities table. */ static xmlEntityPtr -xmlAddEntity(xmlEntitiesTablePtr table, const xmlChar *name, int type, +xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { -#ifndef ENTITY_HASH_SIZE - int i; -#endif - int hash; + xmlEntitiesTablePtr table = NULL; xmlEntityPtr ret; if (name == NULL) return(NULL); -#ifdef ENTITY_HASH_SIZE - hash = xmlEntityComputeHash(name); - ret = table->table[hash]; - while (ret != NULL) { - if (xmlStrEqual(ret->name, name)) { - /* - * The entity is already defined in this Dtd, the spec says to NOT - * override it ... Is it worth a Warning ??? !!! - * Not having a cprinting context this seems hard ... - */ - if (((type == XML_INTERNAL_PARAMETER_ENTITY) || - (type == XML_EXTERNAL_PARAMETER_ENTITY)) && - ((ret->etype == XML_INTERNAL_PARAMETER_ENTITY) || - (ret->etype == XML_EXTERNAL_PARAMETER_ENTITY))) - return(NULL); - else - if (((type != XML_INTERNAL_PARAMETER_ENTITY) && - (type != XML_EXTERNAL_PARAMETER_ENTITY)) && - ((ret->etype != XML_INTERNAL_PARAMETER_ENTITY) && - (ret->etype != XML_EXTERNAL_PARAMETER_ENTITY))) - return(NULL); - } - ret = ret->nexte; - } -#else - for (i = 0;i < table->nb_entities;i++) { - ret = table->table[i]; - if (xmlStrEqual(ret->name, name)) { - /* - * The entity is already defined in this Dtd, the spec says to NOT - * override it ... Is it worth a Warning ??? !!! - * Not having a cprinting context this seems hard ... - */ - if (((type == XML_INTERNAL_PARAMETER_ENTITY) || - (type == XML_EXTERNAL_PARAMETER_ENTITY)) && - ((ret->etype == XML_INTERNAL_PARAMETER_ENTITY) || - (ret->etype == XML_EXTERNAL_PARAMETER_ENTITY))) - return(NULL); - else - if (((type != XML_INTERNAL_PARAMETER_ENTITY) && - (type != XML_EXTERNAL_PARAMETER_ENTITY)) && - ((ret->etype != XML_INTERNAL_PARAMETER_ENTITY) && - (ret->etype != XML_EXTERNAL_PARAMETER_ENTITY))) - return(NULL); - } - } - if (table->nb_entities >= table->max_entities) { - /* - * need more elements. - */ - table->max_entities *= 2; - table->table = (xmlEntityPtr *) - xmlRealloc(table->table, - table->max_entities * sizeof(xmlEntityPtr)); - if (table->table == NULL) { - perror("realloc failed"); - return(NULL); - } + switch (type) { + case XML_INTERNAL_GENERAL_ENTITY: + case XML_EXTERNAL_GENERAL_PARSED_ENTITY: + case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: + if (dtd->entities == NULL) + dtd->entities = xmlHashCreate(0); + table = dtd->entities; + break; + case XML_INTERNAL_PARAMETER_ENTITY: + case XML_EXTERNAL_PARAMETER_ENTITY: + if (dtd->pentities == NULL) + dtd->pentities = xmlHashCreate(0); + table = dtd->pentities; + break; + case XML_INTERNAL_PREDEFINED_ENTITY: + if (xmlPredefinedEntities == NULL) + xmlPredefinedEntities = xmlHashCreate(8); + table = xmlPredefinedEntities; } -#endif + if (table == NULL) + return(NULL); ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity)); if (ret == NULL) { fprintf(stderr, "xmlAddEntity: out of memory\n"); @@ -177,12 +127,6 @@ xmlAddEntity(xmlEntitiesTablePtr table, const xmlChar *name, int type, } memset(ret, 0, sizeof(xmlEntity)); ret->type = XML_ENTITY_DECL; -#ifdef ENTITY_HASH_SIZE - ret->nexte = table->table[hash]; - table->table[hash] = ret; -#else - table->table[table->nb_entities] = ret; -#endif /* * fill the structure. @@ -203,8 +147,13 @@ xmlAddEntity(xmlEntitiesTablePtr table, const xmlChar *name, int type, ret->URI = NULL; /* to be computed by the layer knowing the defining entity */ ret->orig = NULL; - table->nb_entities++; + if (xmlHashAddEntry(table, name, ret)) { + /* + * entity was already defined at another level. + */ + xmlFreeEntity(ret); + } return(ret); } @@ -231,7 +180,8 @@ void xmlInitializePredefinedEntities(void) { in = xmlPredefinedEntityValues[i].value; out = &value[0]; for (;(*out++ = (xmlChar) *in);)in++; - xmlAddEntity(xmlPredefinedEntities, (const xmlChar *) &name[0], + + xmlAddEntity(NULL, (const xmlChar *) &name[0], XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL, &value[0]); } @@ -259,26 +209,9 @@ void xmlCleanupPredefinedEntities(void) { */ xmlEntityPtr xmlGetPredefinedEntity(const xmlChar *name) { - int i; - xmlEntityPtr cur; - if (xmlPredefinedEntities == NULL) xmlInitializePredefinedEntities(); -#ifdef ENTITY_HASH_SIZE - i = xmlEntityComputeHash(name); - cur = xmlPredefinedEntities->table[i]; - while (cur != NULL) { - if (xmlStrEqual(cur->name, name)) - return(cur); - cur = cur->nexte; - } -#else - for (i = 0;i < xmlPredefinedEntities->nb_entities;i++) { - cur = xmlPredefinedEntities->table[i]; - if (xmlStrEqual(cur->name, name)) return(cur); - } -#endif - return(NULL); + return((xmlEntityPtr) xmlHashLookup(xmlPredefinedEntities, name)); } /** @@ -298,7 +231,6 @@ xmlEntityPtr xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { - xmlEntitiesTablePtr table; xmlEntityPtr ret; xmlDtdPtr dtd; @@ -313,12 +245,7 @@ xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type, return(NULL); } dtd = doc->extSubset; - table = (xmlEntitiesTablePtr) dtd->entities; - if (table == NULL) { - table = xmlCreateEntitiesTable(); - dtd->entities = table; - } - ret = xmlAddEntity(table, name, type, ExternalID, SystemID, content); + ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content); if (ret == NULL) return(NULL); /* @@ -353,7 +280,6 @@ xmlEntityPtr xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { - xmlEntitiesTablePtr table; xmlEntityPtr ret; xmlDtdPtr dtd; @@ -368,12 +294,7 @@ xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type, return(NULL); } dtd = doc->intSubset; - table = (xmlEntitiesTablePtr) doc->intSubset->entities; - if (table == NULL) { - table = xmlCreateEntitiesTable(); - doc->intSubset->entities = table; - } - ret = xmlAddEntity(table, name, type, ExternalID, SystemID, content); + ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content); if (ret == NULL) return(NULL); /* @@ -391,143 +312,6 @@ xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type, return(ret); } -#ifdef WITH_EXTRA_ENT_DETECT -/** - * xmlEntityCheckReference: - * @ent: an existing entity - * @to: the entity name it's referencing - * - * Function to keep track of references and detect cycles (well formedness - * errors !). - * - * Returns: 0 if Okay, -1 in case of general error, 1 in case of loop - * detection. - */ -int -xmlEntityCheckReference(xmlEntityPtr ent, const xmlChar *to) { - int i; - xmlDocPtr doc; - - if (ent == NULL) return(-1); - if (to == NULL) return(-1); - - doc = ent->doc; - if (doc == NULL) return(-1); - -#ifdef DEBUG_ENT_REF - printf("xmlEntityCheckReference(%s to %s)\n", ent->name, to); -#endif - - - /* - * Do a recursive checking - */ - for (i = 0;i < ent->entNr;i++) { - xmlEntityPtr indir = NULL; - - if (xmlStrEqual(to, ent->entTab[i])) - return(1); - - switch (ent->etype) { - case XML_INTERNAL_GENERAL_ENTITY: - case XML_EXTERNAL_GENERAL_PARSED_ENTITY: - indir = xmlGetDocEntity(doc, ent->entTab[i]); - break; - case XML_INTERNAL_PARAMETER_ENTITY: - case XML_EXTERNAL_PARAMETER_ENTITY: - indir = xmlGetDtdEntity(doc, ent->entTab[i]); - break; - case XML_INTERNAL_PREDEFINED_ENTITY: - case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: - break; - } - if (xmlEntityCheckReference(indir, to) == 1) - return(1); - } - return(0); -} - -/** - * xmlEntityAddReference: - * @ent: an existing entity - * @to: the entity name it's referencing - * - * Function to register reuse of an existing entity from a (new) one - * Used to keep track of references and detect cycles (well formedness - * errors !). - * - * Returns: 0 if Okay, -1 in case of general error, 1 in case of loop - * detection. - */ -int -xmlEntityAddReference(xmlEntityPtr ent, const xmlChar *to) { - int i; - xmlDocPtr doc; - xmlEntityPtr indir = NULL; - - if (ent == NULL) return(-1); - if (to == NULL) return(-1); - - doc = ent->doc; - if (doc == NULL) return(-1); - -#ifdef DEBUG_ENT_REF - printf("xmlEntityAddReference(%s to %s)\n", ent->name, to); -#endif - if (ent->entTab == NULL) { - ent->entNr = 0; - ent->entMax = 5; - ent->entTab = (xmlChar **) xmlMalloc(ent->entMax * sizeof(xmlChar *)); - if (ent->entTab == NULL) { - fprintf(stderr, "xmlEntityAddReference: out of memory !\n"); - return(-1); - } - } - - for (i = 0;i < ent->entNr;i++) { - if (xmlStrEqual(to, ent->entTab[i])) - return(0); - } - - /* - * Do a recursive checking - */ - - switch (ent->etype) { - case XML_INTERNAL_GENERAL_ENTITY: - case XML_EXTERNAL_GENERAL_PARSED_ENTITY: - indir = xmlGetDocEntity(doc, to); - break; - case XML_INTERNAL_PARAMETER_ENTITY: - case XML_EXTERNAL_PARAMETER_ENTITY: - indir = xmlGetDtdEntity(doc, to); - break; - case XML_INTERNAL_PREDEFINED_ENTITY: - case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: - break; - } - if ((indir != NULL) && - (xmlEntityCheckReference(indir, ent->name) == 1)) - return(1); - - /* - * Add this to the list - */ - if (ent->entMax <= ent->entNr) { - ent->entMax *= 2; - ent->entTab = (xmlChar **) xmlRealloc(ent->entTab, - ent->entMax * sizeof(xmlChar *)); - if (ent->entTab == NULL) { - fprintf(stderr, "xmlEntityAddReference: out of memory !\n"); - return(-1); - } - } - ent->entTab[ent->entNr++] = xmlStrdup(to); - return(0); -} -#endif - - /** * xmlGetEntityFromTable: * @table: an entity table @@ -540,43 +324,8 @@ xmlEntityAddReference(xmlEntityPtr ent, const xmlChar *to) { * Returns A pointer to the entity structure or NULL if not found. */ xmlEntityPtr -xmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name, - int parameter) { - xmlEntityPtr cur; -#ifdef ENTITY_HASH_SIZE - int hash; - - hash = xmlEntityComputeHash(name); - cur = table->table[hash]; - while (cur != NULL) { - switch (cur->etype) { - case XML_INTERNAL_PARAMETER_ENTITY: - case XML_EXTERNAL_PARAMETER_ENTITY: - if ((parameter) && (xmlStrEqual(cur->name, name))) - return(cur); - default: - if ((!parameter) && (xmlStrEqual(cur->name, name))) - return(cur); - } - cur = cur->nexte; - } -#else - int i; - - for (i = 0;i < table->nb_entities;i++) { - cur = table->table[i]; - switch (cur->etype) { - case XML_INTERNAL_PARAMETER_ENTITY: - case XML_EXTERNAL_PARAMETER_ENTITY: - if ((parameter) && (xmlStrEqual(cur->name, name))) - return(cur); - default: - if ((!parameter) && (xmlStrEqual(cur->name, name))) - return(cur); - } - } -#endif - return(NULL); +xmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name) { + return((xmlEntityPtr) xmlHashLookup(table, name)); } /** @@ -594,15 +343,15 @@ xmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) { xmlEntitiesTablePtr table; xmlEntityPtr ret; - if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) { - table = (xmlEntitiesTablePtr) doc->intSubset->entities; - ret = xmlGetEntityFromTable(table, name, 1); + if ((doc->intSubset != NULL) && (doc->intSubset->pentities != NULL)) { + table = (xmlEntitiesTablePtr) doc->intSubset->pentities; + ret = xmlGetEntityFromTable(table, name); if (ret != NULL) return(ret); } - if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) { - table = (xmlEntitiesTablePtr) doc->extSubset->entities; - return(xmlGetEntityFromTable(table, name, 1)); + if ((doc->extSubset != NULL) && (doc->extSubset->pentities != NULL)) { + table = (xmlEntitiesTablePtr) doc->extSubset->pentities; + return(xmlGetEntityFromTable(table, name)); } return(NULL); } @@ -623,7 +372,7 @@ xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) { if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) { table = (xmlEntitiesTablePtr) doc->extSubset->entities; - return(xmlGetEntityFromTable(table, name, 0)); + return(xmlGetEntityFromTable(table, name)); } return(NULL); } @@ -647,13 +396,13 @@ xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) { if (doc != NULL) { if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) { table = (xmlEntitiesTablePtr) doc->intSubset->entities; - cur = xmlGetEntityFromTable(table, name, 0); + cur = xmlGetEntityFromTable(table, name); if (cur != NULL) return(cur); } if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) { table = (xmlEntitiesTablePtr) doc->extSubset->entities; - cur = xmlGetEntityFromTable(table, name, 0); + cur = xmlGetEntityFromTable(table, name); if (cur != NULL) return(cur); } @@ -661,7 +410,7 @@ xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) { if (xmlPredefinedEntities == NULL) xmlInitializePredefinedEntities(); table = xmlPredefinedEntities; - return(xmlGetEntityFromTable(table, name, 0)); + return(xmlGetEntityFromTable(table, name)); } /* @@ -1117,39 +866,7 @@ xmlEncodeSpecialChars(xmlDocPtr doc, const xmlChar *input) { */ xmlEntitiesTablePtr xmlCreateEntitiesTable(void) { - xmlEntitiesTablePtr ret; - - ret = (xmlEntitiesTablePtr) - xmlMalloc(sizeof(xmlEntitiesTable)); - if (ret == NULL) { - fprintf(stderr, "xmlCreateEntitiesTable : xmlMalloc(%ld) failed\n", - (long)sizeof(xmlEntitiesTable)); - return(NULL); - } - ret->nb_entities = 0; -#ifdef ENTITY_HASH_SIZE - ret->max_entities = ENTITY_HASH_SIZE; - ret->table = (xmlEntityPtr *) - xmlMalloc(ret->max_entities * sizeof(xmlEntityPtr)); - if (ret == NULL) { - fprintf(stderr, "xmlCreateEntitiesTable : xmlMalloc(%ld) failed\n", - ret->max_entities * (long)sizeof(xmlEntityPtr)); - xmlFree(ret); - return(NULL); - } - memset(ret->table, 0, ret->max_entities * sizeof(xmlEntityPtr)); -#else - ret->max_entities = XML_MIN_ENTITIES_TABLE; - ret->table = (xmlEntityPtr *) - xmlMalloc(ret->max_entities * sizeof(xmlEntityPtr)); - if (ret == NULL) { - fprintf(stderr, "xmlCreateEntitiesTable : xmlMalloc(%ld) failed\n", - ret->max_entities * (long)sizeof(xmlEntityPtr)); - xmlFree(ret); - return(NULL); - } -#endif - return(ret); + return((xmlEntitiesTablePtr) xmlHashCreate(0)); } /** @@ -1160,29 +877,7 @@ xmlCreateEntitiesTable(void) { */ void xmlFreeEntitiesTable(xmlEntitiesTablePtr table) { - int i; -#ifdef ENTITY_HASH_SIZE - xmlEntityPtr cur, next; -#endif - - if (table == NULL) return; - -#ifdef ENTITY_HASH_SIZE - for (i = 0;i < ENTITY_HASH_SIZE;i++) { - cur = table->table[i]; - while (cur != NULL) { - next = cur->nexte; - xmlFreeEntity(cur); - cur = next; - } - } -#else - for (i = 0;i < table->nb_entities;i++) { - xmlFreeEntity(table->table[i]); - } -#endif - xmlFree(table->table); - xmlFree(table); + xmlHashFree(table, (xmlHashDeallocator) xmlFreeEntity); } /** @@ -1229,50 +924,7 @@ xmlCopyEntity(xmlEntityPtr ent) { */ xmlEntitiesTablePtr xmlCopyEntitiesTable(xmlEntitiesTablePtr table) { - xmlEntitiesTablePtr ret; - xmlEntityPtr cur, ent; - int i; - - ret = (xmlEntitiesTablePtr) xmlMalloc(sizeof(xmlEntitiesTable)); - if (ret == NULL) { - fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n"); - return(NULL); - } -#ifdef ENTITY_HASH_SIZE - ret->table = (xmlEntityPtr *) xmlMalloc(ENTITY_HASH_SIZE * - sizeof(xmlEntityPtr)); - if (ret->table == NULL) { - fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n"); - xmlFree(ret); - return(NULL); - } -#else - ret->table = (xmlEntityPtr *) xmlMalloc(table->max_entities * - sizeof(xmlEntityPtr)); - if (ret->table == NULL) { - fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n"); - xmlFree(ret); - return(NULL); - } -#endif - ret->max_entities = table->max_entities; - ret->nb_entities = table->nb_entities; - for (i = 0;i < ret->nb_entities;i++) { - ent = table->table[i]; - if (ent == NULL) - cur = NULL; - else - cur = xmlCopyEntity(ent); - ret->table[i] = cur; -#ifdef ENTITY_HASH_SIZE - ent = ent->nexte; - while ((ent != NULL) && (cur != NULL)) { - cur->nexte = xmlCopyEntity(ent); - cur = cur->nexte; - } -#endif - } - return(ret); + return(xmlHashCopy(table, (xmlHashCopier) xmlCopyEntity)); } /** @@ -1370,23 +1022,5 @@ xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) { */ void xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) { - int i; - xmlEntityPtr cur; - - if (table == NULL) return; - -#ifdef ENTITY_HASH_SIZE - for (i = 0;i < ENTITY_HASH_SIZE;i++) { - cur = table->table[i]; - while (cur != NULL) { - xmlDumpEntityDecl(buf, cur); - cur = cur->nexte; - } - } -#else - for (i = 0;i < table->nb_entities;i++) { - cur = table->table[i]; - xmlDumpEntityDecl(buf, cur); - } -#endif + xmlHashScan(table, (xmlHashScanner)xmlDumpEntityDecl, buf); } @@ -54,33 +54,17 @@ struct _xmlEntity { const xmlChar *ExternalID; /* External identifier for PUBLIC */ const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC Entity */ - struct _xmlEntity *nexte; /* next entity in the hash table */ + struct _xmlEntity *nexte; /* unused */ const xmlChar *URI; /* the full URI as computed */ - -#ifdef WITH_EXTRA_ENT_DETECT - /* Referenced entities name stack */ - xmlChar *ent; /* Current parsed Node */ - int entNr; /* Depth of the parsing stack */ - int entMax; /* Max depth of the parsing stack */ - xmlChar * *entTab; /* array of nodes */ -#endif }; /* - * ALl entities are stored in a table there is one table per DTD - * and one extra per document. + * ALl entities are stored in an hash table + * there is 2 separate hash tables for global and parmeter entities */ -#define XML_MIN_ENTITIES_TABLE 32 - -typedef struct _xmlEntitiesTable xmlEntitiesTable; +typedef struct _xmlHashTable xmlEntitiesTable; typedef xmlEntitiesTable *xmlEntitiesTablePtr; -struct _xmlEntitiesTable { - int nb_entities; /* number of elements stored */ - int max_entities; /* maximum number of elements */ - xmlEntityPtr *table; /* the table of entities */ -}; - /* * External functions : @@ -122,10 +106,6 @@ void xmlDumpEntityDecl (xmlBufferPtr buf, xmlEntitiesTablePtr xmlCopyEntitiesTable (xmlEntitiesTablePtr table); void xmlCleanupPredefinedEntities(void); -#ifdef WITH_EXTRA_ENT_DETECT -int xmlEntityAddReference (xmlEntityPtr ent, - const xmlChar *to); -#endif #ifdef __cplusplus } diff --git a/include/Makefile.am b/include/Makefile.am index aa845776..18d7cfaa 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -14,6 +14,7 @@ xmlinc_HEADERS = \ libxml/HTMLtree.h \ libxml/debugXML.h \ libxml/tree.h \ + libxml/hash.h \ libxml/xpath.h \ libxml/xpointer.h \ libxml/xmlIO.h \ diff --git a/include/libxml/entities.h b/include/libxml/entities.h index 2fad326b..305d043c 100644 --- a/include/libxml/entities.h +++ b/include/libxml/entities.h @@ -54,33 +54,17 @@ struct _xmlEntity { const xmlChar *ExternalID; /* External identifier for PUBLIC */ const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC Entity */ - struct _xmlEntity *nexte; /* next entity in the hash table */ + struct _xmlEntity *nexte; /* unused */ const xmlChar *URI; /* the full URI as computed */ - -#ifdef WITH_EXTRA_ENT_DETECT - /* Referenced entities name stack */ - xmlChar *ent; /* Current parsed Node */ - int entNr; /* Depth of the parsing stack */ - int entMax; /* Max depth of the parsing stack */ - xmlChar * *entTab; /* array of nodes */ -#endif }; /* - * ALl entities are stored in a table there is one table per DTD - * and one extra per document. + * ALl entities are stored in an hash table + * there is 2 separate hash tables for global and parmeter entities */ -#define XML_MIN_ENTITIES_TABLE 32 - -typedef struct _xmlEntitiesTable xmlEntitiesTable; +typedef struct _xmlHashTable xmlEntitiesTable; typedef xmlEntitiesTable *xmlEntitiesTablePtr; -struct _xmlEntitiesTable { - int nb_entities; /* number of elements stored */ - int max_entities; /* maximum number of elements */ - xmlEntityPtr *table; /* the table of entities */ -}; - /* * External functions : @@ -122,10 +106,6 @@ void xmlDumpEntityDecl (xmlBufferPtr buf, xmlEntitiesTablePtr xmlCopyEntitiesTable (xmlEntitiesTablePtr table); void xmlCleanupPredefinedEntities(void); -#ifdef WITH_EXTRA_ENT_DETECT -int xmlEntityAddReference (xmlEntityPtr ent, - const xmlChar *to); -#endif #ifdef __cplusplus } diff --git a/include/libxml/tree.h b/include/libxml/tree.h index 2a14d1d2..062f551b 100644 --- a/include/libxml/tree.h +++ b/include/libxml/tree.h @@ -233,6 +233,7 @@ struct _xmlDtd { void *entities; /* Hash table for entities if any */ const xmlChar *ExternalID; /* External identifier for PUBLIC DTD */ const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC DTD */ + void *pentities; /* Hash table for param entities if any */ }; /* diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h index a0a55785..add4edda 100644 --- a/include/libxml/xpath.h +++ b/include/libxml/xpath.h @@ -13,6 +13,7 @@ #define __XML_XPATH_H__ #include <libxml/tree.h> +#include <libxml/hash.h> #ifdef __cplusplus extern "C" { @@ -184,9 +185,9 @@ struct _xmlXPathContext { int max_types; /* max number of types */ xmlXPathTypePtr types; /* Array of defined types */ - int nb_funcs; /* number of defined funcs */ - int max_funcs; /* max number of funcs */ - xmlXPathFuncPtr funcs; /* Array of defined funcs */ + int nb_funcs_unused; /* unused (hash table) */ + int max_funcs_unused; /* unused (hash table) */ + xmlHashTablePtr funcHash; /* Hash table of defined funcs */ int nb_axis; /* number of defined axis */ int max_axis; /* max number of axis */ @@ -233,6 +233,7 @@ struct _xmlDtd { void *entities; /* Hash table for entities if any */ const xmlChar *ExternalID; /* External identifier for PUBLIC DTD */ const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC DTD */ + void *pentities; /* Hash table for param entities if any */ }; /* @@ -340,6 +340,17 @@ xmlFileClose (void * context) { fclose((FILE *) context); } +/** + * xmlFileFlush: + * @context: the I/O context + * + * Flush an I/O channel + */ +void +xmlFileFlush (void * context) { + fflush((FILE *) context); +} + #ifdef HAVE_ZLIB_H /************************************************************************ * * @@ -990,7 +1001,7 @@ xmlParserInputBufferCreateFile(FILE *file, xmlCharEncoding enc) { if (ret != NULL) { ret->context = file; ret->readcallback = xmlFileRead; - ret->closecallback = xmlFileClose; + ret->closecallback = xmlFileFlush; } return(ret); @@ -1019,7 +1030,7 @@ xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) { if (ret != NULL) { ret->context = file; ret->writecallback = xmlFileWrite; - ret->closecallback = xmlFileClose; + ret->closecallback = xmlFileFlush; } return(ret); @@ -49,6 +49,7 @@ #include <libxml/valid.h> #include <libxml/xpath.h> #include <libxml/parserInternals.h> +#include <libxml/hash.h> #ifdef LIBXML_XPTR_ENABLED #include <libxml/xpointer.h> #endif @@ -184,6 +185,7 @@ FILE *xmlXPathDebug = NULL; #ifdef LIBXML_DEBUG_ENABLED double xmlXPathStringEvalNumber(const xmlChar *str); void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs); +void xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt); void xmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) { int i; @@ -832,40 +834,16 @@ xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) { int xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name, xmlXPathFunction f) { - int i; - if (ctxt == NULL) return(-1); if (name == NULL) return(-1); - for (i = 0;i < ctxt->nb_funcs;i++) { - if (xmlStrEqual(ctxt->funcs[i].name, name)) { - /* - * It's just an update or a removal - */ - ctxt->funcs[i].func = f; - return(0); - } - } - if (ctxt->max_funcs <= 0) { - ctxt->max_funcs = 10; - ctxt->nb_funcs = 0; - ctxt->funcs = (xmlXPathFuncPtr) xmlMalloc(ctxt->max_funcs * - sizeof(xmlXPathFunct)); - } else if (ctxt->max_funcs <= ctxt->nb_funcs) { - ctxt->max_funcs *= 2; - ctxt->funcs = (xmlXPathFuncPtr) xmlRealloc(ctxt->funcs, - ctxt->max_funcs * sizeof(xmlXPathFunct)); - } - if (ctxt->funcs == NULL) { - fprintf(xmlXPathDebug, "xmlXPathRegisterFunc: out of memory\n"); + if (ctxt->funcHash == NULL) + ctxt->funcHash = xmlHashCreate(0); + if (ctxt->funcHash == NULL) return(-1); - } - ctxt->funcs[ctxt->nb_funcs].name = xmlStrdup(name); - ctxt->funcs[ctxt->nb_funcs].func = f; - ctxt->nb_funcs++; - return(0); + return(xmlHashAddEntry(ctxt->funcHash, name, (void *) f)); } /** @@ -880,19 +858,14 @@ xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name, */ xmlXPathFunction xmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { - int i; - if (ctxt == NULL) return(NULL); + if (ctxt->funcHash == NULL) + return(NULL); if (name == NULL) return(NULL); - for (i = 0;i < ctxt->nb_funcs;i++) { - if (xmlStrEqual(ctxt->funcs[i].name, name)) { - return(ctxt->funcs[i].func); - } - } - return(NULL); + return((xmlXPathFunction) xmlHashLookup(ctxt->funcHash, name)); } /** @@ -903,19 +876,11 @@ xmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) { */ void xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) { - int i; - if (ctxt == NULL) return; - for (i = 0;i < ctxt->nb_funcs;i++) { - xmlFree((xmlChar *) ctxt->funcs[i].name); - } - ctxt->nb_funcs = -1; - ctxt->max_funcs = -1; - if (ctxt->funcs != NULL) - xmlFree(ctxt->funcs); - ctxt->funcs = NULL; + xmlHashFree(ctxt->funcHash, NULL); + ctxt->funcHash = NULL; } /************************************************************************ @@ -1239,9 +1204,7 @@ xmlXPathNewContext(xmlDocPtr doc) { ret->max_types = 0; ret->types = NULL; - ret->nb_funcs = 0; - ret->max_funcs = 0; - ret->funcs = NULL; + ret->funcHash = xmlHashCreate(0); ret->nb_axis = 0; ret->max_axis = 0; @@ -1253,6 +1216,9 @@ xmlXPathNewContext(xmlDocPtr doc) { ret->contextSize = -1; ret->proximityPosition = -1; + + xmlXPathRegisterAllFunctions(ret); + return(ret); } @@ -4012,88 +3978,7 @@ xmlXPathIsNodeType(const xmlChar *name) { */ xmlXPathFunction xmlXPathIsFunction(xmlXPathParserContextPtr ctxt, const xmlChar *name) { - if (name == NULL) - return(NULL); - - switch (name[0]) { - case 'b': - if (xmlStrEqual(name, BAD_CAST "boolean")) - return(xmlXPathBooleanFunction); - break; - case 'c': - if (xmlStrEqual(name, BAD_CAST "ceiling")) - return(xmlXPathCeilingFunction); - if (xmlStrEqual(name, BAD_CAST "count")) - return(xmlXPathCountFunction); - if (xmlStrEqual(name, BAD_CAST "concat")) - return(xmlXPathConcatFunction); - if (xmlStrEqual(name, BAD_CAST "contains")) - return(xmlXPathContainsFunction); - break; - case 'i': - if (xmlStrEqual(name, BAD_CAST "id")) - return(xmlXPathIdFunction); - break; - case 'f': - if (xmlStrEqual(name, BAD_CAST "false")) - return(xmlXPathFalseFunction); - if (xmlStrEqual(name, BAD_CAST "floor")) - return(xmlXPathFloorFunction); - break; - case 'l': - if (xmlStrEqual(name, BAD_CAST "last")) - return(xmlXPathLastFunction); - if (xmlStrEqual(name, BAD_CAST "lang")) - return(xmlXPathLangFunction); - if (xmlStrEqual(name, BAD_CAST "local-part")) - return(xmlXPathLocalPartFunction); - break; - case 'n': - if (xmlStrEqual(name, BAD_CAST "not")) - return(xmlXPathNotFunction); - if (xmlStrEqual(name, BAD_CAST "name")) - return(xmlXPathNameFunction); - if (xmlStrEqual(name, BAD_CAST "namespace")) - return(xmlXPathNamespaceFunction); - if (xmlStrEqual(name, BAD_CAST "normalize-space")) - return(xmlXPathNormalizeFunction); - if (xmlStrEqual(name, BAD_CAST "normalize")) - return(xmlXPathNormalizeFunction); - if (xmlStrEqual(name, BAD_CAST "number")) - return(xmlXPathNumberFunction); - break; - case 'p': - if (xmlStrEqual(name, BAD_CAST "position")) - return(xmlXPathPositionFunction); - break; - case 'r': - if (xmlStrEqual(name, BAD_CAST "round")) - return(xmlXPathRoundFunction); - break; - case 's': - if (xmlStrEqual(name, BAD_CAST "string")) - return(xmlXPathStringFunction); - if (xmlStrEqual(name, BAD_CAST "string-length")) - return(xmlXPathStringLengthFunction); - if (xmlStrEqual(name, BAD_CAST "starts-with")) - return(xmlXPathStartsWithFunction); - if (xmlStrEqual(name, BAD_CAST "substring")) - return(xmlXPathSubstringFunction); - if (xmlStrEqual(name, BAD_CAST "substring-before")) - return(xmlXPathSubstringBeforeFunction); - if (xmlStrEqual(name, BAD_CAST "substring-after")) - return(xmlXPathSubstringAfterFunction); - if (xmlStrEqual(name, BAD_CAST "sum")) - return(xmlXPathSumFunction); - break; - case 't': - if (xmlStrEqual(name, BAD_CAST "true")) - return(xmlXPathTrueFunction); - if (xmlStrEqual(name, BAD_CAST "translate")) - return(xmlXPathTranslateFunction); - break; - } - return(xmlXPathFunctionLookup(ctxt->context, name)); + return((xmlXPathFunction) xmlHashLookup(ctxt->context->funcHash, name)); } /** @@ -5383,4 +5268,65 @@ xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) { return(res); } +void +xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt) +{ + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean", + xmlXPathBooleanFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling", + xmlXPathCeilingFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count", + xmlXPathCountFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat", + xmlXPathConcatFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains", + xmlXPathContainsFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id", + xmlXPathIdFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false", + xmlXPathFalseFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor", + xmlXPathFloorFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last", + xmlXPathLastFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang", + xmlXPathLangFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-part", + xmlXPathLocalPartFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not", + xmlXPathNotFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name", + xmlXPathNameFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace", + xmlXPathNamespaceFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space", + xmlXPathNormalizeFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize", + xmlXPathNormalizeFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number", + xmlXPathNumberFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position", + xmlXPathPositionFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round", + xmlXPathRoundFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string", + xmlXPathStringFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length", + xmlXPathStringLengthFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with", + xmlXPathStartsWithFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring", + xmlXPathSubstringFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before", + xmlXPathSubstringBeforeFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after", + xmlXPathSubstringAfterFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum", + xmlXPathSumFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true", + xmlXPathTrueFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate", + xmlXPathTranslateFunction); +} + #endif /* LIBXML_XPATH_ENABLED */ @@ -13,6 +13,7 @@ #define __XML_XPATH_H__ #include <libxml/tree.h> +#include <libxml/hash.h> #ifdef __cplusplus extern "C" { @@ -184,9 +185,9 @@ struct _xmlXPathContext { int max_types; /* max number of types */ xmlXPathTypePtr types; /* Array of defined types */ - int nb_funcs; /* number of defined funcs */ - int max_funcs; /* max number of funcs */ - xmlXPathFuncPtr funcs; /* Array of defined funcs */ + int nb_funcs_unused; /* unused (hash table) */ + int max_funcs_unused; /* unused (hash table) */ + xmlHashTablePtr funcHash; /* Hash table of defined funcs */ int nb_axis; /* number of defined axis */ int max_axis; /* max number of axis */ |