Commit c08a2c6f authored by Daniel Veillard's avatar Daniel Veillard
Browse files

Bug fixes, improvement on ID/IDREF support, 1.6.2, no memleaks, Daniel

parent 72bd1001
Wed Sep 8 22:46:14 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
* HTMLparser.c : cleanup
* SAX.c valid.c valid.h: added ID/IDREF checking
* tree.c tree.h: extended doc structure for refs
* configure.in: 1.6.2
* parser.c: patched bug in SAX user arg call
* parserInternals.h: patched missing close in C++ wrapping
* testXPath.c xpath.c xpath.h: prepared for extensibility,
especially upcoming XPointer implementation.
* doc/xml.html: augmented, typo
Sat Sep 4 22:48:05 CEST 1999 Timur Bakeyev <mc@bat.ru>
* doc/Makefile.am: replaced "install -d " with "mkinstalldirs" -
......
......@@ -15,7 +15,7 @@ mean that I'm on holliday or on the road.
The reasons I'm asking for an ask before commit policy is that I'm
using a separate CVS base for unstable developments and if you commit
a patch I didn't get, I may loose your change by mistake (it happened
already once) and seriously complicatye my job of merging both bases.
already once) and seriously complicates my job of merging both bases.
(The second base is at http://dev.w3.org/ under the XML module).
thanks in advance for following the rule,
......
......@@ -1133,6 +1133,8 @@ htmlNewDoc(const CHAR *URI, const CHAR *ExternalID) {
cur->encoding = NULL;
cur->standalone = 1;
cur->compression = 0;
cur->ids = NULL;
cur->refs = NULL;
#ifndef XML_WITHOUT_CORBA
cur->_private = NULL;
cur->vepv = NULL;
......
......@@ -492,10 +492,13 @@ startDocument(void *ctx)
void
endDocument(void *ctx)
{
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.endDocument()\n");
#endif
if (ctxt->validate && ctxt->wellFormed &&
ctxt->myDoc && ctxt->myDoc->intSubset)
ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
}
/**
......@@ -572,6 +575,8 @@ attribute(void *ctx, const CHAR *fullname, const CHAR *value)
*/
if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
}
if (name != NULL)
......
......@@ -5,7 +5,7 @@ AM_CONFIG_HEADER(config.h)
LIBXML_MAJOR_VERSION=1
LIBXML_MINOR_VERSION=6
LIBXML_MICRO_VERSION=1
LIBXML_MICRO_VERSION=2
LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION
LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION
......
......@@ -529,7 +529,7 @@ core.</p>
Model</em> this is an API for accessing XML or HTML structured documents.
Native support for DOM in Gnome is on the way (module gnome-dom), and it will
be based on gnome-xml. This will be a far cleaner interface to manipulate XML
files within Gnome since it won't expose the internal structure. DOM defiles a
files within Gnome since it won't expose the internal structure. DOM defines a
set of IDL (or Java) interfaces allowing to traverse and manipulate a
document. The DOM library will allow accessing and modifying "live" documents
presents on other programs like this:</p>
......@@ -747,6 +747,6 @@ base under gnome-xml/example</p>
<p><a href="mailto:Daniel.Veillard@w3.org">Daniel Veillard</a></p>
<p>$Id$</p>
<p>$Id: xml.html,v 1.7 1999/09/04 18:27:23 veillard Exp $</p>
</body>
</html>
......@@ -637,4 +637,7 @@ int inputPush (xmlParserCtxtPtr ctxt,
xmlParserInputPtr value);
xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
#ifdef __cplusplus
}
#endif
#endif /* __XML_PARSER_INTERNALS_H__ */
......@@ -210,6 +210,17 @@ typedef struct xmlID {
} xmlID;
typedef xmlID *xmlIDPtr;
/*
* An XML IDREF instance.
*/
typedef struct xmlRef {
struct xmlRef *next; /* next Ref */
const CHAR *value; /* The Ref name */
xmlAttrPtr attr; /* The attribut holding it */
} xmlRef;
typedef xmlRef *xmlRefPtr;
/*
* A node in an XML tree.
*/
......@@ -253,6 +264,7 @@ typedef struct xmlDoc {
struct xmlNs *oldNs; /* Global namespace, the old way */
struct xmlNode *root; /* the document tree */
void *ids; /* Hash table for ID attributes if any */
void *refs; /* Hash table for IDREFs attributes if any */
} _xmlDoc;
typedef _xmlDoc xmlDoc;
typedef xmlDoc *xmlDocPtr;
......@@ -440,6 +452,12 @@ const CHAR * xmlNodeGetLang (xmlNodePtr cur);
void xmlNodeSetLang (xmlNodePtr cur,
const CHAR *lang);
/*
* Removing content.
*/
int xmlRemoveProp (xmlAttrPtr attr); /* TODO */
int xmlRemoveNode (xmlNodePtr node); /* TODO */
/*
* Internal, don't use
*/
......
......@@ -88,6 +88,20 @@ typedef struct xmlIDTable {
} xmlIDTable;
typedef xmlIDTable *xmlIDTablePtr;
/*
* ALl Refs attributes are stored in a table
* there is one table per document
*/
#define XML_MIN_REF_TABLE 32
typedef struct xmlRefTable {
int nb_refs; /* number of refs stored */
int max_refs; /* maximum number of refs */
xmlRefPtr *table; /* the table of refs */
} xmlRefTable;
typedef xmlRefTable *xmlRefTablePtr;
/* Notation */
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
xmlDtdPtr dtd,
......@@ -148,6 +162,17 @@ int xmlIsID (xmlDocPtr doc,
xmlNodePtr elem,
xmlAttrPtr attr);
/* IDREFs */
xmlRefPtr xmlAddRef (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
const CHAR *value,
xmlAttrPtr attr);
xmlRefTablePtr xmlCopyRefTable (xmlRefTablePtr table);
void xmlFreeRefTable (xmlRefTablePtr table);
int xmlIsRef (xmlDocPtr doc,
xmlNodePtr elem,
xmlAttrPtr attr);
/**
* The public function calls related to validity checking
*/
......@@ -181,6 +206,8 @@ int xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
xmlNodePtr elem,
xmlAttrPtr attr,
const CHAR *value);
int xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
xmlDocPtr doc);
int xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
const CHAR *notationName);
......
......@@ -14,6 +14,8 @@
#include "tree.h"
typedef struct xmlXPathParserContext *xmlXPathParserContextPtr;
/*
* A node-set (an unordered collection of nodes without duplicates)
*/
......@@ -37,6 +39,7 @@ typedef struct xmlNodeSet {
#define XPATH_BOOLEAN 2
#define XPATH_NUMBER 3
#define XPATH_STRING 4
#define XPATH_USERS 5
typedef struct xmlXPathObject {
int type;
......@@ -44,8 +47,66 @@ typedef struct xmlXPathObject {
int boolval;
double floatval;
CHAR *stringval;
void *user;
} xmlXPathObject, *xmlXPathObjectPtr;
/*
* A conversion function is associated to a type and used to cast
* the new type to primitive values.
*/
typedef int (*xmlXPathConvertFunc) (xmlXPathObjectPtr obj, int type);
/*
* Extra type: a name and a conversion function.
*/
typedef struct xmlXPathType {
const CHAR *name; /* the type name */
xmlXPathConvertFunc func; /* the conversion function */
} xmlXPathType, *xmlXPathTypePtr;
/*
* Extra variable: a name and a value.
*/
typedef struct xmlXPathVariable {
const CHAR *name; /* the variable name */
xmlXPathObjectPtr value; /* the value */
} xmlXPathVariable, *xmlXPathVariablePtr;
/*
* an evaluation function, the parameters are on the context stack
*/
typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt, int nargs);
/*
* Extra function: a name and a evaluation function.
*/
typedef struct xmlXPathFunct {
const CHAR *name; /* the function name */
xmlXPathEvalFunc func; /* the evaluation function */
} xmlXPathFunc, *xmlXPathFuncPtr;
/*
* An axis traversal function. To traverse an axis, the engine calls
* the first time with cur == NULL and repeat until the function returns
* NULL indicating the end of the axis traversal.
*/
typedef xmlXPathObjectPtr (*xmlXPathAxisFunc) (xmlXPathParserContextPtr ctxt,
xmlXPathObjectPtr cur);
/*
* Extra axis: a name and an axis function.
*/
typedef struct xmlXPathAxis {
const CHAR *name; /* the axis name */
xmlXPathAxisFunc func; /* the search function */
} xmlXPathAxis, *xmlXPathAxisPtr;
/*
* Expression evaluation occurs with respect to a context.
* he context consists of:
......@@ -60,10 +121,27 @@ typedef struct xmlXPathContext {
xmlDocPtr doc; /* The current document */
xmlNodePtr node; /* The current node */
xmlNodeSetPtr nodelist; /* The current node list */
void *variables; /* TODO !!!! */
void *functions; /* TODO !!!! */
int nb_variables; /* number of defined variables */
int max_variables; /* max number of variables */
xmlXPathVariablePtr *variables; /* Array of defined variables */
int nb_types; /* number of defined types */
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_axis; /* number of defined axis */
int max_axis; /* max number of axis */
xmlXPathAxisPtr *axis; /* Array of defined axis */
/* Namespace traversal should be implemented with user */
xmlNsPtr *namespaces; /* The namespaces lookup */
int nsNr; /* the current Namespace index */
void *user; /* user defined extra info */
} xmlXPathContext, *xmlXPathContextPtr;
/*
......@@ -81,7 +159,7 @@ typedef struct xmlXPathParserContext {
int valueNr; /* number of values stacked */
int valueMax; /* max number of values stacked */
xmlXPathObjectPtr *valueTab; /* stack of values */
} xmlXPathParserContext, *xmlXPathParserContextPtr;
} xmlXPathParserContext;
/*
* An XPath function
......@@ -97,9 +175,26 @@ typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
* *
************************************************************************/
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc,
void *variables,
void *functions);
/**
* Registering extensions to the expression language
*/
/* TODO */ int xmlXPathRegisterType (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathConvertFunc f);
/* TODO */ int xmlXPathRegisterAxis (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathAxisFunc f);
/* TODO */ int xmlXPathRegisterFunc (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathFunction f);
/* TODO */ int xmlXPathRegisterVariable (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathObject value);
/**
* Evaluation functions.
*/
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
xmlXPathObjectPtr xmlXPathEval (const CHAR *str,
xmlXPathContextPtr ctxt);
......
......@@ -3122,11 +3122,11 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
if (isParameter) {
if ((ctxt->sax != NULL) &&
(ctxt->sax->getParameterEntity != NULL))
cur = ctxt->sax->getParameterEntity(ctxt, name);
cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
} else {
if ((ctxt->sax != NULL) &&
(ctxt->sax->getEntity != NULL))
cur = ctxt->sax->getEntity(ctxt, name);
cur = ctxt->sax->getEntity(ctxt->userData, name);
}
if (cur != NULL) {
if (cur->orig != NULL)
......
......@@ -637,4 +637,7 @@ int inputPush (xmlParserCtxtPtr ctxt,
xmlParserInputPtr value);
xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
#ifdef __cplusplus
}
#endif
#endif /* __XML_PARSER_INTERNALS_H__ */
......@@ -125,7 +125,7 @@ void testXPath(const char *str) {
xmlXPathObjectPtr res;
xmlXPathContextPtr ctxt;
ctxt = xmlXPathNewContext(document, NULL, NULL);
ctxt = xmlXPathNewContext(document);
if (expr)
res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
else
......
......@@ -395,6 +395,7 @@ xmlNewDoc(const CHAR *version) {
cur->standalone = -1;
cur->compression = xmlCompressMode;
cur->ids = NULL;
cur->refs = NULL;
#ifndef XML_WITHOUT_CORBA
cur->_private = NULL;
cur->vepv = NULL;
......@@ -425,6 +426,7 @@ xmlFreeDoc(xmlDocPtr cur) {
if (cur->extSubset != NULL) xmlFreeDtd(cur->extSubset);
if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
memset(cur, -1, sizeof(xmlDoc));
xmlFree(cur);
}
......
......@@ -210,6 +210,17 @@ typedef struct xmlID {
} xmlID;
typedef xmlID *xmlIDPtr;
/*
* An XML IDREF instance.
*/
typedef struct xmlRef {
struct xmlRef *next; /* next Ref */
const CHAR *value; /* The Ref name */
xmlAttrPtr attr; /* The attribut holding it */
} xmlRef;
typedef xmlRef *xmlRefPtr;
/*
* A node in an XML tree.
*/
......@@ -253,6 +264,7 @@ typedef struct xmlDoc {
struct xmlNs *oldNs; /* Global namespace, the old way */
struct xmlNode *root; /* the document tree */
void *ids; /* Hash table for ID attributes if any */
void *refs; /* Hash table for IDREFs attributes if any */
} _xmlDoc;
typedef _xmlDoc xmlDoc;
typedef xmlDoc *xmlDocPtr;
......@@ -440,6 +452,12 @@ const CHAR * xmlNodeGetLang (xmlNodePtr cur);
void xmlNodeSetLang (xmlNodePtr cur,
const CHAR *lang);
/*
* Removing content.
*/
int xmlRemoveProp (xmlAttrPtr attr); /* TODO */
int xmlRemoveNode (xmlNodePtr node); /* TODO */
/*
* Internal, don't use
*/
......
......@@ -1316,7 +1316,7 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
/************************************************************************
* *
* NOTATIONs *
* IDs *
* *
************************************************************************/
/**
......@@ -1549,6 +1549,228 @@ xmlGetID(xmlDocPtr doc, const CHAR *ID) {
return(NULL);
}
/************************************************************************
* *
* Refs *
* *
************************************************************************/
/**
* xmlCreateRefTable:
*
* create and initialize an empty ref hash table.
*
* Returns the xmlRefTablePtr just created or NULL in case
* of error.
*/
xmlRefTablePtr
xmlCreateRefTable(void) {
xmlRefTablePtr ret;
ret = (xmlRefTablePtr)
xmlMalloc(sizeof(xmlRefTable));
if (ret == NULL) {
fprintf(stderr, "xmlCreateRefTable : xmlMalloc(%ld) failed\n",
(long)sizeof(xmlRefTable));
return(NULL);
}
ret->max_refs = XML_MIN_NOTATION_TABLE;
ret->nb_refs = 0;
ret->table = (xmlRefPtr *)
xmlMalloc(ret->max_refs * sizeof(xmlRefPtr));
if (ret == NULL) {
fprintf(stderr, "xmlCreateRefTable : xmlMalloc(%ld) failed\n",
ret->max_refs * (long)sizeof(xmlRef));
xmlFree(ret);
return(NULL);
}
return(ret);
}
/**
* xmlAddRef:
* @ctxt: the validation context
* @doc: pointer to the document
* @value: the value name
* @attr: the attribute holding the Ref
*
* Register a new ref declaration
*
* Returns NULL if not, othervise the new xmlRefPtr
*/
xmlRefPtr
xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const CHAR *value,
xmlAttrPtr attr) {
xmlRefPtr ret;
xmlRefTablePtr table;
if (doc == NULL) {
fprintf(stderr, "xmlAddRefDecl: doc == NULL\n");
return(NULL);
}
if (value == NULL) {
fprintf(stderr, "xmlAddRefDecl: value == NULL\n");
return(NULL);
}
if (attr == NULL) {
fprintf(stderr, "xmlAddRefDecl: attr == NULL\n");
return(NULL);
}
/*
* Create the Ref table if needed.
*/
table = doc->refs;
if (table == NULL)
table = doc->refs = xmlCreateRefTable();
if (table == NULL) {
fprintf(stderr, "xmlAddRef: Table creation failed!\n");
return(NULL);
}
/*
* Grow the table, if needed.
*/
if (table->nb_refs >= table->max_refs) {
/*
* need more refs.
*/
table->max_refs *= 2;
table->table = (xmlRefPtr *)
xmlRealloc(table->table, table->max_refs *
sizeof(xmlRefPtr));
if (table->table == NULL) {
fprintf(stderr, "xmlAddRef: out of memory\n");
return(NULL);
}
}
ret = (xmlRefPtr) xmlMalloc(sizeof(xmlRef));
if (ret == NULL) {
fprintf(stderr, "xmlAddRef: out of memory\n");
return(NULL);
}
table->table[table->nb_refs] = ret;
/*
* fill the structure.
*/
ret->value = xmlStrdup(value);
ret->attr = attr;
table->nb_refs++;
return(ret);
}
/**
* xmlFreeRef:
* @not: A ref
*
* Deallocate the memory used by an ref definition
*/
void
xmlFreeRef(xmlRefPtr ref) {
if (ref == NULL) return;
if (ref->value != NULL)
xmlFree((CHAR *) ref->value);
memset(ref, -1, sizeof(xmlRef));
xmlFree(ref);
}
/**
* xmlFreeRefTable:
* @table: An ref table
*
* Deallocate the memory used by an Ref hash table.
*/
void
xmlFreeRefTable(xmlRefTablePtr table) {
int i;
if (table == NULL) return;
for (i = 0;i < table->nb_refs;i++) {
xmlFreeRef(table->table[i]);
}
xmlFree(table->table);
xmlFree(table);
}
/**
* xmlIsRef
* @doc: the document
* @elem: the element carrying the attribute
* @attr: the attribute
*
* Determine whether an attribute is of type Ref. In case we have Dtd(s)
* then this is simple, otherwise we use an heuristic: name Ref (upper
* or lowercase).
*
* Returns 0 or 1 depending on the lookup result
*/
int
xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
return(0);
/*******************
if (((attr->name[0] == 'I') || (attr->name[0] == 'i')) &&
((attr->name[1] == 'D') || (attr->name[1] == 'd')) &&
(attr->name[2] == 0)) return(1);
*******************/
} else {
xmlAttributePtr attrDecl;
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
if ((attrDecl == NULL) && (doc->extSubset != NULL))
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name,
attr->name);
if ((attrDecl != NULL) && (attrDecl->type == XML_ATTRIBUTE_IDREF))
return(1);
}
return(0);
}
/**
* xmlGetRef:
* @doc: pointer to the document
* @Ref: the Ref value
*
* Search the attribute declaring the given Ref
*
* Returns NULL if not found, otherwise the xmlAttrPtr defining the Ref
*/
xmlAttrPtr
xmlGetRef(xmlDocPtr doc, const CHAR *Ref) {
xmlRefPtr cur;
xmlRefTablePtr table;
int i;
if (doc == NULL) {