1 /* $XConsortium: GenericEventHandler.C /main/1 1996/07/29 16:52:15 cde-hp $ */
2 // Copyright (c) 1996 James Clark
3 // See the file COPYING for copying permission.
10 #include "GenericEventHandler.h"
12 #include "ExtendEntityManager.h"
15 namespace SP_NAMESPACE {
18 class SpOpenEntity : public SGMLApplication::OpenEntity {
20 SpOpenEntity(const ConstPtr<Origin> &origin);
21 SGMLApplication::Location location(SGMLApplication::Position) const;
23 ConstPtr<Origin> origin_;
27 void *operator new(size_t n, GenericEventHandler *handler)
29 return handler->allocate(n);
33 void GenericEventHandler::freeAll()
40 void GenericEventHandler::clearNotation(SGMLApplication::Notation &to)
46 void GenericEventHandler::setLocation(SGMLApplication::Position &pos,
49 if (lastOrigin_ != loc.origin())
50 setLocation1(pos, loc);
55 GenericEventHandler::GenericEventHandler(SGMLApplication &app,
57 : app_(&app), generalEntities_(generalEntities),
58 freeBlocks_(0), allocBlocks_(0), firstBlockSpare_(0), firstBlockUsed_(0)
62 GenericEventHandler::~GenericEventHandler()
66 Block *tem = freeBlocks_;
67 freeBlocks_ = freeBlocks_->next;
73 void GenericEventHandler::freeAll1()
76 for (p = &allocBlocks_; *p; p = &(*p)->next)
79 freeBlocks_ = allocBlocks_;
82 firstBlockSpare_ = freeBlocks_->size;
88 void *GenericEventHandler::allocate(size_t n)
92 // round up to avoid alignment problems
93 n = (n + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
95 if (n > firstBlockSpare_) {
96 if (freeBlocks_ && firstBlockUsed_) {
97 Block *tem = freeBlocks_;
98 freeBlocks_ = freeBlocks_->next;
99 tem->next = allocBlocks_;
102 if (!freeBlocks_ || freeBlocks_->size < n) {
103 Block *tem = new Block;
104 tem->size = n < BIG ? int(BIG) : n;
105 tem->mem = new char[tem->size];
106 tem->next = freeBlocks_;
110 firstBlockSpare_ = freeBlocks_->size;
112 char *tem = freeBlocks_->mem + firstBlockUsed_;
113 firstBlockUsed_ += n;
114 firstBlockSpare_ -= n;
118 void GenericEventHandler::startElement(StartElementEvent *event)
120 SGMLApplication::StartElementEvent appEvent;
121 setString(appEvent.gi, event->name());
122 const ElementDefinition *def = event->elementType()->definition();
123 switch (def->declaredContent()) {
124 case ElementDefinition::modelGroup:
126 = (def->compiledModelGroup()->containsPcdata()
127 ? SGMLApplication::StartElementEvent::mixed
128 : SGMLApplication::StartElementEvent::element);
130 case ElementDefinition::any:
131 appEvent.contentType = SGMLApplication::StartElementEvent::mixed;
133 case ElementDefinition::cdata:
134 appEvent.contentType = SGMLApplication::StartElementEvent::cdata;
136 case ElementDefinition::rcdata:
137 appEvent.contentType = SGMLApplication::StartElementEvent::rcdata;
139 case ElementDefinition::empty:
140 appEvent.contentType = SGMLApplication::StartElementEvent::empty;
143 appEvent.included = event->included();
144 appEvent.nAttributes = event->attributes().size();
145 if (appEvent.nAttributes != 0) {
146 if (event->attributes().conref())
147 appEvent.contentType = SGMLApplication::StartElementEvent::empty;
148 setAttributes(appEvent.attributes, event->attributes());
150 setLocation(appEvent.pos, event->location());
151 app_->startElement(appEvent);
156 void GenericEventHandler::endElement(EndElementEvent *event)
158 SGMLApplication::EndElementEvent appEvent;
159 setString(appEvent.gi, event->name());
160 setLocation(appEvent.pos, event->location());
161 app_->endElement(appEvent);
165 void GenericEventHandler::data(DataEvent *event)
167 SGMLApplication::DataEvent appEvent;
168 appEvent.data.ptr = event->data();
169 appEvent.data.len = event->dataLength();
170 setLocation(appEvent.pos, event->location());
171 app_->data(appEvent);
175 void GenericEventHandler::pi(PiEvent *event)
177 SGMLApplication::PiEvent appEvent;
178 appEvent.data.ptr = event->data();
179 appEvent.data.len = event->dataLength();
180 const Entity *entity = event->entity();
182 setString(appEvent.entityName, entity->name());
184 appEvent.entityName.len = 0;
185 setLocation(appEvent.pos, event->location());
190 void GenericEventHandler::sdataEntity(SdataEntityEvent *event)
192 SGMLApplication::SdataEvent appEvent;
193 appEvent.text.ptr = event->data();
194 appEvent.text.len = event->dataLength();
195 setString(appEvent.entityName, event->entity()->name());
196 // Don't want location of chars in entity.
197 setLocation(appEvent.pos, event->location().origin()->parent());
198 app_->sdata(appEvent);
202 void GenericEventHandler::externalDataEntity(ExternalDataEntityEvent *event)
204 SGMLApplication::ExternalDataEntityRefEvent appEvent;
205 setEntity(appEvent.entity, *event->entity());
206 setLocation(appEvent.pos, event->location());
207 app_->externalDataEntityRef(appEvent);
212 void GenericEventHandler::subdocEntity(SubdocEntityEvent *event)
214 SGMLApplication::SubdocEntityRefEvent appEvent;
215 setEntity(appEvent.entity, *event->entity());
216 setLocation(appEvent.pos, event->location());
217 app_->subdocEntityRef(appEvent);
222 void GenericEventHandler::startDtd(StartDtdEvent *event)
224 SGMLApplication::StartDtdEvent appEvent;
225 setString(appEvent.name, event->name());
226 const Entity *entity = event->entity().pointer();
228 appEvent.haveExternalId = 1;
229 setExternalId(appEvent.externalId,
230 entity->asExternalEntity()->externalId());
233 appEvent.haveExternalId = 0;
234 setLocation(appEvent.pos, event->location());
235 app_->startDtd(appEvent);
240 void GenericEventHandler::endDtd(EndDtdEvent *event)
242 SGMLApplication::EndDtdEvent appEvent;
243 setString(appEvent.name, event->dtd().name());
244 setLocation(appEvent.pos, event->location());
245 app_->endDtd(appEvent);
249 void GenericEventHandler::endProlog(EndPrologEvent *event)
251 if (generalEntities_) {
252 SGMLApplication::GeneralEntityEvent entityEvent;
253 const Dtd &dtd = event->dtd();
254 Dtd::ConstEntityIter iter(dtd.generalEntityIter());
256 const Entity *entity = iter.nextTemp();
259 setEntity(entityEvent.entity, *entity);
260 app_->generalEntity(entityEvent);
264 SGMLApplication::EndPrologEvent appEvent;
265 setLocation(appEvent.pos, event->location());
266 app_->endProlog(appEvent);
270 void GenericEventHandler::entityDefaulted(EntityDefaultedEvent *event)
272 if (generalEntities_) {
273 SGMLApplication::GeneralEntityEvent appEvent;
274 setEntity(appEvent.entity, event->entity());
275 app_->generalEntity(appEvent);
280 void GenericEventHandler::appinfo(AppinfoEvent *event)
282 SGMLApplication::AppinfoEvent appEvent;
284 if (event->literal(str)) {
285 setString(appEvent.string, *str);
290 setLocation(appEvent.pos, event->location());
291 app_->appinfo(appEvent);
295 void GenericEventHandler::commentDecl(CommentDeclEvent *event)
297 SGMLApplication::CommentDeclEvent appEvent;
298 appEvent.nComments = 0;
300 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
301 if (iter.type() == Markup::comment)
302 appEvent.nComments++;
304 SGMLApplication::CharString *comments
305 = (SGMLApplication::CharString *)allocate(appEvent.nComments * 2
306 * sizeof(SGMLApplication::CharString));
307 appEvent.comments = comments;
308 appEvent.seps = appEvent.comments + appEvent.nComments;
310 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
311 switch (iter.type()) {
312 case Markup::comment:
313 comments[i].ptr = iter.charsPointer();
314 comments[i].len = iter.charsLength();
315 clearString(comments[appEvent.nComments + i]);
319 comments[appEvent.nComments + i - 1].ptr = iter.charsPointer();
320 comments[appEvent.nComments + i - 1].len = iter.charsLength();
325 setLocation(appEvent.pos, event->location());
326 app_->commentDecl(appEvent);
331 void GenericEventHandler::markedSectionStart(MarkedSectionStartEvent *event)
333 SGMLApplication::MarkedSectionStartEvent appEvent;
335 appEvent.nParams = 0;
337 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
338 switch (iter.type()) {
339 case Markup::reservedName:
343 case Markup::entityStart:
348 case Markup::entityEnd:
355 SGMLApplication::MarkedSectionStartEvent::Param *params
356 = (SGMLApplication::MarkedSectionStartEvent::Param *)
357 allocate(appEvent.nParams * sizeof(appEvent.params[0]));
358 appEvent.params = params;
360 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
361 switch (iter.type()) {
362 case Markup::reservedName:
364 switch (iter.reservedName()) {
367 = SGMLApplication::MarkedSectionStartEvent::Param::temp;
369 case Syntax::rINCLUDE:
371 = SGMLApplication::MarkedSectionStartEvent::Param::include;
373 case Syntax::rRCDATA:
375 = SGMLApplication::MarkedSectionStartEvent::Param::rcdata;
379 = SGMLApplication::MarkedSectionStartEvent::Param::cdata;
381 case Syntax::rIGNORE:
383 = SGMLApplication::MarkedSectionStartEvent::Param::ignore;
388 clearString(params[i].entityName);
392 case Markup::entityStart:
395 = SGMLApplication::MarkedSectionStartEvent::Param::entityRef;
396 setString(params[i].entityName,
397 iter.entityOrigin()->entity()->name());
402 case Markup::entityEnd:
408 switch (event->status()) {
409 case MarkedSectionEvent::include:
410 appEvent.status = SGMLApplication::MarkedSectionStartEvent::include;
412 case MarkedSectionEvent::rcdata:
413 appEvent.status = SGMLApplication::MarkedSectionStartEvent::rcdata;
415 case MarkedSectionEvent::cdata:
416 appEvent.status = SGMLApplication::MarkedSectionStartEvent::cdata;
418 case MarkedSectionEvent::ignore:
419 appEvent.status = SGMLApplication::MarkedSectionStartEvent::ignore;
422 setLocation(appEvent.pos, event->location());
423 app_->markedSectionStart(appEvent);
428 void GenericEventHandler::ignoredChars(IgnoredCharsEvent *event)
430 SGMLApplication::IgnoredCharsEvent appEvent;
431 appEvent.data.ptr = event->data();
432 appEvent.data.len = event->dataLength();
433 setLocation(appEvent.pos, event->location());
434 app_->ignoredChars(appEvent);
438 void GenericEventHandler::markedSectionEnd(MarkedSectionEndEvent *event)
440 SGMLApplication::MarkedSectionEndEvent appEvent;
441 switch (event->status()) {
442 case MarkedSectionEvent::include:
443 appEvent.status = SGMLApplication::MarkedSectionEndEvent::include;
445 case MarkedSectionEvent::rcdata:
446 appEvent.status = SGMLApplication::MarkedSectionEndEvent::rcdata;
448 case MarkedSectionEvent::cdata:
449 appEvent.status = SGMLApplication::MarkedSectionEndEvent::cdata;
451 case MarkedSectionEvent::ignore:
452 appEvent.status = SGMLApplication::MarkedSectionEndEvent::ignore;
455 setLocation(appEvent.pos, event->location());
456 app_->markedSectionEnd(appEvent);
460 void GenericEventHandler::message(MessageEvent *event)
462 SGMLApplication::ErrorEvent appEvent;
463 switch (event->message().type->severity()) {
464 case MessageType::quantityError:
465 appEvent.type = SGMLApplication::ErrorEvent::quantity;
467 case MessageType::idrefError:
468 appEvent.type = SGMLApplication::ErrorEvent::idref;
470 case MessageType::error:
471 appEvent.type = SGMLApplication::ErrorEvent::otherError;
473 case MessageType::info:
474 appEvent.type = SGMLApplication::ErrorEvent::info;
476 case MessageType::warning:
477 appEvent.type = SGMLApplication::ErrorEvent::warning;
480 setLocation(appEvent.pos, event->message().loc);
482 reportMessage(event->message(), str);
483 setString(appEvent.message, str);
484 app_->error(appEvent);
485 ErrorCountEventHandler::message(event);
488 void GenericEventHandler::setLocation1(SGMLApplication::Position &pos,
491 const Location *locp = &loc;
493 if (locp->origin().isNull()) {
495 openEntityPtr_ = (SpOpenEntity *)0;
498 const InputSourceOrigin *origin = locp->origin()->asInputSourceOrigin();
499 if (origin && origin->externalInfo())
501 locp = &locp->origin()->parent();
503 lastOrigin_ = locp->origin();
505 openEntityPtr_ = new SpOpenEntity(locp->origin());
506 app_->openEntityChange(openEntityPtr_);
510 GenericEventHandler::setAttributes(const SGMLApplication::Attribute *&attributes,
511 const AttributeList &attributeList)
513 size_t nAttributes = attributeList.size();
514 SGMLApplication::Attribute *to
515 = (SGMLApplication::Attribute *)allocate(nAttributes * sizeof(*to));
517 for (size_t i = 0; i < nAttributes; i++) {
518 SGMLApplication::Attribute *p = to + i;
519 setString(p->name, attributeList.name(i));
520 const AttributeValue *value = attributeList.value(i);
522 p->type = SGMLApplication::Attribute::invalid;
525 const StringC *string;
526 switch (value->info(text, string)) {
527 case AttributeValue::implied:
528 p->type = SGMLApplication::Attribute::implied;
530 case AttributeValue::tokenized:
532 if (attributeList.specified(i))
533 p->defaulted = SGMLApplication::Attribute::specified;
534 else if (attributeList.current(i))
535 p->defaulted = SGMLApplication::Attribute::current;
537 p->defaulted = SGMLApplication::Attribute::definition;
538 p->type = SGMLApplication::Attribute::tokenized;
540 p->notation.name.len = 0;
541 p->isId = attributeList.id(i);
542 p->isGroup = (attributeList.getAllowedTokens(i) != 0);
543 setString(p->tokens, *string);
544 const AttributeSemantics *semantics = attributeList.semantics(i);
546 ConstPtr<Notation> notation = semantics->notation();
547 if (!notation.isNull())
548 setNotation(p->notation, *notation);
550 size_t nEntities = semantics->nEntities();
552 SGMLApplication::Entity *v
553 = (SGMLApplication::Entity *)allocate(nEntities * sizeof(*v));
555 p->nEntities = nEntities;
556 for (size_t i = 0; i < nEntities; i++)
557 setEntity(v[i], *semantics->entity(i));
563 case AttributeValue::cdata:
565 p->type = SGMLApplication::Attribute::cdata;
566 if (attributeList.specified(i))
567 p->defaulted = SGMLApplication::Attribute::specified;
568 else if (attributeList.current(i))
569 p->defaulted = SGMLApplication::Attribute::current;
571 p->defaulted = SGMLApplication::Attribute::definition;
578 TextIter iter(*text);
579 while (iter.next(type, s, length, loc))
582 case TextItem::sdata:
583 case TextItem::cdata:
591 = (SGMLApplication::Attribute::CdataChunk *)allocate(nChunks * sizeof(SGMLApplication::Attribute::CdataChunk));
592 p->nCdataChunks = nChunks;
596 for (TextIter iter(*text);
597 iter.next(type, s, length, loc);
601 case TextItem::sdata:
602 case TextItem::cdata:
604 SGMLApplication::Attribute::CdataChunk *chunk
605 = (SGMLApplication::Attribute::CdataChunk *)(p->cdataChunks + i);
606 if (type != TextItem::sdata)
610 setString(chunk->entityName,
611 *loc->origin()->asInputSourceOrigin()->entityName());
614 chunk->data.len = length;
630 void GenericEventHandler::setEntity(SGMLApplication::Entity &to,
633 setString(to.name, from.name());
634 switch (from.declType()) {
635 case Entity::generalEntity:
636 to.declType = SGMLApplication::Entity::general;
638 case Entity::parameterEntity:
639 to.declType = SGMLApplication::Entity::parameter;
641 case Entity::doctype:
642 to.declType = SGMLApplication::Entity::doctype;
644 case Entity::linktype:
645 to.declType = SGMLApplication::Entity::linktype;
650 switch (from.dataType()) {
651 case Entity::sgmlText:
652 to.dataType = SGMLApplication::Entity::sgml;
655 to.dataType = SGMLApplication::Entity::cdata;
658 to.dataType = SGMLApplication::Entity::sdata;
661 to.dataType = SGMLApplication::Entity::ndata;
664 to.dataType = SGMLApplication::Entity::subdoc;
667 to.dataType = SGMLApplication::Entity::pi;
670 const InternalEntity *internal = from.asInternalEntity();
673 setString(to.text, internal->string());
676 const ExternalEntity *external = from.asExternalEntity();
678 setExternalId(to.externalId, external->externalId());
679 const ExternalDataEntity *externalData = from.asExternalDataEntity();
681 setNotation(to.notation, *externalData->notation());
682 to.nAttributes = externalData->attributes().size();
684 setAttributes(to.attributes, externalData->attributes());
687 to.notation.name.len = 0;
694 void GenericEventHandler::setNotation(SGMLApplication::Notation &to,
695 const Notation &from)
697 setString(to.name, from.name());
698 setExternalId(to.externalId, from.externalId());
701 void GenericEventHandler::setExternalId(SGMLApplication::ExternalId &to,
702 const ExternalId &from)
705 str = from.systemIdString();
708 setString(to.systemId, *str);
712 str = from.publicIdString();
715 setString(to.publicId, *str);
719 str = &from.effectiveSystemId();
721 to.haveGeneratedSystemId = 1;
722 setString(to.generatedSystemId, *str);
725 to.haveGeneratedSystemId = 0;
728 MsgGenericEventHandler::MsgGenericEventHandler(SGMLApplication &app,
729 bool generalEntities,
730 MessageReporter &reporter,
731 const bool *messagesInhibitedPtr)
732 : GenericEventHandler(app, generalEntities),
733 reporter_(&reporter),
734 messagesInhibitedPtr_(messagesInhibitedPtr)
738 void MsgGenericEventHandler::reportMessage(const Message &msg, StringC &str)
740 WrapReporter wrap(reporter_);
741 reporter_->dispatchMessage(msg);
742 wrap.strStream.extractString(str);
743 if (!*messagesInhibitedPtr_)
744 *wrap.origStream << str;
747 SpOpenEntity::SpOpenEntity(const ConstPtr<Origin> &origin)
752 SGMLApplication::Location
753 SpOpenEntity::location(SGMLApplication::Position pos) const
755 SGMLApplication::Location loc;
756 const Origin *origin = origin_.pointer();
757 const InputSourceOrigin *inputSourceOrigin;
758 const ExternalInfo *externalInfo;
759 Index index = Index(pos);
763 inputSourceOrigin = origin->asInputSourceOrigin();
764 if (inputSourceOrigin) {
765 externalInfo = inputSourceOrigin->externalInfo();
769 const Location &loc = origin->parent();
771 origin = loc.origin().pointer();
773 const StringC *entityName = inputSourceOrigin->entityName();
775 GenericEventHandler::setString(loc.entityName, *entityName);
776 Offset off = inputSourceOrigin->startOffset(index);
777 loc.entityOffset = off;
778 StorageObjectLocation soLoc;
779 if (!ExtendEntityManager::externalize(externalInfo, off, soLoc))
781 loc.lineNumber = soLoc.lineNumber;
782 GenericEventHandler::setString(loc.filename, soLoc.storageObjectSpec->id);
783 loc.columnNumber = soLoc.columnNumber;
784 loc.byteOffset = soLoc.byteIndex;
785 loc.other = soLoc.storageObjectSpec;