Blame lib/Attribute.cxx

Packit 8a864e
// Copyright (c) 1994 James Clark
Packit 8a864e
// See the file COPYING for copying permission.
Packit 8a864e
Packit 8a864e
#ifdef __GNUG__
Packit 8a864e
#pragma implementation
Packit 8a864e
#endif
Packit 8a864e
#include "splib.h"
Packit 8a864e
#include "Attribute.h"
Packit 8a864e
#include "MessageArg.h"
Packit 8a864e
#include "macros.h"
Packit 8a864e
#include "ParserMessages.h"
Packit 8a864e
#include "Syntax.h"
Packit 8a864e
#include "Entity.h"
Packit 8a864e
#include "Notation.h"
Packit 8a864e
Packit 8a864e
#ifdef SP_NAMESPACE
Packit 8a864e
namespace SP_NAMESPACE {
Packit 8a864e
#endif
Packit 8a864e
Packit 8a864e
DeclaredValue::DeclaredValue()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue::~DeclaredValue()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue *DeclaredValue::makeValueFromToken(Text &text,
Packit 8a864e
						  AttributeContext &context,
Packit 8a864e
						  const StringC &name,
Packit 8a864e
						  unsigned &specLength) const
Packit 8a864e
{
Packit 8a864e
  return makeValue(text, context, name, specLength);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics *DeclaredValue::makeSemantics(const TokenizedAttributeValue &,
Packit 8a864e
						 AttributeContext &,
Packit 8a864e
						 const StringC &,
Packit 8a864e
						 unsigned &,
Packit 8a864e
						 unsigned &) const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean DeclaredValue::containsToken(const StringC &) const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean DeclaredValue::isNotation() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean DeclaredValue::isEntity() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean DeclaredValue::isId() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean DeclaredValue::isIdref() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const Vector<StringC> *DeclaredValue::getTokens() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const Vector<StringC> *DeclaredValue::getOrigTokens() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Packit 8a864e
CdataDeclaredValue::CdataDeclaredValue()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean CdataDeclaredValue::tokenized() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void CdataDeclaredValue::checkNormalizedLength(Text &text, 
Packit 8a864e
                                               AttributeContext &context,
Packit 8a864e
                                               unsigned &specLength) const
Packit 8a864e
{
Packit 8a864e
  const Syntax &syntax = context.attributeSyntax();
Packit 8a864e
  size_t normsep = syntax.normsep();
Packit 8a864e
  size_t normalizedLength = text.normalizedLength(normsep);
Packit 8a864e
  specLength += normalizedLength;
Packit 8a864e
  size_t litlen = syntax.litlen();
Packit 8a864e
  // A length error will already have been given if
Packit 8a864e
  // length > litlen - normsep.
Packit 8a864e
  if (litlen >= normsep && text.size() <= litlen - normsep
Packit 8a864e
      && normalizedLength > litlen)
Packit 8a864e
    context.message(ParserMessages::normalizedAttributeValueLength,
Packit 8a864e
		    NumberMessageArg(litlen),
Packit 8a864e
		    NumberMessageArg(normalizedLength));
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue *CdataDeclaredValue::makeValue(Text &text, AttributeContext &context,
Packit 8a864e
					      const StringC &,
Packit 8a864e
					      unsigned &specLength) const
Packit 8a864e
{
Packit 8a864e
  checkNormalizedLength(text, context, specLength);
Packit 8a864e
  return new CdataAttributeValue(text);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void CdataDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.declaredValue = AttributeDefinitionDesc::cdata;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue *CdataDeclaredValue::copy() const
Packit 8a864e
{
Packit 8a864e
  return new CdataDeclaredValue(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DataDeclaredValue::DataDeclaredValue(const ConstPtr<Notation> &nt,
Packit 8a864e
                                     AttributeList &attributes)
Packit 8a864e
: notation_(nt)
Packit 8a864e
{
Packit 8a864e
  attributes.swap(attributes_);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue *DataDeclaredValue::makeValue(Text &text,
Packit 8a864e
                                             AttributeContext &context,
Packit 8a864e
                                             const StringC &,
Packit 8a864e
                                             unsigned &specLength) const
Packit 8a864e
{
Packit 8a864e
  checkNormalizedLength(text, context, specLength);
Packit 8a864e
  return new DataAttributeValue(text, notation_, attributes_);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue *DataDeclaredValue::copy() const
Packit 8a864e
{
Packit 8a864e
  return new DataDeclaredValue(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
TokenizedDeclaredValue::TokenizedDeclaredValue(TokenType type,
Packit 8a864e
					       Boolean isList)
Packit 8a864e
: type_(type), isList_(isList)
Packit 8a864e
{
Packit 8a864e
  switch (type) {
Packit 8a864e
  case name:
Packit 8a864e
  case entityName:
Packit 8a864e
    initialCategories_ = Syntax::nameStartCategory;
Packit 8a864e
    subsequentCategories_ = (Syntax::nameStartCategory|Syntax::digitCategory
Packit 8a864e
			     | Syntax::otherNameCategory);
Packit 8a864e
    break;
Packit 8a864e
  case number:
Packit 8a864e
    initialCategories_ = Syntax::digitCategory;
Packit 8a864e
    subsequentCategories_ = Syntax::digitCategory;
Packit 8a864e
    break;
Packit 8a864e
  case nameToken:
Packit 8a864e
    initialCategories_ = (Syntax::nameStartCategory|Syntax::digitCategory
Packit 8a864e
			  | Syntax::otherNameCategory);
Packit 8a864e
    subsequentCategories_ = initialCategories_;
Packit 8a864e
    break;
Packit 8a864e
  case numberToken:
Packit 8a864e
    initialCategories_ = Syntax::digitCategory;
Packit 8a864e
    subsequentCategories_ = (Syntax::nameStartCategory|Syntax::digitCategory
Packit 8a864e
			     | Syntax::otherNameCategory);
Packit 8a864e
    break;
Packit 8a864e
  }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean TokenizedDeclaredValue::tokenized() const
Packit 8a864e
{
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue *TokenizedDeclaredValue::makeValue(Text &text,
Packit 8a864e
						  AttributeContext &context,
Packit 8a864e
						  const StringC &str,
Packit 8a864e
						  unsigned &specLength) const
Packit 8a864e
{
Packit 8a864e
  return makeTokenizedValue(text, context, str, specLength);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
TokenizedAttributeValue *
Packit 8a864e
TokenizedDeclaredValue::makeTokenizedValue(Text &text,
Packit 8a864e
					   AttributeContext &context,
Packit 8a864e
					   const StringC &name,
Packit 8a864e
					   unsigned &specLength) const
Packit 8a864e
{
Packit 8a864e
  Vector<size_t> spaceIndex;
Packit 8a864e
  const Syntax &syntax = context.attributeSyntax();
Packit 8a864e
  Char space = syntax.space();
Packit 8a864e
  text.subst(*(type_ == entityName
Packit 8a864e
	       ? syntax.entitySubstTable()
Packit 8a864e
	       : syntax.generalSubstTable()),
Packit 8a864e
	     space);
Packit 8a864e
  const StringC &value = text.string();
Packit 8a864e
  size_t i = 0;
Packit 8a864e
  size_t length = value.size();
Packit 8a864e
Packit 8a864e
  for (;;) {
Packit 8a864e
    if (i >= length) {
Packit 8a864e
      // ends with a space (which would have to have been entered
Packit 8a864e
      // via a numeric character reference)
Packit 8a864e
      if (context.validate())
Packit 8a864e
	context.message(ParserMessages::attributeValueSyntax);
Packit 8a864e
      break;
Packit 8a864e
    }
Packit 8a864e
    size_t startIndex = i;
Packit 8a864e
    if (context.validate()) {
Packit 8a864e
      if (!(syntax.charCategory(value[i]) & initialCategories_)) {
Packit 8a864e
        context.Messenger::setNextLocation(text.charLocation(i));
Packit 8a864e
        Char c = value[i];
Packit 8a864e
	if (!(syntax.charCategory(value[i]) & subsequentCategories_))
Packit 8a864e
	  context.message(ParserMessages::attributeValueChar,
Packit 8a864e
	                  StringMessageArg(StringC(&c, 1)),
Packit 8a864e
	                  StringMessageArg(name));
Packit 8a864e
	else if (initialCategories_ == Syntax::digitCategory)
Packit 8a864e
	  context.message(ParserMessages::attributeValueNumberToken,
Packit 8a864e
	                  StringMessageArg(StringC(&c, 1)),
Packit 8a864e
	                  StringMessageArg(name));
Packit 8a864e
	else
Packit 8a864e
	  context.message(ParserMessages::attributeValueName,
Packit 8a864e
	                  StringMessageArg(StringC(&c, 1)),
Packit 8a864e
	                  StringMessageArg(name));
Packit 8a864e
      }
Packit 8a864e
      else {
Packit 8a864e
	for (++i;
Packit 8a864e
             i < length
Packit 8a864e
	     && (syntax.charCategory(value[i]) & subsequentCategories_);
Packit 8a864e
	     i++)
Packit 8a864e
	  ;
Packit 8a864e
	if (i < length && value[i] != space) {
Packit 8a864e
	  Char c = value[i];
Packit 8a864e
	  // character value[i] is not allowed anywhere in the value
Packit 8a864e
	  context.Messenger::setNextLocation(text.charLocation(i));
Packit 8a864e
	  context.message(ParserMessages::attributeValueChar,
Packit 8a864e
		          StringMessageArg(StringC(&c, 1)),
Packit 8a864e
		          StringMessageArg(name));
Packit 8a864e
	}
Packit 8a864e
      }
Packit 8a864e
    }
Packit 8a864e
    while (i < length && value[i] != space)
Packit 8a864e
      i++;
Packit 8a864e
    if (i - startIndex > syntax.namelen()) {
Packit 8a864e
      context.Messenger::setNextLocation(text.charLocation(i));
Packit 8a864e
      context.message(ParserMessages::nameTokenLength,
Packit 8a864e
		      NumberMessageArg(syntax.namelen()));
Packit 8a864e
    }
Packit 8a864e
    if (i == length)
Packit 8a864e
      break;
Packit 8a864e
    if (!isList_ && context.validate() && spaceIndex.size() == 0) {
Packit 8a864e
      context.Messenger::setNextLocation(text.charLocation(i));
Packit 8a864e
      context.message(ParserMessages::attributeValueMultiple,
Packit 8a864e
		      StringMessageArg(name));
Packit 8a864e
    }
Packit 8a864e
    spaceIndex.push_back(i);
Packit 8a864e
    i++;
Packit 8a864e
  }
Packit 8a864e
  size_t normsep = syntax.normsep();
Packit 8a864e
  size_t litlen = syntax.litlen();
Packit 8a864e
  size_t normalizedLength = normsep + length;
Packit 8a864e
  // should we count CDATA and SDATA entities here?
Packit 8a864e
  if (isList_) {
Packit 8a864e
    normalizedLength += 1;
Packit 8a864e
    // length is now the number of characters in each token in the list
Packit 8a864e
    // + 1 for each token in the list; so add normsep - 1 for each
Packit 8a864e
    // token in the list.
Packit 8a864e
    if (normsep > 0)
Packit 8a864e
      normalizedLength += (normsep - 1)*(spaceIndex.size() + 1);
Packit 8a864e
    else
Packit 8a864e
      normalizedLength -= spaceIndex.size() + 1;
Packit 8a864e
  }
Packit 8a864e
  specLength += normalizedLength;
Packit 8a864e
  // A length error will already have been given if
Packit 8a864e
  // length > litlen - normsep.
Packit 8a864e
  if (litlen >= normsep && length <= litlen - normsep
Packit 8a864e
      && normalizedLength > litlen)
Packit 8a864e
    context.message(ParserMessages::normalizedAttributeValueLength,
Packit 8a864e
		    NumberMessageArg(litlen),
Packit 8a864e
		    NumberMessageArg(normalizedLength));
Packit 8a864e
  return new TokenizedAttributeValue(text, spaceIndex);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean TokenizedAttributeValue::recoverUnquoted(const StringC &str,
Packit 8a864e
						 const Location &strLoc,
Packit 8a864e
						 AttributeContext &context,
Packit 8a864e
						 const StringC &name)
Packit 8a864e
{
Packit 8a864e
  TextIter iter(text_);
Packit 8a864e
  TextItem::Type type;
Packit 8a864e
  const Char *s;
Packit 8a864e
  size_t len;
Packit 8a864e
  const Location *loc;
Packit 8a864e
  if (iter.next(type, s, len, loc)
Packit 8a864e
      && type == TextItem::data
Packit 8a864e
      && len == text_.size()
Packit 8a864e
      && loc->origin().pointer() == strLoc.origin().pointer()
Packit 8a864e
      && loc->index() + len == strLoc.index()
Packit 8a864e
      && !iter.next(type, s, len, loc)) {
Packit 8a864e
    context.Messenger::setNextLocation(strLoc);
Packit 8a864e
    context.message(ParserMessages::attributeValueChar,
Packit 8a864e
		    StringMessageArg(StringC(str.data(), 1)),
Packit 8a864e
		    StringMessageArg(name));
Packit 8a864e
    return 1;
Packit 8a864e
  }
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void TokenizedDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.declaredValue = AttributeDefinitionDesc::DeclaredValue(
Packit 8a864e
    type_ - name + (isList_
Packit 8a864e
		    ? AttributeDefinitionDesc::names
Packit 8a864e
		    : AttributeDefinitionDesc::name));
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue *TokenizedDeclaredValue::copy() const
Packit 8a864e
{
Packit 8a864e
  return new TokenizedDeclaredValue(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
GroupDeclaredValue::GroupDeclaredValue(TokenType type,
Packit 8a864e
				       Vector<StringC> &vec)
Packit 8a864e
: TokenizedDeclaredValue(type, 0)
Packit 8a864e
{
Packit 8a864e
  vec.swap(allowedValues_);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void GroupDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.allowedValues = allowedValues_;
Packit 8a864e
  desc.origAllowedValues = origAllowedValues_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue *GroupDeclaredValue::copy() const
Packit 8a864e
{
Packit 8a864e
  return new GroupDeclaredValue(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void GroupDeclaredValue::setOrigAllowedValues(Vector<StringC> &origAllowedValues)
Packit 8a864e
{
Packit 8a864e
  origAllowedValues.swap(origAllowedValues_);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue *GroupDeclaredValue::makeValue(Text &text,
Packit 8a864e
					      AttributeContext &context,
Packit 8a864e
					      const StringC &name,
Packit 8a864e
					      unsigned &specLength) const
Packit 8a864e
{
Packit 8a864e
  TokenizedAttributeValue *val = makeTokenizedValue(text, context, name,
Packit 8a864e
						    specLength);
Packit 8a864e
  if (!val || !context.validate())
Packit 8a864e
    return val;
Packit 8a864e
  for (size_t i = 0; i < allowedValues_.size(); i++)
Packit 8a864e
    if (val->string() == allowedValues_[i])
Packit 8a864e
      return val;
Packit 8a864e
  context.message(ParserMessages::attributeValueNotInGroup,
Packit 8a864e
		  StringMessageArg(val->string()),
Packit 8a864e
		  StringMessageArg(name),
Packit 8a864e
		  StringVectorMessageArg(allowedValues_));
Packit 8a864e
  return val;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue *GroupDeclaredValue::makeValueFromToken(Text &text,
Packit 8a864e
						       AttributeContext &context,
Packit 8a864e
						       const StringC &,
Packit 8a864e
						       unsigned &specLength)
Packit 8a864e
     const
Packit 8a864e
{
Packit 8a864e
  const Syntax &syntax = context.attributeSyntax();
Packit 8a864e
  size_t litlen = syntax.litlen();
Packit 8a864e
  size_t normsep = syntax.normsep();
Packit 8a864e
  if (normsep > litlen || text.size() >  litlen - normsep)
Packit 8a864e
    context.message(ParserMessages::normalizedAttributeValueLength,
Packit 8a864e
		    NumberMessageArg(litlen),
Packit 8a864e
		    NumberMessageArg(text.size() + normsep));
Packit 8a864e
  specLength += text.size() + normsep;
Packit 8a864e
  return new TokenizedAttributeValue(text, Vector<size_t>());
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean GroupDeclaredValue::containsToken(const StringC &token) const
Packit 8a864e
{
Packit 8a864e
  for (size_t i = 0; i < allowedValues_.size(); i++)
Packit 8a864e
    if (allowedValues_[i] == token)
Packit 8a864e
      return 1;
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const Vector<StringC> *GroupDeclaredValue::getTokens() const
Packit 8a864e
{
Packit 8a864e
  return &allowedValues_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const Vector<StringC> *GroupDeclaredValue::getOrigTokens() const
Packit 8a864e
{
Packit 8a864e
  return &origAllowedValues_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
NameTokenGroupDeclaredValue::NameTokenGroupDeclaredValue(Vector<StringC> &vec)
Packit 8a864e
: GroupDeclaredValue(nameToken, vec)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void NameTokenGroupDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  GroupDeclaredValue::buildDesc(desc);
Packit 8a864e
  desc.declaredValue = AttributeDefinitionDesc::nameTokenGroup;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue *NameTokenGroupDeclaredValue::copy() const
Packit 8a864e
{
Packit 8a864e
  return new NameTokenGroupDeclaredValue(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
NotationDeclaredValue::NotationDeclaredValue(Vector<StringC> &vec)
Packit 8a864e
: GroupDeclaredValue(name, vec)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean NotationDeclaredValue::isNotation() const
Packit 8a864e
{
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics *
Packit 8a864e
NotationDeclaredValue::makeSemantics(const TokenizedAttributeValue &value,
Packit 8a864e
				     AttributeContext &context,
Packit 8a864e
				     const StringC &,
Packit 8a864e
				     unsigned &,
Packit 8a864e
				     unsigned &) const
Packit 8a864e
{
Packit 8a864e
  ConstPtr<Notation> notation
Packit 8a864e
    = context.getAttributeNotation(value.string(),
Packit 8a864e
				   value.tokenLocation(0));
Packit 8a864e
  if (notation.isNull()) {
Packit 8a864e
    if (context.validate()) {
Packit 8a864e
      context.setNextLocation(value.tokenLocation(0));
Packit 8a864e
      context.message(ParserMessages::invalidNotationAttribute,
Packit 8a864e
		      StringMessageArg(value.string()));
Packit 8a864e
    }
Packit 8a864e
    return 0;
Packit 8a864e
  }
Packit 8a864e
  return new NotationAttributeSemantics(notation);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void NotationDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  GroupDeclaredValue::buildDesc(desc);
Packit 8a864e
  desc.declaredValue = AttributeDefinitionDesc::notation;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue *NotationDeclaredValue::copy() const
Packit 8a864e
{
Packit 8a864e
  return new NotationDeclaredValue(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
EntityDeclaredValue::EntityDeclaredValue(Boolean isList)
Packit 8a864e
: TokenizedDeclaredValue(entityName, isList)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean EntityDeclaredValue::isEntity() const
Packit 8a864e
{
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics *
Packit 8a864e
EntityDeclaredValue::makeSemantics(const TokenizedAttributeValue &value,
Packit 8a864e
				   AttributeContext &context,
Packit 8a864e
				   const StringC &,
Packit 8a864e
				   unsigned &,
Packit 8a864e
				   unsigned &nEntityNames) const
Packit 8a864e
{
Packit 8a864e
  Boolean valid = 1;
Packit 8a864e
  size_t nTokens = value.nTokens();
Packit 8a864e
  nEntityNames += nTokens;
Packit 8a864e
  Vector<ConstPtr<Entity> > entities(nTokens);
Packit 8a864e
  for (size_t i = 0; i < nTokens; i++) {
Packit 8a864e
    entities[i] = context.getAttributeEntity(value.token(i),
Packit 8a864e
					     value.tokenLocation(i));
Packit 8a864e
    if (entities[i].isNull()) {
Packit 8a864e
      if (context.validate()) {
Packit 8a864e
	context.setNextLocation(value.tokenLocation(i));
Packit 8a864e
	context.message(ParserMessages::invalidEntityAttribute,
Packit 8a864e
		        StringMessageArg(value.token(i)));
Packit 8a864e
      }
Packit 8a864e
      valid = 0;
Packit 8a864e
    }
Packit 8a864e
    else if (!entities[i]->isDataOrSubdoc()) {
Packit 8a864e
      if (context.validate()) {
Packit 8a864e
        context.Messenger::setNextLocation(value.tokenLocation(i));
Packit 8a864e
        context.message(ParserMessages::notDataOrSubdocEntity,
Packit 8a864e
		        StringMessageArg(value.token(i)));
Packit 8a864e
      }
Packit 8a864e
      valid = 0;
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
  if (valid)
Packit 8a864e
    return new EntityAttributeSemantics(entities);
Packit 8a864e
  else
Packit 8a864e
    return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue *EntityDeclaredValue::copy() const
Packit 8a864e
{
Packit 8a864e
  return new EntityDeclaredValue(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
IdDeclaredValue::IdDeclaredValue()
Packit 8a864e
: TokenizedDeclaredValue(name, 0)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean IdDeclaredValue::isId() const
Packit 8a864e
{
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics *
Packit 8a864e
IdDeclaredValue::makeSemantics(const TokenizedAttributeValue &value,
Packit 8a864e
			       AttributeContext &context,
Packit 8a864e
			       const StringC &,
Packit 8a864e
			       unsigned &,
Packit 8a864e
			       unsigned &) const
Packit 8a864e
{
Packit 8a864e
  Location prevLoc;
Packit 8a864e
  if (!context.defineId(value.string(), value.tokenLocation(0), prevLoc)) {
Packit 8a864e
    context.setNextLocation(value.tokenLocation(0));
Packit 8a864e
    context.message(ParserMessages::duplicateId,
Packit 8a864e
		    StringMessageArg(value.string()),
Packit 8a864e
		    prevLoc);
Packit 8a864e
  }
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void IdDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.declaredValue = AttributeDefinitionDesc::id;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue *IdDeclaredValue::copy() const
Packit 8a864e
{
Packit 8a864e
  return new IdDeclaredValue(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
IdrefDeclaredValue::IdrefDeclaredValue(Boolean isList)
Packit 8a864e
: TokenizedDeclaredValue(name, isList)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics *
Packit 8a864e
IdrefDeclaredValue::makeSemantics(const TokenizedAttributeValue &value,
Packit 8a864e
				  AttributeContext &context,
Packit 8a864e
				  const StringC &,
Packit 8a864e
				  unsigned &nIdrefs,
Packit 8a864e
				  unsigned &) const
Packit 8a864e
{
Packit 8a864e
  size_t nTokens = value.nTokens();
Packit 8a864e
  nIdrefs += nTokens;
Packit 8a864e
  for (size_t i = 0; i < nTokens; i++)
Packit 8a864e
    context.noteIdref(value.token(i), value.tokenLocation(i));
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean IdrefDeclaredValue::isIdref() const
Packit 8a864e
{
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void IdrefDeclaredValue::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  TokenizedDeclaredValue::buildDesc(desc);
Packit 8a864e
  if (desc.declaredValue == AttributeDefinitionDesc::name)
Packit 8a864e
    desc.declaredValue = AttributeDefinitionDesc::idref;
Packit 8a864e
  else
Packit 8a864e
    desc.declaredValue = AttributeDefinitionDesc::idrefs;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DeclaredValue *IdrefDeclaredValue::copy() const
Packit 8a864e
{
Packit 8a864e
  return new IdrefDeclaredValue(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Packit 8a864e
AttributeDefinition::AttributeDefinition(const StringC &name,
Packit 8a864e
					 DeclaredValue *value)
Packit 8a864e
: name_(name), declaredValue_(value), implicit_(0), all_(0)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeDefinition::setSpecified(Boolean implicit)
Packit 8a864e
{
Packit 8a864e
  (implicit ? implicit_ : all_) = 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeDefinition::isSpecified(Boolean &implicit)
Packit 8a864e
{
Packit 8a864e
  implicit = implicit_;
Packit 8a864e
  return implicit_ || all_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeDefinition::setOrigName(StringC &origName)
Packit 8a864e
{
Packit 8a864e
  if (&origName != NULL)
Packit 8a864e
    origName.swap(origName_);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinition::~AttributeDefinition()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue *AttributeDefinition::checkValue(AttributeValue *p,
Packit 8a864e
						AttributeContext &) const
Packit 8a864e
{
Packit 8a864e
  return p;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeDefinition::missingValueWouldMatch(const Text &,
Packit 8a864e
						    const AttributeContext &) const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const AttributeValue *
Packit 8a864e
AttributeDefinition::defaultValue(const AttributeValue *) const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeDefinition::getDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.allowedValues.clear();
Packit 8a864e
  desc.defaultValue.clear();
Packit 8a864e
  desc.currentIndex = 0;
Packit 8a864e
  buildDesc(desc);
Packit 8a864e
  declaredValue_->buildDesc(desc);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeDefinition::isConref() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeDefinition::isCurrent() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeDefinition::isFixed() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
RequiredAttributeDefinition::RequiredAttributeDefinition(const StringC &name,
Packit 8a864e
							 DeclaredValue *value)
Packit 8a864e
: AttributeDefinition(name, value)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<AttributeValue>
Packit 8a864e
RequiredAttributeDefinition::makeMissingValue(AttributeContext &context) const
Packit 8a864e
{
Packit 8a864e
  if (context.validate())
Packit 8a864e
    context.message(ParserMessages::requiredAttributeMissing,
Packit 8a864e
		    StringMessageArg(name()));
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void RequiredAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.defaultValueType = AttributeDefinitionDesc::required;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinition *RequiredAttributeDefinition::copy() const
Packit 8a864e
{
Packit 8a864e
  return new RequiredAttributeDefinition(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
CurrentAttributeDefinition::CurrentAttributeDefinition(const StringC &name, DeclaredValue *value, size_t index)
Packit 8a864e
: AttributeDefinition(name, value), currentIndex_(index)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<AttributeValue>
Packit 8a864e
CurrentAttributeDefinition::makeMissingValue(AttributeContext &context) const
Packit 8a864e
{
Packit 8a864e
  if (context.mayDefaultAttribute()) {
Packit 8a864e
    ConstPtr<AttributeValue> currentValue
Packit 8a864e
      = context.getCurrentAttribute(currentIndex_);
Packit 8a864e
    if (currentValue.isNull() && context.validate())
Packit 8a864e
      context.message(ParserMessages::currentAttributeMissing,
Packit 8a864e
		      StringMessageArg(name()));
Packit 8a864e
    return currentValue;
Packit 8a864e
  }
Packit 8a864e
  if (context.validate())
Packit 8a864e
    context.message(ParserMessages::attributeMissing,
Packit 8a864e
		    StringMessageArg(name()));
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean CurrentAttributeDefinition::missingValueWouldMatch(const Text &text,
Packit 8a864e
							   const AttributeContext &context) const
Packit 8a864e
{
Packit 8a864e
  if (!context.mayDefaultAttribute())
Packit 8a864e
    return 0;
Packit 8a864e
  ConstPtr<AttributeValue> currentValue
Packit 8a864e
    = context.getCurrentAttribute(currentIndex_);
Packit 8a864e
  if (currentValue.isNull())
Packit 8a864e
    return 0;
Packit 8a864e
  return text.fixedEqual(*currentValue->text());
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue *
Packit 8a864e
CurrentAttributeDefinition::checkValue(AttributeValue *value,
Packit 8a864e
				       AttributeContext &context) const
Packit 8a864e
{
Packit 8a864e
  context.noteCurrentAttribute(currentIndex_, value);
Packit 8a864e
  return value;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void CurrentAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.defaultValueType = AttributeDefinitionDesc::current;
Packit 8a864e
  desc.currentIndex = currentIndex_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinition *CurrentAttributeDefinition::copy() const
Packit 8a864e
{
Packit 8a864e
  return new CurrentAttributeDefinition(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean CurrentAttributeDefinition::isCurrent() const
Packit 8a864e
{
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ImpliedAttributeDefinition::ImpliedAttributeDefinition(const StringC &name,
Packit 8a864e
						       DeclaredValue *value)
Packit 8a864e
: AttributeDefinition(name, value)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<AttributeValue>
Packit 8a864e
ImpliedAttributeDefinition::makeMissingValue(AttributeContext &context) const
Packit 8a864e
{
Packit 8a864e
  return context.makeImpliedAttributeValue();
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void ImpliedAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.defaultValueType = AttributeDefinitionDesc::implied;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinition *ImpliedAttributeDefinition::copy() const
Packit 8a864e
{
Packit 8a864e
  return new ImpliedAttributeDefinition(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const AttributeValue *
Packit 8a864e
ImpliedAttributeDefinition::defaultValue(const AttributeValue *impliedValue)
Packit 8a864e
     const
Packit 8a864e
{
Packit 8a864e
  return impliedValue;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConrefAttributeDefinition::ConrefAttributeDefinition(const StringC &name,
Packit 8a864e
						     DeclaredValue *value)
Packit 8a864e
: ImpliedAttributeDefinition(name, value)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean ConrefAttributeDefinition::isConref() const
Packit 8a864e
{
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void ConrefAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.defaultValueType = AttributeDefinitionDesc::conref;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinition *ConrefAttributeDefinition::copy() const
Packit 8a864e
{
Packit 8a864e
  return new ConrefAttributeDefinition(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DefaultAttributeDefinition::DefaultAttributeDefinition(const StringC &name,
Packit 8a864e
							DeclaredValue *declaredValue,
Packit 8a864e
							AttributeValue *defaultValue)
Packit 8a864e
: AttributeDefinition(name, declaredValue),
Packit 8a864e
  value_(defaultValue)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<AttributeValue>
Packit 8a864e
DefaultAttributeDefinition::makeMissingValue(AttributeContext &context) const
Packit 8a864e
{
Packit 8a864e
  if (context.mayDefaultAttribute())
Packit 8a864e
    return value_;
Packit 8a864e
  if (context.validate())
Packit 8a864e
    context.message(ParserMessages::attributeMissing,
Packit 8a864e
		    StringMessageArg(name()));
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean DefaultAttributeDefinition::missingValueWouldMatch(const Text &text,
Packit 8a864e
							   const AttributeContext &context) const
Packit 8a864e
{
Packit 8a864e
  return context.mayDefaultAttribute() && text.fixedEqual(*value_->text());
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void DefaultAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  desc.defaultValueType = AttributeDefinitionDesc::defaulted;
Packit 8a864e
  desc.defaultValue = value_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinition *DefaultAttributeDefinition::copy() const
Packit 8a864e
{
Packit 8a864e
  return new DefaultAttributeDefinition(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
FixedAttributeDefinition:: FixedAttributeDefinition(const StringC &name,
Packit 8a864e
						    DeclaredValue *declaredValue,
Packit 8a864e
						    AttributeValue *defaultValue)
Packit 8a864e
: DefaultAttributeDefinition(name, declaredValue, defaultValue)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean FixedAttributeDefinition::isFixed() const
Packit 8a864e
{
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue *FixedAttributeDefinition::checkValue(AttributeValue *value,
Packit 8a864e
						     AttributeContext &context)
Packit 8a864e
     const
Packit 8a864e
{
Packit 8a864e
  const AttributeValue *fixedValue
Packit 8a864e
    = DefaultAttributeDefinition::defaultValue(0);
Packit 8a864e
  if (value && fixedValue && context.validate()) {
Packit 8a864e
    const Text *text;
Packit 8a864e
    const StringC *str;
Packit 8a864e
    const Text *fixedText;
Packit 8a864e
    const StringC *fixedStr;
Packit 8a864e
    switch (value->info(text, str)) {
Packit 8a864e
    case AttributeValue::implied:
Packit 8a864e
      CANNOT_HAPPEN();
Packit 8a864e
    case AttributeValue::cdata:
Packit 8a864e
      if (fixedValue->info(fixedText, fixedStr) == AttributeValue::cdata) {
Packit 8a864e
	if (!text->fixedEqual(*fixedText))
Packit 8a864e
	  context.message(ParserMessages::notFixedValue, StringMessageArg(name()));
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case AttributeValue::tokenized:
Packit 8a864e
      if (fixedValue->info(fixedText, fixedStr) == AttributeValue::tokenized) {
Packit 8a864e
	if (*str != *fixedStr)
Packit 8a864e
	  context.message(ParserMessages::notFixedValue, StringMessageArg(name()));
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
  return value;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void FixedAttributeDefinition::buildDesc(AttributeDefinitionDesc &desc) const
Packit 8a864e
{
Packit 8a864e
  // get the fixed value
Packit 8a864e
  DefaultAttributeDefinition::buildDesc(desc);
Packit 8a864e
  desc.defaultValueType = AttributeDefinitionDesc::fixed;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinition *FixedAttributeDefinition::copy() const
Packit 8a864e
{
Packit 8a864e
  return new FixedAttributeDefinition(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinitionList
Packit 8a864e
::AttributeDefinitionList(Vector<CopyOwner<AttributeDefinition> > &vec,
Packit 8a864e
			  size_t index,
Packit 8a864e
			  Boolean anyCurrent,
Packit 8a864e
			  size_t idIndex,
Packit 8a864e
			  size_t notationIndex)
Packit 8a864e
: index_(index), anyCurrent_(anyCurrent), idIndex_(idIndex),
Packit 8a864e
  notationIndex_(notationIndex)
Packit 8a864e
{
Packit 8a864e
  defs_.swap(vec);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinitionList:: AttributeDefinitionList(const ConstPtr<AttributeDefinitionList> &def)
Packit 8a864e
: prev_(def), index_(size_t(-1))
Packit 8a864e
{
Packit 8a864e
  if (def.isNull()) {
Packit 8a864e
    anyCurrent_ = 0;
Packit 8a864e
    notationIndex_ = size_t(-1);
Packit 8a864e
    idIndex_ = size_t(-1);
Packit 8a864e
  }
Packit 8a864e
  else {
Packit 8a864e
    anyCurrent_ = def->anyCurrent_;
Packit 8a864e
    notationIndex_ = def->notationIndex_;
Packit 8a864e
    idIndex_ = def->idIndex_;
Packit 8a864e
    defs_ = def->defs_;
Packit 8a864e
  }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeDefinitionList::~AttributeDefinitionList() {}
Packit 8a864e
Packit 8a864e
Boolean AttributeDefinitionList::tokenIndex(const StringC &token, unsigned &index) const
Packit 8a864e
{
Packit 8a864e
  for (size_t i = 0; i < defs_.size(); i++)
Packit 8a864e
    if (defs_[i]->containsToken(token)) {
Packit 8a864e
      index = i;
Packit 8a864e
      return 1;
Packit 8a864e
    }
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeDefinitionList::tokenIndexUnique(const StringC &token, unsigned i) const
Packit 8a864e
{
Packit 8a864e
  for (++i; i < defs_.size(); i++)
Packit 8a864e
    if (defs_[i]->containsToken(token))
Packit 8a864e
      return 0;
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Packit 8a864e
Boolean AttributeDefinitionList::attributeIndex(const StringC &name,
Packit 8a864e
						unsigned &index) const
Packit 8a864e
{
Packit 8a864e
  for (size_t i = 0; i < defs_.size(); i++)
Packit 8a864e
    if (defs_[i]->name() == name) {
Packit 8a864e
      index = i;
Packit 8a864e
      return 1;
Packit 8a864e
    }
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeDefinitionList::append(AttributeDefinition *def)
Packit 8a864e
{
Packit 8a864e
  if (def->isId() && idIndex_ == size_t(-1))
Packit 8a864e
    idIndex_ = defs_.size();
Packit 8a864e
  if (def->isNotation() && notationIndex_ == size_t(-1))
Packit 8a864e
    notationIndex_ = defs_.size();
Packit 8a864e
  if (def->isCurrent())
Packit 8a864e
    anyCurrent_ = 1;
Packit 8a864e
  defs_.resize(defs_.size() + 1);
Packit 8a864e
  defs_.back() = def;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics::AttributeSemantics()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics::~AttributeSemantics()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
size_t AttributeSemantics::nEntities() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<Entity> AttributeSemantics::entity(size_t) const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<Notation> AttributeSemantics::notation() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Packit 8a864e
NotationAttributeSemantics::NotationAttributeSemantics(const ConstPtr<Notation> &notation)
Packit 8a864e
: notation_(notation)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<Notation> NotationAttributeSemantics::notation() const
Packit 8a864e
{
Packit 8a864e
  return notation_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics *NotationAttributeSemantics::copy() const
Packit 8a864e
{
Packit 8a864e
  return new NotationAttributeSemantics(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
EntityAttributeSemantics::EntityAttributeSemantics(Vector<ConstPtr<Entity> > &entity)
Packit 8a864e
{
Packit 8a864e
  entity.swap(entity_);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
size_t EntityAttributeSemantics::nEntities() const
Packit 8a864e
{
Packit 8a864e
  return entity_.size();
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<Entity> EntityAttributeSemantics::entity(size_t i) const
Packit 8a864e
{
Packit 8a864e
  return entity_[i];
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics *EntityAttributeSemantics::copy() const
Packit 8a864e
{
Packit 8a864e
  return new EntityAttributeSemantics(*this);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue::AttributeValue()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue::~AttributeValue()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics *AttributeValue::makeSemantics(const DeclaredValue *,
Packit 8a864e
						  AttributeContext &,
Packit 8a864e
						  const StringC &,
Packit 8a864e
						  unsigned &,
Packit 8a864e
						  unsigned &) const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const Text *AttributeValue::text() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeValue::recoverUnquoted(const StringC &, const Location &,
Packit 8a864e
					AttributeContext &, const StringC &)
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ImpliedAttributeValue::ImpliedAttributeValue()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue::Type ImpliedAttributeValue::info(const Text *&,
Packit 8a864e
						 const StringC *&) const
Packit 8a864e
{
Packit 8a864e
  return implied;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
TokenizedAttributeValue::TokenizedAttributeValue(Text &text,
Packit 8a864e
						 const Vector<size_t> &spaceIndex)
Packit 8a864e
: spaceIndex_(spaceIndex)
Packit 8a864e
{
Packit 8a864e
  text.swap(text_);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue::Type TokenizedAttributeValue::info(const Text *&,
Packit 8a864e
						   const StringC *&string) const
Packit 8a864e
{
Packit 8a864e
  string = &text_.string();
Packit 8a864e
  return tokenized;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const Text *TokenizedAttributeValue::text() const
Packit 8a864e
{
Packit 8a864e
  return &text_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeSemantics *
Packit 8a864e
TokenizedAttributeValue::makeSemantics(const DeclaredValue *value,
Packit 8a864e
				       AttributeContext &context,
Packit 8a864e
				       const StringC &name,
Packit 8a864e
				       unsigned &nIdrefs,
Packit 8a864e
				       unsigned &nEntityNames) const
Packit 8a864e
{
Packit 8a864e
  if (text_.size() == 0)
Packit 8a864e
    return 0;
Packit 8a864e
  return value->makeSemantics(*this, context, name, nIdrefs, nEntityNames);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
CdataAttributeValue::CdataAttributeValue(Text &text)
Packit 8a864e
{
Packit 8a864e
  text.swap(text_);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeValue::Type CdataAttributeValue::info(const Text *&text,
Packit 8a864e
					       const StringC *&) const
Packit 8a864e
{
Packit 8a864e
  text = &text_;
Packit 8a864e
  return cdata;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const Text *CdataAttributeValue::text() const
Packit 8a864e
{
Packit 8a864e
  return &text_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean CdataAttributeValue::recoverUnquoted(const StringC &str,
Packit 8a864e
					     const Location &strLoc,
Packit 8a864e
					     AttributeContext &context,
Packit 8a864e
					     const StringC &)
Packit 8a864e
{
Packit 8a864e
  TextIter iter(text_);
Packit 8a864e
  TextItem::Type type;
Packit 8a864e
  const Char *s;
Packit 8a864e
  size_t len;
Packit 8a864e
  const Location *loc;
Packit 8a864e
  if (iter.next(type, s, len, loc)
Packit 8a864e
      && type == TextItem::data
Packit 8a864e
      && len == text_.size()
Packit 8a864e
      && loc->origin().pointer() == strLoc.origin().pointer()
Packit 8a864e
      && loc->index() + len == strLoc.index()
Packit 8a864e
      && !iter.next(type, s, len, loc)) {
Packit 8a864e
    text_.addChars(str, strLoc);
Packit 8a864e
    context.Messenger::setNextLocation(strLoc);
Packit 8a864e
    context.message(ParserMessages::unquotedAttributeValue);
Packit 8a864e
    return 1;
Packit 8a864e
  }
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const Notation *CdataAttributeValue::notation() const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
DataAttributeValue::DataAttributeValue(Text &text,
Packit 8a864e
                                       const ConstPtr<Notation> &nt,
Packit 8a864e
                                       const AttributeList &attributes)
Packit 8a864e
: CdataAttributeValue(text), notation_(nt), attributes_(&attributes)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const AttributeList &DataAttributeValue::attributes() const
Packit 8a864e
{
Packit 8a864e
  return *attributes_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const Notation *DataAttributeValue::notation() const
Packit 8a864e
{
Packit 8a864e
  return notation_.pointer();
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Attribute::Attribute()
Packit 8a864e
: specIndexPlus_(0)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Attribute::Attribute(const Attribute& x)
Packit 8a864e
	: specIndexPlus_(x.specIndexPlus_),
Packit 8a864e
	  value_(x.value_),
Packit 8a864e
	  semantics_(x.semantics_)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Attribute::~Attribute()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Attribute& Attribute::operator=(const Attribute& x)
Packit 8a864e
{
Packit 8a864e
  if (this != &x) {
Packit 8a864e
    specIndexPlus_ = x.specIndexPlus_;
Packit 8a864e
    value_ = x.value_;
Packit 8a864e
    semantics_ = x.semantics_;
Packit 8a864e
  }
Packit 8a864e
  return *this;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void Attribute::clear()
Packit 8a864e
{
Packit 8a864e
  specIndexPlus_ = 0;
Packit 8a864e
  value_.clear();
Packit 8a864e
  semantics_.clear();
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeList::AttributeList(const ConstPtr<AttributeDefinitionList> &def)
Packit 8a864e
: def_(def), vec_(def.isNull() ? 0 : def->size()), nSpec_(0), conref_(0),
Packit 8a864e
  nIdrefs_(0), nEntityNames_(0)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeList::AttributeList()
Packit 8a864e
: nSpec_(0), conref_(0)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeList::init(const ConstPtr<AttributeDefinitionList> &def)
Packit 8a864e
{
Packit 8a864e
  def_ = def;
Packit 8a864e
  nSpec_ = 0;
Packit 8a864e
  conref_ = 0;
Packit 8a864e
  nIdrefs_ = 0;
Packit 8a864e
  nEntityNames_ = 0;
Packit 8a864e
  if (def_.isNull())
Packit 8a864e
    vec_.resize(0);
Packit 8a864e
  else {
Packit 8a864e
    size_t newLength = def_->size();
Packit 8a864e
    size_t clearLim = vec_.size();
Packit 8a864e
    if (clearLim > newLength)
Packit 8a864e
      clearLim = newLength;
Packit 8a864e
    vec_.resize(newLength);
Packit 8a864e
    for (size_t i = 0; i < clearLim; i++)
Packit 8a864e
      vec_[i].clear();
Packit 8a864e
  }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeList::changeDef(const ConstPtr<AttributeDefinitionList> &def)
Packit 8a864e
{
Packit 8a864e
  vec_.resize(def.isNull() ? 0 : def->size());
Packit 8a864e
  def_ = def;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeList::swap(AttributeList &to)
Packit 8a864e
{
Packit 8a864e
  vec_.swap(to.vec_);
Packit 8a864e
  def_.swap(to.def_);
Packit 8a864e
  {
Packit 8a864e
    unsigned tem = to.nIdrefs_;
Packit 8a864e
    to.nIdrefs_ = nIdrefs_;
Packit 8a864e
    nIdrefs_ = tem;
Packit 8a864e
  }
Packit 8a864e
  {
Packit 8a864e
    unsigned tem = to.nEntityNames_;
Packit 8a864e
    to.nEntityNames_ = nEntityNames_;
Packit 8a864e
    nEntityNames_ = tem;
Packit 8a864e
  }
Packit 8a864e
  {
Packit 8a864e
    size_t tem = to.nSpec_;
Packit 8a864e
    to.nSpec_ = nSpec_;
Packit 8a864e
    nSpec_ = tem;
Packit 8a864e
  }
Packit 8a864e
  {
Packit 8a864e
    PackedBoolean tem = to.conref_;
Packit 8a864e
    to.conref_ = conref_;
Packit 8a864e
    conref_ = tem;
Packit 8a864e
  }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeList::finish(AttributeContext &context)
Packit 8a864e
{
Packit 8a864e
  for (size_t i = 0; i < vec_.size(); i++)
Packit 8a864e
    if (!vec_[i].specified()) {
Packit 8a864e
      ConstPtr<AttributeValue> value
Packit 8a864e
	= def(i)->makeMissingValue(context);
Packit 8a864e
      if (!conref_ || def_->notationIndex() != i) {
Packit 8a864e
	vec_[i].setValue(value);
Packit 8a864e
        if (!value.isNull())
Packit 8a864e
      	  vec_[i].setSemantics(def(i)->makeSemantics(value.pointer(),
Packit 8a864e
						     context,
Packit 8a864e
						     nIdrefs_,
Packit 8a864e
						     nEntityNames_));
Packit 8a864e
      }
Packit 8a864e
    }
Packit 8a864e
  const Syntax &syntax = context.attributeSyntax();
Packit 8a864e
  if (nIdrefs_ > syntax.grpcnt())
Packit 8a864e
    context.message(ParserMessages::idrefGrpcnt,
Packit 8a864e
		   NumberMessageArg(syntax.grpcnt()));
Packit 8a864e
  if (nEntityNames_ > syntax.grpcnt())
Packit 8a864e
    context.message(ParserMessages::entityNameGrpcnt,
Packit 8a864e
		   NumberMessageArg(syntax.grpcnt()));
Packit 8a864e
  if (context.validate()
Packit 8a864e
      && conref_
Packit 8a864e
      && def_->notationIndex() != size_t(-1)
Packit 8a864e
      && specified(def_->notationIndex()))
Packit 8a864e
    context.message(ParserMessages::conrefNotation);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeList::setSpec(unsigned i, AttributeContext &context)
Packit 8a864e
{
Packit 8a864e
  if (vec_[i].specified())
Packit 8a864e
    context.message(ParserMessages::duplicateAttributeSpec,
Packit 8a864e
		   StringMessageArg(def(i)->name()));
Packit 8a864e
  else
Packit 8a864e
    vec_[i].setSpec(nSpec_++);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeList::noteInvalidSpec()
Packit 8a864e
{
Packit 8a864e
  // This is needed for error recovery.
Packit 8a864e
  // We don't want nSpec_ to be > 0, if there is no attribute definition.
Packit 8a864e
  if (nSpec_)
Packit 8a864e
    nSpec_++;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeList::setValue(unsigned i, Text &text,
Packit 8a864e
				AttributeContext &context,
Packit 8a864e
				unsigned &specLength)
Packit 8a864e
{
Packit 8a864e
  AttributeValue *value = def(i)->makeValue(text, context, specLength);
Packit 8a864e
  if (def(i)->isConref())
Packit 8a864e
    conref_ = 1;
Packit 8a864e
  vec_[i].setValue(value);
Packit 8a864e
  if (value)
Packit 8a864e
    vec_[i].setSemantics(def(i)->makeSemantics(value, context,
Packit 8a864e
					       nIdrefs_, nEntityNames_));
Packit 8a864e
  else if (AttributeValue::handleAsUnterminated(text, context))
Packit 8a864e
    return 0;
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeList::setValueToken(unsigned i, Text &text,
Packit 8a864e
				  AttributeContext &context,
Packit 8a864e
				  unsigned &specLength)
Packit 8a864e
{
Packit 8a864e
  AttributeValue *value = def(i)->makeValueFromToken(text, context,
Packit 8a864e
						     specLength);
Packit 8a864e
  if (def(i)->isConref())
Packit 8a864e
    conref_ = 1;
Packit 8a864e
  vec_[i].setValue(value);
Packit 8a864e
  if (value)
Packit 8a864e
    vec_[i].setSemantics(def(i)->makeSemantics(value, context,
Packit 8a864e
					       nIdrefs_, nEntityNames_));
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
const StringC *AttributeList::getId() const
Packit 8a864e
{
Packit 8a864e
  // Check for no attributes
Packit 8a864e
  if (def_.isNull())
Packit 8a864e
    return 0;
Packit 8a864e
  // Check for no ID declared
Packit 8a864e
  size_t i = def_->idIndex();
Packit 8a864e
  if (i == size_t(-1))
Packit 8a864e
    return 0;
Packit 8a864e
  // Check for invalid value
Packit 8a864e
  const AttributeValue *v = value(i);
Packit 8a864e
  if (!v)
Packit 8a864e
    return 0;
Packit 8a864e
  // Check for implied value
Packit 8a864e
  const Text *t = v->text();
Packit 8a864e
  if (!t)
Packit 8a864e
    return 0;
Packit 8a864e
  return &t->string();
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeList::recoverUnquoted(const StringC &str,
Packit 8a864e
				       const Location &strLoc,
Packit 8a864e
				       AttributeContext &context)
Packit 8a864e
{
Packit 8a864e
  if (nSpec_ > 0) {
Packit 8a864e
    for (size_t i = 0; i < vec_.size(); i++)
Packit 8a864e
      if (vec_[i].specified() && vec_[i].specIndex() == nSpec_ - 1) {
Packit 8a864e
	const AttributeValue *val = vec_[i].value();
Packit 8a864e
	if (val)
Packit 8a864e
	  // I wish I could avoid casting away const here.
Packit 8a864e
	  return ((AttributeValue *)val)->recoverUnquoted(str, strLoc, context,
Packit 8a864e
							  name(i));
Packit 8a864e
	break;
Packit 8a864e
      }
Packit 8a864e
    return 1;
Packit 8a864e
  }
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeList::handleAsUnterminated(AttributeContext &context)
Packit 8a864e
{
Packit 8a864e
  if (nSpec_ > 0) {
Packit 8a864e
    for (size_t i = 0; i < vec_.size(); i++) {
Packit 8a864e
      if (vec_[i].specified() && vec_[i].specIndex() == nSpec_ - 1) {
Packit 8a864e
	const AttributeValue *val = vec_[i].value();
Packit 8a864e
	const Text *ptr;
Packit 8a864e
	if (val && (ptr = val->text()) != 0
Packit 8a864e
	    && AttributeValue::handleAsUnterminated(*ptr, context))
Packit 8a864e
	  return 1;
Packit 8a864e
	break;
Packit 8a864e
      }
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
// This tries to guess this attribute value looks like if it had
Packit 8a864e
// a missing ending quote.
Packit 8a864e
Packit 8a864e
Boolean AttributeValue::handleAsUnterminated(const Text &text,
Packit 8a864e
					     AttributeContext &context)
Packit 8a864e
{
Packit 8a864e
  TextIter iter(text);
Packit 8a864e
  const Char *lastStr = 0;
Packit 8a864e
  size_t lastLen;
Packit 8a864e
  Location startLoc;
Packit 8a864e
  const Location *loc;
Packit 8a864e
  TextItem::Type type;
Packit 8a864e
  const Char *str;
Packit 8a864e
  size_t len;
Packit 8a864e
  while (iter.next(type, str, len, loc)) {
Packit 8a864e
    if (startLoc.origin().isNull() && !loc->origin().isNull())
Packit 8a864e
      startLoc = *loc;
Packit 8a864e
    switch (type) {
Packit 8a864e
    case TextItem::data:
Packit 8a864e
      if (len != 1 || *str != context.attributeSyntax().space()) {
Packit 8a864e
	lastStr = str;
Packit 8a864e
	lastLen = len;
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case TextItem::endDelim:
Packit 8a864e
    case TextItem::endDelimA:
Packit 8a864e
    case TextItem::ignore:
Packit 8a864e
      break;
Packit 8a864e
    default:
Packit 8a864e
      lastStr = 0;
Packit 8a864e
      break;
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
  if (lastStr) {
Packit 8a864e
    while (lastLen > 0
Packit 8a864e
	   && lastStr[lastLen - 1] == context.attributeSyntax().space())
Packit 8a864e
      lastLen--;
Packit 8a864e
    const StringC &vi = context.attributeSyntax().delimGeneral(Syntax::dVI);
Packit 8a864e
    if (lastLen >= vi.size()
Packit 8a864e
	&& (vi
Packit 8a864e
	    == StringC(lastStr + (lastLen - vi.size()), vi.size()))) {
Packit 8a864e
      context.Messenger::setNextLocation(startLoc);
Packit 8a864e
      context.message(ParserMessages::literalClosingDelimiter);
Packit 8a864e
      return 1;
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeContext::AttributeContext()
Packit 8a864e
: mayDefaultAttribute_(0), validate_(1)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
AttributeContext::~AttributeContext()
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean AttributeContext::defineId(const StringC &, const Location &,
Packit 8a864e
				   Location &)
Packit 8a864e
{
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeContext::noteIdref(const StringC &, const Location &)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void AttributeContext::noteCurrentAttribute(size_t, AttributeValue *)
Packit 8a864e
{
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<AttributeValue> AttributeContext::getCurrentAttribute(size_t) const
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<Entity> AttributeContext::getAttributeEntity(const StringC &,
Packit 8a864e
						      const Location &)
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<Notation> AttributeContext::getAttributeNotation(const StringC &,
Packit 8a864e
							  const Location &)
Packit 8a864e
{
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ConstPtr<AttributeValue> AttributeContext::makeImpliedAttributeValue()
Packit 8a864e
{
Packit 8a864e
  if (impliedAttributeValue_.isNull())
Packit 8a864e
    impliedAttributeValue_ = new ImpliedAttributeValue;
Packit 8a864e
  return impliedAttributeValue_;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
#ifdef SP_NAMESPACE
Packit 8a864e
}
Packit 8a864e
#endif