3065 some functions in the tcp module can be static
[unleashed.git] / usr / src / cmd / man / src / util / nsgmls.src / lib / ArcEngine.cxx
blob0efd9bd3d8044468210bf6b22428caa9d46e9743
1 // Copyright (c) 1996 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
5 #ifdef __GNUG__
6 #pragma implementation
7 #endif
9 #include "splib.h"
10 #include "ArcEngine.h"
11 #include "ArcProcessor.h"
12 #include "Vector.h"
13 #include "NCVector.h"
14 #include "IQueue.h"
15 #include "ArcEngineMessages.h"
16 #include "MessageArg.h"
17 #include "ParserOptions.h"
18 #include "SgmlParser.h"
19 #include "Allocator.h"
20 #include "LinkProcess.h"
21 #include "macros.h"
23 #ifdef SP_NAMESPACE
24 namespace SP_NAMESPACE {
25 #endif
27 static const size_t sizes[] = {
28 sizeof(StartElementEvent),
29 sizeof(EndElementEvent),
30 sizeof(ImmediateDataEvent),
31 sizeof(SdataEntityEvent),
32 sizeof(EndPrologEvent),
33 sizeof(CdataEntityEvent),
34 sizeof(SdataEntityEvent),
35 sizeof(ExternalDataEntityEvent),
36 sizeof(OpenElement)
39 static
40 size_t maxSize(const size_t *v, size_t n)
42 size_t max = 0;
43 for (size_t i = 0; i < n; i++) {
44 if (v[i] > max)
45 max = v[i];
47 return max;
50 const unsigned invalidAtt = unsigned(-1);
51 const unsigned contentPseudoAtt = unsigned(-2);
53 class DelegateEventHandler : public EventHandler {
54 public:
55 #define EVENT(C, f) void f(C *ev) { delegateTo_->f(ev); }
56 #include "events.h"
57 #undef EVENT
58 protected:
59 EventHandler *delegateTo_;
62 class QueueEventHandler : public EventHandler, public IQueue<Event> {
63 public:
64 #define EVENT(C, f) void f(C *ev) { ev->copyData(); append(ev); }
65 #include "events.h"
66 #undef EVENT
69 // This just passes through messages.
71 class NullEventHandler : public EventHandler {
72 public:
73 NullEventHandler(Messenger &mgr) : mgr_(&mgr) { }
74 void message(MessageEvent *event) {
75 mgr_->dispatchMessage(event->message());
77 private:
78 Messenger *mgr_;
81 class ArcEngineImpl : public DelegateEventHandler, private Messenger {
82 public:
83 ArcEngineImpl(Messenger &mgr,
84 const SgmlParser *parser,
85 ArcDirector &director,
86 const volatile sig_atomic_t *cancelPtr,
87 const Notation *,
88 const Vector<StringC> &name,
89 const SubstTable<Char> *table);
90 ~ArcEngineImpl();
91 void sgmlDecl(SgmlDeclEvent *);
92 void appinfo(AppinfoEvent *);
93 void startElement(StartElementEvent *);
94 void endElement(EndElementEvent *);
95 void data(DataEvent *);
96 void sdataEntity(SdataEntityEvent *);
97 void externalDataEntity(ExternalDataEntityEvent *);
98 void pi(PiEvent *);
99 void endProlog(EndPrologEvent *);
100 void startDtd(StartDtdEvent *);
101 void endDtd(EndDtdEvent *);
102 void startLpd(StartLpdEvent *);
103 void endLpd(EndLpdEvent *);
104 void uselink(UselinkEvent *);
105 size_t nBases() const { return arcProcessors_.size(); }
106 EventHandler *delegateHandler() { return eventHandler_; }
107 private:
108 void dispatchMessage(const Message &);
109 void dispatchMessage(Message &);
110 void initMessage(Message &);
112 EventHandler *eventHandler_;
113 NCVector<ArcProcessor> arcProcessors_;
114 ConstPtr<Sd> sd_;
115 ConstPtr<Syntax> syntax_;
116 StringC arcBase_;
117 StringC is10744_;
118 int stage_;
119 QueueEventHandler eventQueue_;
120 NullEventHandler nullHandler_;
121 const SgmlParser *parser_;
122 Location currentLocation_;
123 unsigned gatheringContent_;
124 Text content_;
125 unsigned startAgain_;
126 Allocator alloc_;
127 StringC appinfo_;
128 const AttributeList *linkAttributes_;
129 LinkProcess linkProcess_;
130 Boolean haveLinkProcess_;
131 Vector<StringC> docName_;
132 ArcDirector *director_;
133 Messenger *mgr_;
134 const volatile sig_atomic_t *cancelPtr_;
138 void ArcEngine::parseAll(SgmlParser &parser,
139 Messenger &mgr,
140 ArcDirector &director,
141 const volatile sig_atomic_t *cancelPtr)
143 ArcEngineImpl wrap(mgr, &parser, director, cancelPtr,
144 0, Vector<StringC>(), 0);
145 parser.parseAll(wrap, cancelPtr);
148 EventHandler *
149 SelectOneArcDirector::arcEventHandler(const Notation *,
150 const Vector<StringC> &name,
151 const SubstTable<Char> *table)
153 if (name.size() != select_.size())
154 return 0;
155 for (size_t i = 0; i < name.size(); i++) {
156 StringC tem(select_[i]);
157 table->subst(tem);
158 if (name[i] != tem)
159 return 0;
161 return eh_;
164 void SelectOneArcDirector::dispatchMessage(const Message &msg)
166 eh_->message(new MessageEvent(msg));
169 void SelectOneArcDirector::dispatchMessage(Message &msg)
171 eh_->message(new MessageEvent(msg));
174 ArcEngineImpl::ArcEngineImpl(Messenger &mgr,
175 const SgmlParser *parser,
176 ArcDirector &director,
177 const volatile sig_atomic_t *cancelPtr,
178 const Notation *notation,
179 const Vector<StringC> &docName,
180 const SubstTable<Char> *table)
182 : director_(&director), mgr_(&mgr), cancelPtr_(cancelPtr),
183 parser_(parser), stage_(0),
184 gatheringContent_(0), startAgain_(0), haveLinkProcess_(0),
185 alloc_(maxSize(sizes, SIZEOF(sizes)), 50),
186 nullHandler_(mgr), docName_(docName)
188 eventHandler_ = director.arcEventHandler(notation, docName, table);
189 if (!eventHandler_)
190 eventHandler_ = &nullHandler_;
191 delegateTo_ = eventHandler_;
194 ArcEngineImpl::~ArcEngineImpl()
196 for (size_t i = 0; i < arcProcessors_.size(); i++)
197 if (arcProcessors_[i].valid())
198 arcProcessors_[i].checkIdrefs();
201 void ArcEngineImpl::appinfo(AppinfoEvent *event)
203 const StringC *str;
204 if (event->literal(str))
205 appinfo_ = *str;
206 DelegateEventHandler::appinfo(event);
209 void ArcEngineImpl::pi(PiEvent *event)
211 currentLocation_ = event->location();
212 if (stage_ == 1
213 && arcBase_.size()
214 && event->dataLength() > is10744_.size() + 1) {
215 Boolean match = 1;
216 size_t i = 0;
217 for (size_t j = 0; j < is10744_.size() && match; i++, j++)
218 if ((*syntax_->generalSubstTable())[event->data()[i]] != is10744_[j])
219 match = 0;
220 if (!syntax_->isS(event->data()[i]))
221 match = 0;
222 do {
223 i++;
224 } while (i < event->dataLength() && syntax_->isS(event->data()[i]));
225 for (size_t j = 0; j < arcBase_.size() && match; i++, j++)
226 if (i >= event->dataLength()
227 || (*syntax_->generalSubstTable())[event->data()[i]] != arcBase_[j])
228 match = 0;
229 if (i >= event->dataLength() || !syntax_->isS(event->data()[i]))
230 match = 0;
231 if (match) {
232 size_t dataLength = event->dataLength();
233 const Char *data = event->data();
234 for (;;) {
235 while (i < dataLength && syntax_->isS(data[i]))
236 i++;
237 if (i >= dataLength)
238 break;
239 size_t start = i++;
240 while (i < dataLength && !syntax_->isS(data[i]))
241 i++;
242 StringC name(data + start, i - start);
243 syntax_->generalSubstTable()->subst(name);
244 arcProcessors_.resize(arcProcessors_.size() + 1);
245 arcProcessors_.back().setName(name);
249 DelegateEventHandler::pi(event);
252 void ArcEngineImpl::endProlog(EndPrologEvent *event)
254 currentLocation_ = event->location();
255 for (size_t i = 0; i < arcProcessors_.size(); i++)
256 arcProcessors_[i].init(*event,
257 sd_,
258 syntax_,
259 parser_,
260 this,
261 docName_,
262 *director_,
263 cancelPtr_);
264 if (!event->lpdPointer().isNull()) {
265 haveLinkProcess_ = 1;
266 linkProcess_.init(event->lpdPointer());
268 DelegateEventHandler::endProlog(event);
271 void ArcEngineImpl::startDtd(StartDtdEvent *event)
273 stage_++;
274 DelegateEventHandler::startDtd(event);
277 void ArcEngineImpl::endDtd(EndDtdEvent *event)
279 stage_++;
280 DelegateEventHandler::endDtd(event);
283 void ArcEngineImpl::startLpd(StartLpdEvent *event)
285 if (event->active())
286 stage_ = 1;
287 DelegateEventHandler::startLpd(event);
290 void ArcEngineImpl::endLpd(EndLpdEvent *event)
292 stage_++;
293 DelegateEventHandler::endLpd(event);
296 void ArcEngineImpl::sgmlDecl(SgmlDeclEvent *event)
298 currentLocation_ = event->location();
299 sd_ = event->sdPointer();
300 syntax_ = event->instanceSyntaxPointer();
301 arcBase_ = sd_->execToInternal("ArcBase");
302 syntax_->generalSubstTable()->subst(arcBase_);
303 is10744_ = sd_->execToInternal("IS10744");
304 Boolean atStart = 1;
305 for (size_t i = 0; i < appinfo_.size(); i++)
306 if (syntax_->isS(appinfo_[i]))
307 atStart = 1;
308 else if (atStart) {
309 if (i + 7 > appinfo_.size())
310 break;
311 StringC tem(appinfo_.data() + i, 7);
312 syntax_->generalSubstTable()->subst(tem);
313 if (tem == arcBase_) {
314 if (i + 7 == appinfo_.size() || syntax_->isS(appinfo_[i + 7]))
315 break;
316 if (appinfo_[i + 7] == sd_->execToInternal('=')) {
317 arcBase_.resize(0);
318 for (size_t j = i + 7; j < appinfo_.size(); j++) {
319 if (syntax_->isS(appinfo_[j]))
320 break;
321 arcBase_ += appinfo_[j];
323 // Allow quotes around replacement name.
324 if (arcBase_.size() > 2
325 && (arcBase_[0] == sd_->execToInternal('"')
326 || arcBase_[0] == sd_->execToInternal('\''))
327 && arcBase_[arcBase_.size() - 1] == arcBase_[0]) {
328 for (size_t j = 0; j < arcBase_.size() - 2; j++)
329 arcBase_[j] = arcBase_[j + 1];
330 arcBase_.resize(arcBase_.size() - 2);
332 syntax_->generalSubstTable()->subst(arcBase_);
333 break;
336 atStart = 0;
338 DelegateEventHandler::sgmlDecl(event);
341 void ArcEngineImpl::startElement(StartElementEvent *event)
343 if (gatheringContent_) {
344 gatheringContent_++;
345 DelegateEventHandler::startElement(event);
346 return;
348 currentLocation_ = event->location();
349 const Text *contentP;
350 size_t start;
351 if (startAgain_) {
352 start = startAgain_ - 1;
353 contentP = &content_;
354 startAgain_ = 0;
356 else {
357 contentP = 0;
358 start = 0;
359 if (haveLinkProcess_) {
360 const ResultElementSpec *resultElementSpec;
361 linkProcess_.startElement(event->elementType(),
362 event->attributes(),
363 event->location(),
364 *this, // Messenger &
365 linkAttributes_,
366 resultElementSpec);
368 else
369 linkAttributes_ = 0;
371 for (size_t i = start; i < arcProcessors_.size(); i++) {
372 if (arcProcessors_[i].valid()) {
373 if (!arcProcessors_[i].processStartElement(*event,
374 linkAttributes_,
375 contentP,
376 alloc_)) {
377 ASSERT(contentP == 0);
378 startAgain_ = i + 1;
379 gatheringContent_ = 1;
380 delegateTo_ = &eventQueue_;
381 DelegateEventHandler::startElement(event);
382 return;
387 content_.clear();
388 DelegateEventHandler::startElement(event);
391 void ArcEngineImpl::data(DataEvent *event)
393 const Entity *entity = event->entity();
394 if (gatheringContent_) {
395 if (entity)
396 content_.addCdata(entity->asInternalEntity(),
397 event->location().origin());
398 else {
399 // Do attribute value literal interpretation.
400 Location loc(event->location());
401 for (size_t i = 0; i < event->dataLength(); i++, loc += 1) {
402 Char ch = event->data()[i];
403 if (syntax_->isS(ch) && ch != syntax_->space()) {
404 if (ch == syntax_->standardFunction(Syntax::fRS))
405 content_.ignoreChar(ch, loc);
406 else
407 content_.addChar(syntax_->space(),
408 Location(new ReplacementOrigin(loc, ch), 0));
410 else
411 content_.addChar(ch, loc);
415 else {
416 currentLocation_ = event->location();
417 for (size_t i = 0; i < arcProcessors_.size(); i++) {
418 if (arcProcessors_[i].valid() && arcProcessors_[i].processData()) {
419 if (entity)
420 arcProcessors_[i].docHandler()
421 .data(new (alloc_) CdataEntityEvent(entity->asInternalEntity(),
422 event->location().origin()));
423 else
424 arcProcessors_[i].docHandler()
425 .data(new (alloc_) ImmediateDataEvent(event->type(),
426 event->data(),
427 event->dataLength(),
428 event->location(),
429 0));
433 DelegateEventHandler::data(event);
436 void ArcEngineImpl::sdataEntity(SdataEntityEvent *event)
438 if (gatheringContent_) {
439 content_.addSdata(event->entity()->asInternalEntity(),
440 event->location().origin());
441 return;
443 else {
444 currentLocation_ = event->location();
445 for (size_t i = 0; i < arcProcessors_.size(); i++) {
446 if (arcProcessors_[i].valid() && arcProcessors_[i].processData()) {
447 const Entity *entity = event->entity();
448 arcProcessors_[i].docHandler()
449 .sdataEntity(new (alloc_)
450 SdataEntityEvent(entity->asInternalEntity(),
451 event->location().origin()));
455 DelegateEventHandler::sdataEntity(event);
458 void ArcEngineImpl::externalDataEntity(ExternalDataEntityEvent *event)
460 if (!gatheringContent_) {
461 currentLocation_ = event->location();
462 for (size_t i = 0; i < arcProcessors_.size(); i++) {
463 if (arcProcessors_[i].valid()
464 && arcProcessors_[i].processData()) {
465 ConstPtr<Entity> entity
466 = arcProcessors_[i].dtdPointer()
467 ->lookupEntity(0, event->entity()->name());
468 if (!entity.isNull()) {
469 ConstPtr<EntityOrigin> oldOrigin = event->entityOrigin();
470 Owner<Markup> markup;
471 if (oldOrigin->markup())
472 markup = new Markup(*oldOrigin->markup());
473 ConstPtr<EntityOrigin> newOrigin
474 = EntityOrigin::make(entity,
475 oldOrigin->parent(),
476 oldOrigin->refLength(),
477 markup);
478 arcProcessors_[i].docHandler()
479 .externalDataEntity(new (alloc_)
480 ExternalDataEntityEvent(entity->asExternalDataEntity(),
481 newOrigin));
483 // otherwise entity is not architectural
487 DelegateEventHandler::externalDataEntity(event);
490 void ArcEngineImpl::endElement(EndElementEvent *event)
492 while (gatheringContent_) {
493 if (--gatheringContent_ > 0) {
494 DelegateEventHandler::endElement(event);
495 return;
497 delegateTo_ = delegateHandler();
498 // Clear out eventQueue_ in case handling the events
499 // causes events to be queued again.
500 IQueue<Event> tem;
501 tem.swap(eventQueue_);
502 while (!tem.empty())
503 tem.get()->handle(*this);
505 currentLocation_ = event->location();
506 for (size_t i = 0; i < arcProcessors_.size(); i++)
507 if (arcProcessors_[i].valid())
508 arcProcessors_[i].processEndElement(*event, alloc_);
509 DelegateEventHandler::endElement(event);
510 if (haveLinkProcess_)
511 linkProcess_.endElement();
514 void ArcEngineImpl::uselink(UselinkEvent *event)
516 if (!gatheringContent_)
517 linkProcess_.uselink(event->linkSet(),
518 event->restore(),
519 event->lpd().pointer());
520 DelegateEventHandler::uselink(event);
523 void ArcEngineImpl::dispatchMessage(const Message &msg)
525 mgr_->dispatchMessage(msg);
528 void ArcEngineImpl::dispatchMessage(Message &msg)
530 mgr_->dispatchMessage(msg);
533 void ArcEngineImpl::initMessage(Message &msg)
535 mgr_->initMessage(msg);
536 msg.loc = currentLocation_;
539 ArcProcessor::ArcProcessor()
540 : errorIdref_(1), docHandler_(0), arcAuto_(1),
541 arcDtdIsParam_(0)
545 void ArcProcessor::setName(const StringC &name)
547 name_ = name;
550 const Syntax &ArcProcessor::attributeSyntax() const
552 return *docSyntax_;
555 ConstPtr<Notation> ArcProcessor::getAttributeNotation(const StringC &name,
556 const Location &)
558 if (!metaDtd_.isNull())
559 return metaDtd_->lookupNotation(name);
560 return 0;
563 ConstPtr<Entity> ArcProcessor::getAttributeEntity(const StringC &name,
564 const Location &)
566 // FIXME What about default entity
567 if (!metaDtd_.isNull())
568 return metaDtd_->lookupEntity(0, name);
569 return 0;
572 void ArcProcessor::noteCurrentAttribute(size_t i, AttributeValue *value)
574 if (valid_)
575 currentAttributes_[i] = value;
578 ConstPtr<AttributeValue> ArcProcessor::getCurrentAttribute(size_t i) const
580 return currentAttributes_[i];
583 // This code is the same as in the main parser.
584 // Once handling of ID/IDREF in architectures has been clarified.
585 // Maybe factor out into AttributeContext.
587 Boolean ArcProcessor::defineId(const StringC &str, const Location &loc,
588 Location &prevLoc)
590 if (!valid_)
591 return 1;
592 Id *id = lookupCreateId(str);
593 if (id->defined()) {
594 prevLoc = id->defLocation();
595 return 0;
597 id->define(loc);
598 return 1;
601 void ArcProcessor::noteIdref(const StringC &str, const Location &loc)
603 if (!valid_ || !errorIdref_)
604 return;
605 Id *id = lookupCreateId(str);
606 if (!id->defined())
607 id->addPendingRef(loc);
610 Id *ArcProcessor::lookupCreateId(const StringC &name)
612 Id *id = idTable_.lookup(name);
613 if (!id) {
614 id = new Id(name);
615 idTable_.insert(id);
617 return id;
620 void ArcProcessor::checkIdrefs()
622 NamedTableIter<Id> iter(idTable_);
623 Id *id;
624 while ((id = iter.next()) != 0) {
625 for (size_t i = 0; i < id->pendingRefs().size(); i++) {
626 Messenger::setNextLocation(id->pendingRefs()[i]);
627 message(ArcEngineMessages::missingId, StringMessageArg(id->name()));
632 void ArcProcessor::init(const EndPrologEvent &event,
633 const ConstPtr<Sd> &sd,
634 const ConstPtr<Syntax> &syntax,
635 const SgmlParser *parentParser,
636 Messenger *mgr,
637 const Vector<StringC> &superName,
638 ArcDirector &director,
639 const volatile sig_atomic_t *cancelPtr)
641 director_ = &director;
642 mgr_ = mgr;
643 docSyntax_ = syntax;
644 docSd_ = sd;
645 mgr_ = mgr;
646 valid_ = 0;
647 docDtd_ = event.dtdPointer();
648 metaSyntax_ = docSyntax_;
649 mayDefaultAttribute_ = 1;
650 docSyntax_->generalSubstTable()->subst(name_);
651 Vector<StringC> docName(superName);
652 docName.push_back(name_);
653 ConstPtr<Notation> notation;
654 notation = docDtd_->lookupNotation(name_);
655 if (!notation.isNull()) {
656 ConstPtr<AttributeDefinitionList> notAttDef = notation->attributeDef();
657 attributeList_.init(notAttDef);
658 attributeList_.finish(*this);
659 supportAttributes(attributeList_);
661 else
662 message(ArcEngineMessages::noArcNotation, StringMessageArg(name_));
663 ArcEngineImpl *engine
664 = new ArcEngineImpl(*mgr, parentParser, director, cancelPtr,
665 notation.pointer(),
666 docName,
667 docSyntax_->generalSubstTable());
668 docHandler_ = engine;
669 ownEventHandler_ = engine;
670 if (supportAtts_[rArcDocF].size() == 0)
671 supportAtts_[rArcDocF] = name_;
672 if (supportAtts_[rArcFormA].size() == 0)
673 supportAtts_[rArcFormA] = name_;
674 rniContent_ = docSyntax_->delimGeneral(Syntax::dRNI);
675 rniContent_ += sd->execToInternal("CONTENT");
676 rniDefault_ = docSyntax_->delimGeneral(Syntax::dRNI);
677 rniDefault_ += docSyntax_->reservedName(Syntax::rDEFAULT);
678 rniArcCont_ = metaSyntax_->delimGeneral(Syntax::dRNI);
679 rniArcCont_ += sd->execToInternal("ARCCONT");
680 ConstPtr<Entity> dtdent = makeDtdEntity(notation.pointer());
681 if (dtdent.isNull())
682 return;
683 StringC sysid = dtdent->asExternalEntity()->externalId().effectiveSystemId();
684 if (sysid.size() == 0
685 && !parentParser->entityCatalog().lookup(*dtdent,
686 *docSyntax_,
687 sd->internalCharset(),
688 *mgr_,
689 sysid)) {
690 message(ArcEngineMessages::arcGenerateSystemId,
691 StringMessageArg(name_));
692 return;
694 docHandler_->sgmlDecl(new SgmlDeclEvent(sd, syntax));
695 docHandler_->startDtd(new StartDtdEvent(dtdent->name(),
696 dtdent,
698 event.location(),
699 0));
700 SgmlParser::Params params;
701 params.entityType = SgmlParser::Params::dtd;
702 params.sysid = sysid;
703 params.parent = parentParser;
704 ParserOptions options = parentParser->options();
705 errorIdref_ = options.errorIdref;
706 options.errorAfdr = 0;
707 options.includes = arcOpts_;
708 params.options = &options;
709 params.sd = docSd_;
710 if (metaSyntax_->reservedName(Syntax::rALL).size() == 0) {
711 Ptr<Syntax> tem(new Syntax(*metaSyntax_));
712 tem->setName(Syntax::rALL, docSd_->execToInternal("ALL"));
713 metaSyntax_ = tem;
715 params.prologSyntax = metaSyntax_;
716 params.instanceSyntax = metaSyntax_;
717 params.doctypeName = dtdent->name();
718 SgmlParser parser(params);
719 parser.parseAll(*docHandler_, cancelPtr);
720 Ptr<Dtd> baseDtd = parser.baseDtd();
721 if (baseDtd.isNull()
722 || baseDtd->documentElementType()->definition()->undefined())
723 return;
724 metaDtd_ = baseDtd;
725 metaMapCache_.resize(docDtd_->nElementTypeIndex());
726 mungeMetaDtd(*baseDtd, *docDtd_);
727 docHandler_->endDtd(new EndDtdEvent(metaDtd_, event.location(), 0));
728 startContent(*metaDtd_);
729 currentAttributes_.resize(metaDtd_->nCurrentAttribute());
730 valid_ = 1;
731 docHandler_->endProlog(new EndPrologEvent(metaDtd_, event.location()));
732 if (engine->nBases() == 0)
733 docHandler_ = engine->delegateHandler();
736 void ArcProcessor::mungeMetaDtd(Dtd &metaDtd, const Dtd &docDtd)
738 if (supportAtts_[rArcDataF].size() > 0
739 && metaDtd.lookupNotation(supportAtts_[rArcDataF]).isNull()) {
740 Messenger::message(ArcEngineMessages::noArcDataF,
741 StringMessageArg(supportAtts_[rArcDataF]));
742 metaDtd.insertNotation(new Notation(supportAtts_[rArcDataF],
743 metaDtd.namePointer(),
744 metaDtd.isBase()));
746 // FIXME check for ArcAutoF
747 Dtd::ConstEntityIter iter(docDtd.generalEntityIter());
748 for (;;) {
749 ConstPtr<Entity> ent = iter.next();
750 if (ent.isNull())
751 break;
752 Ptr<Entity> copy(ent->copy());
753 if (!copy->asExternalDataEntity()
754 || mungeDataEntity(*(ExternalDataEntity *)copy.pointer()))
755 metaDtd.insertEntity(copy, 1);
759 Boolean ArcProcessor::mungeDataEntity(ExternalDataEntity &entity)
761 const MetaMap &map = buildMetaMap(0,
762 entity.notation(),
763 entity.attributes(),
766 if (!map.attributed)
767 return 0;
768 AttributeList atts;
769 const Notation *notation = (const Notation *)map.attributed;
770 ConstPtr<AttributeValue> arcContent;
771 if (mapAttributes(entity.attributes(), 0, 0, atts, arcContent, map)) {
772 // FIXME check arcContent
773 entity.setNotation((Notation *)notation, atts);
774 return 1;
776 // FIXME error tried to use #CONTENT
777 return 0;
780 ConstPtr<Entity> ArcProcessor::makeDtdEntity(const Notation *)
782 if (!supportAtts_[rArcDTD].size()) {
783 mgr_->message(ArcEngineMessages::noArcDTDAtt);
784 return 0;
786 ConstPtr<Entity> entity = docDtd_->lookupEntity(arcDtdIsParam_,
787 supportAtts_[rArcDTD]);
788 if (entity.isNull()) {
789 mgr_->message(arcDtdIsParam_
790 ? ArcEngineMessages::arcDtdNotDeclaredParameter
791 : ArcEngineMessages::arcDtdNotDeclaredParameter,
792 StringMessageArg(supportAtts_[rArcDTD]));
793 return 0;
795 if (!entity->asExternalEntity()) {
796 mgr_->message(ArcEngineMessages::arcDtdNotExternal,
797 StringMessageArg(supportAtts_[rArcDTD]));
798 return 0;
800 ExternalId externalId(entity->asExternalEntity()->externalId());
801 #if 0
802 // Use the public identifier of the notation to find the meta-DTD.
803 if (externalId.effectiveSystemId().size() == 0 && notation) {
804 if (notation->externalId().effectiveSystemId().size()) {
805 StringC tem(notation->externalId().effectiveSystemId());
806 externalId.setEffectiveSystem(tem);
808 else if (!externalId.publicId()) {
809 const PublicId *pubid = notation->externalId().publicId();
810 PublicId::OwnerType ownerType;
811 if (pubid && pubid->getOwnerType(ownerType)) {
812 Text pubidText;
813 unsigned textClassPos = 2;
814 if (ownerType != PublicId::ISO)
815 textClassPos += 3;
816 StringC owner;
817 pubid->getOwner(owner);
818 textClassPos += owner.size();
819 pubidText.addChars(pubid->string().data(),
820 textClassPos,
821 pubid->text().charLocation(0));
822 pubidText.addChars(docSd_->execToInternal("DTD"),
823 pubid->text().charLocation(textClassPos));
824 for (; textClassPos < pubid->string().size(); textClassPos++)
825 if (pubid->string()[textClassPos] == docSyntax_->space())
826 break;
827 pubidText.addChars(pubid->string().data() + textClassPos,
828 pubid->string().size() - textClassPos,
829 pubid->text().charLocation(textClassPos));
830 const MessageType1 *msg;
831 externalId.setPublic(pubidText, docSd_->internalCharset(),
832 docSyntax_->space(), msg);
836 #endif
837 return new ExternalTextEntity(supportAtts_[rArcDocF],
838 Entity::doctype,
839 entity->defLocation(),
840 externalId);
843 void ArcProcessor::supportAttributes(const AttributeList &atts)
845 static const char *const s[] = {
846 "ArcFormA",
847 "ArcNamrA",
848 "ArcSuprA",
849 "ArcIgnDA",
850 "ArcDocF",
851 "ArcSuprF",
852 "ArcBridF",
853 "ArcDataF",
854 "ArcAuto",
855 "ArcIndr",
856 "ArcDTD",
857 "ArcQuant",
859 for (size_t i = 0; i < SIZEOF(s); i++) {
860 StringC attName(docSd_->execToInternal(s[i]));
861 docSyntax_->generalSubstTable()->subst(attName);
862 unsigned ind;
863 if (atts.attributeIndex(attName, ind)) {
864 const AttributeValue *value = atts.value(ind);
865 if (value) {
866 const Text *textP = value->text();
867 // FIXME check for empty value
868 if (textP) {
869 supportAtts_[i] = textP->string();
870 switch (i) {
871 case rArcQuant:
872 processArcQuant(*textP);
873 break;
874 case rArcAuto:
875 docSyntax_->generalSubstTable()->subst(supportAtts_[i]);
876 if (supportAtts_[i] == docSd_->execToInternal("ARCAUTO"))
877 arcAuto_ = 1;
878 else if (supportAtts_[i] == docSd_->execToInternal("NARCAUTO"))
879 arcAuto_ = 0;
880 else
881 Messenger::message(ArcEngineMessages::invalidArcAuto,
882 StringMessageArg(supportAtts_[i]));
883 break;
884 case rArcIndr:
885 docSyntax_->generalSubstTable()->subst(supportAtts_[i]);
886 if (supportAtts_[i] == docSd_->execToInternal("ARCINDR")) {
887 Messenger::setNextLocation(textP->charLocation(0));
888 Messenger::message(ArcEngineMessages::arcIndrNotSupported);
890 else if (supportAtts_[i] != docSd_->execToInternal("NARCINDR")) {
891 Messenger::setNextLocation(textP->charLocation(0));
892 Messenger::message(ArcEngineMessages::invalidArcIndr,
893 StringMessageArg(supportAtts_[i]));
895 break;
896 case rArcFormA:
897 case rArcNamrA:
898 case rArcSuprA:
899 case rArcIgnDA:
900 docSyntax_->generalSubstTable()->subst(supportAtts_[i]);
901 break;
902 case rArcDocF:
903 case rArcSuprF:
904 case rArcBridF:
905 case rArcDataF:
906 metaSyntax_->generalSubstTable()->subst(supportAtts_[i]);
907 break;
908 case rArcDTD:
910 const StringC &pero = docSyntax_->delimGeneral(Syntax::dPERO);
911 if (supportAtts_[i].size() >= pero.size()) {
912 StringC tem(supportAtts_[i].data(), pero.size());
913 docSyntax_->generalSubstTable()->subst(tem);
914 if (tem == pero) {
915 arcDtdIsParam_ = 1;
916 tem.assign(supportAtts_[i].data() + pero.size(),
917 supportAtts_[i].size() - pero.size());
918 tem.swap(supportAtts_[i]);
921 docSyntax_->entitySubstTable()->subst(supportAtts_[i]);
923 break;
929 processArcOpts(atts);
932 void ArcProcessor::processArcOpts(const AttributeList &atts)
934 StringC attName(docSd_->execToInternal("ArcOptSA"));
935 docSyntax_->generalSubstTable()->subst(attName);
936 unsigned ind;
937 Vector<StringC> arcOptA;
938 Vector<size_t> arcOptAPos;
939 const Text *arcOptAText = 0;
940 if (atts.attributeIndex(attName, ind)) {
941 const AttributeValue *value = atts.value(ind);
942 if (value) {
943 arcOptAText = value->text();
944 if (arcOptAText)
945 split(*arcOptAText, docSyntax_->space(), arcOptA, arcOptAPos);
948 if (!arcOptAText)
949 arcOptA.push_back(docSd_->execToInternal("ArcOpt"));
950 for (size_t i = 0; i < arcOptA.size(); i++) {
951 docSyntax_->generalSubstTable()->subst(arcOptA[i]);
952 if (atts.attributeIndex(arcOptA[i], ind)) {
953 const AttributeValue *value = atts.value(ind);
954 if (value) {
955 const Text *textP = value->text();
956 if (textP) {
957 Vector<StringC> opts;
958 Vector<size_t> optsPos;
959 split(*textP, docSyntax_->space(), opts, optsPos);
960 arcOpts_.insert(arcOpts_.begin(),
961 opts.begin(), opts.begin() + opts.size());
968 void ArcProcessor::processArcQuant(const Text &text)
970 Ptr<Syntax> newMetaSyntax;
971 Vector<StringC> tokens;
972 Vector<size_t> tokensPos;
973 split(text, docSyntax_->space(), tokens, tokensPos);
974 for (size_t i = 0; i < tokens.size(); i++) {
975 docSyntax_->generalSubstTable()->subst(tokens[i]);
976 Syntax::Quantity quantityName;
977 if (!docSd_->lookupQuantityName(tokens[i], quantityName)) {
978 setNextLocation(text.charLocation(tokensPos[i]));
979 Messenger::message(ArcEngineMessages::invalidQuantity,
980 StringMessageArg(tokens[i]));
982 else if (i + 1 >= tokens.size()) {
983 setNextLocation(text.charLocation(tokensPos[i]));
984 Messenger::message(ArcEngineMessages::missingQuantityValue,
985 StringMessageArg(tokens[i]));
987 else {
988 i++;
989 unsigned long val = 0;
990 if (tokens[i].size() > 8) {
991 setNextLocation(text.charLocation(tokensPos[i] + 8));
992 Messenger::message(ArcEngineMessages::quantityValueTooLong,
993 StringMessageArg(tokens[i]));
994 tokens[i].resize(8);
996 for (size_t j = 0; j < tokens[i].size(); j++) {
997 int weight = docSd_->digitWeight(tokens[i][j]);
998 if (weight < 0) {
999 setNextLocation(text.charLocation(tokensPos[i] + j));
1000 Char c = tokens[i][j];
1001 Messenger::message(ArcEngineMessages::invalidDigit,
1002 StringMessageArg(StringC(&c, 1)));
1003 val = 0;
1004 break;
1006 else {
1007 val *= 10;
1008 val += weight;
1011 if (val > docSyntax_->quantity(quantityName)) {
1012 if (newMetaSyntax.isNull())
1013 newMetaSyntax = new Syntax(*docSyntax_);
1014 newMetaSyntax->setQuantity(quantityName, val);
1018 if (!newMetaSyntax.isNull())
1019 metaSyntax_ = newMetaSyntax;
1022 Boolean ArcProcessor::processStartElement(const StartElementEvent &event,
1023 const AttributeList *linkAttributes,
1024 const Text *content,
1025 Allocator &alloc)
1027 unsigned suppressFlags = (openElementFlags_.size() > 0
1028 ? (openElementFlags_.back() & ~isArc)
1029 : (unsigned)condIgnoreData);
1030 if ((suppressFlags & suppressForm)
1031 && (suppressFlags & suppressSupr)) {
1032 // Make this case efficient.
1033 openElementFlags_.push_back(suppressFlags);
1034 return 1;
1036 const AttributeList &atts = event.attributes();
1037 const MetaMap &map = buildMetaMap(event.elementType(),
1039 atts,
1040 linkAttributes,
1041 suppressFlags);
1042 const ElementType *metaType;
1043 ConstPtr<AttributeValue> arcContent;
1044 if (map.attributed == 0) {
1045 if (!(tagLevel() == 0
1046 && !currentElement().isFinished())) {
1047 if (!arcContent.isNull()
1048 && (currentElement().declaredEmpty()
1049 || !currentElement().tryTransitionPcdata()))
1050 Messenger::message(ArcEngineMessages::invalidArcContent);
1051 openElementFlags_.push_back(map.suppressFlags);
1052 return 1;
1054 metaType = metaDtd_->documentElementType();
1055 mgr_->message(ArcEngineMessages::documentElementNotArc,
1056 StringMessageArg(metaType->name()));
1057 attributeList_.init(metaType->attributeDef());
1058 attributeList_.finish(*this);
1060 else {
1061 if (!mapAttributes(atts, linkAttributes, content, attributeList_,
1062 arcContent, map))
1063 return 0;
1064 metaType = (const ElementType *)map.attributed;
1065 suppressFlags = map.suppressFlags;
1067 StartElementEvent *genEvent
1068 = new (alloc) StartElementEvent(metaType,
1069 metaDtd_,
1070 &attributeList_,
1071 event.location(),
1073 if (metaType->definition()->undefined())
1074 Messenger::message(ArcEngineMessages::undefinedElement,
1075 StringMessageArg(metaType->name()));
1076 else if (elementIsExcluded(metaType))
1077 Messenger::message(ArcEngineMessages::elementExcluded,
1078 StringMessageArg(metaType->name()));
1079 else if (elementIsIncluded(metaType))
1080 genEvent->setIncluded();
1081 else if (!currentElement().tryTransition(metaType))
1082 Messenger::message(ArcEngineMessages::invalidElement,
1083 StringMessageArg(metaType->name()));
1085 pushElement(new (alloc) OpenElement(metaType,
1087 genEvent->included(),
1089 event.location()));
1090 docHandler_->startElement(genEvent);
1091 if (attributeList_.conref())
1092 currentElement().setConref();
1093 if (!arcContent.isNull() && arcContent->text() != 0) {
1094 if (currentElement().declaredEmpty()
1095 || !currentElement().tryTransitionPcdata())
1096 Messenger::message(ArcEngineMessages::invalidArcContent);
1097 else
1098 emitArcContent(*arcContent->text(), docHandler(), alloc);
1099 suppressFlags |= (suppressForm|suppressSupr|ignoreData);
1101 suppressFlags &= ~recoverData;
1102 openElementFlags_.push_back(suppressFlags | isArc);
1103 return 1;
1106 void ArcProcessor::emitArcContent(const Text &text,
1107 EventHandler &handler,
1108 Allocator &alloc)
1110 TextIter iter(text);
1111 TextItem::Type type;
1112 const Char *s;
1113 size_t n;
1114 const Location *loc;
1115 while (iter.next(type, s, n, loc))
1116 switch (type) {
1117 case TextItem::data:
1118 case TextItem::cdata:
1119 // +1 because first dataEvent is the non-architectural data.
1120 if (type == TextItem::data)
1121 handler.data(new (alloc) ImmediateDataEvent(Event::characterData,
1124 *loc,
1125 0));
1126 else
1128 handler.data(new (alloc)
1129 CdataEntityEvent(loc->origin()->asEntityOrigin()
1130 ->entity()->asInternalEntity(),
1131 loc->origin()));
1132 break;
1133 case TextItem::sdata:
1135 handler.sdataEntity(new (alloc)
1136 SdataEntityEvent(loc->origin()->asEntityOrigin()
1137 ->entity()->asInternalEntity(),
1138 loc->origin()));
1139 break;
1140 default:
1141 break;
1145 Boolean ArcProcessor::processData()
1147 if (openElementFlags_.size() > 0
1148 && (openElementFlags_.back() & ignoreData))
1149 return 0;
1150 if (!currentElement().declaredEmpty()
1151 && currentElement().tryTransitionPcdata())
1152 return 1;
1153 else if (openElementFlags_.size() > 0
1154 && (openElementFlags_.back() & condIgnoreData))
1155 return 0;
1156 else {
1157 // Only give this error once per element
1158 if (openElementFlags_.size() > 0) {
1159 if (openElementFlags_.back() & recoverData)
1160 return 1;
1161 openElementFlags_.back() |= recoverData;
1163 Messenger::message(ArcEngineMessages::invalidData);
1164 return 1;
1168 Boolean ArcProcessor::mapAttributes(const AttributeList &from,
1169 const AttributeList *fromLink,
1170 const Text *content,
1171 AttributeList &to,
1172 ConstPtr<AttributeValue> &arcContent,
1173 const MetaMap &map)
1175 if (map.attributed)
1176 to.init(map.attributed->attributeDef());
1177 for (size_t i = 0; i < map.attMapFrom.size(); i++) {
1178 unsigned fromIndex = map.attMapFrom[i];
1179 const AttributeList *fromList = &from;
1180 if (fromIndex != contentPseudoAtt && fromIndex >= fromList->size()) {
1181 fromList = fromLink;
1182 fromIndex -= from.size();
1184 if (map.attMapTo[i] == contentPseudoAtt) {
1185 if (fromIndex != contentPseudoAtt)
1186 arcContent = fromList->valuePointer(fromIndex);
1188 else {
1189 const Text *fromText = 0;
1190 Boolean fromTextTokenized = 0;
1191 if (map.attMapFrom[i] == contentPseudoAtt) {
1192 if (!content)
1193 return 0;
1194 fromText = content;
1196 else {
1197 const AttributeValue *value = fromList->value(fromIndex);
1198 if (value) {
1199 fromText = value->text();
1200 fromTextTokenized = fromList->tokenized(fromIndex);
1201 if (fromText
1202 && fromList == &from
1203 && !from.specified(fromIndex)
1204 && (map.attributed->attributeDef()->def(map.attMapTo[i])
1205 ->missingValueWouldMatch(*fromText, *this)))
1206 fromText = 0;
1209 if (fromText) {
1210 unsigned specLength = 0;
1211 Text tem;
1212 if (!fromTextTokenized && to.tokenized(map.attMapTo[i]))
1213 fromText->tokenize(docSyntax_->space(), tem);
1214 else
1215 tem = *fromText;
1216 to.setSpec(map.attMapTo[i], *this);
1217 to.setValue(map.attMapTo[i], tem, *this, specLength);
1221 if (map.attributed)
1222 to.finish(*this);
1223 return 1;
1226 const ArcProcessor::MetaMap &
1227 ArcProcessor::buildMetaMap(const ElementType *docElementType,
1228 const Notation *notation,
1229 const AttributeList &atts,
1230 const AttributeList *linkAtts,
1231 unsigned suppressFlags)
1233 Boolean isNotation;
1234 const Attributed *attributed = docElementType;
1235 const StringC *nameP;
1236 if (!attributed) {
1237 attributed = notation;
1238 isNotation = 1;
1239 nameP = &notation->name();
1241 else {
1242 isNotation = 0;
1243 nameP = &docElementType->name();
1245 // Try to use cached entry.
1246 Boolean inhibitCache = 0;
1247 size_t cacheIndex;
1248 if (isNotation || docElementType->definition()->undefined()) {
1249 inhibitCache = 1;
1250 cacheIndex = (unsigned)-1;
1252 else {
1253 cacheIndex = docElementType->index();
1254 const MetaMapCache *cache = metaMapCache_[cacheIndex].pointer();
1255 if (cache
1256 && cache->suppressFlags == suppressFlags
1257 && cache->linkAtts == linkAtts) {
1258 for (int i = 0;; i++) {
1259 if (i == MetaMapCache::nNoSpec)
1260 return cache->map;
1261 unsigned attIndex = cache->noSpec[i];
1262 if (attIndex != invalidAtt && atts.specified(attIndex))
1263 break;
1267 // no valid cached MetaMap
1268 // Handle suppression.
1269 unsigned oldSuppressFlags = suppressFlags;
1270 unsigned newSuppressFlags = suppressFlags;
1271 unsigned arcSuprIndex;
1272 if (!isNotation)
1273 considerSupr(atts, linkAtts, suppressFlags, newSuppressFlags, inhibitCache,
1274 arcSuprIndex);
1275 else
1276 arcSuprIndex = invalidAtt;
1277 // Handle ArcIgnD
1278 unsigned arcIgnDIndex;
1279 if (!isNotation)
1280 considerIgnD(atts, linkAtts, suppressFlags, newSuppressFlags, inhibitCache,
1281 arcIgnDIndex);
1282 else
1283 arcIgnDIndex = invalidAtt;
1284 // Handle ArcForm.
1285 unsigned arcFormIndex;
1286 const Attributed *metaAttributed
1287 = considerForm(atts, linkAtts, *nameP, isNotation,
1288 suppressFlags, newSuppressFlags,
1289 inhibitCache, arcFormIndex);
1290 // See if there's a renamer that will inhibit cacheing.
1291 #pragma "%Z%%M% %I% %E% SMI"
1292 unsigned arcNamerIndex;
1293 const Text *namerText;
1294 if (metaAttributed)
1295 namerText = considerNamer(atts, inhibitCache, arcNamerIndex);
1296 else {
1297 arcNamerIndex = invalidAtt;
1298 namerText = 0;
1300 MetaMap *mapP;
1301 if (inhibitCache) {
1302 noCacheMetaMap_.clear();
1303 mapP = &noCacheMetaMap_;
1305 else {
1306 MetaMapCache *cache = metaMapCache_[cacheIndex].pointer();
1307 if (cache)
1308 cache->clear();
1309 else {
1310 cache = new MetaMapCache;
1311 metaMapCache_[cacheIndex] = cache;
1313 cache->noSpec[0] = arcFormIndex;
1314 cache->noSpec[1] = arcNamerIndex;
1315 cache->noSpec[2] = arcSuprIndex;
1316 cache->noSpec[3] = arcIgnDIndex;
1317 cache->suppressFlags = oldSuppressFlags;
1318 cache->linkAtts = linkAtts;
1319 mapP = &cache->map;
1321 mapP->attributed = metaAttributed;
1322 mapP->suppressFlags = newSuppressFlags;
1323 // Build the attribute map.
1324 if (metaAttributed) {
1325 Vector<PackedBoolean> renamed;
1326 ConstPtr<AttributeDefinitionList> metaAttDef
1327 = metaAttributed->attributeDef();
1328 if (!metaAttDef.isNull())
1329 renamed.assign(metaAttDef->size(), PackedBoolean(0));
1330 if (linkAtts) {
1331 Boolean specified;
1332 unsigned index;
1333 const Text *linkNamerText = considerNamer(*linkAtts, specified, index);
1334 if (linkNamerText)
1335 buildAttributeMapRename(*mapP, *linkNamerText, atts, linkAtts, renamed);
1337 if (namerText)
1338 buildAttributeMapRename(*mapP, *namerText, atts, 0, renamed);
1339 buildAttributeMapRest(*mapP, atts, linkAtts, renamed);
1341 return *mapP;
1344 void ArcProcessor::considerSupr(const AttributeList &atts,
1345 const AttributeList *linkAtts,
1346 unsigned &thisSuppressFlags,
1347 unsigned &newSuppressFlags,
1348 Boolean &inhibitCache,
1349 unsigned &arcSuprIndex)
1351 arcSuprIndex = invalidAtt;
1352 if (thisSuppressFlags & suppressSupr)
1353 return;
1354 if (!supportAtts_[rArcSuprA].size())
1355 return;
1356 const AttributeValue *val;
1357 unsigned tem;
1358 if (linkAtts && linkAtts->attributeIndex(supportAtts_[rArcSuprA], tem))
1359 val = linkAtts->value(tem);
1360 else if (atts.attributeIndex(supportAtts_[rArcSuprA], arcSuprIndex)) {
1361 if (atts.current(arcSuprIndex) || atts.specified(arcSuprIndex))
1362 inhibitCache = 1;
1363 val = atts.value(arcSuprIndex);
1365 else
1366 return;
1367 if (!val)
1368 return;
1369 const Text *textP = val->text();
1370 if (!textP)
1371 return;
1372 StringC token = textP->string();
1373 // FIXME trim spaces
1374 docSyntax_->generalSubstTable()->subst(token);
1375 // sArcForm suppress processing for all elements except
1376 // those that have a non-implied ArcSupr attribute.
1377 thisSuppressFlags &= ~suppressForm;
1378 newSuppressFlags &= ~(suppressForm|suppressSupr);
1379 if (matchName(token, "sArcForm"))
1380 newSuppressFlags |= suppressForm;
1381 #if 0
1382 // I don't think this is useful
1383 else if (matchName(token, "sArcSupr"))
1384 newSuppressFlags |= suppressSupr;
1385 #endif
1386 else if (matchName(token, "sArcAll"))
1387 newSuppressFlags |= (suppressSupr|suppressForm);
1388 else if (!matchName(token, "sArcNone")) {
1389 Messenger::setNextLocation(textP->charLocation(0));
1390 Messenger::message(ArcEngineMessages::invalidSuppress,
1391 StringMessageArg(token));
1395 void ArcProcessor::considerIgnD(const AttributeList &atts,
1396 const AttributeList *linkAtts,
1397 unsigned thisSuppressFlags,
1398 unsigned &newSuppressFlags,
1399 Boolean &inhibitCache,
1400 unsigned &arcIgnDIndex)
1402 arcIgnDIndex = invalidAtt;
1403 if (thisSuppressFlags & suppressSupr)
1404 return;
1405 if (!supportAtts_[rArcIgnDA].size())
1406 return;
1407 const AttributeValue *val;
1408 unsigned tem;
1409 if (linkAtts && linkAtts->attributeIndex(supportAtts_[rArcIgnDA], tem))
1410 val = linkAtts->value(tem);
1411 else if (atts.attributeIndex(supportAtts_[rArcIgnDA], arcIgnDIndex)) {
1412 if (atts.current(arcIgnDIndex) || atts.specified(arcIgnDIndex))
1413 inhibitCache = 1;
1414 val = atts.value(arcIgnDIndex);
1416 else
1417 return;
1418 if (!val)
1419 return;
1420 const Text *textP = val->text();
1421 if (!textP)
1422 return;
1423 StringC token = textP->string();
1424 // FIXME trim spaces
1425 docSyntax_->generalSubstTable()->subst(token);
1426 newSuppressFlags &= ~(ignoreData|condIgnoreData);
1427 if (matchName(token, "ArcIgnD"))
1428 newSuppressFlags |= ignoreData;
1429 else if (matchName(token, "cArcIgnD"))
1430 newSuppressFlags |= condIgnoreData;
1431 else if (!matchName(token, "nArcIgnD")) {
1432 Messenger::setNextLocation(textP->charLocation(0));
1433 Messenger::message(ArcEngineMessages::invalidIgnD,
1434 StringMessageArg(token));
1438 const Attributed *
1439 ArcProcessor::considerForm(const AttributeList &atts,
1440 const AttributeList *linkAtts,
1441 const StringC &name,
1442 Boolean isNotation,
1443 unsigned thisSuppressFlags,
1444 unsigned &newSuppressFlags,
1445 Boolean &inhibitCache,
1446 unsigned &arcFormIndex)
1448 arcFormIndex = invalidAtt;
1449 if ((thisSuppressFlags & suppressForm)
1450 && (supportAtts_[rArcSuprF].size() == 0
1451 || (thisSuppressFlags & suppressSupr)
1452 || isNotation))
1453 return 0;
1454 unsigned tem;
1455 const AttributeValue *val;
1456 if (linkAtts && linkAtts->attributeIndex(supportAtts_[rArcFormA], tem))
1457 val = linkAtts->value(tem);
1458 else if (atts.attributeIndex(supportAtts_[rArcFormA], arcFormIndex)) {
1459 if (atts.current(arcFormIndex) || atts.specified(arcFormIndex))
1460 inhibitCache = 1;
1461 val = atts.value(arcFormIndex);
1463 else
1464 return autoForm(atts, name, isNotation,
1465 thisSuppressFlags, newSuppressFlags,
1466 inhibitCache, arcFormIndex);
1468 if (!val)
1469 return 0;
1470 const Text *textP = val->text();
1471 if (!textP)
1472 return 0;
1473 StringC metaName;
1474 metaName = textP->string();
1475 // FIXME should trim leading and trailing spaces
1476 metaSyntax_->generalSubstTable()->subst(metaName);
1477 if (!isNotation) {
1478 const Attributed *metaAttributed = metaDtd_->lookupElementType(metaName);
1479 if (!metaAttributed) // CONSTDTD
1480 metaAttributed = lookupCreateUndefinedElement(metaName, Location(), *metaDtd_);
1481 if (metaName == supportAtts_[rArcSuprF]) {
1482 newSuppressFlags |= suppressForm;
1483 return metaAttributed;
1485 if (thisSuppressFlags & suppressForm)
1486 return 0;
1487 return metaAttributed;
1489 else
1490 return metaDtd_->lookupNotation(metaName).pointer();
1493 const Attributed *
1494 ArcProcessor::autoForm(const AttributeList &atts,
1495 const StringC &name,
1496 Boolean isNotation,
1497 unsigned thisSuppressFlags,
1498 unsigned &newSuppressFlags,
1499 Boolean &inhibitCache,
1500 unsigned &idIndex)
1502 if (!isNotation) {
1503 const Attributed *metaAttributed;
1504 if (openElementFlags_.size() == 0) {
1505 metaAttributed = metaDtd_->documentElementType();
1506 inhibitCache = 1;
1508 else {
1509 metaAttributed = 0;
1510 if (arcAuto_)
1511 metaAttributed = metaDtd_->lookupElementType(name);
1512 if (!metaAttributed
1513 && supportAtts_[rArcBridF].size() > 0
1514 && atts.idIndex(idIndex)
1515 && atts.specified(idIndex)) {
1516 inhibitCache = 1;
1517 metaAttributed
1518 = metaDtd_->lookupElementType(supportAtts_[rArcBridF]);
1521 if (metaAttributed
1522 && name == supportAtts_[rArcSuprF]) {
1523 newSuppressFlags = suppressForm|ignoreData;
1525 else if (thisSuppressFlags & suppressForm)
1526 return 0;
1527 return metaAttributed;
1529 else if (thisSuppressFlags & suppressForm)
1530 return 0;
1531 else {
1532 const Attributed *metaAttributed = 0;
1533 if (arcAuto_)
1534 metaAttributed = metaDtd_->lookupNotation(name).pointer();
1535 if (!metaAttributed && supportAtts_[rArcDataF].size() > 0)
1536 metaAttributed
1537 = metaDtd_->lookupNotation(supportAtts_[rArcDataF]).pointer();
1538 return metaAttributed;
1543 const Text *
1544 ArcProcessor::considerNamer(const AttributeList &atts,
1545 Boolean &inhibitCache,
1546 unsigned &arcNamerIndex)
1548 arcNamerIndex = invalidAtt;
1549 if (supportAtts_[rArcNamrA].size() == 0
1550 || !atts.attributeIndex(supportAtts_[rArcNamrA], arcNamerIndex))
1551 return 0;
1552 if (atts.current(arcNamerIndex) || atts.specified(arcNamerIndex))
1553 inhibitCache = 1;
1554 const AttributeValue *val = atts.value(arcNamerIndex);
1555 if (!val)
1556 return 0;
1557 return val->text();
1560 void ArcProcessor::buildAttributeMapRename(MetaMap &map,
1561 const Text &rename,
1562 const AttributeList &atts,
1563 const AttributeList *linkAtts,
1564 Vector<PackedBoolean> &attRenamed)
1566 Vector<StringC> tokens;
1567 Vector<size_t> tokensPos;
1568 split(rename, docSyntax_->space(), tokens, tokensPos);
1569 ConstPtr<AttributeDefinitionList> metaAttDef;
1570 if (map.attributed)
1571 metaAttDef = map.attributed->attributeDef();
1572 // FIXME Should check that ARCCONT doesn't appear more than once.
1573 for (size_t i = 0; i < tokens.size(); i += 2) {
1574 unsigned fromIndex = invalidAtt;
1575 unsigned toIndex = invalidAtt;
1576 metaSyntax_->generalSubstTable()->subst(tokens[i]);
1577 if (tokens[i] == rniArcCont_)
1578 toIndex = contentPseudoAtt;
1579 else if (metaAttDef.isNull()
1580 || !metaAttDef->attributeIndex(tokens[i], toIndex)) {
1581 setNextLocation(rename.charLocation(tokensPos[i]));
1582 Messenger::message(ArcEngineMessages::renameToInvalid,
1583 StringMessageArg(tokens[i]));
1585 else if (attRenamed[toIndex]) {
1586 toIndex = invalidAtt;
1587 setNextLocation(rename.charLocation(tokensPos[i]));
1588 Messenger::message(ArcEngineMessages::renameToDuplicate,
1589 StringMessageArg(tokens[i]));
1591 if (i + 1 >= tokens.size()) {
1592 setNextLocation(rename.charLocation(tokensPos[i]));
1593 Messenger::message(ArcEngineMessages::renameMissingAttName);
1595 else {
1596 docSyntax_->generalSubstTable()->subst(tokens[i + 1]);
1597 if (tokens[i + 1] == rniContent_) {
1598 fromIndex = contentPseudoAtt;
1600 else if (tokens[i + 1] == rniDefault_) {
1601 if (toIndex != contentPseudoAtt)
1602 attRenamed[toIndex] = 1;
1604 else if (linkAtts
1605 && linkAtts->attributeIndex(tokens[i + 1], fromIndex))
1606 fromIndex += atts.size();
1607 else if (!atts.attributeIndex(tokens[i + 1], fromIndex)) {
1608 setNextLocation(rename.charLocation(tokensPos[i + 1]));
1609 Messenger::message(ArcEngineMessages::renameFromInvalid,
1610 StringMessageArg(tokens[i + 1]));
1613 if (fromIndex != invalidAtt && toIndex != invalidAtt) {
1614 map.attMapFrom.push_back(fromIndex);
1615 map.attMapTo.push_back(toIndex);
1616 if (toIndex != contentPseudoAtt) {
1617 attRenamed[toIndex] = 1;
1618 if (metaAttDef->def(toIndex)->isId()
1619 && (fromIndex >= atts.size() || !atts.id(fromIndex)))
1620 Messenger::message(ArcEngineMessages::idMismatch,
1621 StringMessageArg(metaAttDef->def(toIndex)
1622 ->name()));
1628 void ArcProcessor::buildAttributeMapRest(MetaMap &map,
1629 const AttributeList &atts,
1630 const AttributeList *linkAtts,
1631 const Vector<PackedBoolean> &attRenamed)
1633 ConstPtr<AttributeDefinitionList> metaAttDef
1634 = map.attributed->attributeDef();
1635 if (metaAttDef.isNull())
1636 return;
1637 for (unsigned i = 0; i < metaAttDef->size(); i++)
1638 if (!attRenamed[i]) {
1639 unsigned fromIndex;
1640 if (metaAttDef->def(i)->isId()) {
1641 for (unsigned j = 0; j < atts.size(); j++)
1642 if (atts.id(j)) {
1643 map.attMapFrom.push_back(j);
1644 map.attMapTo.push_back(i);
1645 break;
1648 else if (linkAtts && linkAtts->attributeIndex(metaAttDef->def(i)->name(),
1649 fromIndex)) {
1650 map.attMapFrom.push_back(fromIndex + atts.size());
1651 map.attMapTo.push_back(i);
1653 else if (atts.attributeIndex(metaAttDef->def(i)->name(), fromIndex)) {
1654 map.attMapFrom.push_back(fromIndex);
1655 map.attMapTo.push_back(i);
1660 Boolean ArcProcessor::matchName(const StringC &name, const char *key)
1662 if (name.size() != strlen(key))
1663 return 0;
1664 StringC tem(docSd_->execToInternal(key));
1665 docSyntax_->generalSubstTable()->subst(tem);
1666 return name == tem;
1669 void ArcProcessor::split(const Text &text,
1670 Char space,
1671 Vector<StringC> &tokens,
1672 Vector<size_t> &tokensPos)
1674 const StringC &str = text.string();
1675 for (size_t i = 0;;) {
1676 for (; i < str.size() && str[i] == space; i++)
1678 if (i >= str.size())
1679 break;
1680 size_t start = i;
1681 for (; i < str.size() && str[i] != space; i++)
1683 tokens.push_back(StringC(str.data() + start, i - start));
1684 tokensPos.push_back(start);
1688 void ArcProcessor::processEndElement(const EndElementEvent &event,
1689 Allocator &alloc)
1691 Boolean wasArc = (openElementFlags_.back() & isArc);
1692 openElementFlags_.resize(openElementFlags_.size() - 1);
1693 if (wasArc) {
1694 EndElementEvent *genEvent
1695 = new (alloc) EndElementEvent(currentElement().type(),
1696 metaDtd_,
1697 event.location(),
1699 if (currentElement().included())
1700 genEvent->setIncluded();
1701 docHandler_->endElement(genEvent);
1702 if (!currentElement().isFinished())
1703 Messenger::message(ArcEngineMessages::unfinishedElement,
1704 StringMessageArg(currentElement().type()->name()));
1705 popElement();
1709 void ArcProcessor::dispatchMessage(Message &msg)
1711 mgr_->dispatchMessage(msg);
1714 void ArcProcessor::dispatchMessage(const Message &msg)
1716 mgr_->dispatchMessage(msg);
1719 void ArcProcessor::initMessage(Message &msg)
1721 mgr_->initMessage(msg);
1722 if (valid_) {
1723 StringC rniPcdata = metaSyntax_->delimGeneral(Syntax::dRNI);
1724 rniPcdata += metaSyntax_->reservedName(Syntax::rPCDATA);
1725 getOpenElementInfo(msg.openElementInfo, rniPcdata);
1729 ArcProcessor::MetaMapCache::MetaMapCache()
1731 for (int i = 0; i < nNoSpec; i++)
1732 noSpec[i] = invalidAtt;
1733 linkAtts = 0;
1736 void ArcProcessor::MetaMapCache::clear()
1738 for (int i = 0; i < nNoSpec; i++)
1739 noSpec[i] = invalidAtt;
1740 linkAtts = 0;
1741 map.clear();
1744 ArcProcessor::MetaMap::MetaMap()
1745 : attributed(0)
1749 void ArcProcessor::MetaMap::clear()
1751 attMapFrom.clear();
1752 attMapTo.clear();
1753 attributed = 0;
1756 #ifdef SP_NAMESPACE
1758 #endif