/* * 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 librararies 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 Dummy_IListIter_OpenElement; #endif ContentState::ContentState() : documentElementContainer_(StringC(), size_t(-1)) { } void ContentState::startContent(const Dtd &dtd) { NCVector > tokens(1); tokens[0] = new ElementToken(dtd.documentElementType(), ContentToken::none); Owner model(new SeqModelGroup(tokens, ContentToken::none)); Owner compiledModel(new CompiledModelGroup(model)); Vector ambiguities; Boolean pcdataUnreachable; compiledModel->compile(dtd.nElementTypeIndex(), ambiguities, pcdataUnreachable); ASSERT(ambiguities.size() == 0); ConstPtr 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 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 &v, const StringC &rniPcdata) const { v.clear(); v.resize(tagLevel_); unsigned i = tagLevel_; for (IListIter 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