2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: ArcEngine.C /main/1 1996/07/29 16:46:09 cde-hp $ */
24 // Copyright (c) 1996 James Clark
25 // See the file COPYING for copying permission.
28 #pragma implementation
32 #include "ArcEngine.h"
33 #include "ArcProcessor.h"
37 #include "ArcEngineMessages.h"
38 #include "MessageArg.h"
39 #include "ParserOptions.h"
40 #include "SgmlParser.h"
41 #include "Allocator.h"
42 #include "LinkProcess.h"
46 namespace SP_NAMESPACE {
49 static const char notationSetArchPublicId[]
50 = "ISO/IEC 10744//NOTATION AFDR ARCBASE \
51 Notation Set Architecture Definition Document//EN";
53 static const size_t sizes[] = {
54 sizeof(StartElementEvent),
55 sizeof(EndElementEvent),
56 sizeof(ImmediateDataEvent),
57 sizeof(SdataEntityEvent),
58 sizeof(EndPrologEvent),
59 sizeof(CdataEntityEvent),
60 sizeof(SdataEntityEvent),
61 sizeof(ExternalDataEntityEvent),
66 size_t maxSize(const size_t *v, size_t n)
69 for (size_t i = 0; i < n; i++) {
76 const unsigned invalidAtt = unsigned(-1);
77 const unsigned contentPseudoAtt = unsigned(-2);
79 class DelegateEventHandler : public EventHandler {
81 #define EVENT(C, f) void f(C *ev) { delegateTo_->f(ev); }
85 EventHandler *delegateTo_;
88 class QueueEventHandler : public EventHandler, public IQueue<Event> {
90 #define EVENT(C, f) void f(C *ev) { ev->copyData(); append(ev); }
95 // This just passes through messages.
97 class NullEventHandler : public EventHandler {
99 NullEventHandler(Messenger &mgr) : mgr_(&mgr) { }
100 void message(MessageEvent *event) {
101 mgr_->dispatchMessage(event->message());
107 class ArcEngineImpl : public DelegateEventHandler, private Messenger {
109 ArcEngineImpl(Messenger &mgr,
110 const SgmlParser *parser,
111 ArcDirector &director,
112 SP_CONST SP_VOLATILE sig_atomic_t *cancelPtr,
114 const Vector<StringC> &name,
115 const SubstTable<Char> *table);
117 void sgmlDecl(SgmlDeclEvent *);
118 void appinfo(AppinfoEvent *);
119 void startElement(StartElementEvent *);
120 void endElement(EndElementEvent *);
121 void data(DataEvent *);
122 void sdataEntity(SdataEntityEvent *);
123 void externalDataEntity(ExternalDataEntityEvent *);
125 void endProlog(EndPrologEvent *);
126 void startDtd(StartDtdEvent *);
127 void endDtd(EndDtdEvent *);
128 void startLpd(StartLpdEvent *);
129 void endLpd(EndLpdEvent *);
130 void uselink(UselinkEvent *);
131 size_t nBases() const { return arcProcessors_.size(); }
132 EventHandler *delegateHandler() { return eventHandler_; }
134 void dispatchMessage(const Message &);
135 void dispatchMessage(Message &);
136 void initMessage(Message &);
138 EventHandler *eventHandler_;
139 NCVector<ArcProcessor> arcProcessors_;
141 ConstPtr<Syntax> syntax_;
144 QueueEventHandler eventQueue_;
145 NullEventHandler nullHandler_;
146 const SgmlParser *parser_;
147 Location currentLocation_;
148 unsigned gatheringContent_;
150 unsigned startAgain_;
151 Allocator allocator_;
153 const AttributeList *linkAttributes_;
154 LinkProcess linkProcess_;
155 Boolean haveLinkProcess_;
156 Vector<StringC> docName_;
157 ArcDirector *director_;
159 SP_CONST SP_VOLATILE sig_atomic_t *cancelPtr_;
163 void ArcEngine::parseAll(SgmlParser &parser,
165 ArcDirector &director,
166 SP_CONST SP_VOLATILE sig_atomic_t *cancelPtr)
168 ArcEngineImpl wrap(mgr, &parser, director, cancelPtr,
169 0, Vector<StringC>(), 0);
170 parser.parseAll(wrap, cancelPtr);
174 SelectOneArcDirector::arcEventHandler(const Notation *,
175 const Vector<StringC> &name,
176 const SubstTable<Char> *table)
178 if (name.size() != select_.size())
180 for (size_t i = 0; i < name.size(); i++) {
181 StringC tem(select_[i]);
189 void SelectOneArcDirector::dispatchMessage(const Message &msg)
191 eh_->message(new MessageEvent(msg));
194 void SelectOneArcDirector::dispatchMessage(Message &msg)
196 eh_->message(new MessageEvent(msg));
199 ArcEngineImpl::ArcEngineImpl(Messenger &mgr,
200 const SgmlParser *parser,
201 ArcDirector &director,
202 SP_CONST SP_VOLATILE sig_atomic_t *cancelPtr,
203 const Notation *notation,
204 const Vector<StringC> &docName,
205 const SubstTable<Char> *table)
207 : director_(&director), mgr_(&mgr), cancelPtr_(cancelPtr),
208 parser_(parser), stage_(0),
209 gatheringContent_(0), startAgain_(0), haveLinkProcess_(0),
210 allocator_(maxSize(sizes, SIZEOF(sizes)), 50),
211 nullHandler_(mgr), docName_(docName), linkAttributes_(NULL)
213 eventHandler_ = director.arcEventHandler(notation, docName, table);
215 eventHandler_ = &nullHandler_;
216 delegateTo_ = eventHandler_;
219 ArcEngineImpl::~ArcEngineImpl()
221 for (size_t i = 0; i < arcProcessors_.size(); i++)
222 if (arcProcessors_[i].valid())
223 arcProcessors_[i].checkIdrefs();
226 void ArcEngineImpl::appinfo(AppinfoEvent *event)
229 if (event->literal(str))
231 DelegateEventHandler::appinfo(event);
234 void ArcEngineImpl::pi(PiEvent *event)
236 currentLocation_ = event->location();
239 && event->dataLength() > arcBase_.size()) {
241 for (size_t i = 0; i < arcBase_.size() && match; i++)
242 if ((*syntax_->generalSubstTable())[event->data()[i]] != arcBase_[i])
244 if (!syntax_->isS(event->data()[arcBase_.size()]))
247 size_t i = arcBase_.size();
248 size_t dataLength = event->dataLength();
249 const Char *data = event->data();
251 while (i < dataLength && syntax_->isS(data[i]))
256 while (i < dataLength && !syntax_->isS(data[i]))
258 StringC name(data + start, i - start);
259 syntax_->generalSubstTable()->subst(name);
260 arcProcessors_.resize(arcProcessors_.size() + 1);
261 arcProcessors_.back().setName(name);
265 DelegateEventHandler::pi(event);
268 void ArcEngineImpl::endProlog(EndPrologEvent *event)
270 currentLocation_ = event->location();
271 for (size_t i = 0; i < arcProcessors_.size(); i++)
272 arcProcessors_[i].init(*event,
280 if (!event->lpdPointer().isNull()) {
281 haveLinkProcess_ = 1;
282 linkProcess_.init(event->lpdPointer());
284 DelegateEventHandler::endProlog(event);
287 void ArcEngineImpl::startDtd(StartDtdEvent *event)
290 DelegateEventHandler::startDtd(event);
293 void ArcEngineImpl::endDtd(EndDtdEvent *event)
296 DelegateEventHandler::endDtd(event);
299 void ArcEngineImpl::startLpd(StartLpdEvent *event)
303 DelegateEventHandler::startLpd(event);
306 void ArcEngineImpl::endLpd(EndLpdEvent *event)
309 DelegateEventHandler::endLpd(event);
312 void ArcEngineImpl::sgmlDecl(SgmlDeclEvent *event)
314 currentLocation_ = event->location();
315 sd_ = event->sdPointer();
316 syntax_ = event->instanceSyntaxPointer();
317 arcBase_ = sd_->execToDoc("ArcBase");
318 syntax_->generalSubstTable()->subst(arcBase_);
320 for (size_t i = 0; i < appinfo_.size(); i++)
321 if (syntax_->isS(appinfo_[i]))
324 if (i + 7 > appinfo_.size())
326 StringC tem(appinfo_.data() + i, 7);
327 syntax_->generalSubstTable()->subst(tem);
328 if (tem == arcBase_) {
329 if (i + 7 == appinfo_.size() || syntax_->isS(appinfo_[i + 7]))
331 if (appinfo_[i + 7] == sd_->execToDoc('=')) {
333 for (size_t j = i + 7; j < appinfo_.size(); j++) {
334 if (syntax_->isS(appinfo_[j]))
336 arcBase_ += appinfo_[j];
338 syntax_->generalSubstTable()->subst(arcBase_);
344 DelegateEventHandler::sgmlDecl(event);
347 void ArcEngineImpl::startElement(StartElementEvent *event)
349 if (gatheringContent_) {
351 DelegateEventHandler::startElement(event);
354 currentLocation_ = event->location();
355 const Text *contentP;
358 start = startAgain_ - 1;
359 contentP = &content_;
365 if (haveLinkProcess_) {
366 const ResultElementSpec *resultElementSpec;
367 linkProcess_.startElement(event->elementType(),
370 *this, // Messenger &
377 for (size_t i = start; i < arcProcessors_.size(); i++) {
378 if (arcProcessors_[i].valid()) {
379 if (!arcProcessors_[i].processStartElement(*event,
383 ASSERT(contentP == 0);
385 gatheringContent_ = 1;
386 delegateTo_ = &eventQueue_;
387 DelegateEventHandler::startElement(event);
394 DelegateEventHandler::startElement(event);
397 void ArcEngineImpl::data(DataEvent *event)
399 const Entity *entity = event->entity();
400 if (gatheringContent_) {
402 content_.addCdata(entity->asInternalEntity(),
403 event->location().origin());
405 // Do attribute value literal interpretation.
406 Location loc(event->location());
407 for (size_t i = 0; i < event->dataLength(); i++, loc += 1) {
408 Char ch = event->data()[i];
409 if (syntax_->isS(ch) && ch != syntax_->space()) {
410 if (ch == syntax_->standardFunction(Syntax::fRS))
411 content_.ignoreChar(ch, loc);
413 content_.addChar(syntax_->space(),
414 Location(new ReplacementOrigin(loc, ch), 0));
417 content_.addChar(ch, loc);
422 currentLocation_ = event->location();
423 for (size_t i = 0; i < arcProcessors_.size(); i++) {
424 if (arcProcessors_[i].valid() && arcProcessors_[i].processData()) {
426 arcProcessors_[i].docHandler()
427 .data(new (allocator_) CdataEntityEvent(entity->asInternalEntity(),
428 event->location().origin()));
430 arcProcessors_[i].docHandler()
431 .data(new (allocator_) ImmediateDataEvent(event->type(),
439 DelegateEventHandler::data(event);
442 void ArcEngineImpl::sdataEntity(SdataEntityEvent *event)
444 if (gatheringContent_) {
445 content_.addSdata(event->entity()->asInternalEntity(),
446 event->location().origin());
450 currentLocation_ = event->location();
451 for (size_t i = 0; i < arcProcessors_.size(); i++) {
452 if (arcProcessors_[i].valid() && arcProcessors_[i].processData()) {
453 const Entity *entity = event->entity();
454 arcProcessors_[i].docHandler()
455 .sdataEntity(new (allocator_)
456 SdataEntityEvent(entity->asInternalEntity(),
457 event->location().origin()));
461 DelegateEventHandler::sdataEntity(event);
464 void ArcEngineImpl::externalDataEntity(ExternalDataEntityEvent *event)
466 if (!gatheringContent_) {
467 currentLocation_ = event->location();
468 for (size_t i = 0; i < arcProcessors_.size(); i++) {
469 if (arcProcessors_[i].valid()
470 && arcProcessors_[i].processData()) {
471 ConstPtr<Entity> entity
472 = arcProcessors_[i].dtdPointer()
473 ->lookupEntity(0, event->entity()->name());
474 if (!entity.isNull()) {
475 ConstPtr<EntityOrigin> oldOrigin = event->entityOrigin();
476 Owner<Markup> markup;
477 if (oldOrigin->markup())
478 markup = new Markup(*oldOrigin->markup());
479 ConstPtr<EntityOrigin> newOrigin
480 = new EntityOrigin(entity,
482 oldOrigin->refLength(),
484 arcProcessors_[i].docHandler()
485 .externalDataEntity(new (allocator_)
486 ExternalDataEntityEvent(entity->asExternalDataEntity(),
489 // otherwise entity is not architectural
493 DelegateEventHandler::externalDataEntity(event);
496 void ArcEngineImpl::endElement(EndElementEvent *event)
498 while (gatheringContent_) {
499 if (--gatheringContent_ > 0) {
500 DelegateEventHandler::endElement(event);
503 delegateTo_ = delegateHandler();
504 // Clear out eventQueue_ in case handling the events
505 // causes events to be queued again.
507 tem.swap(eventQueue_);
509 tem.get()->handle(*this);
511 currentLocation_ = event->location();
512 for (size_t i = 0; i < arcProcessors_.size(); i++)
513 if (arcProcessors_[i].valid())
514 arcProcessors_[i].processEndElement(*event, allocator_);
515 DelegateEventHandler::endElement(event);
516 if (haveLinkProcess_)
517 linkProcess_.endElement();
520 void ArcEngineImpl::uselink(UselinkEvent *event)
522 if (!gatheringContent_)
523 linkProcess_.uselink(event->linkSet(),
525 event->lpd().pointer());
526 DelegateEventHandler::uselink(event);
529 void ArcEngineImpl::dispatchMessage(const Message &msg)
531 mgr_->dispatchMessage(msg);
534 void ArcEngineImpl::dispatchMessage(Message &msg)
536 mgr_->dispatchMessage(msg);
539 void ArcEngineImpl::initMessage(Message &msg)
541 mgr_->initMessage(msg);
542 msg.loc = currentLocation_;
545 ArcProcessor::ArcProcessor()
546 : errorIdref_(1), notationSetArch_(0), docHandler_(0), arcAuto_(1),
547 arcDtdIsParam_(0), valid_(false), mgr_(NULL), director_(NULL), docIndex_(0)
551 void ArcProcessor::setName(const StringC &name)
556 const Syntax &ArcProcessor::attributeSyntax() const
561 ConstPtr<Notation> ArcProcessor::getAttributeNotation(const StringC &name,
564 if (!metaDtd_.isNull())
565 return metaDtd_->lookupNotation(name);
569 ConstPtr<Entity> ArcProcessor::getAttributeEntity(const StringC &name,
572 // FIXME What about default entity
573 if (!notationSetArch_ && !metaDtd_.isNull())
574 return metaDtd_->lookupEntity(0, name);
578 void ArcProcessor::noteCurrentAttribute(size_t i, AttributeValue *value)
580 if (valid_ && !notationSetArch_)
581 currentAttributes_[i] = value;
584 ConstPtr<AttributeValue> ArcProcessor::getCurrentAttribute(size_t i) const
586 if (notationSetArch_)
588 return currentAttributes_[i];
591 // This code is the same as in the main parser.
592 // Once handling of ID/IDREF in architectures has been clarified.
593 // Maybe factor out into AttributeContext.
595 Boolean ArcProcessor::defineId(const StringC &str, const Location &loc,
600 Id *id = lookupCreateId(str);
602 prevLoc = id->defLocation();
609 void ArcProcessor::noteIdref(const StringC &str, const Location &loc)
611 if (!valid_ || !errorIdref_)
613 Id *id = lookupCreateId(str);
615 id->addPendingRef(loc);
618 Id *ArcProcessor::lookupCreateId(const StringC &name)
620 Id *id = idTable_.lookup(name);
628 void ArcProcessor::checkIdrefs()
630 NamedTableIter<Id> iter(idTable_);
632 while ((id = iter.next()) != 0) {
633 for (size_t i = 0; i < id->pendingRefs().size(); i++) {
634 Messenger::setNextLocation(id->pendingRefs()[i]);
635 message(ArcEngineMessages::missingId, StringMessageArg(id->name()));
640 void ArcProcessor::init(const EndPrologEvent &event,
641 const ConstPtr<Sd> &sd,
642 const ConstPtr<Syntax> &syntax,
643 const SgmlParser *parentParser,
645 const Vector<StringC> &superName,
646 ArcDirector &director,
647 SP_CONST SP_VOLATILE sig_atomic_t *cancelPtr)
649 director_ = &director;
655 docDtd_ = event.dtdPointer();
656 metaSyntax_ = docSyntax_;
657 mayDefaultAttribute_ = 1;
658 docSyntax_->generalSubstTable()->subst(name_);
659 Vector<StringC> docName(superName);
660 docName.push_back(name_);
661 ConstPtr<Notation> notation;
662 if (name_ == docSyntax_->rniReservedName(Syntax::rNOTATION)) {
663 notationSetArch_ = 1;
664 supportAtts_[rArcNamrA] = docSd_->execToDoc("NOTNAMES");
665 supportAtts_[rArcSuprA] = docSd_->execToDoc("NOTSUPR");
668 notation = docDtd_->lookupNotation(name_);
669 if (!notation.isNull()) {
670 ConstPtr<AttributeDefinitionList> notAttDef = notation->attributeDef();
671 attributeList_.init(notAttDef);
672 attributeList_.finish(*this);
673 supportAttributes(attributeList_);
674 // FIXME make sure locations in error messages are right
675 if (notation->externalId().publicIdString()
676 && (*notation->externalId().publicIdString()
677 == docSd_->execToDoc(notationSetArchPublicId))) {
678 notationSetArch_ = 1;
682 message(ArcEngineMessages::noArcNotation, StringMessageArg(name_));
684 ArcEngineImpl *engine
685 = new ArcEngineImpl(*mgr, parentParser, director, cancelPtr,
688 docSyntax_->generalSubstTable());
689 docHandler_ = engine;
690 ownEventHandler_ = engine;
691 if (notationSetArch_) {
692 initNotationSet(event.location());
695 if (supportAtts_[rArcDocF].size() == 0)
696 supportAtts_[rArcDocF] = name_;
697 if (supportAtts_[rArcFormA].size() == 0)
698 supportAtts_[rArcFormA] = name_;
699 rniContent_ = docSyntax_->delimGeneral(Syntax::dRNI);
700 rniContent_ += sd->execToDoc("CONTENT");
701 rniDefault_ = docSyntax_->delimGeneral(Syntax::dRNI);
702 rniDefault_ += docSyntax_->reservedName(Syntax::rDEFAULT);
703 rniArcCont_ = metaSyntax_->delimGeneral(Syntax::dRNI);
704 rniArcCont_ += sd->execToDoc("ARCCONT");
705 ConstPtr<Entity> dtdent = makeDtdEntity(notation.pointer());
708 StringC sysid = dtdent->asExternalEntity()->externalId().effectiveSystemId();
709 if (sysid.size() == 0
710 && !parentParser->entityCatalog().lookup(*dtdent,
715 message(ArcEngineMessages::arcGenerateSystemId,
716 StringMessageArg(name_));
719 docHandler_->sgmlDecl(new SgmlDeclEvent(sd, syntax));
720 docHandler_->startDtd(new StartDtdEvent(dtdent->name(),
725 SgmlParser::Params params;
726 params.entityType = SgmlParser::Params::dtd;
727 params.sysid = sysid;
728 params.parent = parentParser;
729 ParserOptions options = parentParser->options();
730 errorIdref_ = options.errorIdref;
731 options.errorAfdr = 0;
732 options.includes = arcOpts_;
733 params.options = &options;
735 params.prologSyntax = metaSyntax_;
736 params.instanceSyntax = metaSyntax_;
737 params.doctypeName = dtdent->name();
738 SgmlParser parser(params);
739 parser.parseAll(*docHandler_, cancelPtr);
740 Ptr<Dtd> baseDtd = parser.baseDtd();
742 || baseDtd->documentElementType()->definition()->undefined())
745 metaMapCache_.resize(docDtd_->nElementTypeIndex());
746 mungeMetaDtd(*baseDtd, *docDtd_);
747 docHandler_->endDtd(new EndDtdEvent(metaDtd_, event.location(), 0));
748 startContent(*metaDtd_);
749 currentAttributes_.resize(metaDtd_->nCurrentAttribute());
751 docHandler_->endProlog(new EndPrologEvent(metaDtd_, event.location()));
752 if (engine->nBases() == 0)
753 docHandler_ = engine->delegateHandler();
756 void ArcProcessor::initNotationSet(const Location &loc)
758 StringC name(docSyntax_->rniReservedName(Syntax::rNOTATION));
759 Ptr<Dtd> notDtd(new Dtd(name, 1));
761 ConstPtr<ElementDefinition> def
762 = new ElementDefinition(loc,
763 notDtd->allocElementDefinitionIndex(),
765 ElementDefinition::any);
766 notDtd->lookupElementType(name)->setElementDefinition(def, 0);
767 Dtd::ConstNotationIter iter(docDtd_->notationIter());
768 for (size_t i = 1;; i++) {
769 const Notation *notation = iter.next().pointer();
772 ElementType *e = new ElementType(notation->name(),
773 notDtd->nElementTypeIndex());
774 notDtd->insertElementType(e);
775 e->setElementDefinition(def, i);
776 if (!notation->attributeDef().isNull()) {
777 Vector<CopyOwner<AttributeDefinition> >
778 attdefs(notation->attributeDef()->size());
779 for (size_t i = 0; i < attdefs.size(); i++)
780 attdefs[i] = notation->attributeDef()->def(i)->copy();
781 e->setAttributeDef(new AttributeDefinitionList(attdefs,
782 notDtd->allocAttributeDefinitionListIndex()));
785 docHandler_->endProlog(new EndPrologEvent(metaDtd_, loc));
786 metaMapCache_.resize(docDtd_->nElementTypeIndex());
787 startContent(*notDtd);
791 void ArcProcessor::mungeMetaDtd(Dtd &metaDtd, const Dtd &docDtd)
793 if (supportAtts_[rArcDataF].size() > 0
794 && metaDtd.lookupNotation(supportAtts_[rArcDataF]).isNull()) {
795 Messenger::message(ArcEngineMessages::noArcDataF,
796 StringMessageArg(supportAtts_[rArcDataF]));
797 metaDtd.insertNotation(new Notation(supportAtts_[rArcDataF],
798 metaDtd.namePointer(),
801 // FIXME check for ArcAutoF
802 Dtd::ConstEntityIter iter(docDtd.generalEntityIter());
804 ConstPtr<Entity> ent = iter.next();
807 Ptr<Entity> copy(ent->copy());
808 if (!copy->asExternalDataEntity()
809 || mungeDataEntity(*(ExternalDataEntity *)copy.pointer()))
810 metaDtd.insertEntity(copy, 1);
814 Boolean ArcProcessor::mungeDataEntity(ExternalDataEntity &entity)
816 const MetaMap &map = buildMetaMap(0,
824 const Notation *notation = (const Notation *)map.attributed;
825 ConstPtr<AttributeValue> arcContent;
826 if (mapAttributes(entity.attributes(), 0, 0, atts, arcContent, map)) {
827 // FIXME check arcContent
828 entity.setNotation((Notation *)notation, atts);
831 // FIXME error tried to use #CONTENT
835 ConstPtr<Entity> ArcProcessor::makeDtdEntity(const Notation *)
837 if (!supportAtts_[rArcDTD].size()) {
838 mgr_->message(ArcEngineMessages::noArcDTDAtt);
841 ConstPtr<Entity> entity = docDtd_->lookupEntity(arcDtdIsParam_,
842 supportAtts_[rArcDTD]);
843 if (entity.isNull()) {
844 mgr_->message(ArcEngineMessages::arcDtdNotDeclared,
845 StringMessageArg(supportAtts_[rArcDTD]));
848 if (!entity->asExternalEntity()) {
849 mgr_->message(ArcEngineMessages::arcDtdNotExternal,
850 StringMessageArg(supportAtts_[rArcDTD]));
853 ExternalId externalId(entity->asExternalEntity()->externalId());
855 // Use the public identifier of the notation to find the meta-DTD.
856 if (externalId.effectiveSystemId().size() == 0 && notation) {
857 if (notation->externalId().effectiveSystemId().size()) {
858 StringC tem(notation->externalId().effectiveSystemId());
859 externalId.setEffectiveSystem(tem);
861 else if (!externalId.publicId()) {
862 const PublicId *pubid = notation->externalId().publicId();
863 PublicId::OwnerType ownerType;
864 if (pubid && pubid->getOwnerType(ownerType)) {
866 unsigned textClassPos = 2;
867 if (ownerType != PublicId::ISO)
870 pubid->getOwner(owner);
871 textClassPos += owner.size();
872 pubidText.addChars(pubid->string().data(),
874 pubid->text().charLocation(0));
875 pubidText.addChars(docSd_->execToDoc("DTD"),
876 pubid->text().charLocation(textClassPos));
877 for (; textClassPos < pubid->string().size(); textClassPos++)
878 if (pubid->string()[textClassPos] == docSyntax_->space())
880 pubidText.addChars(pubid->string().data() + textClassPos,
881 pubid->string().size() - textClassPos,
882 pubid->text().charLocation(textClassPos));
883 const MessageType1 *msg;
884 externalId.setPublic(pubidText, docSd_->docCharset(),
885 docSyntax_->space(), msg);
890 return new ExternalTextEntity(supportAtts_[rArcDocF],
892 entity->defLocation(),
896 void ArcProcessor::supportAttributes(const AttributeList &atts)
898 static const char *const s[] = {
912 for (size_t i = 0; i < SIZEOF(s); i++) {
913 StringC attName(docSd_->execToDoc(s[i]));
914 docSyntax_->generalSubstTable()->subst(attName);
916 if (atts.attributeIndex(attName, ind)) {
917 const AttributeValue *value = atts.value(ind);
919 const Text *textP = value->text();
920 // FIXME check for empty value
922 supportAtts_[i] = textP->string();
925 processArcQuant(*textP);
928 docSyntax_->generalSubstTable()->subst(supportAtts_[i]);
929 if (supportAtts_[i] == docSd_->execToDoc("ARCAUTO"))
931 else if (supportAtts_[i] == docSd_->execToDoc("NARCAUTO"))
934 Messenger::message(ArcEngineMessages::invalidArcAuto,
935 StringMessageArg(supportAtts_[i]));
938 docSyntax_->generalSubstTable()->subst(supportAtts_[i]);
939 if (supportAtts_[i] == docSd_->execToDoc("ARCINDR")) {
940 Messenger::setNextLocation(textP->charLocation(0));
941 Messenger::message(ArcEngineMessages::arcIndrNotSupported);
943 else if (supportAtts_[i] != docSd_->execToDoc("NARCINDR")) {
944 Messenger::setNextLocation(textP->charLocation(0));
945 Messenger::message(ArcEngineMessages::invalidArcIndr,
946 StringMessageArg(supportAtts_[i]));
953 docSyntax_->generalSubstTable()->subst(supportAtts_[i]);
959 metaSyntax_->generalSubstTable()->subst(supportAtts_[i]);
963 const StringC &pero = docSyntax_->delimGeneral(Syntax::dPERO);
964 if (supportAtts_[i].size() >= pero.size()) {
965 StringC tem(supportAtts_[i].data(), pero.size());
966 docSyntax_->generalSubstTable()->subst(tem);
969 tem.assign(supportAtts_[i].data() + pero.size(),
970 supportAtts_[i].size() - pero.size());
971 tem.swap(supportAtts_[i]);
974 docSyntax_->entitySubstTable()->subst(supportAtts_[i]);
982 processArcOpts(atts);
985 void ArcProcessor::processArcOpts(const AttributeList &atts)
987 StringC attName(docSd_->execToDoc("ArcOptSA"));
988 docSyntax_->generalSubstTable()->subst(attName);
990 Vector<StringC> arcOptA;
991 Vector<size_t> arcOptAPos;
992 const Text *arcOptAText = 0;
993 if (atts.attributeIndex(attName, ind)) {
994 const AttributeValue *value = atts.value(ind);
996 arcOptAText = value->text();
998 split(*arcOptAText, docSyntax_->space(), arcOptA, arcOptAPos);
1002 arcOptA.push_back(docSd_->execToDoc("ArcOpt"));
1003 for (size_t i = 0; i < arcOptA.size(); i++) {
1004 docSyntax_->generalSubstTable()->subst(arcOptA[i]);
1005 if (atts.attributeIndex(arcOptA[i], ind)) {
1006 const AttributeValue *value = atts.value(ind);
1008 const Text *textP = value->text();
1010 Vector<StringC> opts;
1011 Vector<size_t> optsPos;
1012 split(*textP, docSyntax_->space(), opts, optsPos);
1013 arcOpts_.insert(arcOpts_.begin(),
1014 opts.begin(), opts.begin() + opts.size());
1021 void ArcProcessor::processArcQuant(const Text &text)
1023 Ptr<Syntax> newMetaSyntax;
1024 Vector<StringC> tokens;
1025 Vector<size_t> tokensPos;
1026 split(text, docSyntax_->space(), tokens, tokensPos);
1027 for (size_t i = 0; i < tokens.size(); i++) {
1028 docSyntax_->generalSubstTable()->subst(tokens[i]);
1029 Syntax::Quantity quantityName;
1030 if (!docSd_->lookupQuantityName(tokens[i], quantityName)) {
1031 setNextLocation(text.charLocation(tokensPos[i]));
1032 Messenger::message(ArcEngineMessages::invalidQuantity,
1033 StringMessageArg(tokens[i]));
1035 else if (i + 1 >= tokens.size()) {
1036 setNextLocation(text.charLocation(tokensPos[i]));
1037 Messenger::message(ArcEngineMessages::missingQuantityValue,
1038 StringMessageArg(tokens[i]));
1042 unsigned long val = 0;
1043 if (tokens[i].size() > 8) {
1044 setNextLocation(text.charLocation(tokensPos[i] + 8));
1045 Messenger::message(ArcEngineMessages::quantityValueTooLong,
1046 StringMessageArg(tokens[i]));
1047 tokens[i].resize(8);
1049 for (size_t j = 0; j < tokens[i].size(); j++) {
1050 int weight = docSd_->digitWeight(tokens[i][j]);
1052 setNextLocation(text.charLocation(tokensPos[i] + j));
1053 Char c = tokens[i][j];
1054 Messenger::message(ArcEngineMessages::invalidDigit,
1055 StringMessageArg(StringC(&c, 1)));
1064 if (val > docSyntax_->quantity(quantityName)) {
1065 if (newMetaSyntax.isNull())
1066 newMetaSyntax = new Syntax(*docSyntax_);
1067 newMetaSyntax->setQuantity(quantityName, val);
1071 if (!newMetaSyntax.isNull())
1072 metaSyntax_ = newMetaSyntax;
1075 Boolean ArcProcessor::processStartElement(const StartElementEvent &event,
1076 const AttributeList *linkAttributes,
1077 const Text *content,
1078 Allocator &allocator)
1080 unsigned suppressFlags = (openElementFlags_.size() > 0
1081 ? (openElementFlags_.back() & ~isArc)
1082 : (unsigned)condIgnoreData);
1083 if ((suppressFlags & suppressForm)
1084 && (suppressFlags & suppressSupr)) {
1085 // Make this case efficient.
1086 openElementFlags_.push_back(suppressFlags);
1089 const AttributeList &atts = event.attributes();
1090 const MetaMap &map = buildMetaMap(event.elementType(),
1095 const ElementType *metaType;
1096 ConstPtr<AttributeValue> arcContent;
1097 if (map.attributed == 0) {
1098 if (!(tagLevel() == 0
1099 && !currentElement().isFinished())) {
1100 if (!arcContent.isNull()
1101 && (currentElement().declaredEmpty()
1102 || !currentElement().tryTransitionPcdata()))
1103 Messenger::message(ArcEngineMessages::invalidArcContent);
1104 openElementFlags_.push_back(map.suppressFlags);
1107 metaType = metaDtd_->documentElementType();
1108 if (!notationSetArch_)
1109 mgr_->message(ArcEngineMessages::documentElementNotArc,
1110 StringMessageArg(metaType->name()));
1111 attributeList_.init(metaType->attributeDef());
1112 attributeList_.finish(*this);
1115 if (!mapAttributes(atts, linkAttributes, content, attributeList_,
1118 metaType = (const ElementType *)map.attributed;
1119 suppressFlags = map.suppressFlags;
1121 StartElementEvent *genEvent
1122 = new (allocator) StartElementEvent(metaType,
1127 if (notationSetArch_) {
1129 && !currentElement().isFinished())
1130 currentElement().tryTransition(metaDtd_->documentElementType());
1132 else if (metaType->definition()->undefined())
1133 Messenger::message(ArcEngineMessages::undefinedElement,
1134 StringMessageArg(metaType->name()));
1135 else if (elementIsExcluded(metaType))
1136 Messenger::message(ArcEngineMessages::elementExcluded,
1137 StringMessageArg(metaType->name()));
1138 else if (elementIsIncluded(metaType))
1139 genEvent->setIncluded();
1140 else if (!currentElement().tryTransition(metaType))
1141 Messenger::message(ArcEngineMessages::invalidElement,
1142 StringMessageArg(metaType->name()));
1144 pushElement(new (allocator) OpenElement(metaType,
1146 genEvent->included(),
1149 docHandler_->startElement(genEvent);
1150 if (attributeList_.conref())
1151 currentElement().setConref();
1152 if (!arcContent.isNull() && arcContent->text() != 0) {
1153 if (currentElement().declaredEmpty()
1154 || !currentElement().tryTransitionPcdata())
1155 Messenger::message(ArcEngineMessages::invalidArcContent);
1157 emitArcContent(*arcContent->text(), docHandler(), allocator);
1158 suppressFlags |= (suppressForm|suppressSupr|ignoreData);
1160 suppressFlags &= ~recoverData;
1161 openElementFlags_.push_back(suppressFlags | isArc);
1165 void ArcProcessor::emitArcContent(const Text &text,
1166 EventHandler &handler,
1167 Allocator &allocator)
1169 TextIter iter(text);
1170 TextItem::Type type;
1173 const Location *loc;
1174 while (iter.next(type, s, n, loc))
1176 case TextItem::data:
1177 case TextItem::cdata:
1178 // +1 because first dataEvent is the non-architectural data.
1179 if (type == TextItem::data)
1180 handler.data(new (allocator) ImmediateDataEvent(Event::characterData,
1187 handler.data(new (allocator)
1188 CdataEntityEvent(loc->origin()->asEntityOrigin()
1189 ->entity()->asInternalEntity(),
1192 case TextItem::sdata:
1194 handler.sdataEntity(new (allocator)
1195 SdataEntityEvent(loc->origin()->asEntityOrigin()
1196 ->entity()->asInternalEntity(),
1204 Boolean ArcProcessor::processData()
1206 if (openElementFlags_.size() > 0
1207 && (openElementFlags_.back() & ignoreData))
1209 if (notationSetArch_)
1210 return currentElement().type() != metaDtd_->documentElementType();
1211 else if (!currentElement().declaredEmpty()
1212 && currentElement().tryTransitionPcdata())
1214 else if (openElementFlags_.size() > 0
1215 && (openElementFlags_.back() & condIgnoreData))
1218 // Only give this error once per element
1219 if (openElementFlags_.size() > 0) {
1220 if (openElementFlags_.back() & recoverData)
1222 openElementFlags_.back() |= recoverData;
1224 Messenger::message(ArcEngineMessages::invalidData);
1229 Boolean ArcProcessor::mapAttributes(const AttributeList &from,
1230 const AttributeList *fromLink,
1231 const Text *content,
1233 ConstPtr<AttributeValue> &arcContent,
1237 to.init(map.attributed->attributeDef());
1238 for (size_t i = 0; i < map.attMapFrom.size(); i++) {
1239 unsigned fromIndex = map.attMapFrom[i];
1240 const AttributeList *fromList = &from;
1241 if (fromIndex != contentPseudoAtt && fromIndex >= fromList->size()) {
1242 fromList = fromLink;
1243 fromIndex -= from.size();
1245 if (map.attMapTo[i] == contentPseudoAtt) {
1246 if (fromIndex != contentPseudoAtt)
1247 arcContent = fromList->valuePointer(fromIndex);
1250 const Text *fromText = 0;
1251 Boolean fromTextTokenized = 0;
1252 if (map.attMapFrom[i] == contentPseudoAtt) {
1258 const AttributeValue *value = fromList->value(fromIndex);
1260 fromText = value->text();
1261 fromTextTokenized = fromList->tokenized(fromIndex);
1263 && fromList == &from
1264 && !from.specified(fromIndex)
1265 && (map.attributed->attributeDef()->def(map.attMapTo[i])
1266 ->missingValueWouldMatch(*fromText, *this)))
1271 unsigned specLength = 0;
1273 if (!fromTextTokenized && to.tokenized(map.attMapTo[i]))
1274 fromText->tokenize(docSyntax_->space(), tem);
1277 to.setSpec(map.attMapTo[i], *this);
1278 to.setValue(map.attMapTo[i], tem, *this, specLength);
1287 const ArcProcessor::MetaMap &
1288 ArcProcessor::buildMetaMap(const ElementType *docElementType,
1289 const Notation *notation,
1290 const AttributeList &atts,
1291 const AttributeList *linkAtts,
1292 unsigned suppressFlags)
1295 const Attributed *attributed = docElementType;
1296 const StringC *nameP;
1298 attributed = notation;
1300 nameP = ¬ation->name();
1304 nameP = &docElementType->name();
1306 // Try to use cached entry.
1307 Boolean inhibitCache = 0;
1309 if (isNotation || docElementType->definition()->undefined()) {
1311 cacheIndex = (unsigned)-1;
1314 cacheIndex = docElementType->index();
1315 const MetaMapCache *cache = metaMapCache_[cacheIndex].pointer();
1317 && cache->suppressFlags == suppressFlags
1318 && cache->linkAtts == linkAtts) {
1319 for (int i = 0;; i++) {
1320 if (i == MetaMapCache::nNoSpec)
1322 unsigned attIndex = cache->noSpec[i];
1323 if (attIndex != invalidAtt && atts.specified(attIndex))
1328 // no valid cached MetaMap
1329 // Handle suppression.
1330 unsigned oldSuppressFlags = suppressFlags;
1331 unsigned newSuppressFlags = suppressFlags;
1332 unsigned arcSuprIndex;
1334 considerSupr(atts, linkAtts, suppressFlags, newSuppressFlags, inhibitCache,
1337 arcSuprIndex = invalidAtt;
1339 unsigned arcIgnDIndex;
1341 considerIgnD(atts, linkAtts, suppressFlags, newSuppressFlags, inhibitCache,
1344 arcIgnDIndex = invalidAtt;
1346 unsigned arcFormIndex;
1347 const Attributed *metaAttributed
1349 ? considerNotation(atts, suppressFlags, inhibitCache, arcFormIndex)
1350 : considerForm(atts, linkAtts, *nameP, isNotation,
1351 suppressFlags, newSuppressFlags,
1352 inhibitCache, arcFormIndex));
1353 // See if there's a renamer that will inhibit cacheing.
1354 unsigned arcNamerIndex;
1355 const Text *namerText;
1357 namerText = considerNamer(atts, inhibitCache, arcNamerIndex);
1359 arcNamerIndex = invalidAtt;
1364 noCacheMetaMap_.clear();
1365 mapP = &noCacheMetaMap_;
1368 MetaMapCache *cache = metaMapCache_[cacheIndex].pointer();
1372 cache = new MetaMapCache;
1373 metaMapCache_[cacheIndex] = cache;
1375 cache->noSpec[0] = arcFormIndex;
1376 cache->noSpec[1] = arcNamerIndex;
1377 cache->noSpec[2] = arcSuprIndex;
1378 cache->noSpec[3] = arcIgnDIndex;
1379 cache->suppressFlags = oldSuppressFlags;
1380 cache->linkAtts = linkAtts;
1383 mapP->attributed = metaAttributed;
1384 mapP->suppressFlags = newSuppressFlags;
1385 // Build the attribute map.
1386 if (metaAttributed) {
1387 Vector<PackedBoolean> renamed;
1388 ConstPtr<AttributeDefinitionList> metaAttDef
1389 = metaAttributed->attributeDef();
1390 if (!metaAttDef.isNull())
1391 renamed.assign(metaAttDef->size(), PackedBoolean(0));
1395 const Text *linkNamerText = considerNamer(*linkAtts, specified, index);
1397 buildAttributeMapRename(*mapP, *linkNamerText, atts, linkAtts, renamed);
1400 buildAttributeMapRename(*mapP, *namerText, atts, 0, renamed);
1401 buildAttributeMapRest(*mapP, atts, linkAtts, renamed);
1406 void ArcProcessor::considerSupr(const AttributeList &atts,
1407 const AttributeList *linkAtts,
1408 unsigned &thisSuppressFlags,
1409 unsigned &newSuppressFlags,
1410 Boolean &inhibitCache,
1411 unsigned &arcSuprIndex)
1413 arcSuprIndex = invalidAtt;
1414 if (thisSuppressFlags & suppressSupr)
1416 if (!supportAtts_[rArcSuprA].size())
1418 const AttributeValue *val;
1420 if (linkAtts && linkAtts->attributeIndex(supportAtts_[rArcSuprA], tem))
1421 val = linkAtts->value(tem);
1422 else if (atts.attributeIndex(supportAtts_[rArcSuprA], arcSuprIndex)) {
1423 if (atts.current(arcSuprIndex) || atts.specified(arcSuprIndex))
1425 val = atts.value(arcSuprIndex);
1431 const Text *textP = val->text();
1434 StringC token = textP->string();
1435 // FIXME trim spaces
1436 docSyntax_->generalSubstTable()->subst(token);
1437 // sArcForm suppress processing for all elements except
1438 // those that have a non-implied ArcSupr attribute.
1439 thisSuppressFlags &= ~suppressForm;
1440 newSuppressFlags &= ~(suppressForm|suppressSupr);
1441 if (matchName(token, "sArcForm"))
1442 newSuppressFlags |= suppressForm;
1444 // I don't think this is useful
1445 else if (matchName(token, "sArcSupr"))
1446 newSuppressFlags |= suppressSupr;
1448 else if (matchName(token, "sArcAll"))
1449 newSuppressFlags |= (suppressSupr|suppressForm);
1450 else if (!matchName(token, "sArcNone")) {
1451 Messenger::setNextLocation(textP->charLocation(0));
1452 Messenger::message(ArcEngineMessages::invalidSuppress,
1453 StringMessageArg(token));
1457 void ArcProcessor::considerIgnD(const AttributeList &atts,
1458 const AttributeList *linkAtts,
1459 unsigned thisSuppressFlags,
1460 unsigned &newSuppressFlags,
1461 Boolean &inhibitCache,
1462 unsigned &arcIgnDIndex)
1464 arcIgnDIndex = invalidAtt;
1465 if (thisSuppressFlags & suppressSupr)
1467 if (!supportAtts_[rArcIgnDA].size())
1469 const AttributeValue *val;
1471 if (linkAtts && linkAtts->attributeIndex(supportAtts_[rArcIgnDA], tem))
1472 val = linkAtts->value(tem);
1473 else if (atts.attributeIndex(supportAtts_[rArcIgnDA], arcIgnDIndex)) {
1474 if (atts.current(arcIgnDIndex) || atts.specified(arcIgnDIndex))
1476 val = atts.value(arcIgnDIndex);
1482 const Text *textP = val->text();
1485 StringC token = textP->string();
1486 // FIXME trim spaces
1487 docSyntax_->generalSubstTable()->subst(token);
1488 newSuppressFlags &= ~(ignoreData|condIgnoreData);
1489 if (matchName(token, "ArcIgnD"))
1490 newSuppressFlags |= ignoreData;
1491 else if (matchName(token, "cArcIgnD"))
1492 newSuppressFlags |= condIgnoreData;
1493 else if (!matchName(token, "nArcIgnD")) {
1494 Messenger::setNextLocation(textP->charLocation(0));
1495 Messenger::message(ArcEngineMessages::invalidIgnD,
1496 StringMessageArg(token));
1501 ArcProcessor::considerNotation(const AttributeList &atts,
1502 unsigned thisSuppressFlags,
1503 Boolean &inhibitCache,
1504 unsigned ¬AttIndex)
1506 if (thisSuppressFlags & suppressForm)
1508 for (unsigned i = 0; i < atts.size(); i++) {
1509 const AttributeSemantics *sem = atts.semantics(i);
1511 ConstPtr<Notation> notation = sem->notation();
1512 if (!notation.isNull()) {
1514 if (atts.current(notAttIndex) || atts.specified(notAttIndex))
1516 return metaDtd_->lookupElementType(notation->name());
1520 notAttIndex = invalidAtt;
1525 ArcProcessor::considerForm(const AttributeList &atts,
1526 const AttributeList *linkAtts,
1527 const StringC &name,
1529 unsigned thisSuppressFlags,
1530 unsigned &newSuppressFlags,
1531 Boolean &inhibitCache,
1532 unsigned &arcFormIndex)
1534 arcFormIndex = invalidAtt;
1535 if ((thisSuppressFlags & suppressForm)
1536 && (supportAtts_[rArcSuprF].size() == 0
1537 || (thisSuppressFlags & suppressSupr)
1541 const AttributeValue *val;
1542 if (linkAtts && linkAtts->attributeIndex(supportAtts_[rArcFormA], tem))
1543 val = linkAtts->value(tem);
1544 else if (atts.attributeIndex(supportAtts_[rArcFormA], arcFormIndex)) {
1545 if (atts.current(arcFormIndex) || atts.specified(arcFormIndex))
1547 val = atts.value(arcFormIndex);
1550 return autoForm(atts, name, isNotation,
1551 thisSuppressFlags, newSuppressFlags,
1552 inhibitCache, arcFormIndex);
1556 const Text *textP = val->text();
1560 metaName = textP->string();
1561 // FIXME should trim leading and trailing spaces
1562 metaSyntax_->generalSubstTable()->subst(metaName);
1564 const Attributed *metaAttributed = metaDtd_->lookupElementType(metaName);
1565 if (!metaAttributed)
1566 metaAttributed = lookupCreateUndefinedElement(metaName, Location());
1567 if (metaName == supportAtts_[rArcSuprF]) {
1568 newSuppressFlags |= suppressForm;
1569 return metaAttributed;
1571 if (thisSuppressFlags & suppressForm)
1573 return metaAttributed;
1576 return metaDtd_->lookupNotation(metaName).pointer();
1580 ArcProcessor::autoForm(const AttributeList &atts,
1581 const StringC &name,
1583 unsigned thisSuppressFlags,
1584 unsigned &newSuppressFlags,
1585 Boolean &inhibitCache,
1589 const Attributed *metaAttributed;
1590 if (openElementFlags_.size() == 0) {
1591 metaAttributed = metaDtd_->documentElementType();
1597 metaAttributed = metaDtd_->lookupElementType(name);
1599 && supportAtts_[rArcBridF].size() > 0
1600 && atts.idIndex(idIndex)
1601 && atts.specified(idIndex)) {
1604 = metaDtd_->lookupElementType(supportAtts_[rArcBridF]);
1608 && name == supportAtts_[rArcSuprF]) {
1609 newSuppressFlags = suppressForm|ignoreData;
1611 else if (thisSuppressFlags & suppressForm)
1613 return metaAttributed;
1615 else if (thisSuppressFlags & suppressForm)
1618 const Attributed *metaAttributed = 0;
1620 metaAttributed = metaDtd_->lookupNotation(name).pointer();
1621 if (!metaAttributed && supportAtts_[rArcDataF].size() > 0)
1623 = metaDtd_->lookupNotation(supportAtts_[rArcDataF]).pointer();
1624 return metaAttributed;
1630 ArcProcessor::considerNamer(const AttributeList &atts,
1631 Boolean &inhibitCache,
1632 unsigned &arcNamerIndex)
1634 arcNamerIndex = invalidAtt;
1635 if (supportAtts_[rArcNamrA].size() == 0
1636 || !atts.attributeIndex(supportAtts_[rArcNamrA], arcNamerIndex))
1638 if (atts.current(arcNamerIndex) || atts.specified(arcNamerIndex))
1640 const AttributeValue *val = atts.value(arcNamerIndex);
1646 void ArcProcessor::buildAttributeMapRename(MetaMap &map,
1648 const AttributeList &atts,
1649 const AttributeList *linkAtts,
1650 Vector<PackedBoolean> &attRenamed)
1652 Vector<StringC> tokens;
1653 Vector<size_t> tokensPos;
1654 split(rename, docSyntax_->space(), tokens, tokensPos);
1655 ConstPtr<AttributeDefinitionList> metaAttDef;
1657 metaAttDef = map.attributed->attributeDef();
1658 // FIXME Should check that ARCCONT doesn't appear more than once.
1659 for (size_t i = 0; i < tokens.size(); i += 2) {
1660 unsigned fromIndex = invalidAtt;
1661 unsigned toIndex = invalidAtt;
1662 metaSyntax_->generalSubstTable()->subst(tokens[i]);
1663 if (tokens[i] == rniArcCont_)
1664 toIndex = contentPseudoAtt;
1665 else if (metaAttDef.isNull()
1666 || !metaAttDef->attributeIndex(tokens[i], toIndex)) {
1667 setNextLocation(rename.charLocation(tokensPos[i]));
1668 Messenger::message(ArcEngineMessages::renameToInvalid,
1669 StringMessageArg(tokens[i]));
1671 else if (attRenamed[toIndex]) {
1672 toIndex = invalidAtt;
1673 setNextLocation(rename.charLocation(tokensPos[i]));
1674 Messenger::message(ArcEngineMessages::renameToDuplicate,
1675 StringMessageArg(tokens[i]));
1677 if (i + 1 >= tokens.size()) {
1678 setNextLocation(rename.charLocation(tokensPos[i]));
1679 Messenger::message(ArcEngineMessages::renameMissingAttName);
1682 docSyntax_->generalSubstTable()->subst(tokens[i + 1]);
1683 if (tokens[i + 1] == rniContent_) {
1684 fromIndex = contentPseudoAtt;
1686 else if (tokens[i + 1] == rniDefault_) {
1687 if (toIndex != contentPseudoAtt)
1688 attRenamed[toIndex] = 1;
1691 && linkAtts->attributeIndex(tokens[i + 1], fromIndex))
1692 fromIndex += atts.size();
1693 else if (!atts.attributeIndex(tokens[i + 1], fromIndex)) {
1694 setNextLocation(rename.charLocation(tokensPos[i + 1]));
1695 Messenger::message(ArcEngineMessages::renameFromInvalid,
1696 StringMessageArg(tokens[i + 1]));
1699 if (fromIndex != invalidAtt && toIndex != invalidAtt) {
1700 map.attMapFrom.push_back(fromIndex);
1701 map.attMapTo.push_back(toIndex);
1702 if (toIndex != contentPseudoAtt) {
1703 attRenamed[toIndex] = 1;
1704 if (metaAttDef->def(toIndex)->isId()
1705 && (fromIndex >= atts.size() || !atts.id(fromIndex)))
1706 Messenger::message(ArcEngineMessages::idMismatch,
1707 StringMessageArg(metaAttDef->def(toIndex)
1714 void ArcProcessor::buildAttributeMapRest(MetaMap &map,
1715 const AttributeList &atts,
1716 const AttributeList *linkAtts,
1717 const Vector<PackedBoolean> &attRenamed)
1719 ConstPtr<AttributeDefinitionList> metaAttDef
1720 = map.attributed->attributeDef();
1721 if (metaAttDef.isNull())
1723 for (unsigned i = 0; i < metaAttDef->size(); i++)
1724 if (!attRenamed[i]) {
1726 if (metaAttDef->def(i)->isId()) {
1727 for (unsigned j = 0; j < atts.size(); j++)
1729 map.attMapFrom.push_back(j);
1730 map.attMapTo.push_back(i);
1734 else if (linkAtts && linkAtts->attributeIndex(metaAttDef->def(i)->name(),
1736 map.attMapFrom.push_back(fromIndex + atts.size());
1737 map.attMapTo.push_back(i);
1739 else if (atts.attributeIndex(metaAttDef->def(i)->name(), fromIndex)) {
1740 map.attMapFrom.push_back(fromIndex);
1741 map.attMapTo.push_back(i);
1746 Boolean ArcProcessor::matchName(const StringC &name, const char *key)
1748 if (name.size() != strlen(key))
1750 StringC tem(docSd_->execToDoc(key));
1751 docSyntax_->generalSubstTable()->subst(tem);
1755 void ArcProcessor::split(const Text &text,
1757 Vector<StringC> &tokens,
1758 Vector<size_t> &tokensPos)
1760 const StringC &str = text.string();
1761 for (size_t i = 0;;) {
1762 for (; i < str.size() && str[i] == space; i++)
1764 if (i >= str.size())
1767 for (; i < str.size() && str[i] != space; i++)
1769 tokens.push_back(StringC(str.data() + start, i - start));
1770 tokensPos.push_back(start);
1774 void ArcProcessor::processEndElement(const EndElementEvent &event,
1775 Allocator &allocator)
1777 Boolean wasArc = (openElementFlags_.back() & isArc);
1778 openElementFlags_.resize(openElementFlags_.size() - 1);
1780 EndElementEvent *genEvent
1781 = new (allocator) EndElementEvent(currentElement().type(),
1785 if (currentElement().included())
1786 genEvent->setIncluded();
1787 docHandler_->endElement(genEvent);
1788 if (!currentElement().isFinished())
1789 Messenger::message(ArcEngineMessages::unfinishedElement,
1790 StringMessageArg(currentElement().type()->name()));
1795 void ArcProcessor::dispatchMessage(Message &msg)
1797 mgr_->dispatchMessage(msg);
1800 void ArcProcessor::dispatchMessage(const Message &msg)
1802 mgr_->dispatchMessage(msg);
1805 void ArcProcessor::initMessage(Message &msg)
1807 mgr_->initMessage(msg);
1809 StringC rniPcdata = metaSyntax_->delimGeneral(Syntax::dRNI);
1810 rniPcdata += metaSyntax_->reservedName(Syntax::rPCDATA);
1811 getOpenElementInfo(msg.openElementInfo, rniPcdata);
1815 ArcProcessor::MetaMapCache::MetaMapCache()
1817 for (int i = 0; i < nNoSpec; i++)
1818 noSpec[i] = invalidAtt;
1823 void ArcProcessor::MetaMapCache::clear()
1825 for (int i = 0; i < nNoSpec; i++)
1826 noSpec[i] = invalidAtt;
1831 ArcProcessor::MetaMap::MetaMap()
1832 : attributed(0), suppressFlags(0)
1836 void ArcProcessor::MetaMap::clear()