1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
10 #include "MessageArg.h"
12 #include "ParserMessages.h"
13 #include "StringVectorMessageArg.h"
19 namespace SP_NAMESPACE
{
22 DeclaredValue::DeclaredValue()
26 DeclaredValue::~DeclaredValue()
30 AttributeValue
*DeclaredValue::makeValueFromToken(Text
&text
,
31 AttributeContext
&context
,
33 unsigned &specLength
) const
35 return makeValue(text
, context
, name
, specLength
);
38 AttributeSemantics
*DeclaredValue::makeSemantics(const TokenizedAttributeValue
&,
47 Boolean
DeclaredValue::containsToken(const StringC
&) const
52 Boolean
DeclaredValue::isNotation() const
57 Boolean
DeclaredValue::isEntity() const
62 Boolean
DeclaredValue::isId() const
67 Boolean
DeclaredValue::isIdref() const
72 const Vector
<StringC
> *DeclaredValue::getTokens() const
78 CdataDeclaredValue::CdataDeclaredValue()
82 Boolean
CdataDeclaredValue::tokenized() const
87 AttributeValue
*CdataDeclaredValue::makeValue(Text
&text
, AttributeContext
&context
,
89 unsigned &specLength
) const
91 const Syntax
&syntax
= context
.attributeSyntax();
92 size_t normsep
= syntax
.normsep();
93 size_t normalizedLength
= text
.normalizedLength(normsep
);
94 specLength
+= normalizedLength
;
95 size_t litlen
= syntax
.litlen();
96 // A length error will already have been given if
97 // length > litlen - normsep.
98 if (litlen
>= normsep
&& text
.size() <= litlen
- normsep
99 && normalizedLength
> litlen
)
100 context
.message(ParserMessages::normalizedAttributeValueLength
,
101 NumberMessageArg(litlen
),
102 NumberMessageArg(normalizedLength
));
103 return new CdataAttributeValue(text
);
106 void CdataDeclaredValue::buildDesc(AttributeDefinitionDesc
&desc
) const
108 desc
.declaredValue
= AttributeDefinitionDesc::cdata
;
111 DeclaredValue
*CdataDeclaredValue::copy() const
113 return new CdataDeclaredValue(*this);
116 TokenizedDeclaredValue::TokenizedDeclaredValue(TokenType type
,
118 : type_(type
), isList_(isList
)
123 initialCategories_
= Syntax::nameStartCategory
;
124 subsequentCategories_
= (Syntax::nameStartCategory
|Syntax::digitCategory
125 | Syntax::otherNameCategory
);
128 initialCategories_
= Syntax::digitCategory
;
129 subsequentCategories_
= Syntax::digitCategory
;
132 initialCategories_
= (Syntax::nameStartCategory
|Syntax::digitCategory
133 | Syntax::otherNameCategory
);
134 subsequentCategories_
= initialCategories_
;
137 initialCategories_
= Syntax::digitCategory
;
138 subsequentCategories_
= (Syntax::nameStartCategory
|Syntax::digitCategory
139 | Syntax::otherNameCategory
);
144 Boolean
TokenizedDeclaredValue::tokenized() const
149 AttributeValue
*TokenizedDeclaredValue::makeValue(Text
&text
,
150 AttributeContext
&context
,
152 unsigned &specLength
) const
154 return makeTokenizedValue(text
, context
, str
, specLength
);
157 TokenizedAttributeValue
*
158 TokenizedDeclaredValue::makeTokenizedValue(Text
&text
,
159 AttributeContext
&context
,
160 const StringC
&LOCALname
,
161 unsigned &specLength
) const
163 Vector
<size_t> spaceIndex
;
164 const Syntax
&syntax
= context
.attributeSyntax();
165 Char space
= syntax
.space();
166 text
.subst(*(type_
== entityName
167 ? syntax
.entitySubstTable()
168 : syntax
.generalSubstTable()),
170 const StringC
&value
= text
.string();
172 size_t length
= value
.size();
176 // ends with a space (which would have to have been entered
177 // via a numeric character reference)
178 if (context
.validate())
179 context
.message(ParserMessages::attributeValueSyntax
);
182 size_t startIndex
= i
;
183 if (context
.validate()) {
184 if (!(syntax
.charCategory(value
[i
]) & initialCategories_
)) {
185 context
.Messenger::setNextLocation(text
.charLocation(i
));
187 if (!(syntax
.charCategory(value
[i
]) & subsequentCategories_
))
188 context
.message(ParserMessages::attributeValueChar
,
189 StringMessageArg(StringC(&c
, 1)),
190 StringMessageArg(LOCALname
));
191 else if (initialCategories_
== Syntax::digitCategory
)
192 context
.message(ParserMessages::attributeValueNumberToken
,
193 StringMessageArg(StringC(&c
, 1)),
194 StringMessageArg(LOCALname
));
196 context
.message(ParserMessages::attributeValueName
,
197 StringMessageArg(StringC(&c
, 1)),
198 StringMessageArg(LOCALname
));
203 && (syntax
.charCategory(value
[i
]) & subsequentCategories_
);
206 if (i
< length
&& value
[i
] != space
) {
208 // character value[i] is not allowed anywhere in the value
209 context
.Messenger::setNextLocation(text
.charLocation(i
));
210 context
.message(ParserMessages::attributeValueChar
,
211 StringMessageArg(StringC(&c
, 1)),
212 StringMessageArg(LOCALname
));
216 while (i
< length
&& value
[i
] != space
)
218 if (i
- startIndex
> syntax
.namelen()) {
219 context
.Messenger::setNextLocation(text
.charLocation(i
));
220 context
.message(ParserMessages::nameTokenLength
,
221 NumberMessageArg(syntax
.namelen()));
225 if (!isList_
&& context
.validate() && spaceIndex
.size() == 0) {
226 context
.Messenger::setNextLocation(text
.charLocation(i
));
227 context
.message(ParserMessages::attributeValueMultiple
,
228 StringMessageArg(LOCALname
));
230 spaceIndex
.push_back(i
);
233 size_t normsep
= syntax
.normsep();
234 size_t litlen
= syntax
.litlen();
235 size_t normalizedLength
= normsep
+ length
;
236 // should we count CDATA and SDATA entities here?
238 normalizedLength
+= 1;
239 // length is now the number of characters in each token in the list
240 // + 1 for each token in the list; so add normsep - 1 for each
241 // token in the list.
243 normalizedLength
+= (normsep
- 1)*(spaceIndex
.size() + 1);
245 normalizedLength
-= spaceIndex
.size() + 1;
247 specLength
+= normalizedLength
;
248 // A length error will already have been given if
249 // length > litlen - normsep.
250 if (litlen
>= normsep
&& length
<= litlen
- normsep
251 && normalizedLength
> litlen
)
252 context
.message(ParserMessages::normalizedAttributeValueLength
,
253 NumberMessageArg(litlen
),
254 NumberMessageArg(normalizedLength
));
255 return new TokenizedAttributeValue(text
, spaceIndex
);
258 Boolean
TokenizedAttributeValue::recoverUnquoted(const StringC
&str
,
259 const Location
&strLoc
,
260 AttributeContext
&context
,
263 TextIter
iter(text_
);
268 if (iter
.next(type
, s
, len
, loc
)
269 && type
== TextItem::data
270 && len
== text_
.size()
271 && loc
->origin().pointer() == strLoc
.origin().pointer()
272 && loc
->index() + len
== strLoc
.index()
273 && !iter
.next(type
, s
, len
, loc
)) {
274 context
.Messenger::setNextLocation(strLoc
);
275 context
.message(ParserMessages::attributeValueChar
,
276 StringMessageArg(StringC(str
.data(), 1)),
277 StringMessageArg(name
));
283 void TokenizedDeclaredValue::buildDesc(AttributeDefinitionDesc
&desc
) const
285 desc
.declaredValue
= AttributeDefinitionDesc::DeclaredValue(
286 type_
- name
+ (isList_
287 ? AttributeDefinitionDesc::names
288 : AttributeDefinitionDesc::name
));
291 DeclaredValue
*TokenizedDeclaredValue::copy() const
293 return new TokenizedDeclaredValue(*this);
296 GroupDeclaredValue::GroupDeclaredValue(TokenType type
,
297 Vector
<StringC
> &vec
)
298 : TokenizedDeclaredValue(type
, 0)
300 vec
.swap(allowedValues_
);
303 void GroupDeclaredValue::buildDesc(AttributeDefinitionDesc
&desc
) const
305 desc
.allowedValues
= allowedValues_
;
308 DeclaredValue
*GroupDeclaredValue::copy() const
310 return new GroupDeclaredValue(*this);
313 AttributeValue
*GroupDeclaredValue::makeValue(Text
&text
,
314 AttributeContext
&context
,
315 const StringC
&LOCALname
,
316 unsigned &specLength
) const
318 TokenizedAttributeValue
*val
= makeTokenizedValue(text
, context
, LOCALname
,
320 if (!val
|| !context
.validate())
322 for (size_t i
= 0; i
< allowedValues_
.size(); i
++)
323 if (val
->string() == allowedValues_
[i
])
325 context
.message(ParserMessages::attributeValueNotInGroup
,
326 StringMessageArg(val
->string()),
327 StringMessageArg(LOCALname
),
328 StringVectorMessageArg(allowedValues_
));
332 AttributeValue
*GroupDeclaredValue::makeValueFromToken(Text
&text
,
333 AttributeContext
&context
,
335 unsigned &specLength
)
338 const Syntax
&syntax
= context
.attributeSyntax();
339 size_t litlen
= syntax
.litlen();
340 size_t normsep
= syntax
.normsep();
341 if (normsep
> litlen
|| text
.size() > litlen
- normsep
)
342 context
.message(ParserMessages::normalizedAttributeValueLength
,
343 NumberMessageArg(litlen
),
344 NumberMessageArg(text
.size() + normsep
));
345 specLength
+= text
.size() + normsep
;
346 return new TokenizedAttributeValue(text
, Vector
<size_t>());
349 Boolean
GroupDeclaredValue::containsToken(const StringC
&token
) const
351 for (size_t i
= 0; i
< allowedValues_
.size(); i
++)
352 if (allowedValues_
[i
] == token
)
357 const Vector
<StringC
> *GroupDeclaredValue::getTokens() const
359 return &allowedValues_
;
362 NameTokenGroupDeclaredValue::NameTokenGroupDeclaredValue(Vector
<StringC
> &vec
)
363 : GroupDeclaredValue(nameToken
, vec
)
367 void NameTokenGroupDeclaredValue::buildDesc(AttributeDefinitionDesc
&desc
) const
369 GroupDeclaredValue::buildDesc(desc
);
370 desc
.declaredValue
= AttributeDefinitionDesc::nameTokenGroup
;
373 DeclaredValue
*NameTokenGroupDeclaredValue::copy() const
375 return new NameTokenGroupDeclaredValue(*this);
378 NotationDeclaredValue::NotationDeclaredValue(Vector
<StringC
> &vec
)
379 : GroupDeclaredValue(name
, vec
)
383 Boolean
NotationDeclaredValue::isNotation() const
389 NotationDeclaredValue::makeSemantics(const TokenizedAttributeValue
&value
,
390 AttributeContext
&context
,
395 ConstPtr
<Notation
> notation
396 = context
.getAttributeNotation(value
.string(),
397 value
.tokenLocation(0));
398 if (notation
.isNull()) {
399 if (context
.validate()) {
400 context
.setNextLocation(value
.tokenLocation(0));
401 context
.message(ParserMessages::invalidNotationAttribute
,
402 StringMessageArg(value
.string()));
406 return new NotationAttributeSemantics(notation
);
409 void NotationDeclaredValue::buildDesc(AttributeDefinitionDesc
&desc
) const
411 GroupDeclaredValue::buildDesc(desc
);
412 desc
.declaredValue
= AttributeDefinitionDesc::notation
;
415 DeclaredValue
*NotationDeclaredValue::copy() const
417 return new NotationDeclaredValue(*this);
420 EntityDeclaredValue::EntityDeclaredValue(Boolean isList
)
421 : TokenizedDeclaredValue(entityName
, isList
)
425 Boolean
EntityDeclaredValue::isEntity() const
431 EntityDeclaredValue::makeSemantics(const TokenizedAttributeValue
&value
,
432 AttributeContext
&context
,
435 unsigned &nEntityNames
) const
438 size_t nTokens
= value
.nTokens();
439 nEntityNames
+= nTokens
;
440 Vector
<ConstPtr
<Entity
> > entities(nTokens
);
441 for (size_t i
= 0; i
< nTokens
; i
++) {
442 entities
[i
] = context
.getAttributeEntity(value
.token(i
),
443 value
.tokenLocation(i
));
444 if (entities
[i
].isNull()) {
445 if (context
.validate()) {
446 context
.setNextLocation(value
.tokenLocation(i
));
447 context
.message(ParserMessages::invalidEntityAttribute
,
448 StringMessageArg(value
.token(i
)));
452 else if (!entities
[i
]->isDataOrSubdoc()) {
453 if (context
.validate()) {
454 context
.Messenger::setNextLocation(value
.tokenLocation(i
));
455 context
.message(ParserMessages::notDataOrSubdocEntity
,
456 StringMessageArg(value
.token(i
)));
462 return new EntityAttributeSemantics(entities
);
467 DeclaredValue
*EntityDeclaredValue::copy() const
469 return new EntityDeclaredValue(*this);
472 IdDeclaredValue::IdDeclaredValue()
473 : TokenizedDeclaredValue(name
, 0)
477 Boolean
IdDeclaredValue::isId() const
483 IdDeclaredValue::makeSemantics(const TokenizedAttributeValue
&value
,
484 AttributeContext
&context
,
490 if (!context
.defineId(value
.string(), value
.tokenLocation(0), prevLoc
)) {
491 context
.setNextLocation(value
.tokenLocation(0));
492 context
.message(ParserMessages::duplicateId
,
493 StringMessageArg(value
.string()),
499 void IdDeclaredValue::buildDesc(AttributeDefinitionDesc
&desc
) const
501 desc
.declaredValue
= AttributeDefinitionDesc::id
;
504 DeclaredValue
*IdDeclaredValue::copy() const
506 return new IdDeclaredValue(*this);
509 IdrefDeclaredValue::IdrefDeclaredValue(Boolean isList
)
510 : TokenizedDeclaredValue(name
, isList
)
515 IdrefDeclaredValue::makeSemantics(const TokenizedAttributeValue
&value
,
516 AttributeContext
&context
,
521 size_t nTokens
= value
.nTokens();
523 for (size_t i
= 0; i
< nTokens
; i
++)
524 context
.noteIdref(value
.token(i
), value
.tokenLocation(i
));
528 Boolean
IdrefDeclaredValue::isIdref() const
533 void IdrefDeclaredValue::buildDesc(AttributeDefinitionDesc
&desc
) const
535 TokenizedDeclaredValue::buildDesc(desc
);
536 if (desc
.declaredValue
== AttributeDefinitionDesc::name
)
537 desc
.declaredValue
= AttributeDefinitionDesc::idref
;
539 desc
.declaredValue
= AttributeDefinitionDesc::idrefs
;
542 DeclaredValue
*IdrefDeclaredValue::copy() const
544 return new IdrefDeclaredValue(*this);
548 AttributeDefinition::AttributeDefinition(const StringC
&name
,
549 DeclaredValue
*value
)
550 : name_(name
), declaredValue_(value
)
554 AttributeDefinition::~AttributeDefinition()
558 AttributeValue
*AttributeDefinition::checkValue(AttributeValue
*p
,
559 AttributeContext
&) const
564 Boolean
AttributeDefinition::missingValueWouldMatch(const Text
&,
565 const AttributeContext
&) const
570 const AttributeValue
*
571 AttributeDefinition::defaultValue(const AttributeValue
*) const
576 void AttributeDefinition::getDesc(AttributeDefinitionDesc
&desc
) const
578 desc
.allowedValues
.clear();
579 desc
.defaultValue
.clear();
580 desc
.currentIndex
= 0;
582 declaredValue_
->buildDesc(desc
);
585 Boolean
AttributeDefinition::isConref() const
590 Boolean
AttributeDefinition::isCurrent() const
595 Boolean
AttributeDefinition::isFixed() const
600 RequiredAttributeDefinition::RequiredAttributeDefinition(const StringC
&name
,
601 DeclaredValue
*value
)
602 : AttributeDefinition(name
, value
)
606 ConstPtr
<AttributeValue
>
607 RequiredAttributeDefinition::makeMissingValue(AttributeContext
&context
) const
609 if (context
.validate())
610 context
.message(ParserMessages::requiredAttributeMissing
,
611 StringMessageArg(name()));
615 void RequiredAttributeDefinition::buildDesc(AttributeDefinitionDesc
&desc
) const
617 desc
.defaultValueType
= AttributeDefinitionDesc::required
;
620 AttributeDefinition
*RequiredAttributeDefinition::copy() const
622 return new RequiredAttributeDefinition(*this);
625 CurrentAttributeDefinition::CurrentAttributeDefinition(const StringC
&name
, DeclaredValue
*value
, size_t index
)
626 : AttributeDefinition(name
, value
), currentIndex_(index
)
630 ConstPtr
<AttributeValue
>
631 CurrentAttributeDefinition::makeMissingValue(AttributeContext
&context
) const
633 if (context
.mayDefaultAttribute()) {
634 ConstPtr
<AttributeValue
> currentValue
635 = context
.getCurrentAttribute(currentIndex_
);
636 if (currentValue
.isNull() && context
.validate())
637 context
.message(ParserMessages::currentAttributeMissing
,
638 StringMessageArg(name()));
641 if (context
.validate())
642 context
.message(ParserMessages::attributeMissing
,
643 StringMessageArg(name()));
647 Boolean
CurrentAttributeDefinition::missingValueWouldMatch(const Text
&text
,
648 const AttributeContext
&context
) const
650 if (!context
.mayDefaultAttribute())
652 ConstPtr
<AttributeValue
> currentValue
653 = context
.getCurrentAttribute(currentIndex_
);
654 if (currentValue
.isNull())
656 return text
.fixedEqual(*currentValue
->text());
660 CurrentAttributeDefinition::checkValue(AttributeValue
*value
,
661 AttributeContext
&context
) const
663 context
.noteCurrentAttribute(currentIndex_
, value
);
667 void CurrentAttributeDefinition::buildDesc(AttributeDefinitionDesc
&desc
) const
669 desc
.defaultValueType
= AttributeDefinitionDesc::current
;
670 desc
.currentIndex
= currentIndex_
;
673 AttributeDefinition
*CurrentAttributeDefinition::copy() const
675 return new CurrentAttributeDefinition(*this);
678 Boolean
CurrentAttributeDefinition::isCurrent() const
683 ImpliedAttributeDefinition::ImpliedAttributeDefinition(const StringC
&name
,
684 DeclaredValue
*value
)
685 : AttributeDefinition(name
, value
)
689 ConstPtr
<AttributeValue
>
690 ImpliedAttributeDefinition::makeMissingValue(AttributeContext
&context
) const
692 return context
.makeImpliedAttributeValue();
695 void ImpliedAttributeDefinition::buildDesc(AttributeDefinitionDesc
&desc
) const
697 desc
.defaultValueType
= AttributeDefinitionDesc::implied
;
700 AttributeDefinition
*ImpliedAttributeDefinition::copy() const
702 return new ImpliedAttributeDefinition(*this);
705 const AttributeValue
*
706 ImpliedAttributeDefinition::defaultValue(const AttributeValue
*impliedValue
)
712 ConrefAttributeDefinition::ConrefAttributeDefinition(const StringC
&name
,
713 DeclaredValue
*value
)
714 : ImpliedAttributeDefinition(name
, value
)
718 Boolean
ConrefAttributeDefinition::isConref() const
723 void ConrefAttributeDefinition::buildDesc(AttributeDefinitionDesc
&desc
) const
725 desc
.defaultValueType
= AttributeDefinitionDesc::conref
;
728 AttributeDefinition
*ConrefAttributeDefinition::copy() const
730 return new ConrefAttributeDefinition(*this);
733 DefaultAttributeDefinition::DefaultAttributeDefinition(const StringC
&name
,
734 DeclaredValue
*declaredValue
,
735 AttributeValue
*defaultValue
)
736 : AttributeDefinition(name
, declaredValue
),
741 ConstPtr
<AttributeValue
>
742 DefaultAttributeDefinition::makeMissingValue(AttributeContext
&context
) const
744 if (context
.mayDefaultAttribute())
746 if (context
.validate())
747 context
.message(ParserMessages::attributeMissing
,
748 StringMessageArg(name()));
752 Boolean
DefaultAttributeDefinition::missingValueWouldMatch(const Text
&text
,
753 const AttributeContext
&context
) const
755 return context
.mayDefaultAttribute() && text
.fixedEqual(*value_
->text());
758 void DefaultAttributeDefinition::buildDesc(AttributeDefinitionDesc
&desc
) const
760 desc
.defaultValueType
= AttributeDefinitionDesc::defaulted
;
761 desc
.defaultValue
= value_
;
764 AttributeDefinition
*DefaultAttributeDefinition::copy() const
766 return new DefaultAttributeDefinition(*this);
769 FixedAttributeDefinition:: FixedAttributeDefinition(const StringC
&name
,
770 DeclaredValue
*declaredValue
,
771 AttributeValue
*defaultValue
)
772 : DefaultAttributeDefinition(name
, declaredValue
, defaultValue
)
776 Boolean
FixedAttributeDefinition::isFixed() const
781 AttributeValue
*FixedAttributeDefinition::checkValue(AttributeValue
*value
,
782 AttributeContext
&context
)
785 const AttributeValue
*fixedValue
786 = DefaultAttributeDefinition::defaultValue(0);
787 if (value
&& fixedValue
&& context
.validate()) {
790 const Text
*fixedText
;
791 const StringC
*fixedStr
;
792 switch (value
->info(text
, str
)) {
793 case AttributeValue::implied
:
795 case AttributeValue::cdata
:
796 if (fixedValue
->info(fixedText
, fixedStr
) == AttributeValue::cdata
) {
797 if (!text
->fixedEqual(*fixedText
))
798 context
.message(ParserMessages::notFixedValue
, StringMessageArg(name()));
801 case AttributeValue::tokenized
:
802 if (fixedValue
->info(fixedText
, fixedStr
) == AttributeValue::tokenized
) {
803 if (*str
!= *fixedStr
)
804 context
.message(ParserMessages::notFixedValue
, StringMessageArg(name()));
812 void FixedAttributeDefinition::buildDesc(AttributeDefinitionDesc
&desc
) const
814 // get the fixed value
815 DefaultAttributeDefinition::buildDesc(desc
);
816 desc
.defaultValueType
= AttributeDefinitionDesc::fixed
;
819 AttributeDefinition
*FixedAttributeDefinition::copy() const
821 return new FixedAttributeDefinition(*this);
824 AttributeDefinitionList
825 ::AttributeDefinitionList(Vector
<CopyOwner
<AttributeDefinition
> > &vec
,
829 size_t notationIndex
)
830 : index_(index
), anyCurrent_(anyCurrent
), idIndex_(idIndex
),
831 notationIndex_(notationIndex
)
836 AttributeDefinitionList:: AttributeDefinitionList(const ConstPtr
<AttributeDefinitionList
> &def
)
837 : prev_(def
), index_(size_t(-1))
841 notationIndex_
= size_t(-1);
842 idIndex_
= size_t(-1);
845 anyCurrent_
= def
->anyCurrent_
;
846 notationIndex_
= def
->notationIndex_
;
847 idIndex_
= def
->idIndex_
;
852 Boolean
AttributeDefinitionList::tokenIndex(const StringC
&token
, unsigned &index
) const
854 for (size_t i
= 0; i
< defs_
.size(); i
++)
855 if (defs_
[i
]->containsToken(token
)) {
862 Boolean
AttributeDefinitionList::tokenIndexUnique(const StringC
&token
, unsigned i
) const
864 for (++i
; i
< defs_
.size(); i
++)
865 if (defs_
[i
]->containsToken(token
))
871 Boolean
AttributeDefinitionList::attributeIndex(const StringC
&name
,
872 unsigned &index
) const
874 for (size_t i
= 0; i
< defs_
.size(); i
++)
875 if (defs_
[i
]->name() == name
) {
882 void AttributeDefinitionList::append(AttributeDefinition
*def
)
884 if (def
->isId() && idIndex_
== size_t(-1))
885 idIndex_
= defs_
.size();
886 if (def
->isNotation() && notationIndex_
== size_t(-1))
887 notationIndex_
= defs_
.size();
888 if (def
->isCurrent())
890 defs_
.resize(defs_
.size() + 1);
894 AttributeSemantics::AttributeSemantics()
898 AttributeSemantics::~AttributeSemantics()
902 size_t AttributeSemantics::nEntities() const
907 ConstPtr
<Entity
> AttributeSemantics::entity(size_t) const
912 ConstPtr
<Notation
> AttributeSemantics::notation() const
918 NotationAttributeSemantics::NotationAttributeSemantics(const ConstPtr
<Notation
> ¬ation
)
919 : notation_(notation
)
923 ConstPtr
<Notation
> NotationAttributeSemantics::notation() const
928 AttributeSemantics
*NotationAttributeSemantics::copy() const
930 return new NotationAttributeSemantics(*this);
933 EntityAttributeSemantics::EntityAttributeSemantics(Vector
<ConstPtr
<Entity
> > &entity
)
935 entity
.swap(entity_
);
938 size_t EntityAttributeSemantics::nEntities() const
940 return entity_
.size();
943 ConstPtr
<Entity
> EntityAttributeSemantics::entity(size_t i
) const
948 AttributeSemantics
*EntityAttributeSemantics::copy() const
950 return new EntityAttributeSemantics(*this);
953 AttributeValue::AttributeValue()
957 AttributeValue::~AttributeValue()
961 AttributeSemantics
*AttributeValue::makeSemantics(const DeclaredValue
*,
970 const Text
*AttributeValue::text() const
975 Boolean
AttributeValue::recoverUnquoted(const StringC
&, const Location
&,
976 AttributeContext
&, const StringC
&)
981 ImpliedAttributeValue::ImpliedAttributeValue()
985 AttributeValue::Type
ImpliedAttributeValue::info(const Text
*&,
986 const StringC
*&) const
991 TokenizedAttributeValue::TokenizedAttributeValue(Text
&text
,
992 const Vector
<size_t> &spaceIndex
)
993 : spaceIndex_(spaceIndex
)
998 AttributeValue::Type
TokenizedAttributeValue::info(const Text
*&,
999 const StringC
*&string
) const
1001 string
= &text_
.string();
1005 const Text
*TokenizedAttributeValue::text() const
1010 AttributeSemantics
*
1011 TokenizedAttributeValue::makeSemantics(const DeclaredValue
*value
,
1012 AttributeContext
&context
,
1013 const StringC
&name
,
1015 unsigned &nEntityNames
) const
1017 if (text_
.size() == 0)
1019 return value
->makeSemantics(*this, context
, name
, nIdrefs
, nEntityNames
);
1022 CdataAttributeValue::CdataAttributeValue(Text
&text
)
1027 AttributeValue::Type
CdataAttributeValue::info(const Text
*&text
,
1028 const StringC
*&) const
1034 const Text
*CdataAttributeValue::text() const
1039 Boolean
CdataAttributeValue::recoverUnquoted(const StringC
&str
,
1040 const Location
&strLoc
,
1041 AttributeContext
&context
,
1044 TextIter
iter(text_
);
1045 TextItem::Type type
;
1048 const Location
*loc
;
1049 if (iter
.next(type
, s
, len
, loc
)
1050 && type
== TextItem::data
1051 && len
== text_
.size()
1052 && loc
->origin().pointer() == strLoc
.origin().pointer()
1053 && loc
->index() + len
== strLoc
.index()
1054 && !iter
.next(type
, s
, len
, loc
)) {
1055 text_
.addChars(str
, strLoc
);
1056 context
.Messenger::setNextLocation(strLoc
);
1057 context
.message(ParserMessages::unquotedAttributeValue
);
1063 Attribute::Attribute()
1068 void Attribute::clear()
1075 AttributeList::AttributeList(const ConstPtr
<AttributeDefinitionList
> &def
)
1076 : def_(def
), vec_(def
.isNull() ? 0 : def
->size()), nSpec_(0), conref_(0),
1077 nIdrefs_(0), nEntityNames_(0)
1081 AttributeList::AttributeList()
1082 : nSpec_(0), conref_(0)
1086 void AttributeList::init(const ConstPtr
<AttributeDefinitionList
> &def
)
1096 size_t newLength
= def_
->size();
1097 size_t clearLim
= vec_
.size();
1098 if (clearLim
> newLength
)
1099 clearLim
= newLength
;
1100 vec_
.resize(newLength
);
1101 for (size_t i
= 0; i
< clearLim
; i
++)
1106 void AttributeList::changeDef(const ConstPtr
<AttributeDefinitionList
> &def
)
1108 vec_
.resize(def
.isNull() ? 0 : def
->size());
1112 void AttributeList::swap(AttributeList
&to
)
1117 unsigned tem
= to
.nIdrefs_
;
1118 to
.nIdrefs_
= nIdrefs_
;
1122 unsigned tem
= to
.nEntityNames_
;
1123 to
.nEntityNames_
= nEntityNames_
;
1124 nEntityNames_
= tem
;
1127 size_t tem
= to
.nSpec_
;
1132 PackedBoolean tem
= to
.conref_
;
1133 to
.conref_
= conref_
;
1138 void AttributeList::finish(AttributeContext
&context
)
1140 for (size_t i
= 0; i
< vec_
.size(); i
++)
1141 if (!vec_
[i
].specified()) {
1142 ConstPtr
<AttributeValue
> value
1143 = def(i
)->makeMissingValue(context
);
1144 vec_
[i
].setValue(value
);
1145 if (!value
.isNull())
1146 vec_
[i
].setSemantics(def(i
)->makeSemantics(value
.pointer(),
1151 const Syntax
&syntax
= context
.attributeSyntax();
1152 if (nIdrefs_
> syntax
.grpcnt())
1153 context
.message(ParserMessages::idrefGrpcnt
,
1154 NumberMessageArg(syntax
.grpcnt()));
1155 if (nEntityNames_
> syntax
.grpcnt())
1156 context
.message(ParserMessages::entityNameGrpcnt
,
1157 NumberMessageArg(syntax
.grpcnt()));
1158 if (context
.validate()
1160 && def_
->notationIndex() != size_t(-1)
1161 && specified(def_
->notationIndex()))
1162 context
.message(ParserMessages::conrefNotation
);
1165 void AttributeList::setSpec(unsigned i
, AttributeContext
&context
)
1167 if (vec_
[i
].specified())
1168 context
.message(ParserMessages::duplicateAttributeSpec
,
1169 StringMessageArg(def(i
)->name()));
1171 vec_
[i
].setSpec(nSpec_
++);
1174 void AttributeList::noteInvalidSpec()
1176 // This is needed for error recovery.
1177 // We don't want nSpec_ to be > 0, if there is no attribute definition.
1182 Boolean
AttributeList::setValue(unsigned i
, Text
&text
,
1183 AttributeContext
&context
,
1184 unsigned &specLength
)
1186 AttributeValue
*value
= def(i
)->makeValue(text
, context
, specLength
);
1187 if (def(i
)->isConref())
1189 vec_
[i
].setValue(value
);
1191 vec_
[i
].setSemantics(def(i
)->makeSemantics(value
, context
,
1192 nIdrefs_
, nEntityNames_
));
1193 else if (AttributeValue::handleAsUnterminated(text
, context
))
1198 void AttributeList::setValueToken(unsigned i
, Text
&text
,
1199 AttributeContext
&context
,
1200 unsigned &specLength
)
1202 AttributeValue
*value
= def(i
)->makeValueFromToken(text
, context
,
1204 if (def(i
)->isConref())
1206 vec_
[i
].setValue(value
);
1208 vec_
[i
].setSemantics(def(i
)->makeSemantics(value
, context
,
1209 nIdrefs_
, nEntityNames_
));
1212 const StringC
*AttributeList::getId() const
1214 // Check for no attributes
1217 // Check for no ID declared
1218 size_t i
= def_
->idIndex();
1219 if (i
== size_t(-1))
1221 // Check for invalid value
1222 const AttributeValue
*v
= value(i
);
1225 // Check for implied value
1226 const Text
*t
= v
->text();
1229 return &t
->string();
1232 Boolean
AttributeList::recoverUnquoted(const StringC
&str
,
1233 const Location
&strLoc
,
1234 AttributeContext
&context
)
1237 for (size_t i
= 0; i
< vec_
.size(); i
++)
1238 if (vec_
[i
].specified() && vec_
[i
].specIndex() == nSpec_
- 1) {
1239 const AttributeValue
*val
= vec_
[i
].value();
1241 // I wish I could avoid casting away const here.
1242 return ((AttributeValue
*)val
)->recoverUnquoted(str
, strLoc
, context
,
1251 Boolean
AttributeList::handleAsUnterminated(AttributeContext
&context
)
1254 for (size_t i
= 0; i
< vec_
.size(); i
++) {
1255 if (vec_
[i
].specified() && vec_
[i
].specIndex() == nSpec_
- 1) {
1256 const AttributeValue
*val
= vec_
[i
].value();
1258 if (val
&& (ptr
= val
->text()) != 0
1259 && AttributeValue::handleAsUnterminated(*ptr
, context
))
1268 // This tries to guess this attribute value looks like if it had
1269 // a missing ending quote.
1271 Boolean
AttributeValue::handleAsUnterminated(const Text
&text
,
1272 AttributeContext
&context
)
1274 TextIter
iter(text
);
1275 const Char
*lastStr
= 0;
1278 const Location
*loc
;
1279 TextItem::Type type
;
1282 while (iter
.next(type
, str
, len
, loc
)) {
1283 if (startLoc
.origin().isNull() && !loc
->origin().isNull())
1286 case TextItem::data
:
1287 if (len
!= 1 || *str
!= context
.attributeSyntax().space()) {
1292 case TextItem::endDelim
:
1293 case TextItem::endDelimA
:
1294 case TextItem::ignore
:
1303 && lastStr
[lastLen
- 1] == context
.attributeSyntax().space())
1305 const StringC
&vi
= context
.attributeSyntax().delimGeneral(Syntax::dVI
);
1306 if (lastLen
>= vi
.size()
1308 == StringC(lastStr
+ (lastLen
- vi
.size()), vi
.size()))) {
1309 context
.Messenger::setNextLocation(startLoc
);
1310 context
.message(ParserMessages::literalClosingDelimiter
);
1317 AttributeContext::AttributeContext()
1318 : mayDefaultAttribute_(0), validate_(1)
1322 AttributeContext::~AttributeContext()
1326 Boolean
AttributeContext::defineId(const StringC
&, const Location
&,
1332 void AttributeContext::noteIdref(const StringC
&, const Location
&)
1336 void AttributeContext::noteCurrentAttribute(size_t, AttributeValue
*)
1340 ConstPtr
<AttributeValue
> AttributeContext::getCurrentAttribute(size_t) const
1345 ConstPtr
<Entity
> AttributeContext::getAttributeEntity(const StringC
&,
1351 ConstPtr
<Notation
> AttributeContext::getAttributeNotation(const StringC
&,
1357 ConstPtr
<AttributeValue
> AttributeContext::makeImpliedAttributeValue()
1359 if (impliedAttributeValue_
.isNull())
1360 impliedAttributeValue_
= new ImpliedAttributeValue
;
1361 return impliedAttributeValue_
;