static void formatNode()

in src/xercesc/validators/common/ContentSpecNode.cpp [138:273]


static void formatNode( const   ContentSpecNode* const      curNode
                        ,       XMLBuffer&                  bufToFill
						,		MemoryManager* const		memMgr)
{
    if (!curNode)
        return;

	ValueStackOf<formatNodeHolder> toBeProcessed(10, memMgr);
	toBeProcessed.push(formatNodeHolder(curNode, ContentSpecNode::UnknownType, 0));

	while(!toBeProcessed.empty())
	{
		formatNodeHolder item=toBeProcessed.pop();
		if(item.character!=0)
		{
			bufToFill.append(item.character);
			continue;
		}
		const ContentSpecNode* curNode = item.node;
		if(!curNode)
			continue;
		const ContentSpecNode::NodeTypes parentType = item.parentType; 
		const ContentSpecNode* first = curNode->getFirst();
		const ContentSpecNode* second = curNode->getSecond();
		const ContentSpecNode::NodeTypes curType = curNode->getType();

		// Get the type of the first node
		const ContentSpecNode::NodeTypes firstType = first ?
													 first->getType() :
													 ContentSpecNode::Leaf;

		// Calculate the parens flag for the rep nodes
		bool doRepParens = false;
		if (((firstType != ContentSpecNode::Leaf)
				&& (parentType != ContentSpecNode::UnknownType))
		||  ((firstType == ContentSpecNode::Leaf)
				&& (parentType == ContentSpecNode::UnknownType)))
		{
			doRepParens = true;
		}

		// Now handle our type
		switch(curType & 0x0f)
		{
			case ContentSpecNode::Leaf :
				if (curNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
					bufToFill.append(XMLElementDecl::fgPCDataElemName);
				else
				{
					bufToFill.append(curNode->getElement()->getRawName());
					// show the + and * modifiers also when we have a non-infinite number of repetitions
					if(curNode->getMinOccurs()==0 && (curNode->getMaxOccurs()==-1 || curNode->getMaxOccurs()>1))
						bufToFill.append(chAsterisk);
					else if(curNode->getMinOccurs()==0 && curNode->getMaxOccurs()==1)
						bufToFill.append(chQuestion);
					else if(curNode->getMinOccurs()==1 && (curNode->getMaxOccurs()==-1 || curNode->getMaxOccurs()>1))
						bufToFill.append(chPlus);
				}
				break;

			case ContentSpecNode::ZeroOrOne :
				if (doRepParens)
					bufToFill.append(chOpenParen);

				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chQuestion));
				if (doRepParens)
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::ZeroOrMore :
				if (doRepParens)
					bufToFill.append(chOpenParen);

				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chAsterisk));
				if (doRepParens)
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::OneOrMore :
				if (doRepParens)
					bufToFill.append(chOpenParen);

				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chPlus));
				if (doRepParens)
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::Choice :
				if ((parentType & 0x0f) != (curType & 0x0f))
					bufToFill.append(chOpenParen);

				if ((parentType & 0x0f) != (curType & 0x0f))
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				if(second!=NULL)
				{
					toBeProcessed.push(formatNodeHolder(second, curType, 0));
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chPipe));
				}
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::Sequence :
				if ((parentType & 0x0f) != (curType & 0x0f))
					bufToFill.append(chOpenParen);

				if ((parentType & 0x0f) != (curType & 0x0f))
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				if(second!=NULL)
				{
					toBeProcessed.push(formatNodeHolder(second, curType, 0));
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chComma));
				}
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;

			case ContentSpecNode::All :
				if ((parentType & 0x0f) != (curType & 0x0f))
				{
					bufToFill.append(chLatin_A);
					bufToFill.append(chLatin_l);
					bufToFill.append(chLatin_l);
					bufToFill.append(chOpenParen);
				}

				if ((parentType & 0x0f) != (curType & 0x0f))
					toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chCloseParen));
				toBeProcessed.push(formatNodeHolder(second, curType, 0));
				toBeProcessed.push(formatNodeHolder(0, ContentSpecNode::UnknownType, chComma));
				toBeProcessed.push(formatNodeHolder(first, curType, 0));
				break;
		}
	}
}