/* * 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: LinkProcess.C /main/1 1996/07/29 16:55:45 cde-hp $ */ // Copyright (c) 1994 James Clark // See the file COPYING for copying permission. #ifdef __GNUG__ #pragma implementation #endif #include "splib.h" #include "LinkProcess.h" // ParserState is used for access to parser messages #include "ParserState.h" #include "MessageArg.h" #include "ParserMessages.h" #ifdef SP_NAMESPACE namespace SP_NAMESPACE { #endif LinkProcess::LinkProcess() { } void LinkProcess::init(const ConstPtr &lpd) { lpd_ = lpd; open_.clear(); open_.insert(new LinkProcessOpenElement(lpd_->initialLinkSet())); } Boolean LinkProcess::startElement(const ElementType *element, const AttributeList &attributes, const Location &location, Messenger &mgr, const AttributeList *&linkAttributes, const ResultElementSpec *&resultElementSpec) { if (lpd_.isNull()) { linkAttributes = 0; resultElementSpec = 0; return 1; } const StringC *id = attributes.getId(); if (id) { const IdLinkRuleGroup *p = lpd_->lookupIdLink(*id); if (p) { size_t selected; if (p->nLinkRules() > 1) { linkAttributes_.resize(p->nLinkRules()); for (size_t i = 0; i < linkAttributes_.size(); i++) linkAttributes_[i] = &p->linkRule(i).attributes(); if (!selectLinkRule(linkAttributes_, location, selected)) return 0; } else selected = 0; const IdLinkRule &rule = p->linkRule(selected); open_.insert(new LinkProcessOpenElement(open_.head()->current, rule)); linkAttributes = &rule.attributes(); resultElementSpec = &rule.resultElementSpec(); if (!rule.isAssociatedWith(element)) { mgr.setNextLocation(location); mgr.message(ParserMessages::idlinkElementType, StringMessageArg(element->name()), StringMessageArg(*id)); } return 1; } } const LinkSet *currentLinkSet = open_.head()->current; size_t nRules = currentLinkSet->nLinkRules(element); if (nRules > 0) { size_t selected; if (nRules > 1) { linkAttributes_.resize(nRules); for (size_t i = 0; i < nRules; i++) linkAttributes_[i] = ¤tLinkSet->linkRule(element, i).attributes(); if (!selectLinkRule(linkAttributes_, location, selected)) return 0; } else selected = 0; const SourceLinkRule &rule = currentLinkSet->linkRule(element, selected); open_.insert(new LinkProcessOpenElement(open_.head()->current, rule)); linkAttributes = &rule.attributes(); resultElementSpec = &rule.resultElementSpec(); return 1; } // FIXME construct attributes from attribute definition list linkAttributes = 0; resultElementSpec = 0; open_.insert(new LinkProcessOpenElement(open_.head()->current)); return 1; } void LinkProcess::endElement() { if (lpd_.isNull()) return; LinkProcessOpenElement *top = open_.get(); if (top->post) open_.head()->current = top->post; else if (top->postRestore) open_.head()->current = open_.head()->restore; delete top; } void LinkProcess::uselink(const LinkSet *linkSet, Boolean restore, const Lpd *lpd) { if (lpd_.isNull()) return; if (lpd != lpd_.pointer()) return; if (restore) open_.head()->current = open_.head()->restore; else if (linkSet) open_.head()->current = linkSet; } size_t LinkProcess::nImpliedLinkRules() const { if (!open_.head()) return 0; return open_.head()->current->nImpliedLinkRules(); } const ResultElementSpec &LinkProcess::impliedLinkRule(size_t i) const { return open_.head()->current->impliedLinkRule(i); } // Usually redefined by application. Boolean LinkProcess::selectLinkRule(const Vector &, const Location &, size_t &selected) { selected = 0; return 1; } void LinkProcess::clear() { open_.clear(); lpd_.clear(); linkAttributes_.clear(); } void LinkProcess::swap(LinkProcess &to) { open_.swap(to.open_); lpd_.swap(to.lpd_); linkAttributes_.swap(to.linkAttributes_); } LinkProcessOpenElement::LinkProcessOpenElement(const LinkSet *cur, const SourceLinkRule &rule) { current = rule.uselink(); if (!current) current = cur; restore = cur; post = rule.postlink(); postRestore = rule.postlinkRestore(); } LinkProcessOpenElement::LinkProcessOpenElement(const LinkSet *cur) { restore = current = cur; post = 0; postRestore = 0; } #ifdef SP_NAMESPACE } #endif