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 <marc@calderasystems.com>
- 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
This commit is contained in:
Daniel Veillard 2000-10-24 17:10:12 +00:00
parent 3fe876892e
commit 126f27992d
23 changed files with 935 additions and 1242 deletions

View File

@ -1,3 +1,21 @@
Tue Oct 24 18:49:34 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
* 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 <marc@calderasystems.com>
* 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 <Daniel.Veillard@w3.org>
* entities.[ch] xpath.[ch] hash.[ch] debugXML.c tree.h: added/hacked

View File

@ -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;

View File

@ -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");
}

View File

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

289
hash.c
View File

@ -21,6 +21,27 @@
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
/*
* 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;
}
}

65
hash.h
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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 */

View File

@ -966,9 +966,6 @@ xmlNanoHTTPClose(void *ctx) {
xmlNanoHTTPFreeCtxt(ctxt);
}
#ifndef DEBUG_HTTP
#define DEBUG_HTTP
#endif
/**
* xmlNanoHTTPMethod:
* @URL: The URL to load

View File

@ -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:

View File

@ -89,8 +89,7 @@ eval("page" + id + " = window.open(URL, '" + id + "', 'toolbars=0, scrollbars=0,
<a href="http://bp6.gamesquad.net/win2k_install.phtml"><font color="white" face="Verdana" size="1">Win2k Install</font></a>
</p></td>
<td valign="top" width="15%"><p align="center">
<a href="http://www.gentus.com/">
<img align="bottom" alt="Taking a first look at the Abit Linux release called " border="0" height="45" src="doc3_files/gentusbox.gif" width="70" gentus>?.?&gt;</a>
<a href="http://www.gentus.com/"><img align="bottom" alt="Taking a first look at the Abit Linux release called " border="0" height="45" src="doc3_files/gentusbox.gif" width="70" gentus></a>
<br>
<a href="http://www.gentus.com/"><font color="white" face="Verdana" size="1">Gentus</font></a>
</p></td>

View File

@ -13,12 +13,6 @@ _top"><img src="http://ads.gamesquad.net/addclick.exe/adcycle.cgi?group=52&medi
./test/HTML/doc3.htm:140: error: error parsing attribute name
width=70 Gentus?.?></A><BR><A
^
./test/HTML/doc3.htm:140: error: htmlParseStartTag: problem parsing attributes
width=70 Gentus?.?></A><BR><A
^
./test/HTML/doc3.htm:140: error: Couldn't find end of Start Tag img
width=70 Gentus?.?></A><BR><A
^
./test/HTML/doc3.htm:143: error: Unexpected end tag : p
</P></TD></TR></TBODY></TABLE></CENTER></TD></TR></TBODY></TABLE></CENTER></P
^

View File

@ -320,10 +320,8 @@ SAX.characters(
SAX.startElement(p, align='center')
SAX.startElement(a, href='http://www.gentus.com/')
SAX.error: error parsing attribute name
SAX.error: htmlParseStartTag: problem parsing attributes
SAX.startElement(img, align='bottom', alt='Taking a first look at the Abit Linux release called ', border='0', height='45', src='doc3_files/gentusbox.gif', width='70', gentus)
SAX.error: Couldn't find end of Start Tag img
SAX.characters(?.?&gt;, 4)
SAX.endElement(img)
SAX.endElement(a)
SAX.startElement(br)
SAX.endElement(br)

View File

@ -9,7 +9,9 @@
<td rowspan="2" align="LEFT" bgcolor="FFFFFF"><input type="IMAGE" src="http://static.wired.com/advertising/blipverts/allapartments/990625jpa_ssthome.gif" width="375" height="60" border="0" value="search" hspace="0" alt="Search over 6,000,000 Apts with SpringStreet"></td>
</tr>
<tr><td bgcolor="#330099">
<select name="state"><option value="WA" selected>WA
<select name="state">
<option value="WA" selected>WA
</option>
<option value="AL">AL</option>
<option value="AK">AK</option>
<option value="AZ">AZ</option>
@ -62,7 +64,7 @@
<option value="WV">WV</option>
<option value="WI">WI</option>
<option value="WY">WY</option>
</option></select>
</select>
<input type="hidden" name="source" value="2hb8bhc059">
</td></tr>
</form></table>
@ -166,22 +168,36 @@
<tr><td bgcolor="#CCFFCC"><form action="http://r.wired.com/r/wn_nav_c_bn/http://barnesandnoble.bfast.com/booklink/click">
<input type="hidden" name="sourceid" value="383471">
<input type="hidden" name="categoryid" value="categorydropdown">
<font size="2"><select name="Subjects" size="4"><option value="301">Business Top 20
<font size="2"><select name="Subjects" size="4">
<option value="301">Business Top 20
</option>
<option value="500">Computers
</option>
<option value="503">Computer Games
</option>
<option value="1604">Current Affairs
</option>
<option value="511">Cyberculture
</option>
<option value="510">Internet/Web
</option>
<option value="303">Investing
</option>
<option value="1606">Law
</option>
<option value="513">Multimedia
</option>
<option value="1605">Newsmakers
</option>
<option value="1607">Politics/Govt.
<option value="315"> Web Business
<option value="2800"> Bargain Books
</option>
<option value="315"> Web Business
</option>
<option value="2800"> Bargain Books
</option>
<option value="4">Other
@ -189,19 +205,7 @@
</option>
</option>
</option>
</option>
</option>
</option>
</option>
</option>
</option>
</option>
</option>
</option>
</option>
</option></select></font>
</select></font>
</form></td></tr>
<tr align="left" valign="top"><td valign="top" bgcolor="#CCFFCC">
<input type="submit" value="GO">

View File

@ -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

2
tree.c
View File

@ -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);

1298
valid.c

File diff suppressed because it is too large Load Diff

48
valid.h
View File

@ -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,

View File

@ -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;

65
xpath.c
View File

@ -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;

View File

@ -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 */