diff --git a/expat/xmlparse/xmlparse.c b/expat/xmlparse/xmlparse.c index 82e5fd66..86d06865 100755 --- a/expat/xmlparse/xmlparse.c +++ b/expat/xmlparse/xmlparse.c @@ -173,6 +173,7 @@ typedef struct { typedef struct { const XML_Char *name; PREFIX *prefix; + const ATTRIBUTE_ID *idAtt; int nDefaultAtts; int allocDefaultAtts; DEFAULT_ATTRIBUTE *defaultAtts; @@ -243,7 +244,7 @@ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char static int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr); static int -defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue); +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, int isId, const XML_Char *dfltValue); static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *, STRING_POOL *); @@ -357,6 +358,7 @@ typedef struct { ELEMENT_TYPE *m_declElementType; ATTRIBUTE_ID *m_declAttributeId; char m_declAttributeIsCdata; + char m_declAttributeIsId; DTD m_dtd; const XML_Char *m_curBase; TAG *m_tagStack; @@ -365,6 +367,7 @@ typedef struct { BINDING *m_freeBindingList; int m_attsSize; int m_nSpecifiedAtts; + int m_idAttIndex; ATTRIBUTE *m_atts; POSITION m_position; STRING_POOL m_tempPool; @@ -435,6 +438,7 @@ typedef struct { #define declElementType (((Parser *)parser)->m_declElementType) #define declAttributeId (((Parser *)parser)->m_declAttributeId) #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata) +#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId) #define freeTagList (((Parser *)parser)->m_freeTagList) #define freeBindingList (((Parser *)parser)->m_freeBindingList) #define inheritedBindings (((Parser *)parser)->m_inheritedBindings) @@ -442,6 +446,7 @@ typedef struct { #define atts (((Parser *)parser)->m_atts) #define attsSize (((Parser *)parser)->m_attsSize) #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts) +#define idAttIndex (((Parser *)parser)->m_idAttIndex) #define tempPool (((Parser *)parser)->m_tempPool) #define temp2Pool (((Parser *)parser)->m_temp2Pool) #define groupConnector (((Parser *)parser)->m_groupConnector) @@ -746,6 +751,11 @@ int XML_GetSpecifiedAttributeCount(XML_Parser parser) return nSpecifiedAtts; } +int XML_GetIdAttributeIndex(XML_Parser parser) +{ + return idAttIndex; +} + void XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end) @@ -1700,10 +1710,19 @@ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, else attIndex++; } - nSpecifiedAtts = attIndex; - /* do attribute defaulting */ if (tagNamePtr) { int j; + nSpecifiedAtts = attIndex; + if (elementType->idAtt && (elementType->idAtt->name)[-1]) { + for (i = 0; i < attIndex; i += 2) + if (appAtts[i] == elementType->idAtt->name) { + idAttIndex = i; + break; + } + } + else + idAttIndex = -1; + /* do attribute defaulting */ for (j = 0; j < nDefaultAtts; j++) { const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j; if (!(da->id->name)[-1] && da->value) { @@ -2351,14 +2370,19 @@ doProlog(XML_Parser parser, if (!declAttributeId) return XML_ERROR_NO_MEMORY; declAttributeIsCdata = 0; + declAttributeIsId = 0; break; case XML_ROLE_ATTRIBUTE_TYPE_CDATA: declAttributeIsCdata = 1; break; + case XML_ROLE_ATTRIBUTE_TYPE_ID: + declAttributeIsId = 1; + break; case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: if (dtd.complete - && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0)) + && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, + declAttributeIsId, 0)) return XML_ERROR_NO_MEMORY; break; case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: @@ -2375,7 +2399,8 @@ doProlog(XML_Parser parser, attVal = poolStart(&dtd.pool); poolFinish(&dtd.pool); if (dtd.complete - && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal)) + // ID attributes aren't allowed to have a default + && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal)) return XML_ERROR_NO_MEMORY; break; } @@ -3113,16 +3138,18 @@ reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char static int -defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value) +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, int isId, const XML_Char *value) { DEFAULT_ATTRIBUTE *att; - if (value) { + if (value || isId) { /* The handling of default attributes gets messed up if we have a default which duplicates a non-default. */ int i; for (i = 0; i < type->nDefaultAtts; i++) if (attId == type->defaultAtts[i].id) return 1; + if (isId && !type->idAtt && !attId->xmlns) + type->idAtt = attId; } if (type->nDefaultAtts == type->allocDefaultAtts) { if (type->allocDefaultAtts == 0) { @@ -3502,6 +3529,8 @@ static int dtdCopy(DTD *newDtd, const DTD *oldDtd) if (!newE->defaultAtts) return 0; } + if (oldE->idAtt) + newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0); newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; if (oldE->prefix) newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0); diff --git a/expat/xmlparse/xmlparse.h b/expat/xmlparse/xmlparse.h index d87d2d71..538ccb37 100755 --- a/expat/xmlparse/xmlparse.h +++ b/expat/xmlparse/xmlparse.h @@ -393,12 +393,20 @@ XML_SetBase(XML_Parser parser, const XML_Char *base); const XML_Char XMLPARSEAPI * XML_GetBase(XML_Parser parser); -/* Returns the number of the attributes passed in last call to the -XML_StartElementHandler that were specified in the start-tag rather -than defaulted. */ +/* Returns the number of the attribute/value pairs passed in last call +to the XML_StartElementHandler that were specified in the start-tag +rather than defaulted. Each attribute/value pair counts as 2; thus +this correspondds to an index into the atts array passed to the +XML_StartElementHandler. */ int XMLPARSEAPI XML_GetSpecifiedAttributeCount(XML_Parser parser); +/* Returns the index of the ID attribute passed in the last call to +XML_StartElementHandler, or -1 if there is no ID attribute. Each +attribute/value pair counts as 2; thus this correspondds to an index +into the atts array passed to the XML_StartElementHandler. */ +int XMLPARSEAPI XML_GetIdAttributeIndex(XML_Parser parser); + /* Parses some input. Returns 0 if a fatal error is detected. The last call to XML_Parse must have isFinal true; len may be zero for this call (or any other). */ diff --git a/expat/xmlwf/xmlwf.c b/expat/xmlwf/xmlwf.c index 1297a0c0..9e0d94f6 100755 --- a/expat/xmlwf/xmlwf.c +++ b/expat/xmlwf/xmlwf.c @@ -333,7 +333,14 @@ void metaStartElement(XML_Parser parser, const XML_Char *name, const XML_Char ** { FILE *fp = XML_GetUserData(parser); const XML_Char **specifiedAttsEnd - = atts + 2*XML_GetSpecifiedAttributeCount(parser); + = atts + XML_GetSpecifiedAttributeCount(parser); + const XML_Char **idAttPtr; + int idAttIndex = XML_GetIdAttributeIndex(parser); + if (idAttIndex < 0) + idAttPtr = 0; + else + idAttPtr = atts + idAttIndex; + ftprintf(fp, T("= specifiedAttsEnd) fputts(T("\" defaulted=\"yes\"/>\n"), fp); + else if (atts == idAttPtr) + fputts(T("\" id=\"yes\"/>\n"), fp); else fputts(T("\"/>\n"), fp); } while (*(atts += 2));