Commit 126f2799 authored by Daniel Veillard's avatar Daniel Veillard
Browse files

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
parent 3fe87689
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
......
......@@ -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;
......
......@@ -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");
}
......
......@@ -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);
}
......
......@@ -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,6 +139,115 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
*/
int
xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
}
/**
* 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));
}
/**
* xmlHashUpdateEntry:
* @table: the hash table
* @name: the 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. Existing entry for this name will be removed
* and freed with @f if found.
*
* Returns 0 the addition succeeded and -1 in case of error.
*/
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;
......@@ -130,10 +264,14 @@ xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
} 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))
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
(xmlStrEqual(insert->name3, name3)))
return(-1);
}
......@@ -141,6 +279,8 @@ xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
if (entry == NULL)
return(-1);
entry->name = xmlStrdup(name);
entry->name2 = xmlStrdup(name2);
entry->name3 = xmlStrdup(name3);
entry->payload = userdata;
entry->next = NULL;
......@@ -154,21 +294,24 @@ xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
}
/**
* xmlHashUpdateEntry:
* 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 name. Existing entry for this name will be removed
* and freed with @f if found.
* 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
xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
void *userdata, xmlHashDeallocator f) {
xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
const xmlChar *name2, const xmlChar *name3,
void *userdata, xmlHashDeallocator f) {
unsigned long key;
xmlHashEntryPtr entry;
xmlHashEntryPtr insert;
......@@ -185,16 +328,20 @@ 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))) {
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;
}
}
......
......@@ -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,