Blame lib/parseParam.cxx

Packit 8a864e
// Copyright (c) 1994 James Clark
Packit 8a864e
// See the file COPYING for copying permission.
Packit 8a864e
Packit 8a864e
#include "splib.h"
Packit 8a864e
#include "Parser.h"
Packit 8a864e
#include "Param.h"
Packit 8a864e
#include "Group.h"
Packit 8a864e
#include "Markup.h"
Packit 8a864e
#include "ParserMessages.h"
Packit 8a864e
#include "MessageArg.h"
Packit 8a864e
#include "TokenMessageArg.h"
Packit 8a864e
#include "token.h"
Packit 8a864e
#include "macros.h"
Packit 8a864e
Packit 8a864e
#ifdef SP_NAMESPACE
Packit 8a864e
namespace SP_NAMESPACE {
Packit 8a864e
#endif
Packit 8a864e
Packit 8a864e
Boolean Parser::parseParam(const AllowedParams &allow,
Packit 8a864e
			   unsigned declInputLevel,
Packit 8a864e
			   Param &parm)
Packit 8a864e
{
Packit 8a864e
  for (;;) {
Packit 8a864e
    Token token = getToken(allow.mainMode());
Packit 8a864e
    switch (token) {
Packit 8a864e
    case tokenUnrecognized:
Packit 8a864e
      if (reportNonSgmlCharacter())
Packit 8a864e
	break;
Packit 8a864e
      {
Packit 8a864e
	message(ParserMessages::markupDeclarationCharacter,
Packit 8a864e
		StringMessageArg(currentToken()),
Packit 8a864e
		AllowedParamsMessageArg(allow, syntaxPointer()));
Packit 8a864e
      }
Packit 8a864e
      return 0;
Packit 8a864e
    case tokenEe:
Packit 8a864e
      if (inputLevel() <= declInputLevel) {
Packit 8a864e
	message(ParserMessages::declarationLevel);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addEntityEnd();
Packit 8a864e
      popInputStack();
Packit 8a864e
      break;
Packit 8a864e
    case tokenCom:
Packit 8a864e
      if (!parseComment(comMode))
Packit 8a864e
	return 0;
Packit 8a864e
      if (options().warnPsComment)
Packit 8a864e
	message(ParserMessages::psComment);
Packit 8a864e
      break;
Packit 8a864e
    case tokenDso:
Packit 8a864e
      if (!allow.dso()) {
Packit 8a864e
	paramInvalidToken(tokenDso, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dDSO);
Packit 8a864e
      parm.type = Param::dso;
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenGrpo:
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dGRPO);
Packit 8a864e
      switch (allow.group()) {
Packit 8a864e
      case Param::invalid:
Packit 8a864e
	paramInvalidToken(tokenGrpo, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      case Param::modelGroup:
Packit 8a864e
	{
Packit 8a864e
	  ModelGroup *group;
Packit 8a864e
	  if (!parseModelGroup(1, declInputLevel, group, grpsufMode))
Packit 8a864e
	    return 0;
Packit 8a864e
	  parm.type = Param::modelGroup;
Packit 8a864e
	  parm.modelGroupPtr = group;
Packit 8a864e
	}
Packit 8a864e
	break;
Packit 8a864e
      case Param::nameGroup:
Packit 8a864e
	if (!parseNameGroup(declInputLevel, parm))
Packit 8a864e
	  return 0;
Packit 8a864e
	break;
Packit 8a864e
      case Param::nameTokenGroup:
Packit 8a864e
	if (!parseNameTokenGroup(declInputLevel, parm))
Packit 8a864e
	  return 0;
Packit 8a864e
	break;
Packit 8a864e
      default:
Packit 8a864e
	CANNOT_HAPPEN();
Packit 8a864e
      }
Packit 8a864e
      parm.type = allow.group();
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenLita:
Packit 8a864e
    case tokenLit:
Packit 8a864e
      parm.type = allow.literal();
Packit 8a864e
      parm.lita = token == tokenLita;
Packit 8a864e
      switch (allow.literal()) {
Packit 8a864e
      case Param::invalid:
Packit 8a864e
	paramInvalidToken(token, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      case Param::minimumLiteral:
Packit 8a864e
	if (!parseMinimumLiteral(parm.lita, parm.literalText))
Packit 8a864e
	  return 0;
Packit 8a864e
	break;
Packit 8a864e
      case Param::attributeValueLiteral:
Packit 8a864e
	if (!parseAttributeValueLiteral(parm.lita, parm.literalText))
Packit 8a864e
	  return 0;
Packit 8a864e
	break;
Packit 8a864e
      case Param::tokenizedAttributeValueLiteral:
Packit 8a864e
	if (!parseTokenizedAttributeValueLiteral(parm.lita, parm.literalText))
Packit 8a864e
	  return 0;
Packit 8a864e
	break;
Packit 8a864e
      case Param::systemIdentifier:
Packit 8a864e
	if (!parseSystemIdentifier(parm.lita, parm.literalText))
Packit 8a864e
	  return 0;
Packit 8a864e
	break;
Packit 8a864e
      case Param::paramLiteral:
Packit 8a864e
	if (!parseParameterLiteral(parm.lita, parm.literalText))
Packit 8a864e
	  return 0;
Packit 8a864e
	break;
Packit 8a864e
      }
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addLiteral(parm.literalText);
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenMdc:
Packit 8a864e
      if (!allow.mdc()) {
Packit 8a864e
	paramInvalidToken(tokenMdc, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      if (inputLevel() > declInputLevel)
Packit 8a864e
	message(ParserMessages::parameterEntityNotEnded);
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dMDC);
Packit 8a864e
      parm.type = Param::mdc;
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenMinus:
Packit 8a864e
      parm.type = Param::minus;
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dMINUS);
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenMinusGrpo:
Packit 8a864e
      if (!allow.exclusions()) {
Packit 8a864e
	paramInvalidToken(tokenMinusGrpo, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      if (currentMarkup()) {
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dMINUS);
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dGRPO);
Packit 8a864e
      }
Packit 8a864e
      parm.type = Param::exclusions;
Packit 8a864e
      return parseElementNameGroup(declInputLevel, parm);
Packit 8a864e
    case tokenPero:
Packit 8a864e
      parm.type = Param::pero;
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dPERO);
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenPeroGrpo:
Packit 8a864e
      if (!inInstance())
Packit 8a864e
	message(ParserMessages::peroGrpoProlog);
Packit 8a864e
      // fall through
Packit 8a864e
    case tokenPeroNameStart:
Packit 8a864e
      {
Packit 8a864e
	if (inInstance()) {
Packit 8a864e
	  if (options().warnInstanceParamEntityRef)
Packit 8a864e
	    message(ParserMessages::instanceParamEntityRef);
Packit 8a864e
	}
Packit 8a864e
	else {
Packit 8a864e
	  if (options().warnInternalSubsetPsParamEntityRef && inputLevel() == 1)
Packit 8a864e
	    message(ParserMessages::internalSubsetPsParamEntityRef);
Packit 8a864e
	}
Packit 8a864e
	ConstPtr<Entity> entity;
Packit 8a864e
	Ptr<EntityOrigin> origin;
Packit 8a864e
	if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))
Packit 8a864e
	  return 0;
Packit 8a864e
	if (!entity.isNull())
Packit 8a864e
	  entity->declReference(*this, origin);
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case tokenPlusGrpo:
Packit 8a864e
      if (!allow.inclusions()) {
Packit 8a864e
	paramInvalidToken(tokenPlusGrpo, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      if (currentMarkup()) {
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dPLUS);
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dGRPO);
Packit 8a864e
      }
Packit 8a864e
      parm.type = Param::inclusions;
Packit 8a864e
      return parseElementNameGroup(declInputLevel, parm);
Packit 8a864e
    case tokenRni:
Packit 8a864e
      if (!allow.rni()) {
Packit 8a864e
	paramInvalidToken(tokenRni, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      return parseIndicatedReservedName(allow, parm);
Packit 8a864e
    case tokenS:
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addS(currentChar());
Packit 8a864e
      break;
Packit 8a864e
    case tokenNameStart:
Packit 8a864e
      switch (allow.nameStart()) {
Packit 8a864e
      case Param::invalid:
Packit 8a864e
	paramInvalidToken(tokenNameStart, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      case Param::reservedName:
Packit 8a864e
	return parseReservedName(allow, parm);
Packit 8a864e
      case Param::name:
Packit 8a864e
        {
Packit 8a864e
	extendNameToken(syntax().namelen(), ParserMessages::nameLength);
Packit 8a864e
	parm.type = Param::name;
Packit 8a864e
        getCurrentToken(parm.origToken);
Packit 8a864e
        parm.token = StringC(parm.origToken);
Packit 8a864e
        const SubstTable *subst = syntax().generalSubstTable();
Packit 8a864e
        StringC::iterator s = parm.token.begin();
Packit 8a864e
        size_t count = parm.token.size();
Packit 8a864e
        const Char *tokenData = parm.token.data();
Packit 8a864e
        for (; count > 0; --count)
Packit 8a864e
          *s++ = (*subst)[*tokenData++];
Packit 8a864e
	if (currentMarkup())
Packit 8a864e
	  currentMarkup()->addName(currentInput());
Packit 8a864e
	return 1;
Packit 8a864e
        }
Packit 8a864e
      case Param::entityName:
Packit 8a864e
	extendNameToken(syntax().namelen(), ParserMessages::nameLength);
Packit 8a864e
	parm.type = Param::entityName;
Packit 8a864e
	getCurrentToken(syntax().entitySubstTable(), parm.token);
Packit 8a864e
	if (currentMarkup())
Packit 8a864e
	  currentMarkup()->addName(currentInput());
Packit 8a864e
	return 1;
Packit 8a864e
      case Param::paramEntityName:
Packit 8a864e
	extendNameToken(syntax().penamelen(),
Packit 8a864e
			ParserMessages::parameterEntityNameLength);
Packit 8a864e
	parm.type = Param::paramEntityName;
Packit 8a864e
	getCurrentToken(syntax().entitySubstTable(), parm.token);
Packit 8a864e
	if (currentMarkup())
Packit 8a864e
	  currentMarkup()->addName(currentInput());
Packit 8a864e
	return 1;
Packit 8a864e
      case Param::attributeValue:
Packit 8a864e
	return parseAttributeValueParam(parm);
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case tokenDigit:
Packit 8a864e
      switch (allow.digit()) {
Packit 8a864e
      case Param::invalid:
Packit 8a864e
	paramInvalidToken(tokenDigit, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      case Param::number:
Packit 8a864e
	extendNumber(syntax().namelen(), ParserMessages::numberLength);
Packit 8a864e
	parm.type = Param::number;
Packit 8a864e
	getCurrentToken(parm.token);
Packit 8a864e
	if (currentMarkup())
Packit 8a864e
	  currentMarkup()->addNumber(currentInput());
Packit 8a864e
	return 1;
Packit 8a864e
      case Param::attributeValue:
Packit 8a864e
	return parseAttributeValueParam(parm);
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case tokenLcUcNmchar:
Packit 8a864e
      switch (allow.nmchar()) {
Packit 8a864e
      case Param::invalid:
Packit 8a864e
	paramInvalidToken(tokenLcUcNmchar, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      case Param::attributeValue:
Packit 8a864e
	return parseAttributeValueParam(parm);
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    default:
Packit 8a864e
      CANNOT_HAPPEN();
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void Parser::paramInvalidToken(Token token, const AllowedParams &allow)
Packit 8a864e
{
Packit 8a864e
  if (!allow.silent())
Packit 8a864e
    message(ParserMessages::paramInvalidToken,
Packit 8a864e
	    TokenMessageArg(token, allow.mainMode(),
Packit 8a864e
			    syntaxPointer(), sdPointer()),
Packit 8a864e
	    AllowedParamsMessageArg(allow, syntaxPointer()));
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseGroupToken(const AllowedGroupTokens &allow,
Packit 8a864e
				unsigned nestingLevel,
Packit 8a864e
				unsigned declInputLevel,
Packit 8a864e
				unsigned groupInputLevel,
Packit 8a864e
				GroupToken &gt)
Packit 8a864e
{
Packit 8a864e
  for (;;) {
Packit 8a864e
    Token token = getToken(grpMode);
Packit 8a864e
    switch (token) {
Packit 8a864e
    case tokenEe:
Packit 8a864e
      if (inputLevel() <= groupInputLevel) {
Packit 8a864e
	message(ParserMessages::groupLevel);
Packit 8a864e
	if (inputLevel() <= declInputLevel)
Packit 8a864e
	  return 0;
Packit 8a864e
      }
Packit 8a864e
      else if (!sd().www())
Packit 8a864e
	message(ParserMessages::groupEntityEnd);
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addEntityEnd();
Packit 8a864e
      popInputStack();
Packit 8a864e
      break;
Packit 8a864e
    case tokenPeroGrpo:
Packit 8a864e
      {
Packit 8a864e
	if (!inInstance())
Packit 8a864e
	  message(ParserMessages::peroGrpoProlog);
Packit 8a864e
	Boolean start;
Packit 8a864e
	if (inTag(start))
Packit 8a864e
	    message(start
Packit 8a864e
		    ? ParserMessages::peroGrpoStartTag
Packit 8a864e
		    : ParserMessages::peroGrpoEndTag);
Packit 8a864e
	// fall through
Packit 8a864e
      }
Packit 8a864e
    case tokenPeroNameStart:
Packit 8a864e
      {
Packit 8a864e
	if (options().warnInternalSubsetTsParamEntityRef && inputLevel() == 1)
Packit 8a864e
	  message(ParserMessages::internalSubsetTsParamEntityRef);
Packit 8a864e
	ConstPtr<Entity> entity;
Packit 8a864e
	Ptr<EntityOrigin> origin;
Packit 8a864e
	if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))
Packit 8a864e
	  return 0;
Packit 8a864e
	if (!entity.isNull())
Packit 8a864e
	  entity->declReference(*this, origin);
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case tokenUnrecognized:
Packit 8a864e
      if (reportNonSgmlCharacter())
Packit 8a864e
	break;
Packit 8a864e
      {
Packit 8a864e
	message(ParserMessages::groupCharacter,
Packit 8a864e
		StringMessageArg(currentToken()),
Packit 8a864e
		AllowedGroupTokensMessageArg(allow, syntaxPointer()));
Packit 8a864e
      }
Packit 8a864e
      return 0;
Packit 8a864e
    case tokenDtgo:
Packit 8a864e
      if (!allow.groupToken(GroupToken::dataTagGroup)) {
Packit 8a864e
	groupTokenInvalidToken(tokenDtgo, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      if (sd().datatag())
Packit 8a864e
	message(ParserMessages::datatagNotImplemented);
Packit 8a864e
      if (!defDtd().isBase())
Packit 8a864e
	message(ParserMessages::datatagBaseDtd);
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dDTGO);
Packit 8a864e
      return parseDataTagGroup(nestingLevel + 1, declInputLevel, gt);
Packit 8a864e
    case tokenGrpo:
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dGRPO);
Packit 8a864e
      switch (allow.group()) {
Packit 8a864e
      case GroupToken::modelGroup:
Packit 8a864e
	{
Packit 8a864e
	  ModelGroup *modelGroup;
Packit 8a864e
	  if (!parseModelGroup(nestingLevel + 1, declInputLevel, modelGroup,
Packit 8a864e
			       grpMode))
Packit 8a864e
	    return 0;
Packit 8a864e
	  gt.model = modelGroup;
Packit 8a864e
	  gt.type = GroupToken::modelGroup;
Packit 8a864e
	  return 1;
Packit 8a864e
	}
Packit 8a864e
      case GroupToken::dataTagTemplateGroup:
Packit 8a864e
	return parseDataTagTemplateGroup(nestingLevel + 1, declInputLevel, gt);
Packit 8a864e
      default:
Packit 8a864e
	groupTokenInvalidToken(tokenGrpo, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case tokenRni:
Packit 8a864e
      if (!allow.groupToken(GroupToken::pcdata)
Packit 8a864e
          && !allow.groupToken(GroupToken::all)
Packit 8a864e
          && !allow.groupToken(GroupToken::implicit)) {
Packit 8a864e
	groupTokenInvalidToken(tokenRni, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      Syntax::ReservedName rn;
Packit 8a864e
      if (!getIndicatedReservedName(&rn))
Packit 8a864e
	return 0;
Packit 8a864e
      if (rn == Syntax::rPCDATA && allow.groupToken(GroupToken::pcdata)) {
Packit 8a864e
        gt.type = GroupToken::pcdata;
Packit 8a864e
        gt.contentToken = new PcdataToken;
Packit 8a864e
        return 1;
Packit 8a864e
      }
Packit 8a864e
      else if (rn == Syntax::rALL && allow.groupToken(GroupToken::all)) {
Packit 8a864e
        message(ParserMessages::sorryAllImplicit);
Packit 8a864e
        return 0;
Packit 8a864e
      }
Packit 8a864e
      else if (rn == Syntax::rIMPLICIT && allow.groupToken(GroupToken::implicit)) {
Packit 8a864e
        message(ParserMessages::sorryAllImplicit);
Packit 8a864e
        return 0;
Packit 8a864e
      }
Packit 8a864e
      else {
Packit 8a864e
        StringC token(syntax().delimGeneral(Syntax::dRNI));
Packit 8a864e
        token += syntax().reservedName(rn);
Packit 8a864e
        message(ParserMessages::invalidToken, StringMessageArg(token));
Packit 8a864e
        return 0;
Packit 8a864e
      }
Packit 8a864e
    case tokenS:
Packit 8a864e
      if (currentMarkup()) {
Packit 8a864e
	extendS();
Packit 8a864e
	currentMarkup()->addS(currentInput());
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case tokenNameStart:
Packit 8a864e
      switch (allow.nameStart()) {
Packit 8a864e
      case GroupToken::elementToken:
Packit 8a864e
	{
Packit 8a864e
	  extendNameToken(syntax().namelen(), ParserMessages::nameLength);
Packit 8a864e
	  gt.type = GroupToken::elementToken;
Packit 8a864e
	  StringC &buffer = nameBuffer();
Packit 8a864e
	  getCurrentToken(syntax().generalSubstTable(), buffer);
Packit 8a864e
	  if (currentMarkup())
Packit 8a864e
	    currentMarkup()->addName(currentInput());
Packit 8a864e
	  const ElementType *e = lookupCreateElement(buffer);
Packit 8a864e
	  ContentToken::OccurrenceIndicator oi
Packit 8a864e
	    = getOccurrenceIndicator(grpMode);
Packit 8a864e
	  gt.contentToken = new ElementToken(e, oi);
Packit 8a864e
	  return 1;
Packit 8a864e
	}
Packit 8a864e
      case GroupToken::name:
Packit 8a864e
      case GroupToken::nameToken:
Packit 8a864e
	extendNameToken(syntax().namelen(),
Packit 8a864e
			token == GroupToken::name
Packit 8a864e
			? ParserMessages::nameLength
Packit 8a864e
			: ParserMessages::nameTokenLength);
Packit 8a864e
	getCurrentToken(syntax().generalSubstTable(), gt.token);
Packit 8a864e
	gt.type = allow.nameStart();
Packit 8a864e
	if (currentMarkup()) {
Packit 8a864e
	  if (gt.type == GroupToken::nameToken)
Packit 8a864e
	    currentMarkup()->addNameToken(currentInput());
Packit 8a864e
	  else
Packit 8a864e
	    currentMarkup()->addName(currentInput());
Packit 8a864e
	}
Packit 8a864e
	return 1;
Packit 8a864e
      default:
Packit 8a864e
	groupTokenInvalidToken(tokenNameStart, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
    case tokenDigit:
Packit 8a864e
    case tokenLcUcNmchar:
Packit 8a864e
      if (!allow.groupToken(GroupToken::nameToken)) {
Packit 8a864e
	groupTokenInvalidToken(token, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      extendNameToken(syntax().namelen(), ParserMessages::nameTokenLength);
Packit 8a864e
      getCurrentToken(syntax().generalSubstTable(), gt.token);
Packit 8a864e
      gt.type = GroupToken::nameToken;
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addNameToken(currentInput());
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenLit:
Packit 8a864e
    case tokenLita:
Packit 8a864e
      // parameter literal in data tag pattern
Packit 8a864e
      if (!allow.groupToken(GroupToken::dataTagLiteral)) {
Packit 8a864e
	groupTokenInvalidToken(token, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      if (!parseDataTagParameterLiteral(token == tokenLita, gt.text))
Packit 8a864e
	return 0;
Packit 8a864e
      gt.type = GroupToken::dataTagLiteral;
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addLiteral(gt.text);
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenAnd:
Packit 8a864e
    case tokenSeq:
Packit 8a864e
    case tokenOr:
Packit 8a864e
    case tokenDtgc:
Packit 8a864e
    case tokenGrpc:
Packit 8a864e
    case tokenOpt:
Packit 8a864e
    case tokenPlus:
Packit 8a864e
    case tokenRep:
Packit 8a864e
      groupTokenInvalidToken(token, allow);
Packit 8a864e
      return 0;
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Packit 8a864e
void Parser::groupTokenInvalidToken(Token token, const AllowedGroupTokens &allow)
Packit 8a864e
{
Packit 8a864e
  message(ParserMessages::groupTokenInvalidToken,
Packit 8a864e
	  TokenMessageArg(token, grpMode, syntaxPointer(), sdPointer()),
Packit 8a864e
	  AllowedGroupTokensMessageArg(allow, syntaxPointer()));
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Packit 8a864e
Boolean Parser::parseGroupConnector(const AllowedGroupConnectors &allow,
Packit 8a864e
				    unsigned declInputLevel,
Packit 8a864e
				    unsigned groupInputLevel,
Packit 8a864e
				    GroupConnector &gc)
Packit 8a864e
{
Packit 8a864e
  for (;;) {
Packit 8a864e
    Token token = getToken(grpMode);
Packit 8a864e
    switch (token) {
Packit 8a864e
    case tokenEe:
Packit 8a864e
      if (inputLevel() <= groupInputLevel) {
Packit 8a864e
	message(ParserMessages::groupLevel);
Packit 8a864e
	if (inputLevel() <= declInputLevel)
Packit 8a864e
	  return 0;
Packit 8a864e
      }
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addEntityEnd();
Packit 8a864e
      popInputStack();
Packit 8a864e
      break;
Packit 8a864e
    case tokenS:
Packit 8a864e
      if (currentMarkup()) {
Packit 8a864e
	extendS();
Packit 8a864e
	currentMarkup()->addS(currentInput());
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case tokenPeroGrpo:
Packit 8a864e
      if (inInstance()) {
Packit 8a864e
	message(ParserMessages::peroGrpoProlog);
Packit 8a864e
	break;
Packit 8a864e
      }
Packit 8a864e
      // fall through
Packit 8a864e
    case tokenPeroNameStart:
Packit 8a864e
      if (!sd().www())
Packit 8a864e
	message(ParserMessages::groupEntityReference);
Packit 8a864e
      else {
Packit 8a864e
	ConstPtr<Entity> entity;
Packit 8a864e
	Ptr<EntityOrigin> origin;
Packit 8a864e
	if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))
Packit 8a864e
	  return 0;
Packit 8a864e
	if (!entity.isNull())
Packit 8a864e
	  entity->declReference(*this, origin);
Packit 8a864e
      }
Packit 8a864e
      break;
Packit 8a864e
    case tokenUnrecognized:
Packit 8a864e
      if (reportNonSgmlCharacter())
Packit 8a864e
	break;
Packit 8a864e
      {
Packit 8a864e
	message(ParserMessages::groupCharacter,
Packit 8a864e
		StringMessageArg(currentToken()),
Packit 8a864e
		AllowedGroupConnectorsMessageArg(allow, syntaxPointer()));
Packit 8a864e
      }
Packit 8a864e
      return 0;
Packit 8a864e
    case tokenAnd:
Packit 8a864e
      if (!allow.groupConnector(GroupConnector::andGC)) {
Packit 8a864e
	groupConnectorInvalidToken(tokenAnd, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      gc.type = GroupConnector::andGC;
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dAND);
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenSeq:
Packit 8a864e
      if (!allow.groupConnector(GroupConnector::seqGC)) {
Packit 8a864e
	groupConnectorInvalidToken(tokenSeq, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      gc.type = GroupConnector::seqGC;
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dSEQ);
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenOr:
Packit 8a864e
      if (!allow.groupConnector(GroupConnector::orGC)) {
Packit 8a864e
	groupConnectorInvalidToken(tokenOr, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      gc.type = GroupConnector::orGC;
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dOR);
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenDtgc:
Packit 8a864e
      if (!allow.groupConnector(GroupConnector::dtgcGC)) {
Packit 8a864e
	groupConnectorInvalidToken(tokenDtgc, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      gc.type = GroupConnector::dtgcGC;
Packit 8a864e
      if (inputLevel() > groupInputLevel)
Packit 8a864e
	message(ParserMessages::groupParameterEntityNotEnded);
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dDTGC);
Packit 8a864e
      return 1;
Packit 8a864e
    case tokenGrpc:
Packit 8a864e
      if (!allow.groupConnector(GroupConnector::grpcGC)) {
Packit 8a864e
	groupConnectorInvalidToken(tokenGrpc, allow);
Packit 8a864e
	return 0;
Packit 8a864e
      }
Packit 8a864e
      gc.type = GroupConnector::grpcGC;
Packit 8a864e
      if (inputLevel() > groupInputLevel)
Packit 8a864e
	message(ParserMessages::groupParameterEntityNotEnded);
Packit 8a864e
      if (currentMarkup())
Packit 8a864e
	currentMarkup()->addDelim(Syntax::dGRPC);
Packit 8a864e
      return 1;
Packit 8a864e
    default:
Packit 8a864e
      groupConnectorInvalidToken(token, allow);
Packit 8a864e
      return 0;
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
void Parser::groupConnectorInvalidToken(Token token,
Packit 8a864e
					const AllowedGroupConnectors &allow)
Packit 8a864e
{
Packit 8a864e
  message(ParserMessages::connectorInvalidToken,
Packit 8a864e
	  TokenMessageArg(token, grpMode, syntaxPointer(), sdPointer()),
Packit 8a864e
	  AllowedGroupConnectorsMessageArg(allow, syntaxPointer()));
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
static AllowedGroupTokens allowName(GroupToken::name);
Packit 8a864e
Packit 8a864e
Boolean Parser::parseElementNameGroup(unsigned declInputLevel, Param &parm)
Packit 8a864e
{
Packit 8a864e
  static AllowedGroupTokens allowCommonName(GroupToken::name,
Packit 8a864e
                                             GroupToken::all,
Packit 8a864e
                                             GroupToken::implicit);
Packit 8a864e
  if (!parseGroup(sd().www() ? allowCommonName : allowName, declInputLevel, parm))
Packit 8a864e
    return 0;
Packit 8a864e
  parm.elementVector.resize(parm.nameTokenVector.size());
Packit 8a864e
  for (size_t i = 0; i < parm.nameTokenVector.size(); i++)
Packit 8a864e
    parm.elementVector[i] = lookupCreateElement(parm.nameTokenVector[i].name);
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseEntityReferenceNameGroup(Boolean &ignore)
Packit 8a864e
{
Packit 8a864e
  Param parm;
Packit 8a864e
  if (!parseNameGroup(inputLevel(), parm))
Packit 8a864e
    return 0;
Packit 8a864e
  if (inInstance()) {
Packit 8a864e
    for (size_t i = 0; i < parm.nameTokenVector.size(); i++) {
Packit 8a864e
      const Lpd *lpd = lookupLpd(parm.nameTokenVector[i].name).pointer();
Packit 8a864e
      if (lpd && lpd->active()) {
Packit 8a864e
	ignore = 0;
Packit 8a864e
	return 1;
Packit 8a864e
      }
Packit 8a864e
      Ptr<Dtd> dtd = lookupDtd(parm.nameTokenVector[i].name).pointer();
Packit 8a864e
      if (!dtd.isNull()) {
Packit 8a864e
	instantiateDtd(dtd);
Packit 8a864e
	if (currentDtdPointer() == dtd) {
Packit 8a864e
	  ignore = 0;
Packit 8a864e
	  return 1;
Packit 8a864e
	}
Packit 8a864e
      }
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
  ignore = 1;
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseTagNameGroup(Boolean &active, Boolean start)
Packit 8a864e
{
Packit 8a864e
  Param parm;
Packit 8a864e
  enterTag(start);
Packit 8a864e
  Boolean ret = parseNameGroup(inputLevel(), parm);
Packit 8a864e
  leaveTag();
Packit 8a864e
  if (!ret)
Packit 8a864e
    return 0;
Packit 8a864e
  active = 0;
Packit 8a864e
  for (size_t i = 0; i < parm.nameTokenVector.size(); i++) {
Packit 8a864e
    Ptr<Dtd> dtd = lookupDtd(parm.nameTokenVector[i].name).pointer();
Packit 8a864e
    if (!dtd.isNull()) {
Packit 8a864e
      instantiateDtd(dtd);
Packit 8a864e
      if (currentDtdPointer() == dtd)
Packit 8a864e
	active = 1;
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseNameGroup(unsigned declInputLevel, Param &parm)
Packit 8a864e
{
Packit 8a864e
  return parseGroup(allowName, declInputLevel, parm);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseNameTokenGroup(unsigned declInputLevel, Param &parm)
Packit 8a864e
{
Packit 8a864e
  static AllowedGroupTokens allowNameToken(GroupToken::nameToken);
Packit 8a864e
  return parseGroup(allowNameToken, declInputLevel, parm);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
static
Packit 8a864e
Boolean groupContains(const Vector<NameToken> &vec, const StringC &str)
Packit 8a864e
{
Packit 8a864e
  for (size_t i = 0; i < vec.size(); i++)
Packit 8a864e
    if (vec[i].name == str)
Packit 8a864e
      return 1;
Packit 8a864e
  return 0;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseGroup(const AllowedGroupTokens &allowToken,
Packit 8a864e
			   unsigned declInputLevel,
Packit 8a864e
			   Param &parm)
Packit 8a864e
{
Packit 8a864e
  unsigned groupInputLevel = inputLevel();
Packit 8a864e
  int nDuplicates = 0;
Packit 8a864e
  Vector<NameToken> &vec = parm.nameTokenVector;
Packit 8a864e
  vec.clear();
Packit 8a864e
  GroupConnector::Type connector = GroupConnector::grpcGC;
Packit 8a864e
  GroupToken gt;
Packit 8a864e
  for (;;) {
Packit 8a864e
    if (!parseGroupToken(allowToken, 0, declInputLevel, groupInputLevel, gt))
Packit 8a864e
      return 0;
Packit 8a864e
    if (groupContains(vec, gt.token)) {
Packit 8a864e
      nDuplicates++;
Packit 8a864e
      message(ParserMessages::duplicateGroupToken,
Packit 8a864e
	      StringMessageArg(gt.token));
Packit 8a864e
    }
Packit 8a864e
    else {
Packit 8a864e
      vec.resize(vec.size() + 1);
Packit 8a864e
      gt.token.swap(vec.back().name);
Packit 8a864e
      getCurrentToken(vec.back().origName);
Packit 8a864e
      vec.back().loc = currentLocation();
Packit 8a864e
    }
Packit 8a864e
    GroupConnector gc;
Packit 8a864e
    static AllowedGroupConnectors allowAnyConnectorGrpc(GroupConnector::orGC,
Packit 8a864e
							GroupConnector::andGC,
Packit 8a864e
							GroupConnector::seqGC,
Packit 8a864e
							GroupConnector::grpcGC);
Packit 8a864e
Packit 8a864e
    if (!parseGroupConnector(allowAnyConnectorGrpc, declInputLevel,
Packit 8a864e
			     groupInputLevel, gc))
Packit 8a864e
      return 0;
Packit 8a864e
    if (gc.type == GroupConnector::grpcGC)
Packit 8a864e
      break;
Packit 8a864e
    if (options().warnNameGroupNotOr) {
Packit 8a864e
      if (gc.type != GroupConnector::orGC)
Packit 8a864e
	message(ParserMessages::nameGroupNotOr);
Packit 8a864e
    }
Packit 8a864e
    else if (options().warnShould) {
Packit 8a864e
      if (connector == GroupConnector::grpcGC)
Packit 8a864e
	connector = gc.type;
Packit 8a864e
      else if (gc.type != connector) {
Packit 8a864e
	message(ParserMessages::mixedConnectors);
Packit 8a864e
	connector = gc.type;
Packit 8a864e
      }
Packit 8a864e
    }
Packit 8a864e
  }
Packit 8a864e
  if (nDuplicates + vec.size() > syntax().grpcnt())
Packit 8a864e
    message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt()));
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseDataTagGroup(unsigned nestingLevel,
Packit 8a864e
				  unsigned declInputLevel, GroupToken &result)
Packit 8a864e
{
Packit 8a864e
  if (nestingLevel - 1 == syntax().grplvl())
Packit 8a864e
    message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl()));
Packit 8a864e
  unsigned groupInputLevel = inputLevel();
Packit 8a864e
  GroupToken gt;
Packit 8a864e
  static AllowedGroupTokens allowName(GroupToken::name);
Packit 8a864e
  if (!parseGroupToken(allowName, nestingLevel, declInputLevel,
Packit 8a864e
		       groupInputLevel, gt))
Packit 8a864e
    return 0;
Packit 8a864e
  const ElementType *element = lookupCreateElement(gt.token);
Packit 8a864e
  GroupConnector gc;
Packit 8a864e
  static AllowedGroupConnectors allowSeq(GroupConnector::seqGC);
Packit 8a864e
  if (!parseGroupConnector(allowSeq, declInputLevel, groupInputLevel, gc))
Packit 8a864e
    return 0;
Packit 8a864e
  static AllowedGroupTokens
Packit 8a864e
    allowDataTagLiteralDataTagTemplateGroup(GroupToken::dataTagLiteral,
Packit 8a864e
					    GroupToken::dataTagTemplateGroup);
Packit 8a864e
  if (!parseGroupToken(allowDataTagLiteralDataTagTemplateGroup,
Packit 8a864e
		       nestingLevel,
Packit 8a864e
		       declInputLevel,
Packit 8a864e
		       groupInputLevel,
Packit 8a864e
		       gt))
Packit 8a864e
    return 0;
Packit 8a864e
  Vector<Text> templates;
Packit 8a864e
  if (gt.type == GroupToken::dataTagTemplateGroup)
Packit 8a864e
    gt.textVector.swap(templates);
Packit 8a864e
  else {
Packit 8a864e
    templates.resize(1);
Packit 8a864e
    gt.text.swap(templates[0]);
Packit 8a864e
  }
Packit 8a864e
  static AllowedGroupConnectors allowSeqDtgc(GroupConnector::seqGC,
Packit 8a864e
					     GroupConnector::dtgcGC);
Packit 8a864e
  if (!parseGroupConnector(allowSeqDtgc, declInputLevel, groupInputLevel, gc))
Packit 8a864e
    return 0;
Packit 8a864e
  NCVector<Owner<ContentToken> > vec(2);
Packit 8a864e
  vec[1] = new PcdataToken;
Packit 8a864e
  if (gc.type != GroupConnector::dtgcGC) {
Packit 8a864e
    static AllowedGroupTokens allowDataTagLiteral(GroupToken::dataTagLiteral);
Packit 8a864e
    if (!parseGroupToken(allowDataTagLiteral,
Packit 8a864e
			 nestingLevel,
Packit 8a864e
			 declInputLevel,
Packit 8a864e
			 groupInputLevel,
Packit 8a864e
			 gt))
Packit 8a864e
      return 0;
Packit 8a864e
    vec[0] = new DataTagElementToken(element, templates, gt.text);
Packit 8a864e
    static AllowedGroupConnectors allowDtgc(GroupConnector::dtgcGC);
Packit 8a864e
    if (!parseGroupConnector(allowDtgc, declInputLevel, groupInputLevel, gc))
Packit 8a864e
      return 0;
Packit 8a864e
  }
Packit 8a864e
  else
Packit 8a864e
    vec[0] = new DataTagElementToken(element, templates);
Packit 8a864e
  ContentToken::OccurrenceIndicator oi = getOccurrenceIndicator(grpMode);
Packit 8a864e
  result.contentToken = new DataTagGroup(vec, oi);
Packit 8a864e
  result.type = GroupToken::dataTagGroup;
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseDataTagTemplateGroup(unsigned nestingLevel,
Packit 8a864e
					  unsigned declInputLevel,
Packit 8a864e
					  GroupToken &result)
Packit 8a864e
{
Packit 8a864e
  if (nestingLevel - 1 == syntax().grplvl())
Packit 8a864e
    message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl()));
Packit 8a864e
  unsigned groupInputLevel = inputLevel();
Packit 8a864e
  Vector<Text> &vec = result.textVector;
Packit 8a864e
  for (;;) {
Packit 8a864e
    GroupToken gt;
Packit 8a864e
    static AllowedGroupTokens allowDataTagLiteral(GroupToken::dataTagLiteral);
Packit 8a864e
    if (!parseGroupToken(allowDataTagLiteral,
Packit 8a864e
			 nestingLevel,
Packit 8a864e
			 declInputLevel,
Packit 8a864e
			 groupInputLevel,
Packit 8a864e
			 gt))
Packit 8a864e
      return 0;
Packit 8a864e
    if (vec.size() == syntax().grpcnt())
Packit 8a864e
      message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt()));
Packit 8a864e
    vec.resize(vec.size() + 1);
Packit 8a864e
    gt.text.swap(vec.back());
Packit 8a864e
    static AllowedGroupConnectors allowOrGrpc(GroupConnector::orGC,
Packit 8a864e
					      GroupConnector::grpcGC);
Packit 8a864e
    GroupConnector gc;
Packit 8a864e
    if (!parseGroupConnector(allowOrGrpc, declInputLevel, groupInputLevel, gc))
Packit 8a864e
      return 0;
Packit 8a864e
    if (gc.type == GroupConnector::grpcGC)
Packit 8a864e
      break;
Packit 8a864e
  }
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseModelGroup(unsigned nestingLevel, unsigned declInputLevel,
Packit 8a864e
				ModelGroup *&group, Mode oiMode)
Packit 8a864e
{
Packit 8a864e
  if (nestingLevel - 1 == syntax().grplvl())
Packit 8a864e
    message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl()));
Packit 8a864e
  unsigned groupInputLevel = inputLevel();
Packit 8a864e
  GroupToken gt;
Packit 8a864e
  NCVector<Owner<ContentToken> > tokenVector;
Packit 8a864e
  GroupConnector::Type connector = GroupConnector::grpcGC;
Packit 8a864e
  
Packit 8a864e
  static AllowedGroupTokens allowContentToken(GroupToken::pcdata,
Packit 8a864e
					      GroupToken::dataTagGroup,
Packit 8a864e
					      GroupToken::elementToken,
Packit 8a864e
					      GroupToken::modelGroup);
Packit 8a864e
  static AllowedGroupTokens allowCommonContentToken(GroupToken::pcdata,
Packit 8a864e
                                                    GroupToken::all,
Packit 8a864e
                                                    GroupToken::implicit,
Packit 8a864e
					            GroupToken::dataTagGroup,
Packit 8a864e
					            GroupToken::elementToken,
Packit 8a864e
					            GroupToken::modelGroup);
Packit 8a864e
  static AllowedGroupConnectors allowAnyConnectorGrpc(GroupConnector::orGC,
Packit 8a864e
						      GroupConnector::andGC,
Packit 8a864e
						      GroupConnector::seqGC,
Packit 8a864e
						      GroupConnector::grpcGC);
Packit 8a864e
			    
Packit 8a864e
  static AllowedGroupConnectors allowOrGrpc(GroupConnector::orGC,
Packit 8a864e
					    GroupConnector::grpcGC);
Packit 8a864e
  static AllowedGroupConnectors allowAndGrpc(GroupConnector::andGC,
Packit 8a864e
					     GroupConnector::grpcGC);
Packit 8a864e
  static AllowedGroupConnectors allowSeqGrpc(GroupConnector::seqGC,
Packit 8a864e
					     GroupConnector::grpcGC);
Packit 8a864e
  const AllowedGroupConnectors *connectorp = &allowAnyConnectorGrpc;
Packit 8a864e
Packit 8a864e
  GroupConnector gc;
Packit 8a864e
  Boolean pcdataCheck = 0;
Packit 8a864e
  do {
Packit 8a864e
    if (!parseGroupToken(sd().www() ? allowCommonContentToken 
Packit 8a864e
                                    : allowContentToken, 
Packit 8a864e
                         nestingLevel, declInputLevel, groupInputLevel, gt))
Packit 8a864e
      return 0;
Packit 8a864e
    ContentToken *contentToken;
Packit 8a864e
    if (gt.type == GroupToken::modelGroup)
Packit 8a864e
      contentToken = gt.model.extract();
Packit 8a864e
    else
Packit 8a864e
      contentToken = gt.contentToken.extract();
Packit 8a864e
    if (tokenVector.size() == syntax().grpcnt())
Packit 8a864e
      message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt()));
Packit 8a864e
    tokenVector.resize(tokenVector.size() + 1);
Packit 8a864e
    tokenVector.back() = contentToken;
Packit 8a864e
    if (!parseGroupConnector(*connectorp, declInputLevel, groupInputLevel, gc))
Packit 8a864e
      return 0;
Packit 8a864e
    if (options().warnMixedContentRepOrGroup && gt.type == GroupToken::pcdata) {
Packit 8a864e
      if (tokenVector.size() != 1)
Packit 8a864e
	message(ParserMessages::pcdataNotFirstInGroup);
Packit 8a864e
      else if (gc.type == GroupConnector::seqGC)
Packit 8a864e
	message(ParserMessages::pcdataInSeqGroup);
Packit 8a864e
      else
Packit 8a864e
	pcdataCheck = 1;
Packit 8a864e
      if (nestingLevel != 1)
Packit 8a864e
	message(ParserMessages::pcdataInNestedModelGroup);
Packit 8a864e
    }
Packit 8a864e
    else if (pcdataCheck) {
Packit 8a864e
      if (gt.type == GroupToken::modelGroup)
Packit 8a864e
	message(ParserMessages::pcdataGroupMemberModelGroup);
Packit 8a864e
      if (contentToken->occurrenceIndicator() != ContentToken::none)
Packit 8a864e
	message(ParserMessages::pcdataGroupMemberOccurrenceIndicator);
Packit 8a864e
    }
Packit 8a864e
    if (tokenVector.size() == 1) {
Packit 8a864e
      connector = gc.type;
Packit 8a864e
      switch (gc.type) {
Packit 8a864e
      case GroupConnector::orGC:
Packit 8a864e
	connectorp = &allowOrGrpc;
Packit 8a864e
	break;
Packit 8a864e
      case GroupConnector::seqGC:
Packit 8a864e
	connectorp = &allowSeqGrpc;
Packit 8a864e
	break;
Packit 8a864e
      case GroupConnector::andGC:
Packit 8a864e
	connectorp = &allowAndGrpc;
Packit 8a864e
	if (options().warnAndGroup)
Packit 8a864e
	  message(ParserMessages::andGroup);
Packit 8a864e
	break;
Packit 8a864e
      default:
Packit 8a864e
	break;
Packit 8a864e
      }
Packit 8a864e
    }
Packit 8a864e
  } while (gc.type != GroupConnector::grpcGC);
Packit 8a864e
  ContentToken::OccurrenceIndicator oi
Packit 8a864e
    = getOccurrenceIndicator(oiMode);
Packit 8a864e
  switch (connector) {
Packit 8a864e
  case GroupConnector::orGC:
Packit 8a864e
    group = new OrModelGroup(tokenVector, oi);
Packit 8a864e
    if (pcdataCheck && oi != ContentToken::rep)
Packit 8a864e
      message(ParserMessages::pcdataGroupNotRep);
Packit 8a864e
    break;
Packit 8a864e
  case GroupConnector::grpcGC:
Packit 8a864e
    if (pcdataCheck && oi != ContentToken::rep && oi != ContentToken::none)
Packit 8a864e
      message(ParserMessages::pcdataGroupNotRep);
Packit 8a864e
    // fall through
Packit 8a864e
  case GroupConnector::seqGC:
Packit 8a864e
    group = new SeqModelGroup(tokenVector, oi);
Packit 8a864e
    break;
Packit 8a864e
  case GroupConnector::andGC:
Packit 8a864e
    group = new AndModelGroup(tokenVector, oi);
Packit 8a864e
    break;
Packit 8a864e
  default:
Packit 8a864e
    break;
Packit 8a864e
  }
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
ContentToken::OccurrenceIndicator
Packit 8a864e
Parser::getOccurrenceIndicator(Mode oiMode)
Packit 8a864e
{
Packit 8a864e
  Token token = getToken(oiMode);
Packit 8a864e
  switch (token) {
Packit 8a864e
  case tokenPlus:
Packit 8a864e
    if (currentMarkup())
Packit 8a864e
      currentMarkup()->addDelim(Syntax::dPLUS);
Packit 8a864e
    return ContentToken::plus;
Packit 8a864e
  case tokenOpt: 
Packit 8a864e
    if (currentMarkup())
Packit 8a864e
      currentMarkup()->addDelim(Syntax::dOPT);
Packit 8a864e
   return ContentToken::opt;
Packit 8a864e
  case tokenRep:
Packit 8a864e
    if (currentMarkup())
Packit 8a864e
      currentMarkup()->addDelim(Syntax::dREP);
Packit 8a864e
    return ContentToken::rep;
Packit 8a864e
  default:
Packit 8a864e
    currentInput()->ungetToken();
Packit 8a864e
    return ContentToken::none;
Packit 8a864e
  }
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseMinimumLiteral(Boolean lita, Text &text)
Packit 8a864e
{
Packit 8a864e
  return parseLiteral(lita ? mlitaMode : mlitMode, mlitMode,
Packit 8a864e
		      Syntax::referenceQuantity(Syntax::qLITLEN),
Packit 8a864e
		      ParserMessages::minimumLiteralLength,
Packit 8a864e
		      literalSingleSpace|literalMinimumData
Packit 8a864e
		      |(eventsWanted().wantPrologMarkup()
Packit 8a864e
			? literalDelimInfo
Packit 8a864e
			: 0),
Packit 8a864e
		      text);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseSystemIdentifier(Boolean lita, Text &text)
Packit 8a864e
{
Packit 8a864e
  return parseLiteral(lita ? slitaMode : slitMode, slitMode, syntax().litlen(),
Packit 8a864e
		      ParserMessages::systemIdentifierLength,
Packit 8a864e
		      (eventsWanted().wantPrologMarkup()
Packit 8a864e
			? literalDelimInfo
Packit 8a864e
			: 0), text);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseParameterLiteral(Boolean lita, Text &text)
Packit 8a864e
{
Packit 8a864e
  return parseLiteral(lita ? plitaMode : plitMode, pliteMode, syntax().litlen(), 
Packit 8a864e
		      ParserMessages::parameterLiteralLength,
Packit 8a864e
		      (eventsWanted().wantPrologMarkup()
Packit 8a864e
		       ? literalDelimInfo
Packit 8a864e
		       : 0),
Packit 8a864e
		      text);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseDataTagParameterLiteral(Boolean lita, Text &text)
Packit 8a864e
{
Packit 8a864e
  return parseLiteral(lita ? plitaMode : plitMode, pliteMode,
Packit 8a864e
		      syntax().dtemplen(), 
Packit 8a864e
		      ParserMessages::dataTagPatternLiteralLength,
Packit 8a864e
		      literalDataTag
Packit 8a864e
		      | (eventsWanted().wantPrologMarkup()
Packit 8a864e
			 ? literalDelimInfo
Packit 8a864e
			 : 0),
Packit 8a864e
		      text);
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseIndicatedReservedName(const AllowedParams &allow,
Packit 8a864e
					   Param &parm)
Packit 8a864e
{
Packit 8a864e
  Syntax::ReservedName rn;
Packit 8a864e
  if (!getIndicatedReservedName(&rn))
Packit 8a864e
    return 0;
Packit 8a864e
  if (!allow.reservedName(rn)) {
Packit 8a864e
    message(ParserMessages::invalidReservedName,
Packit 8a864e
	    StringMessageArg(currentToken()));
Packit 8a864e
    return 0;
Packit 8a864e
  }
Packit 8a864e
  parm.type = Param::indicatedReservedName + rn;
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::parseReservedName(const AllowedParams &allow,
Packit 8a864e
				  Param &parm)
Packit 8a864e
{
Packit 8a864e
  Syntax::ReservedName rn;
Packit 8a864e
  if (!getReservedName(&rn))
Packit 8a864e
    return 0;
Packit 8a864e
  if (!allow.reservedName(rn)) {
Packit 8a864e
    message(ParserMessages::invalidReservedName,
Packit 8a864e
	    StringMessageArg(syntax().reservedName(rn)));
Packit 8a864e
    return 0;
Packit 8a864e
  }
Packit 8a864e
  parm.type = Param::reservedName + rn;
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Packit 8a864e
Boolean Parser::parseAttributeValueParam(Param &parm)
Packit 8a864e
{
Packit 8a864e
  extendNameToken(syntax().litlen() > syntax().normsep()
Packit 8a864e
		  ? syntax().litlen() - syntax().normsep()
Packit 8a864e
		  : 0,
Packit 8a864e
		  ParserMessages::attributeValueLength);
Packit 8a864e
  parm.type = Param::attributeValue;
Packit 8a864e
  Text text;
Packit 8a864e
  text.addChars(currentInput()->currentTokenStart(),
Packit 8a864e
		currentInput()->currentTokenLength(),
Packit 8a864e
		currentLocation());
Packit 8a864e
  text.swap(parm.literalText);
Packit 8a864e
  if (currentMarkup())
Packit 8a864e
    currentMarkup()->addAttributeValue(currentInput());
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::getIndicatedReservedName(Syntax::ReservedName *result)
Packit 8a864e
{
Packit 8a864e
  if (currentMarkup())
Packit 8a864e
    currentMarkup()->addDelim(Syntax::dRNI);
Packit 8a864e
  InputSource *in = currentInput();
Packit 8a864e
  in->startToken();
Packit 8a864e
  if (!syntax().isNameStartCharacter(in->tokenChar(messenger()))) {
Packit 8a864e
    message(ParserMessages::rniNameStart);
Packit 8a864e
    return 0;
Packit 8a864e
  }
Packit 8a864e
  extendNameToken(syntax().namelen(), ParserMessages::nameLength);
Packit 8a864e
  StringC &buffer = nameBuffer();
Packit 8a864e
  getCurrentToken(syntax().generalSubstTable(), buffer);
Packit 8a864e
  if (!syntax().lookupReservedName(buffer, result)) {
Packit 8a864e
    message(ParserMessages::noSuchReservedName, StringMessageArg(buffer));
Packit 8a864e
    return 0;
Packit 8a864e
  }
Packit 8a864e
  if (currentMarkup())
Packit 8a864e
    currentMarkup()->addReservedName(*result, currentInput());
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Boolean Parser::getReservedName(Syntax::ReservedName *result)
Packit 8a864e
{
Packit 8a864e
  extendNameToken(syntax().namelen(), ParserMessages::nameLength);
Packit 8a864e
  StringC &buffer = nameBuffer();
Packit 8a864e
  getCurrentToken(syntax().generalSubstTable(), buffer);
Packit 8a864e
  if (!syntax().lookupReservedName(buffer, result)) {
Packit 8a864e
    message(ParserMessages::noSuchReservedName, StringMessageArg(buffer));
Packit 8a864e
    return 0;
Packit 8a864e
  }
Packit 8a864e
  if (currentMarkup())
Packit 8a864e
    currentMarkup()->addReservedName(*result, currentInput());
Packit 8a864e
  return 1;
Packit 8a864e
}
Packit 8a864e
Packit 8a864e
Packit 8a864e
#ifdef SP_NAMESPACE
Packit 8a864e
}
Packit 8a864e
#endif