xref: /onnv-gate/usr/src/cmd/man/src/util/nsgmls.src/lib/Attribute.cxx (revision 0:68f95e015346)
1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident	"%Z%%M%	%I%	%E% SMI"
4 
5 #ifdef __GNUG__
6 #pragma implementation
7 #endif
8 #include "splib.h"
9 #include "Attribute.h"
10 #include "MessageArg.h"
11 #include "macros.h"
12 #include "ParserMessages.h"
13 #include "StringVectorMessageArg.h"
14 #include "Syntax.h"
15 #include "Entity.h"
16 #include "Notation.h"
17 
18 #ifdef SP_NAMESPACE
19 namespace SP_NAMESPACE {
20 #endif
21 
DeclaredValue()22 DeclaredValue::DeclaredValue()
23 {
24 }
25 
~DeclaredValue()26 DeclaredValue::~DeclaredValue()
27 {
28 }
29 
makeValueFromToken(Text & text,AttributeContext & context,const StringC & name,unsigned & specLength) const30 AttributeValue *DeclaredValue::makeValueFromToken(Text &text,
31 						  AttributeContext &context,
32 						  const StringC &name,
33 						  unsigned &specLength) const
34 {
35   return makeValue(text, context, name, specLength);
36 }
37 
makeSemantics(const TokenizedAttributeValue &,AttributeContext &,const StringC &,unsigned &,unsigned &) const38 AttributeSemantics *DeclaredValue::makeSemantics(const TokenizedAttributeValue &,
39 						 AttributeContext &,
40 						 const StringC &,
41 						 unsigned &,
42 						 unsigned &) const
43 {
44   return 0;
45 }
46 
containsToken(const StringC &) const47 Boolean DeclaredValue::containsToken(const StringC &) const
48 {
49   return 0;
50 }
51 
isNotation() const52 Boolean DeclaredValue::isNotation() const
53 {
54   return 0;
55 }
56 
isEntity() const57 Boolean DeclaredValue::isEntity() const
58 {
59   return 0;
60 }
61 
isId() const62 Boolean DeclaredValue::isId() const
63 {
64   return 0;
65 }
66 
isIdref() const67 Boolean DeclaredValue::isIdref() const
68 {
69   return 0;
70 }
71 
getTokens() const72 const Vector<StringC> *DeclaredValue::getTokens() const
73 {
74   return 0;
75 }
76 
77 
CdataDeclaredValue()78 CdataDeclaredValue::CdataDeclaredValue()
79 {
80 }
81 
tokenized() const82 Boolean CdataDeclaredValue::tokenized() const
83 {
84   return 0;
85 }
86 
makeValue(Text & text,AttributeContext & context,const StringC &,unsigned & specLength) const87 AttributeValue *CdataDeclaredValue::makeValue(Text &text, AttributeContext &context,
88 					      const StringC &,
89 					      unsigned &specLength) const
90 {
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);
104 }
105 
buildDesc(AttributeDefinitionDesc & desc) const106 void CdataDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
107 {
108   desc.declaredValue = AttributeDefinitionDesc::cdata;
109 }
110 
copy() const111 DeclaredValue *CdataDeclaredValue::copy() const
112 {
113   return new CdataDeclaredValue(*this);
114 }
115 
TokenizedDeclaredValue(TokenType type,Boolean isList)116 TokenizedDeclaredValue::TokenizedDeclaredValue(TokenType type,
117 					       Boolean isList)
118 : type_(type), isList_(isList)
119 {
120   switch (type) {
121   case name:
122   case entityName:
123     initialCategories_ = Syntax::nameStartCategory;
124     subsequentCategories_ = (Syntax::nameStartCategory|Syntax::digitCategory
125 			     | Syntax::otherNameCategory);
126     break;
127   case number:
128     initialCategories_ = Syntax::digitCategory;
129     subsequentCategories_ = Syntax::digitCategory;
130     break;
131   case nameToken:
132     initialCategories_ = (Syntax::nameStartCategory|Syntax::digitCategory
133 			  | Syntax::otherNameCategory);
134     subsequentCategories_ = initialCategories_;
135     break;
136   case numberToken:
137     initialCategories_ = Syntax::digitCategory;
138     subsequentCategories_ = (Syntax::nameStartCategory|Syntax::digitCategory
139 			     | Syntax::otherNameCategory);
140     break;
141   }
142 }
143 
tokenized() const144 Boolean TokenizedDeclaredValue::tokenized() const
145 {
146   return 1;
147 }
148 
makeValue(Text & text,AttributeContext & context,const StringC & str,unsigned & specLength) const149 AttributeValue *TokenizedDeclaredValue::makeValue(Text &text,
150 						  AttributeContext &context,
151 						  const StringC &str,
152 						  unsigned &specLength) const
153 {
154   return makeTokenizedValue(text, context, str, specLength);
155 }
156 
157 TokenizedAttributeValue *
makeTokenizedValue(Text & text,AttributeContext & context,const StringC & LOCALname,unsigned & specLength) const158 TokenizedDeclaredValue::makeTokenizedValue(Text &text,
159 					   AttributeContext &context,
160 					   const StringC &LOCALname,
161 					   unsigned &specLength) const
162 {
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()),
169 	     space);
170   const StringC &value = text.string();
171   size_t i = 0;
172   size_t length = value.size();
173 
174   for (;;) {
175     if (i >= length) {
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);
180       break;
181     }
182     size_t startIndex = i;
183     if (context.validate()) {
184       if (!(syntax.charCategory(value[i]) & initialCategories_)) {
185         context.Messenger::setNextLocation(text.charLocation(i));
186         Char c = value[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));
195 	else
196 	  context.message(ParserMessages::attributeValueName,
197 	                  StringMessageArg(StringC(&c, 1)),
198 	                  StringMessageArg(LOCALname));
199       }
200       else {
201 	for (++i;
202              i < length
203 	     && (syntax.charCategory(value[i]) & subsequentCategories_);
204 	     i++)
205 	  ;
206 	if (i < length && value[i] != space) {
207 	  Char c = value[i];
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));
213 	}
214       }
215     }
216     while (i < length && value[i] != space)
217       i++;
218     if (i - startIndex > syntax.namelen()) {
219       context.Messenger::setNextLocation(text.charLocation(i));
220       context.message(ParserMessages::nameTokenLength,
221 		      NumberMessageArg(syntax.namelen()));
222     }
223     if (i == length)
224       break;
225     if (!isList_ && context.validate() && spaceIndex.size() == 0) {
226       context.Messenger::setNextLocation(text.charLocation(i));
227       context.message(ParserMessages::attributeValueMultiple,
228 		      StringMessageArg(LOCALname));
229     }
230     spaceIndex.push_back(i);
231     i++;
232   }
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?
237   if (isList_) {
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.
242     if (normsep > 0)
243       normalizedLength += (normsep - 1)*(spaceIndex.size() + 1);
244     else
245       normalizedLength -= spaceIndex.size() + 1;
246   }
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);
256 }
257 
recoverUnquoted(const StringC & str,const Location & strLoc,AttributeContext & context,const StringC & name)258 Boolean TokenizedAttributeValue::recoverUnquoted(const StringC &str,
259 						 const Location &strLoc,
260 						 AttributeContext &context,
261 						 const StringC &name)
262 {
263   TextIter iter(text_);
264   TextItem::Type type;
265   const Char *s;
266   size_t len;
267   const Location *loc;
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));
278     return 1;
279   }
280   return 0;
281 }
282 
buildDesc(AttributeDefinitionDesc & desc) const283 void TokenizedDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
284 {
285   desc.declaredValue = AttributeDefinitionDesc::DeclaredValue(
286     type_ - name + (isList_
287 		    ? AttributeDefinitionDesc::names
288 		    : AttributeDefinitionDesc::name));
289 }
290 
copy() const291 DeclaredValue *TokenizedDeclaredValue::copy() const
292 {
293   return new TokenizedDeclaredValue(*this);
294 }
295 
GroupDeclaredValue(TokenType type,Vector<StringC> & vec)296 GroupDeclaredValue::GroupDeclaredValue(TokenType type,
297 				       Vector<StringC> &vec)
298 : TokenizedDeclaredValue(type, 0)
299 {
300   vec.swap(allowedValues_);
301 }
302 
buildDesc(AttributeDefinitionDesc & desc) const303 void GroupDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
304 {
305   desc.allowedValues = allowedValues_;
306 }
307 
copy() const308 DeclaredValue *GroupDeclaredValue::copy() const
309 {
310   return new GroupDeclaredValue(*this);
311 }
312 
makeValue(Text & text,AttributeContext & context,const StringC & LOCALname,unsigned & specLength) const313 AttributeValue *GroupDeclaredValue::makeValue(Text &text,
314 					      AttributeContext &context,
315 					      const StringC &LOCALname,
316 					      unsigned &specLength) const
317 {
318   TokenizedAttributeValue *val = makeTokenizedValue(text, context, LOCALname,
319 						    specLength);
320   if (!val || !context.validate())
321     return val;
322   for (size_t i = 0; i < allowedValues_.size(); i++)
323     if (val->string() == allowedValues_[i])
324       return val;
325   context.message(ParserMessages::attributeValueNotInGroup,
326 		  StringMessageArg(val->string()),
327 		  StringMessageArg(LOCALname),
328 		  StringVectorMessageArg(allowedValues_));
329   return val;
330 }
331 
makeValueFromToken(Text & text,AttributeContext & context,const StringC &,unsigned & specLength) const332 AttributeValue *GroupDeclaredValue::makeValueFromToken(Text &text,
333 						       AttributeContext &context,
334 						       const StringC &,
335 						       unsigned &specLength)
336      const
337 {
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>());
347 }
348 
containsToken(const StringC & token) const349 Boolean GroupDeclaredValue::containsToken(const StringC &token) const
350 {
351   for (size_t i = 0; i < allowedValues_.size(); i++)
352     if (allowedValues_[i] == token)
353       return 1;
354   return 0;
355 }
356 
getTokens() const357 const Vector<StringC> *GroupDeclaredValue::getTokens() const
358 {
359   return &allowedValues_;
360 }
361 
NameTokenGroupDeclaredValue(Vector<StringC> & vec)362 NameTokenGroupDeclaredValue::NameTokenGroupDeclaredValue(Vector<StringC> &vec)
363 : GroupDeclaredValue(nameToken, vec)
364 {
365 }
366 
buildDesc(AttributeDefinitionDesc & desc) const367 void NameTokenGroupDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
368 {
369   GroupDeclaredValue::buildDesc(desc);
370   desc.declaredValue = AttributeDefinitionDesc::nameTokenGroup;
371 }
372 
copy() const373 DeclaredValue *NameTokenGroupDeclaredValue::copy() const
374 {
375   return new NameTokenGroupDeclaredValue(*this);
376 }
377 
NotationDeclaredValue(Vector<StringC> & vec)378 NotationDeclaredValue::NotationDeclaredValue(Vector<StringC> &vec)
379 : GroupDeclaredValue(name, vec)
380 {
381 }
382 
isNotation() const383 Boolean NotationDeclaredValue::isNotation() const
384 {
385   return 1;
386 }
387 
388 AttributeSemantics *
makeSemantics(const TokenizedAttributeValue & value,AttributeContext & context,const StringC &,unsigned &,unsigned &) const389 NotationDeclaredValue::makeSemantics(const TokenizedAttributeValue &value,
390 				     AttributeContext &context,
391 				     const StringC &,
392 				     unsigned &,
393 				     unsigned &) const
394 {
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()));
403     }
404     return 0;
405   }
406   return new NotationAttributeSemantics(notation);
407 }
408 
buildDesc(AttributeDefinitionDesc & desc) const409 void NotationDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
410 {
411   GroupDeclaredValue::buildDesc(desc);
412   desc.declaredValue = AttributeDefinitionDesc::notation;
413 }
414 
copy() const415 DeclaredValue *NotationDeclaredValue::copy() const
416 {
417   return new NotationDeclaredValue(*this);
418 }
419 
EntityDeclaredValue(Boolean isList)420 EntityDeclaredValue::EntityDeclaredValue(Boolean isList)
421 : TokenizedDeclaredValue(entityName, isList)
422 {
423 }
424 
isEntity() const425 Boolean EntityDeclaredValue::isEntity() const
426 {
427   return 1;
428 }
429 
430 AttributeSemantics *
makeSemantics(const TokenizedAttributeValue & value,AttributeContext & context,const StringC &,unsigned &,unsigned & nEntityNames) const431 EntityDeclaredValue::makeSemantics(const TokenizedAttributeValue &value,
432 				   AttributeContext &context,
433 				   const StringC &,
434 				   unsigned &,
435 				   unsigned &nEntityNames) const
436 {
437   Boolean valid = 1;
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)));
449       }
450       valid = 0;
451     }
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)));
457       }
458       valid = 0;
459     }
460   }
461   if (valid)
462     return new EntityAttributeSemantics(entities);
463   else
464     return 0;
465 }
466 
copy() const467 DeclaredValue *EntityDeclaredValue::copy() const
468 {
469   return new EntityDeclaredValue(*this);
470 }
471 
IdDeclaredValue()472 IdDeclaredValue::IdDeclaredValue()
473 : TokenizedDeclaredValue(name, 0)
474 {
475 }
476 
isId() const477 Boolean IdDeclaredValue::isId() const
478 {
479   return 1;
480 }
481 
482 AttributeSemantics *
makeSemantics(const TokenizedAttributeValue & value,AttributeContext & context,const StringC &,unsigned &,unsigned &) const483 IdDeclaredValue::makeSemantics(const TokenizedAttributeValue &value,
484 			       AttributeContext &context,
485 			       const StringC &,
486 			       unsigned &,
487 			       unsigned &) const
488 {
489   Location prevLoc;
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()),
494 		    prevLoc);
495   }
496   return 0;
497 }
498 
buildDesc(AttributeDefinitionDesc & desc) const499 void IdDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
500 {
501   desc.declaredValue = AttributeDefinitionDesc::id;
502 }
503 
copy() const504 DeclaredValue *IdDeclaredValue::copy() const
505 {
506   return new IdDeclaredValue(*this);
507 }
508 
IdrefDeclaredValue(Boolean isList)509 IdrefDeclaredValue::IdrefDeclaredValue(Boolean isList)
510 : TokenizedDeclaredValue(name, isList)
511 {
512 }
513 
514 AttributeSemantics *
makeSemantics(const TokenizedAttributeValue & value,AttributeContext & context,const StringC &,unsigned & nIdrefs,unsigned &) const515 IdrefDeclaredValue::makeSemantics(const TokenizedAttributeValue &value,
516 				  AttributeContext &context,
517 				  const StringC &,
518 				  unsigned &nIdrefs,
519 				  unsigned &) const
520 {
521   size_t nTokens = value.nTokens();
522   nIdrefs += nTokens;
523   for (size_t i = 0; i < nTokens; i++)
524     context.noteIdref(value.token(i), value.tokenLocation(i));
525   return 0;
526 }
527 
isIdref() const528 Boolean IdrefDeclaredValue::isIdref() const
529 {
530   return 1;
531 }
532 
buildDesc(AttributeDefinitionDesc & desc) const533 void IdrefDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
534 {
535   TokenizedDeclaredValue::buildDesc(desc);
536   if (desc.declaredValue == AttributeDefinitionDesc::name)
537     desc.declaredValue = AttributeDefinitionDesc::idref;
538   else
539     desc.declaredValue = AttributeDefinitionDesc::idrefs;
540 }
541 
copy() const542 DeclaredValue *IdrefDeclaredValue::copy() const
543 {
544   return new IdrefDeclaredValue(*this);
545 }
546 
547 
AttributeDefinition(const StringC & name,DeclaredValue * value)548 AttributeDefinition::AttributeDefinition(const StringC &name,
549 					 DeclaredValue *value)
550 : name_(name), declaredValue_(value)
551 {
552 }
553 
~AttributeDefinition()554 AttributeDefinition::~AttributeDefinition()
555 {
556 }
557 
checkValue(AttributeValue * p,AttributeContext &) const558 AttributeValue *AttributeDefinition::checkValue(AttributeValue *p,
559 						AttributeContext &) const
560 {
561   return p;
562 }
563 
missingValueWouldMatch(const Text &,const AttributeContext &) const564 Boolean AttributeDefinition::missingValueWouldMatch(const Text &,
565 						    const AttributeContext &) const
566 {
567   return 0;
568 }
569 
570 const AttributeValue *
defaultValue(const AttributeValue *) const571 AttributeDefinition::defaultValue(const AttributeValue *) const
572 {
573   return 0;
574 }
575 
getDesc(AttributeDefinitionDesc & desc) const576 void AttributeDefinition::getDesc(AttributeDefinitionDesc &desc) const
577 {
578   desc.allowedValues.clear();
579   desc.defaultValue.clear();
580   desc.currentIndex = 0;
581   buildDesc(desc);
582   declaredValue_->buildDesc(desc);
583 }
584 
isConref() const585 Boolean AttributeDefinition::isConref() const
586 {
587   return 0;
588 }
589 
isCurrent() const590 Boolean AttributeDefinition::isCurrent() const
591 {
592   return 0;
593 }
594 
isFixed() const595 Boolean AttributeDefinition::isFixed() const
596 {
597   return 0;
598 }
599 
RequiredAttributeDefinition(const StringC & name,DeclaredValue * value)600 RequiredAttributeDefinition::RequiredAttributeDefinition(const StringC &name,
601 							 DeclaredValue *value)
602 : AttributeDefinition(name, value)
603 {
604 }
605 
606 ConstPtr<AttributeValue>
makeMissingValue(AttributeContext & context) const607 RequiredAttributeDefinition::makeMissingValue(AttributeContext &context) const
608 {
609   if (context.validate())
610     context.message(ParserMessages::requiredAttributeMissing,
611 		    StringMessageArg(name()));
612   return 0;
613 }
614 
buildDesc(AttributeDefinitionDesc & desc) const615 void RequiredAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
616 {
617   desc.defaultValueType = AttributeDefinitionDesc::required;
618 }
619 
copy() const620 AttributeDefinition *RequiredAttributeDefinition::copy() const
621 {
622   return new RequiredAttributeDefinition(*this);
623 }
624 
CurrentAttributeDefinition(const StringC & name,DeclaredValue * value,size_t index)625 CurrentAttributeDefinition::CurrentAttributeDefinition(const StringC &name, DeclaredValue *value, size_t index)
626 : AttributeDefinition(name, value), currentIndex_(index)
627 {
628 }
629 
630 ConstPtr<AttributeValue>
makeMissingValue(AttributeContext & context) const631 CurrentAttributeDefinition::makeMissingValue(AttributeContext &context) const
632 {
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()));
639     return currentValue;
640   }
641   if (context.validate())
642     context.message(ParserMessages::attributeMissing,
643 		    StringMessageArg(name()));
644   return 0;
645 }
646 
missingValueWouldMatch(const Text & text,const AttributeContext & context) const647 Boolean CurrentAttributeDefinition::missingValueWouldMatch(const Text &text,
648 							   const AttributeContext &context) const
649 {
650   if (!context.mayDefaultAttribute())
651     return 0;
652   ConstPtr<AttributeValue> currentValue
653     = context.getCurrentAttribute(currentIndex_);
654   if (currentValue.isNull())
655     return 0;
656   return text.fixedEqual(*currentValue->text());
657 }
658 
659 AttributeValue *
checkValue(AttributeValue * value,AttributeContext & context) const660 CurrentAttributeDefinition::checkValue(AttributeValue *value,
661 				       AttributeContext &context) const
662 {
663   context.noteCurrentAttribute(currentIndex_, value);
664   return value;
665 }
666 
buildDesc(AttributeDefinitionDesc & desc) const667 void CurrentAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
668 {
669   desc.defaultValueType = AttributeDefinitionDesc::current;
670   desc.currentIndex = currentIndex_;
671 }
672 
copy() const673 AttributeDefinition *CurrentAttributeDefinition::copy() const
674 {
675   return new CurrentAttributeDefinition(*this);
676 }
677 
isCurrent() const678 Boolean CurrentAttributeDefinition::isCurrent() const
679 {
680   return 1;
681 }
682 
ImpliedAttributeDefinition(const StringC & name,DeclaredValue * value)683 ImpliedAttributeDefinition::ImpliedAttributeDefinition(const StringC &name,
684 						       DeclaredValue *value)
685 : AttributeDefinition(name, value)
686 {
687 }
688 
689 ConstPtr<AttributeValue>
makeMissingValue(AttributeContext & context) const690 ImpliedAttributeDefinition::makeMissingValue(AttributeContext &context) const
691 {
692   return context.makeImpliedAttributeValue();
693 }
694 
buildDesc(AttributeDefinitionDesc & desc) const695 void ImpliedAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
696 {
697   desc.defaultValueType = AttributeDefinitionDesc::implied;
698 }
699 
copy() const700 AttributeDefinition *ImpliedAttributeDefinition::copy() const
701 {
702   return new ImpliedAttributeDefinition(*this);
703 }
704 
705 const AttributeValue *
defaultValue(const AttributeValue * impliedValue) const706 ImpliedAttributeDefinition::defaultValue(const AttributeValue *impliedValue)
707      const
708 {
709   return impliedValue;
710 }
711 
ConrefAttributeDefinition(const StringC & name,DeclaredValue * value)712 ConrefAttributeDefinition::ConrefAttributeDefinition(const StringC &name,
713 						     DeclaredValue *value)
714 : ImpliedAttributeDefinition(name, value)
715 {
716 }
717 
isConref() const718 Boolean ConrefAttributeDefinition::isConref() const
719 {
720   return 1;
721 }
722 
buildDesc(AttributeDefinitionDesc & desc) const723 void ConrefAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
724 {
725   desc.defaultValueType = AttributeDefinitionDesc::conref;
726 }
727 
copy() const728 AttributeDefinition *ConrefAttributeDefinition::copy() const
729 {
730   return new ConrefAttributeDefinition(*this);
731 }
732 
DefaultAttributeDefinition(const StringC & name,DeclaredValue * declaredValue,AttributeValue * defaultValue)733 DefaultAttributeDefinition::DefaultAttributeDefinition(const StringC &name,
734 							DeclaredValue *declaredValue,
735 							AttributeValue *defaultValue)
736 : AttributeDefinition(name, declaredValue),
737   value_(defaultValue)
738 {
739 }
740 
741 ConstPtr<AttributeValue>
makeMissingValue(AttributeContext & context) const742 DefaultAttributeDefinition::makeMissingValue(AttributeContext &context) const
743 {
744   if (context.mayDefaultAttribute())
745     return value_;
746   if (context.validate())
747     context.message(ParserMessages::attributeMissing,
748 		    StringMessageArg(name()));
749   return 0;
750 }
751 
missingValueWouldMatch(const Text & text,const AttributeContext & context) const752 Boolean DefaultAttributeDefinition::missingValueWouldMatch(const Text &text,
753 							   const AttributeContext &context) const
754 {
755   return context.mayDefaultAttribute() && text.fixedEqual(*value_->text());
756 }
757 
buildDesc(AttributeDefinitionDesc & desc) const758 void DefaultAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
759 {
760   desc.defaultValueType = AttributeDefinitionDesc::defaulted;
761   desc.defaultValue = value_;
762 }
763 
copy() const764 AttributeDefinition *DefaultAttributeDefinition::copy() const
765 {
766   return new DefaultAttributeDefinition(*this);
767 }
768 
FixedAttributeDefinition(const StringC & name,DeclaredValue * declaredValue,AttributeValue * defaultValue)769 FixedAttributeDefinition:: FixedAttributeDefinition(const StringC &name,
770 						    DeclaredValue *declaredValue,
771 						    AttributeValue *defaultValue)
772 : DefaultAttributeDefinition(name, declaredValue, defaultValue)
773 {
774 }
775 
isFixed() const776 Boolean FixedAttributeDefinition::isFixed() const
777 {
778   return 1;
779 }
780 
checkValue(AttributeValue * value,AttributeContext & context) const781 AttributeValue *FixedAttributeDefinition::checkValue(AttributeValue *value,
782 						     AttributeContext &context)
783      const
784 {
785   const AttributeValue *fixedValue
786     = DefaultAttributeDefinition::defaultValue(0);
787   if (value && fixedValue && context.validate()) {
788     const Text *text;
789     const StringC *str;
790     const Text *fixedText;
791     const StringC *fixedStr;
792     switch (value->info(text, str)) {
793     case AttributeValue::implied:
794       CANNOT_HAPPEN();
795     case AttributeValue::cdata:
796       if (fixedValue->info(fixedText, fixedStr) == AttributeValue::cdata) {
797 	if (!text->fixedEqual(*fixedText))
798 	  context.message(ParserMessages::notFixedValue, StringMessageArg(name()));
799       }
800       break;
801     case AttributeValue::tokenized:
802       if (fixedValue->info(fixedText, fixedStr) == AttributeValue::tokenized) {
803 	if (*str != *fixedStr)
804 	  context.message(ParserMessages::notFixedValue, StringMessageArg(name()));
805       }
806       break;
807     }
808   }
809   return value;
810 }
811 
buildDesc(AttributeDefinitionDesc & desc) const812 void FixedAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
813 {
814   // get the fixed value
815   DefaultAttributeDefinition::buildDesc(desc);
816   desc.defaultValueType = AttributeDefinitionDesc::fixed;
817 }
818 
copy() const819 AttributeDefinition *FixedAttributeDefinition::copy() const
820 {
821   return new FixedAttributeDefinition(*this);
822 }
823 
824 AttributeDefinitionList
AttributeDefinitionList(Vector<CopyOwner<AttributeDefinition>> & vec,size_t index,Boolean anyCurrent,size_t idIndex,size_t notationIndex)825 ::AttributeDefinitionList(Vector<CopyOwner<AttributeDefinition> > &vec,
826 			  size_t index,
827 			  Boolean anyCurrent,
828 			  size_t idIndex,
829 			  size_t notationIndex)
830 : index_(index), anyCurrent_(anyCurrent), idIndex_(idIndex),
831   notationIndex_(notationIndex)
832 {
833   defs_.swap(vec);
834 }
835 
AttributeDefinitionList(const ConstPtr<AttributeDefinitionList> & def)836 AttributeDefinitionList:: AttributeDefinitionList(const ConstPtr<AttributeDefinitionList> &def)
837 : prev_(def), index_(size_t(-1))
838 {
839   if (def.isNull()) {
840     anyCurrent_ = 0;
841     notationIndex_ = size_t(-1);
842     idIndex_ = size_t(-1);
843   }
844   else {
845     anyCurrent_ = def->anyCurrent_;
846     notationIndex_ = def->notationIndex_;
847     idIndex_ = def->idIndex_;
848     defs_ = def->defs_;
849   }
850 }
851 
tokenIndex(const StringC & token,unsigned & index) const852 Boolean AttributeDefinitionList::tokenIndex(const StringC &token, unsigned &index) const
853 {
854   for (size_t i = 0; i < defs_.size(); i++)
855     if (defs_[i]->containsToken(token)) {
856       index = i;
857       return 1;
858     }
859   return 0;
860 }
861 
tokenIndexUnique(const StringC & token,unsigned i) const862 Boolean AttributeDefinitionList::tokenIndexUnique(const StringC &token, unsigned i) const
863 {
864   for (++i; i < defs_.size(); i++)
865     if (defs_[i]->containsToken(token))
866       return 0;
867   return 1;
868 }
869 
870 
attributeIndex(const StringC & name,unsigned & index) const871 Boolean AttributeDefinitionList::attributeIndex(const StringC &name,
872 						unsigned &index) const
873 {
874   for (size_t i = 0; i < defs_.size(); i++)
875     if (defs_[i]->name() == name) {
876       index = i;
877       return 1;
878     }
879   return 0;
880 }
881 
append(AttributeDefinition * def)882 void AttributeDefinitionList::append(AttributeDefinition *def)
883 {
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())
889     anyCurrent_ = 1;
890   defs_.resize(defs_.size() + 1);
891   defs_.back() = def;
892 }
893 
AttributeSemantics()894 AttributeSemantics::AttributeSemantics()
895 {
896 }
897 
~AttributeSemantics()898 AttributeSemantics::~AttributeSemantics()
899 {
900 }
901 
nEntities() const902 size_t AttributeSemantics::nEntities() const
903 {
904   return 0;
905 }
906 
entity(size_t) const907 ConstPtr<Entity> AttributeSemantics::entity(size_t) const
908 {
909   return 0;
910 }
911 
notation() const912 ConstPtr<Notation> AttributeSemantics::notation() const
913 {
914   return 0;
915 }
916 
917 
NotationAttributeSemantics(const ConstPtr<Notation> & notation)918 NotationAttributeSemantics::NotationAttributeSemantics(const ConstPtr<Notation> &notation)
919 : notation_(notation)
920 {
921 }
922 
notation() const923 ConstPtr<Notation> NotationAttributeSemantics::notation() const
924 {
925   return notation_;
926 }
927 
copy() const928 AttributeSemantics *NotationAttributeSemantics::copy() const
929 {
930   return new NotationAttributeSemantics(*this);
931 }
932 
EntityAttributeSemantics(Vector<ConstPtr<Entity>> & entity)933 EntityAttributeSemantics::EntityAttributeSemantics(Vector<ConstPtr<Entity> > &entity)
934 {
935   entity.swap(entity_);
936 }
937 
nEntities() const938 size_t EntityAttributeSemantics::nEntities() const
939 {
940   return entity_.size();
941 }
942 
entity(size_t i) const943 ConstPtr<Entity> EntityAttributeSemantics::entity(size_t i) const
944 {
945   return entity_[i];
946 }
947 
copy() const948 AttributeSemantics *EntityAttributeSemantics::copy() const
949 {
950   return new EntityAttributeSemantics(*this);
951 }
952 
AttributeValue()953 AttributeValue::AttributeValue()
954 {
955 }
956 
~AttributeValue()957 AttributeValue::~AttributeValue()
958 {
959 }
960 
makeSemantics(const DeclaredValue *,AttributeContext &,const StringC &,unsigned &,unsigned &) const961 AttributeSemantics *AttributeValue::makeSemantics(const DeclaredValue *,
962 						  AttributeContext &,
963 						  const StringC &,
964 						  unsigned &,
965 						  unsigned &) const
966 {
967   return 0;
968 }
969 
text() const970 const Text *AttributeValue::text() const
971 {
972   return 0;
973 }
974 
recoverUnquoted(const StringC &,const Location &,AttributeContext &,const StringC &)975 Boolean AttributeValue::recoverUnquoted(const StringC &, const Location &,
976 					AttributeContext &, const StringC &)
977 {
978   return 0;
979 }
980 
ImpliedAttributeValue()981 ImpliedAttributeValue::ImpliedAttributeValue()
982 {
983 }
984 
info(const Text * &,const StringC * &) const985 AttributeValue::Type ImpliedAttributeValue::info(const Text *&,
986 						 const StringC *&) const
987 {
988   return implied;
989 }
990 
TokenizedAttributeValue(Text & text,const Vector<size_t> & spaceIndex)991 TokenizedAttributeValue::TokenizedAttributeValue(Text &text,
992 						 const Vector<size_t> &spaceIndex)
993 : spaceIndex_(spaceIndex)
994 {
995   text.swap(text_);
996 }
997 
info(const Text * &,const StringC * & string) const998 AttributeValue::Type TokenizedAttributeValue::info(const Text *&,
999 						   const StringC *&string) const
1000 {
1001   string = &text_.string();
1002   return tokenized;
1003 }
1004 
text() const1005 const Text *TokenizedAttributeValue::text() const
1006 {
1007   return &text_;
1008 }
1009 
1010 AttributeSemantics *
makeSemantics(const DeclaredValue * value,AttributeContext & context,const StringC & name,unsigned & nIdrefs,unsigned & nEntityNames) const1011 TokenizedAttributeValue::makeSemantics(const DeclaredValue *value,
1012 				       AttributeContext &context,
1013 				       const StringC &name,
1014 				       unsigned &nIdrefs,
1015 				       unsigned &nEntityNames) const
1016 {
1017   if (text_.size() == 0)
1018     return 0;
1019   return value->makeSemantics(*this, context, name, nIdrefs, nEntityNames);
1020 }
1021 
CdataAttributeValue(Text & text)1022 CdataAttributeValue::CdataAttributeValue(Text &text)
1023 {
1024   text.swap(text_);
1025 }
1026 
info(const Text * & text,const StringC * &) const1027 AttributeValue::Type CdataAttributeValue::info(const Text *&text,
1028 					       const StringC *&) const
1029 {
1030   text = &text_;
1031   return cdata;
1032 }
1033 
text() const1034 const Text *CdataAttributeValue::text() const
1035 {
1036   return &text_;
1037 }
1038 
recoverUnquoted(const StringC & str,const Location & strLoc,AttributeContext & context,const StringC &)1039 Boolean CdataAttributeValue::recoverUnquoted(const StringC &str,
1040 					     const Location &strLoc,
1041 					     AttributeContext &context,
1042 					     const StringC &)
1043 {
1044   TextIter iter(text_);
1045   TextItem::Type type;
1046   const Char *s;
1047   size_t len;
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);
1058     return 1;
1059   }
1060   return 0;
1061 }
1062 
Attribute()1063 Attribute::Attribute()
1064 : specIndexPlus_(0)
1065 {
1066 }
1067 
clear()1068 void Attribute::clear()
1069 {
1070   specIndexPlus_ = 0;
1071   value_.clear();
1072   semantics_.clear();
1073 }
1074 
AttributeList(const ConstPtr<AttributeDefinitionList> & def)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)
1078 {
1079 }
1080 
AttributeList()1081 AttributeList::AttributeList()
1082 : nSpec_(0), conref_(0)
1083 {
1084 }
1085 
init(const ConstPtr<AttributeDefinitionList> & def)1086 void AttributeList::init(const ConstPtr<AttributeDefinitionList> &def)
1087 {
1088   def_ = def;
1089   nSpec_ = 0;
1090   conref_ = 0;
1091   nIdrefs_ = 0;
1092   nEntityNames_ = 0;
1093   if (def_.isNull())
1094     vec_.resize(0);
1095   else {
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++)
1102       vec_[i].clear();
1103   }
1104 }
1105 
changeDef(const ConstPtr<AttributeDefinitionList> & def)1106 void AttributeList::changeDef(const ConstPtr<AttributeDefinitionList> &def)
1107 {
1108   vec_.resize(def.isNull() ? 0 : def->size());
1109   def_ = def;
1110 }
1111 
swap(AttributeList & to)1112 void AttributeList::swap(AttributeList &to)
1113 {
1114   vec_.swap(to.vec_);
1115   def_.swap(to.def_);
1116   {
1117     unsigned tem = to.nIdrefs_;
1118     to.nIdrefs_ = nIdrefs_;
1119     nIdrefs_ = tem;
1120   }
1121   {
1122     unsigned tem = to.nEntityNames_;
1123     to.nEntityNames_ = nEntityNames_;
1124     nEntityNames_ = tem;
1125   }
1126   {
1127     size_t tem = to.nSpec_;
1128     to.nSpec_ = nSpec_;
1129     nSpec_ = tem;
1130   }
1131   {
1132     PackedBoolean tem = to.conref_;
1133     to.conref_ = conref_;
1134     conref_ = tem;
1135   }
1136 }
1137 
finish(AttributeContext & context)1138 void AttributeList::finish(AttributeContext &context)
1139 {
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(),
1147 						   context,
1148 						   nIdrefs_,
1149 						   nEntityNames_));
1150     }
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()
1159       && conref_
1160       && def_->notationIndex() != size_t(-1)
1161       && specified(def_->notationIndex()))
1162     context.message(ParserMessages::conrefNotation);
1163 }
1164 
setSpec(unsigned i,AttributeContext & context)1165 void AttributeList::setSpec(unsigned i, AttributeContext &context)
1166 {
1167   if (vec_[i].specified())
1168     context.message(ParserMessages::duplicateAttributeSpec,
1169 		   StringMessageArg(def(i)->name()));
1170   else
1171     vec_[i].setSpec(nSpec_++);
1172 }
1173 
noteInvalidSpec()1174 void AttributeList::noteInvalidSpec()
1175 {
1176   // This is needed for error recovery.
1177   // We don't want nSpec_ to be > 0, if there is no attribute definition.
1178   if (nSpec_)
1179     nSpec_++;
1180 }
1181 
setValue(unsigned i,Text & text,AttributeContext & context,unsigned & specLength)1182 Boolean AttributeList::setValue(unsigned i, Text &text,
1183 				AttributeContext &context,
1184 				unsigned &specLength)
1185 {
1186   AttributeValue *value = def(i)->makeValue(text, context, specLength);
1187   if (def(i)->isConref())
1188     conref_ = 1;
1189   vec_[i].setValue(value);
1190   if (value)
1191     vec_[i].setSemantics(def(i)->makeSemantics(value, context,
1192 					       nIdrefs_, nEntityNames_));
1193   else if (AttributeValue::handleAsUnterminated(text, context))
1194     return 0;
1195   return 1;
1196 }
1197 
setValueToken(unsigned i,Text & text,AttributeContext & context,unsigned & specLength)1198 void AttributeList::setValueToken(unsigned i, Text &text,
1199 				  AttributeContext &context,
1200 				  unsigned &specLength)
1201 {
1202   AttributeValue *value = def(i)->makeValueFromToken(text, context,
1203 						     specLength);
1204   if (def(i)->isConref())
1205     conref_ = 1;
1206   vec_[i].setValue(value);
1207   if (value)
1208     vec_[i].setSemantics(def(i)->makeSemantics(value, context,
1209 					       nIdrefs_, nEntityNames_));
1210 }
1211 
getId() const1212 const StringC *AttributeList::getId() const
1213 {
1214   // Check for no attributes
1215   if (def_.isNull())
1216     return 0;
1217   // Check for no ID declared
1218   size_t i = def_->idIndex();
1219   if (i == size_t(-1))
1220     return 0;
1221   // Check for invalid value
1222   const AttributeValue *v = value(i);
1223   if (!v)
1224     return 0;
1225   // Check for implied value
1226   const Text *t = v->text();
1227   if (!t)
1228     return 0;
1229   return &t->string();
1230 }
1231 
recoverUnquoted(const StringC & str,const Location & strLoc,AttributeContext & context)1232 Boolean AttributeList::recoverUnquoted(const StringC &str,
1233 				       const Location &strLoc,
1234 				       AttributeContext &context)
1235 {
1236   if (nSpec_ > 0) {
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();
1240 	if (val)
1241 	  // I wish I could avoid casting away const here.
1242 	  return ((AttributeValue *)val)->recoverUnquoted(str, strLoc, context,
1243 							  name(i));
1244 	break;
1245       }
1246     return 1;
1247   }
1248   return 0;
1249 }
1250 
handleAsUnterminated(AttributeContext & context)1251 Boolean AttributeList::handleAsUnterminated(AttributeContext &context)
1252 {
1253   if (nSpec_ > 0) {
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();
1257 	const Text *ptr;
1258 	if (val && (ptr = val->text()) != 0
1259 	    && AttributeValue::handleAsUnterminated(*ptr, context))
1260 	  return 1;
1261 	break;
1262       }
1263     }
1264   }
1265   return 0;
1266 }
1267 
1268 // This tries to guess this attribute value looks like if it had
1269 // a missing ending quote.
1270 
handleAsUnterminated(const Text & text,AttributeContext & context)1271 Boolean AttributeValue::handleAsUnterminated(const Text &text,
1272 					     AttributeContext &context)
1273 {
1274   TextIter iter(text);
1275   const Char *lastStr = 0;
1276   size_t lastLen;
1277   Location startLoc;
1278   const Location *loc;
1279   TextItem::Type type;
1280   const Char *str;
1281   size_t len;
1282   while (iter.next(type, str, len, loc)) {
1283     if (startLoc.origin().isNull() && !loc->origin().isNull())
1284       startLoc = *loc;
1285     switch (type) {
1286     case TextItem::data:
1287       if (len != 1 || *str != context.attributeSyntax().space()) {
1288 	lastStr = str;
1289 	lastLen = len;
1290       }
1291       break;
1292     case TextItem::endDelim:
1293     case TextItem::endDelimA:
1294     case TextItem::ignore:
1295       break;
1296     default:
1297       lastStr = 0;
1298       break;
1299     }
1300   }
1301   if (lastStr) {
1302     while (lastLen > 0
1303 	   && lastStr[lastLen - 1] == context.attributeSyntax().space())
1304       lastLen--;
1305     const StringC &vi = context.attributeSyntax().delimGeneral(Syntax::dVI);
1306     if (lastLen >= vi.size()
1307 	&& (vi
1308 	    == StringC(lastStr + (lastLen - vi.size()), vi.size()))) {
1309       context.Messenger::setNextLocation(startLoc);
1310       context.message(ParserMessages::literalClosingDelimiter);
1311       return 1;
1312     }
1313   }
1314   return 0;
1315 }
1316 
AttributeContext()1317 AttributeContext::AttributeContext()
1318 : mayDefaultAttribute_(0), validate_(1)
1319 {
1320 }
1321 
~AttributeContext()1322 AttributeContext::~AttributeContext()
1323 {
1324 }
1325 
defineId(const StringC &,const Location &,Location &)1326 Boolean AttributeContext::defineId(const StringC &, const Location &,
1327 				   Location &)
1328 {
1329   return 1;
1330 }
1331 
noteIdref(const StringC &,const Location &)1332 void AttributeContext::noteIdref(const StringC &, const Location &)
1333 {
1334 }
1335 
noteCurrentAttribute(size_t,AttributeValue *)1336 void AttributeContext::noteCurrentAttribute(size_t, AttributeValue *)
1337 {
1338 }
1339 
getCurrentAttribute(size_t) const1340 ConstPtr<AttributeValue> AttributeContext::getCurrentAttribute(size_t) const
1341 {
1342   return 0;
1343 }
1344 
getAttributeEntity(const StringC &,const Location &)1345 ConstPtr<Entity> AttributeContext::getAttributeEntity(const StringC &,
1346 						      const Location &)
1347 {
1348   return 0;
1349 }
1350 
getAttributeNotation(const StringC &,const Location &)1351 ConstPtr<Notation> AttributeContext::getAttributeNotation(const StringC &,
1352 							  const Location &)
1353 {
1354   return 0;
1355 }
1356 
makeImpliedAttributeValue()1357 ConstPtr<AttributeValue> AttributeContext::makeImpliedAttributeValue()
1358 {
1359   if (impliedAttributeValue_.isNull())
1360     impliedAttributeValue_ = new ImpliedAttributeValue;
1361   return impliedAttributeValue_;
1362 }
1363 
1364 #ifdef SP_NAMESPACE
1365 }
1366 #endif
1367