1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00
cde/cde/programs/nsgmls/ContentState.C
2018-04-28 12:30:20 -06:00

196 lines
5.6 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: ContentState.C /main/1 1996/07/29 16:48:21 cde-hp $ */
// Copyright (c) 1994, 1996 James Clark
// See the file COPYING for copying permission.
#ifdef __GNUG__
#pragma implementation
#endif
#include "splib.h"
#include "ContentState.h"
#include "IListIter.h"
#include "NCVector.h"
#include "macros.h"
#ifdef SP_NAMESPACE
namespace SP_NAMESPACE {
#endif
const ShortReferenceMap ContentState::theEmptyMap;
#ifdef __GNUG__
typedef IListIter<OpenElement> Dummy_IListIter_OpenElement;
#endif
ContentState::ContentState()
: documentElementContainer_(StringC(), size_t(-1)),
totalExcludeCount_(0),
tagLevel_(0),
netEnablingCount_(0),
lastEndedElementType_(NULL)
{
}
void ContentState::startContent(const Dtd &dtd)
{
NCVector<Owner<ContentToken> > tokens(1);
tokens[0] = new ElementToken(dtd.documentElementType(),
ContentToken::none);
Owner<ModelGroup> model(new SeqModelGroup(tokens, ContentToken::none));
Owner<CompiledModelGroup> compiledModel(new CompiledModelGroup(model));
Vector<ContentModelAmbiguity> ambiguities;
Boolean pcdataUnreachable;
compiledModel->compile(dtd.nElementTypeIndex(), ambiguities,
pcdataUnreachable);
ASSERT(ambiguities.size() == 0);
ConstPtr<ElementDefinition> def
= new ElementDefinition(Location(),
0,
0,
ElementDefinition::modelGroup,
compiledModel);
documentElementContainer_.setElementDefinition(def, 0);
tagLevel_ = 0;
while (!openElements_.empty())
delete openElements_.get();
openElements_.insert(new OpenElement(&documentElementContainer_,
0,
0,
&theEmptyMap,
Location()));
includeCount_.assign(dtd.nElementTypeIndex(), 0);
excludeCount_.assign(dtd.nElementTypeIndex(), 0);
openElementCount_.assign(dtd.nElementTypeIndex(), 0);
netEnablingCount_ = 0;
totalExcludeCount_ = 0;
lastEndedElementType_ = 0;
undefinedElementTypeTable_.clear();
}
void ContentState::pushElement(OpenElement *e)
{
tagLevel_++;
openElementCount_[e->type()->index()]++;
const ElementDefinition *def = e->type()->definition();
if (def) {
size_t i;
for (i = 0; i < def->nInclusions(); i++)
includeCount_[def->inclusion(i)->index()]++;
for (i = 0; i < def->nExclusions(); i++) {
excludeCount_[def->exclusion(i)->index()]++;
totalExcludeCount_++;
}
}
if (e->netEnabling())
netEnablingCount_++;
openElements_.insert(e);
}
OpenElement *ContentState::popSaveElement()
{
ASSERT(tagLevel_ > 0);
OpenElement *e = openElements_.get();
tagLevel_--;
openElementCount_[e->type()->index()]--;
const ElementDefinition *def = e->type()->definition();
if (def) {
size_t i;
for (i = 0; i < def->nInclusions(); i++)
includeCount_[def->inclusion(i)->index()]--;
for (i = 0; i < def->nExclusions(); i++) {
excludeCount_[def->exclusion(i)->index()]--;
totalExcludeCount_--;
}
}
if (e->netEnabling())
netEnablingCount_--;
lastEndedElementType_ = e->type();
return e;
}
void ContentState::popElement()
{
delete popSaveElement();
}
Boolean ContentState::checkImplyLoop(unsigned count)
{
for (IListIter<OpenElement> iter(openElements_);
count > 0;
iter.next(), count--)
if (iter.cur()->type() == openElements_.head()->type()
// I'm not sure whether this is necessary.
&& iter.cur()->matchState() == openElements_.head()->matchState())
return 0;
return 1;
}
void ContentState::getOpenElementInfo(Vector<OpenElementInfo> &v,
const StringC &rniPcdata) const
{
v.clear();
v.resize(tagLevel_);
unsigned i = tagLevel_;
for (IListIter<OpenElement> iter(openElements_);
!iter.done() && i > 0;
iter.next()) {
OpenElementInfo &e = v[--i];
e.gi = iter.cur()->type()->name();
const LeafContentToken *token = iter.cur()->currentPosition();
if (token && !token->isInitial()) {
e.matchIndex = token->typeIndex() + 1;
const ElementType *type = token->elementType();
e.matchType = type ? type->name() : rniPcdata;
}
e.included = iter.cur()->included();
}
}
const ElementType *
ContentState::lookupCreateUndefinedElement(const StringC &name,
const Location &loc)
{
const ElementType *e = undefinedElementTypeTable_.lookup(name);
if (e)
return e;
ElementType *p = new ElementType(name,
openElementCount_.size());
p->setElementDefinition(new ElementDefinition(loc,
ElementDefinition::undefinedIndex,
(ElementDefinition::omitStart
|ElementDefinition::omitEnd),
ElementDefinition::any),
0);
undefinedElementTypeTable_.insert(p);
includeCount_.push_back(0);
excludeCount_.push_back(0);
openElementCount_.push_back(0);
return p;
}
#ifdef SP_NAMESPACE
}
#endif