1 // Copyright (c) 1996 James Clark
2 // See the file COPYING for copying permission.
9 #include "GenericEventHandler.h"
11 #include "ExtendEntityManager.h"
14 namespace SP_NAMESPACE {
17 class SpOpenEntity : public SGMLApplication::OpenEntity {
19 SpOpenEntity(const ConstPtr<Origin> &origin);
20 SGMLApplication::Location location(SGMLApplication::Position) const;
22 ConstPtr<Origin> origin_;
23 StorageObjectLocation soLoc_;
27 void GenericEventHandler::freeAll()
34 void GenericEventHandler::clearNotation(SGMLApplication::Notation &to)
40 void GenericEventHandler::setLocation(SGMLApplication::Position &pos,
43 if (lastOrigin_ != loc.origin())
44 setLocation1(pos, loc);
49 GenericEventHandler::GenericEventHandler(SGMLApplication &app,
51 : app_(&app), generalEntities_(generalEntities),
52 freeBlocks_(0), allocBlocks_(0), firstBlockSpare_(0), firstBlockUsed_(0)
56 GenericEventHandler::~GenericEventHandler()
60 Block *tem = freeBlocks_;
61 freeBlocks_ = freeBlocks_->next;
67 void GenericEventHandler::freeAll1()
70 for (p = &allocBlocks_; *p; p = &(*p)->next)
73 freeBlocks_ = allocBlocks_;
76 firstBlockSpare_ = freeBlocks_->size;
82 void *GenericEventHandler::allocate(size_t n)
86 // round up to avoid alignment problems
87 n = (n + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
89 if (n > firstBlockSpare_) {
90 if (freeBlocks_ && firstBlockUsed_) {
91 Block *tem = freeBlocks_;
92 freeBlocks_ = freeBlocks_->next;
93 tem->next = allocBlocks_;
96 if (!freeBlocks_ || freeBlocks_->size < n) {
97 Block *tem = new Block;
98 tem->size = n < BIG ? int(BIG) : n;
99 tem->mem = new char[tem->size];
100 tem->next = freeBlocks_;
104 firstBlockSpare_ = freeBlocks_->size;
106 char *tem = freeBlocks_->mem + firstBlockUsed_;
107 firstBlockUsed_ += n;
108 firstBlockSpare_ -= n;
112 void GenericEventHandler::startElement(StartElementEvent *event)
114 SGMLApplication::StartElementEvent appEvent;
115 setString(appEvent.gi, event->name());
116 const ElementDefinition *def = event->elementType()->definition();
117 switch (def->declaredContent()) {
118 case ElementDefinition::modelGroup:
120 = (def->compiledModelGroup()->containsPcdata()
121 ? SGMLApplication::StartElementEvent::mixed
122 : SGMLApplication::StartElementEvent::element);
124 case ElementDefinition::any:
125 appEvent.contentType = SGMLApplication::StartElementEvent::mixed;
127 case ElementDefinition::cdata:
128 appEvent.contentType = SGMLApplication::StartElementEvent::cdata;
130 case ElementDefinition::rcdata:
131 appEvent.contentType = SGMLApplication::StartElementEvent::rcdata;
133 case ElementDefinition::empty:
134 appEvent.contentType = SGMLApplication::StartElementEvent::empty;
137 appEvent.included = event->included();
138 appEvent.nAttributes = event->attributes().size();
139 if (appEvent.nAttributes != 0) {
140 if (event->attributes().conref())
141 appEvent.contentType = SGMLApplication::StartElementEvent::empty;
142 setAttributes(appEvent.attributes, event->attributes());
144 setLocation(appEvent.pos, event->location());
145 app_->startElement(appEvent);
150 void GenericEventHandler::endElement(EndElementEvent *event)
152 SGMLApplication::EndElementEvent appEvent;
153 setString(appEvent.gi, event->name());
154 setLocation(appEvent.pos, event->location());
155 app_->endElement(appEvent);
159 void GenericEventHandler::data(DataEvent *event)
161 SGMLApplication::DataEvent appEvent;
162 appEvent.data.ptr = event->data();
163 appEvent.data.len = event->dataLength();
164 setLocation(appEvent.pos, event->location());
165 app_->data(appEvent);
169 void GenericEventHandler::pi(PiEvent *event)
171 SGMLApplication::PiEvent appEvent;
172 appEvent.data.ptr = event->data();
173 appEvent.data.len = event->dataLength();
174 const Entity *entity = event->entity();
176 setString(appEvent.entityName, entity->name());
178 appEvent.entityName.len = 0;
179 setLocation(appEvent.pos, event->location());
184 void GenericEventHandler::sdataEntity(SdataEntityEvent *event)
186 SGMLApplication::SdataEvent appEvent;
187 appEvent.text.ptr = event->data();
188 appEvent.text.len = event->dataLength();
189 setString(appEvent.entityName, event->entity()->name());
190 // Don't want location of chars in entity.
191 setLocation(appEvent.pos, event->location().origin()->parent());
192 app_->sdata(appEvent);
196 void GenericEventHandler::externalDataEntity(ExternalDataEntityEvent *event)
198 SGMLApplication::ExternalDataEntityRefEvent appEvent;
199 setEntity(appEvent.entity, *event->entity());
200 setLocation(appEvent.pos, event->location());
201 app_->externalDataEntityRef(appEvent);
206 void GenericEventHandler::subdocEntity(SubdocEntityEvent *event)
208 SGMLApplication::SubdocEntityRefEvent appEvent;
209 setEntity(appEvent.entity, *event->entity());
210 setLocation(appEvent.pos, event->location());
211 app_->subdocEntityRef(appEvent);
216 void GenericEventHandler::nonSgmlChar(NonSgmlCharEvent *event)
218 SGMLApplication::NonSgmlCharEvent appEvent;
219 appEvent.c = event->character();
220 setLocation(appEvent.pos, event->location());
221 app_->nonSgmlChar(appEvent);
225 void GenericEventHandler::startDtd(StartDtdEvent *event)
227 SGMLApplication::StartDtdEvent appEvent;
228 setString(appEvent.name, event->name());
229 const Entity *entity = event->entity().pointer();
231 appEvent.haveExternalId = 1;
232 setExternalId(appEvent.externalId,
233 entity->asExternalEntity()->externalId());
236 appEvent.haveExternalId = 0;
237 setLocation(appEvent.pos, event->location());
238 app_->startDtd(appEvent);
243 void GenericEventHandler::endDtd(EndDtdEvent *event)
245 SGMLApplication::EndDtdEvent appEvent;
246 setString(appEvent.name, event->dtd().name());
247 setLocation(appEvent.pos, event->location());
248 app_->endDtd(appEvent);
252 void GenericEventHandler::endProlog(EndPrologEvent *event)
254 if (generalEntities_) {
255 SGMLApplication::GeneralEntityEvent entityEvent;
256 const Dtd &dtd = event->dtd();
257 Dtd::ConstEntityIter iter(dtd.generalEntityIter());
259 const Entity *entity = iter.nextTemp();
262 setEntity(entityEvent.entity, *entity);
263 app_->generalEntity(entityEvent);
267 SGMLApplication::EndPrologEvent appEvent;
268 setLocation(appEvent.pos, event->location());
269 app_->endProlog(appEvent);
273 void GenericEventHandler::entityDefaulted(EntityDefaultedEvent *event)
275 if (generalEntities_) {
276 SGMLApplication::GeneralEntityEvent appEvent;
277 setEntity(appEvent.entity, event->entity());
278 app_->generalEntity(appEvent);
283 void GenericEventHandler::appinfo(AppinfoEvent *event)
285 SGMLApplication::AppinfoEvent appEvent;
287 if (event->literal(str)) {
288 setString(appEvent.string, *str);
293 setLocation(appEvent.pos, event->location());
294 app_->appinfo(appEvent);
298 void GenericEventHandler::commentDecl(CommentDeclEvent *event)
300 SGMLApplication::CommentDeclEvent appEvent;
301 appEvent.nComments = 0;
303 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
304 if (iter.type() == Markup::comment)
305 appEvent.nComments++;
307 SGMLApplication::CharString *comments
308 = (SGMLApplication::CharString *)allocate(appEvent.nComments * 2
309 * sizeof(SGMLApplication::CharString));
310 appEvent.comments = comments;
311 appEvent.seps = appEvent.comments + appEvent.nComments;
313 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
314 switch (iter.type()) {
315 case Markup::comment:
316 comments[i].ptr = iter.charsPointer();
317 comments[i].len = iter.charsLength();
318 clearString(comments[appEvent.nComments + i]);
322 comments[appEvent.nComments + i - 1].ptr = iter.charsPointer();
323 comments[appEvent.nComments + i - 1].len = iter.charsLength();
328 setLocation(appEvent.pos, event->location());
329 app_->commentDecl(appEvent);
334 void GenericEventHandler::markedSectionStart(MarkedSectionStartEvent *event)
336 SGMLApplication::MarkedSectionStartEvent appEvent;
338 appEvent.nParams = 0;
340 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
341 switch (iter.type()) {
342 case Markup::reservedName:
346 case Markup::entityStart:
351 case Markup::entityEnd:
358 SGMLApplication::MarkedSectionStartEvent::Param *params
359 = (SGMLApplication::MarkedSectionStartEvent::Param *)
360 allocate(appEvent.nParams * sizeof(appEvent.params[0]));
361 appEvent.params = params;
363 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
364 switch (iter.type()) {
365 case Markup::reservedName:
367 switch (iter.reservedName()) {
370 = SGMLApplication::MarkedSectionStartEvent::Param::temp;
372 case Syntax::rINCLUDE:
374 = SGMLApplication::MarkedSectionStartEvent::Param::include;
376 case Syntax::rRCDATA:
378 = SGMLApplication::MarkedSectionStartEvent::Param::rcdata;
382 = SGMLApplication::MarkedSectionStartEvent::Param::cdata;
384 case Syntax::rIGNORE:
386 = SGMLApplication::MarkedSectionStartEvent::Param::ignore;
391 clearString(params[i].entityName);
395 case Markup::entityStart:
398 = SGMLApplication::MarkedSectionStartEvent::Param::entityRef;
399 setString(params[i].entityName,
400 iter.entityOrigin()->entity()->name());
405 case Markup::entityEnd:
411 switch (event->status()) {
412 case MarkedSectionEvent::include:
413 appEvent.status = SGMLApplication::MarkedSectionStartEvent::include;
415 case MarkedSectionEvent::rcdata:
416 appEvent.status = SGMLApplication::MarkedSectionStartEvent::rcdata;
418 case MarkedSectionEvent::cdata:
419 appEvent.status = SGMLApplication::MarkedSectionStartEvent::cdata;
421 case MarkedSectionEvent::ignore:
422 appEvent.status = SGMLApplication::MarkedSectionStartEvent::ignore;
425 setLocation(appEvent.pos, event->location());
426 app_->markedSectionStart(appEvent);
431 void GenericEventHandler::ignoredChars(IgnoredCharsEvent *event)
433 SGMLApplication::IgnoredCharsEvent appEvent;
434 appEvent.data.ptr = event->data();
435 appEvent.data.len = event->dataLength();
436 setLocation(appEvent.pos, event->location());
437 app_->ignoredChars(appEvent);
441 void GenericEventHandler::markedSectionEnd(MarkedSectionEndEvent *event)
443 SGMLApplication::MarkedSectionEndEvent appEvent;
444 switch (event->status()) {
445 case MarkedSectionEvent::include:
446 appEvent.status = SGMLApplication::MarkedSectionEndEvent::include;
448 case MarkedSectionEvent::rcdata:
449 appEvent.status = SGMLApplication::MarkedSectionEndEvent::rcdata;
451 case MarkedSectionEvent::cdata:
452 appEvent.status = SGMLApplication::MarkedSectionEndEvent::cdata;
454 case MarkedSectionEvent::ignore:
455 appEvent.status = SGMLApplication::MarkedSectionEndEvent::ignore;
458 setLocation(appEvent.pos, event->location());
459 app_->markedSectionEnd(appEvent);
463 void GenericEventHandler::message(MessageEvent *event)
465 SGMLApplication::ErrorEvent appEvent;
466 switch (event->message().type->severity()) {
467 case MessageType::quantityError:
468 appEvent.type = SGMLApplication::ErrorEvent::quantity;
470 case MessageType::idrefError:
471 appEvent.type = SGMLApplication::ErrorEvent::idref;
473 case MessageType::error:
474 appEvent.type = SGMLApplication::ErrorEvent::otherError;
476 case MessageType::info:
477 appEvent.type = SGMLApplication::ErrorEvent::info;
479 case MessageType::warning:
480 appEvent.type = SGMLApplication::ErrorEvent::warning;
483 setLocation(appEvent.pos, event->message().loc);
485 reportMessage(event->message(), str);
486 setString(appEvent.message, str);
487 app_->error(appEvent);
488 ErrorCountEventHandler::message(event);
491 void GenericEventHandler::setLocation1(SGMLApplication::Position &pos,
494 const Location *locp = &loc;
496 if (locp->origin().isNull()) {
498 openEntityPtr_ = (SpOpenEntity *)0;
501 const InputSourceOrigin *origin = locp->origin()->asInputSourceOrigin();
502 if (origin && origin->externalInfo())
504 locp = &locp->origin()->parent();
506 lastOrigin_ = locp->origin();
508 openEntityPtr_ = new SpOpenEntity(locp->origin());
509 app_->openEntityChange(openEntityPtr_);
513 GenericEventHandler::setAttributes(const SGMLApplication::Attribute *&attributes,
514 const AttributeList &attributeList)
516 size_t nAttributes = attributeList.size();
517 SGMLApplication::Attribute *to
518 = (SGMLApplication::Attribute *)allocate(nAttributes * sizeof(*to));
520 for (size_t i = 0; i < nAttributes; i++) {
521 SGMLApplication::Attribute *p = to + i;
522 setString(p->name, attributeList.name(i));
523 const AttributeValue *value = attributeList.value(i);
525 p->type = SGMLApplication::Attribute::invalid;
528 const StringC *string;
529 switch (value->info(text, string)) {
530 case AttributeValue::implied:
531 p->type = SGMLApplication::Attribute::implied;
533 case AttributeValue::tokenized:
535 if (attributeList.specified(i))
536 p->defaulted = SGMLApplication::Attribute::specified;
537 else if (attributeList.current(i))
538 p->defaulted = SGMLApplication::Attribute::current;
540 p->defaulted = SGMLApplication::Attribute::definition;
541 p->type = SGMLApplication::Attribute::tokenized;
543 p->notation.name.len = 0;
544 p->isId = attributeList.id(i);
545 p->isGroup = (attributeList.getAllowedTokens(i) != 0);
546 setString(p->tokens, *string);
547 const AttributeSemantics *semantics = attributeList.semantics(i);
549 ConstPtr<Notation> notation = semantics->notation();
550 if (!notation.isNull())
551 setNotation(p->notation, *notation);
553 size_t nEntities = semantics->nEntities();
555 SGMLApplication::Entity *v
556 = (SGMLApplication::Entity *)allocate(nEntities * sizeof(*v));
558 p->nEntities = nEntities;
559 for (size_t i = 0; i < nEntities; i++)
560 setEntity(v[i], *semantics->entity(i));
566 case AttributeValue::cdata:
568 p->type = SGMLApplication::Attribute::cdata;
569 if (attributeList.specified(i))
570 p->defaulted = SGMLApplication::Attribute::specified;
571 else if (attributeList.current(i))
572 p->defaulted = SGMLApplication::Attribute::current;
574 p->defaulted = SGMLApplication::Attribute::definition;
581 TextIter iter(*text);
582 while (iter.next(type, s, length, loc))
585 case TextItem::sdata:
586 case TextItem::cdata:
587 case TextItem::nonSgml:
595 = (SGMLApplication::Attribute::CdataChunk *)allocate(nChunks * sizeof(SGMLApplication::Attribute::CdataChunk));
596 p->nCdataChunks = nChunks;
600 for (TextIter iter(*text); iter.next(type, s, length, loc);) {
603 case TextItem::sdata:
604 case TextItem::cdata:
606 SGMLApplication::Attribute::CdataChunk *chunk
607 = (SGMLApplication::Attribute::CdataChunk *)(p->cdataChunks + i++);
608 if (type != TextItem::sdata) {
610 chunk->isNonSgml = 0;
614 setString(chunk->entityName,
615 *loc->origin()->asInputSourceOrigin()->entityName());
618 chunk->data.len = length;
621 case TextItem::nonSgml:
623 SGMLApplication::Attribute::CdataChunk *chunk
624 = (SGMLApplication::Attribute::CdataChunk *)(p->cdataChunks + i++);
626 chunk->isNonSgml = 1;
627 chunk->nonSgmlChar = *s;
645 void GenericEventHandler::setEntity(SGMLApplication::Entity &to,
648 setString(to.name, from.name());
649 switch (from.declType()) {
650 case Entity::generalEntity:
651 to.declType = SGMLApplication::Entity::general;
653 case Entity::parameterEntity:
654 to.declType = SGMLApplication::Entity::parameter;
656 case Entity::doctype:
657 to.declType = SGMLApplication::Entity::doctype;
659 case Entity::linktype:
660 to.declType = SGMLApplication::Entity::linktype;
665 switch (from.dataType()) {
666 case Entity::sgmlText:
667 to.dataType = SGMLApplication::Entity::sgml;
670 to.dataType = SGMLApplication::Entity::cdata;
673 to.dataType = SGMLApplication::Entity::sdata;
676 to.dataType = SGMLApplication::Entity::ndata;
679 to.dataType = SGMLApplication::Entity::subdoc;
682 to.dataType = SGMLApplication::Entity::pi;
685 const InternalEntity *internal = from.asInternalEntity();
688 setString(to.text, internal->string());
691 const ExternalEntity *external = from.asExternalEntity();
693 setExternalId(to.externalId, external->externalId());
694 const ExternalDataEntity *externalData = from.asExternalDataEntity();
696 setNotation(to.notation, *externalData->notation());
697 to.nAttributes = externalData->attributes().size();
699 setAttributes(to.attributes, externalData->attributes());
702 to.notation.name.len = 0;
709 void GenericEventHandler::setNotation(SGMLApplication::Notation &to,
710 const Notation &from)
712 setString(to.name, from.name());
713 setExternalId(to.externalId, from.externalId());
716 void GenericEventHandler::setExternalId(SGMLApplication::ExternalId &to,
717 const ExternalId &from)
720 str = from.systemIdString();
723 setString(to.systemId, *str);
727 str = from.publicIdString();
730 setString(to.publicId, *str);
734 str = &from.effectiveSystemId();
736 to.haveGeneratedSystemId = 1;
737 setString(to.generatedSystemId, *str);
740 to.haveGeneratedSystemId = 0;
743 MsgGenericEventHandler::MsgGenericEventHandler(SGMLApplication &app,
744 bool generalEntities,
745 MessageReporter &reporter,
746 const bool *messagesInhibitedPtr)
747 : GenericEventHandler(app, generalEntities),
748 reporter_(&reporter),
749 messagesInhibitedPtr_(messagesInhibitedPtr)
753 void MsgGenericEventHandler::reportMessage(const Message &msg, StringC &str)
755 WrapReporter wrap(reporter_);
756 reporter_->dispatchMessage(msg);
757 wrap.strStream.extractString(str);
758 if (!*messagesInhibitedPtr_)
759 *wrap.origStream << str;
762 SpOpenEntity::SpOpenEntity(const ConstPtr<Origin> &origin)
767 SGMLApplication::Location
768 SpOpenEntity::location(SGMLApplication::Position pos) const
770 SGMLApplication::Location loc;
771 const Origin *origin = origin_.pointer();
772 const InputSourceOrigin *inputSourceOrigin;
773 const ExternalInfo *externalInfo;
774 Index index = Index(pos);
778 inputSourceOrigin = origin->asInputSourceOrigin();
779 if (inputSourceOrigin) {
780 externalInfo = inputSourceOrigin->externalInfo();
784 // Qualifier is for CodeWarrior
785 const ::SP_NAMESPACE_SCOPE Location &loc = origin->parent();
787 origin = loc.origin().pointer();
789 const StringC *entityName = inputSourceOrigin->entityName();
791 GenericEventHandler::setString(loc.entityName, *entityName);
792 Offset off = inputSourceOrigin->startOffset(index);
793 loc.entityOffset = off;
794 if (!ExtendEntityManager::externalize(externalInfo, off, ((SpOpenEntity *)this)->soLoc_))
796 loc.lineNumber = soLoc_.lineNumber;
797 GenericEventHandler::setString(loc.filename, soLoc_.actualStorageId);
798 loc.columnNumber = soLoc_.columnNumber;
799 loc.byteOffset = soLoc_.byteIndex;
800 loc.other = soLoc_.storageObjectSpec;