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 librararies 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: GenericEventHandler.C /main/1 1996/07/29 16:52:15 cde-hp $ */
24 // Copyright (c) 1996 James Clark
25 // See the file COPYING for copying permission.
28 #pragma implementation
32 #include "GenericEventHandler.h"
34 #include "ExtendEntityManager.h"
37 namespace SP_NAMESPACE {
40 class SpOpenEntity : public SGMLApplication::OpenEntity {
42 SpOpenEntity(const ConstPtr<Origin> &origin);
43 SGMLApplication::Location location(SGMLApplication::Position) const;
45 ConstPtr<Origin> origin_;
49 void *operator new(size_t n, GenericEventHandler *handler)
51 return handler->allocate(n);
55 void GenericEventHandler::freeAll()
62 void GenericEventHandler::clearNotation(SGMLApplication::Notation &to)
68 void GenericEventHandler::setLocation(SGMLApplication::Position &pos,
71 if (lastOrigin_ != loc.origin())
72 setLocation1(pos, loc);
77 GenericEventHandler::GenericEventHandler(SGMLApplication &app,
79 : app_(&app), generalEntities_(generalEntities),
80 freeBlocks_(0), allocBlocks_(0), firstBlockSpare_(0), firstBlockUsed_(0)
84 GenericEventHandler::~GenericEventHandler()
88 Block *tem = freeBlocks_;
89 freeBlocks_ = freeBlocks_->next;
95 void GenericEventHandler::freeAll1()
98 for (p = &allocBlocks_; *p; p = &(*p)->next)
101 freeBlocks_ = allocBlocks_;
104 firstBlockSpare_ = freeBlocks_->size;
106 firstBlockSpare_ = 0;
110 void *GenericEventHandler::allocate(size_t n)
114 // round up to avoid alignment problems
115 n = (n + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
117 if (n > firstBlockSpare_) {
118 if (freeBlocks_ && firstBlockUsed_) {
119 Block *tem = freeBlocks_;
120 freeBlocks_ = freeBlocks_->next;
121 tem->next = allocBlocks_;
124 if (!freeBlocks_ || freeBlocks_->size < n) {
125 Block *tem = new Block;
126 tem->size = n < BIG ? int(BIG) : n;
127 tem->mem = new char[tem->size];
128 tem->next = freeBlocks_;
132 firstBlockSpare_ = freeBlocks_->size;
134 char *tem = freeBlocks_->mem + firstBlockUsed_;
135 firstBlockUsed_ += n;
136 firstBlockSpare_ -= n;
140 void GenericEventHandler::startElement(StartElementEvent *event)
142 SGMLApplication::StartElementEvent appEvent;
143 setString(appEvent.gi, event->name());
144 const ElementDefinition *def = event->elementType()->definition();
145 switch (def->declaredContent()) {
146 case ElementDefinition::modelGroup:
148 = (def->compiledModelGroup()->containsPcdata()
149 ? SGMLApplication::StartElementEvent::mixed
150 : SGMLApplication::StartElementEvent::element);
152 case ElementDefinition::any:
153 appEvent.contentType = SGMLApplication::StartElementEvent::mixed;
155 case ElementDefinition::cdata:
156 appEvent.contentType = SGMLApplication::StartElementEvent::cdata;
158 case ElementDefinition::rcdata:
159 appEvent.contentType = SGMLApplication::StartElementEvent::rcdata;
161 case ElementDefinition::empty:
162 appEvent.contentType = SGMLApplication::StartElementEvent::empty;
165 appEvent.included = event->included();
166 appEvent.nAttributes = event->attributes().size();
167 if (appEvent.nAttributes != 0) {
168 if (event->attributes().conref())
169 appEvent.contentType = SGMLApplication::StartElementEvent::empty;
170 setAttributes(appEvent.attributes, event->attributes());
172 setLocation(appEvent.pos, event->location());
173 app_->startElement(appEvent);
178 void GenericEventHandler::endElement(EndElementEvent *event)
180 SGMLApplication::EndElementEvent appEvent;
181 setString(appEvent.gi, event->name());
182 setLocation(appEvent.pos, event->location());
183 app_->endElement(appEvent);
187 void GenericEventHandler::data(DataEvent *event)
189 SGMLApplication::DataEvent appEvent;
190 appEvent.data.ptr = event->data();
191 appEvent.data.len = event->dataLength();
192 setLocation(appEvent.pos, event->location());
193 app_->data(appEvent);
197 void GenericEventHandler::pi(PiEvent *event)
199 SGMLApplication::PiEvent appEvent;
200 appEvent.data.ptr = event->data();
201 appEvent.data.len = event->dataLength();
202 const Entity *entity = event->entity();
204 setString(appEvent.entityName, entity->name());
206 appEvent.entityName.len = 0;
207 setLocation(appEvent.pos, event->location());
212 void GenericEventHandler::sdataEntity(SdataEntityEvent *event)
214 SGMLApplication::SdataEvent appEvent;
215 appEvent.text.ptr = event->data();
216 appEvent.text.len = event->dataLength();
217 setString(appEvent.entityName, event->entity()->name());
218 // Don't want location of chars in entity.
219 setLocation(appEvent.pos, event->location().origin()->parent());
220 app_->sdata(appEvent);
224 void GenericEventHandler::externalDataEntity(ExternalDataEntityEvent *event)
226 SGMLApplication::ExternalDataEntityRefEvent appEvent;
227 setEntity(appEvent.entity, *event->entity());
228 setLocation(appEvent.pos, event->location());
229 app_->externalDataEntityRef(appEvent);
234 void GenericEventHandler::subdocEntity(SubdocEntityEvent *event)
236 SGMLApplication::SubdocEntityRefEvent appEvent;
237 setEntity(appEvent.entity, *event->entity());
238 setLocation(appEvent.pos, event->location());
239 app_->subdocEntityRef(appEvent);
244 void GenericEventHandler::startDtd(StartDtdEvent *event)
246 SGMLApplication::StartDtdEvent appEvent;
247 setString(appEvent.name, event->name());
248 const Entity *entity = event->entity().pointer();
250 appEvent.haveExternalId = 1;
251 setExternalId(appEvent.externalId,
252 entity->asExternalEntity()->externalId());
255 appEvent.haveExternalId = 0;
256 setLocation(appEvent.pos, event->location());
257 app_->startDtd(appEvent);
262 void GenericEventHandler::endDtd(EndDtdEvent *event)
264 SGMLApplication::EndDtdEvent appEvent;
265 setString(appEvent.name, event->dtd().name());
266 setLocation(appEvent.pos, event->location());
267 app_->endDtd(appEvent);
271 void GenericEventHandler::endProlog(EndPrologEvent *event)
273 if (generalEntities_) {
274 SGMLApplication::GeneralEntityEvent entityEvent;
275 const Dtd &dtd = event->dtd();
276 Dtd::ConstEntityIter iter(dtd.generalEntityIter());
278 const Entity *entity = iter.nextTemp();
281 setEntity(entityEvent.entity, *entity);
282 app_->generalEntity(entityEvent);
286 SGMLApplication::EndPrologEvent appEvent;
287 setLocation(appEvent.pos, event->location());
288 app_->endProlog(appEvent);
292 void GenericEventHandler::entityDefaulted(EntityDefaultedEvent *event)
294 if (generalEntities_) {
295 SGMLApplication::GeneralEntityEvent appEvent;
296 setEntity(appEvent.entity, event->entity());
297 app_->generalEntity(appEvent);
302 void GenericEventHandler::appinfo(AppinfoEvent *event)
304 SGMLApplication::AppinfoEvent appEvent;
306 if (event->literal(str)) {
307 setString(appEvent.string, *str);
312 setLocation(appEvent.pos, event->location());
313 app_->appinfo(appEvent);
317 void GenericEventHandler::commentDecl(CommentDeclEvent *event)
319 SGMLApplication::CommentDeclEvent appEvent;
320 appEvent.nComments = 0;
322 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
323 if (iter.type() == Markup::comment)
324 appEvent.nComments++;
326 SGMLApplication::CharString *comments
327 = (SGMLApplication::CharString *)allocate(appEvent.nComments * 2
328 * sizeof(SGMLApplication::CharString));
329 appEvent.comments = comments;
330 appEvent.seps = appEvent.comments + appEvent.nComments;
332 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
333 switch (iter.type()) {
334 case Markup::comment:
335 comments[i].ptr = iter.charsPointer();
336 comments[i].len = iter.charsLength();
337 clearString(comments[appEvent.nComments + i]);
341 comments[appEvent.nComments + i - 1].ptr = iter.charsPointer();
342 comments[appEvent.nComments + i - 1].len = iter.charsLength();
347 setLocation(appEvent.pos, event->location());
348 app_->commentDecl(appEvent);
353 void GenericEventHandler::markedSectionStart(MarkedSectionStartEvent *event)
355 SGMLApplication::MarkedSectionStartEvent appEvent;
357 appEvent.nParams = 0;
359 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
360 switch (iter.type()) {
361 case Markup::reservedName:
365 case Markup::entityStart:
370 case Markup::entityEnd:
377 SGMLApplication::MarkedSectionStartEvent::Param *params
378 = (SGMLApplication::MarkedSectionStartEvent::Param *)
379 allocate(appEvent.nParams * sizeof(appEvent.params[0]));
380 appEvent.params = params;
382 for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
383 switch (iter.type()) {
384 case Markup::reservedName:
386 switch (iter.reservedName()) {
389 = SGMLApplication::MarkedSectionStartEvent::Param::temp;
391 case Syntax::rINCLUDE:
393 = SGMLApplication::MarkedSectionStartEvent::Param::include;
395 case Syntax::rRCDATA:
397 = SGMLApplication::MarkedSectionStartEvent::Param::rcdata;
401 = SGMLApplication::MarkedSectionStartEvent::Param::cdata;
403 case Syntax::rIGNORE:
405 = SGMLApplication::MarkedSectionStartEvent::Param::ignore;
410 clearString(params[i].entityName);
414 case Markup::entityStart:
417 = SGMLApplication::MarkedSectionStartEvent::Param::entityRef;
418 setString(params[i].entityName,
419 iter.entityOrigin()->entity()->name());
424 case Markup::entityEnd:
430 switch (event->status()) {
431 case MarkedSectionEvent::include:
432 appEvent.status = SGMLApplication::MarkedSectionStartEvent::include;
434 case MarkedSectionEvent::rcdata:
435 appEvent.status = SGMLApplication::MarkedSectionStartEvent::rcdata;
437 case MarkedSectionEvent::cdata:
438 appEvent.status = SGMLApplication::MarkedSectionStartEvent::cdata;
440 case MarkedSectionEvent::ignore:
441 appEvent.status = SGMLApplication::MarkedSectionStartEvent::ignore;
444 setLocation(appEvent.pos, event->location());
445 app_->markedSectionStart(appEvent);
450 void GenericEventHandler::ignoredChars(IgnoredCharsEvent *event)
452 SGMLApplication::IgnoredCharsEvent appEvent;
453 appEvent.data.ptr = event->data();
454 appEvent.data.len = event->dataLength();
455 setLocation(appEvent.pos, event->location());
456 app_->ignoredChars(appEvent);
460 void GenericEventHandler::markedSectionEnd(MarkedSectionEndEvent *event)
462 SGMLApplication::MarkedSectionEndEvent appEvent;
463 switch (event->status()) {
464 case MarkedSectionEvent::include:
465 appEvent.status = SGMLApplication::MarkedSectionEndEvent::include;
467 case MarkedSectionEvent::rcdata:
468 appEvent.status = SGMLApplication::MarkedSectionEndEvent::rcdata;
470 case MarkedSectionEvent::cdata:
471 appEvent.status = SGMLApplication::MarkedSectionEndEvent::cdata;
473 case MarkedSectionEvent::ignore:
474 appEvent.status = SGMLApplication::MarkedSectionEndEvent::ignore;
477 setLocation(appEvent.pos, event->location());
478 app_->markedSectionEnd(appEvent);
482 void GenericEventHandler::message(MessageEvent *event)
484 SGMLApplication::ErrorEvent appEvent;
485 switch (event->message().type->severity()) {
486 case MessageType::quantityError:
487 appEvent.type = SGMLApplication::ErrorEvent::quantity;
489 case MessageType::idrefError:
490 appEvent.type = SGMLApplication::ErrorEvent::idref;
492 case MessageType::error:
493 appEvent.type = SGMLApplication::ErrorEvent::otherError;
495 case MessageType::info:
496 appEvent.type = SGMLApplication::ErrorEvent::info;
498 case MessageType::warning:
499 appEvent.type = SGMLApplication::ErrorEvent::warning;
502 setLocation(appEvent.pos, event->message().loc);
504 reportMessage(event->message(), str);
505 setString(appEvent.message, str);
506 app_->error(appEvent);
507 ErrorCountEventHandler::message(event);
510 void GenericEventHandler::setLocation1(SGMLApplication::Position &pos,
513 const Location *locp = &loc;
515 if (locp->origin().isNull()) {
517 openEntityPtr_ = (SpOpenEntity *)0;
520 const InputSourceOrigin *origin = locp->origin()->asInputSourceOrigin();
521 if (origin && origin->externalInfo())
523 locp = &locp->origin()->parent();
525 lastOrigin_ = locp->origin();
527 openEntityPtr_ = new SpOpenEntity(locp->origin());
528 app_->openEntityChange(openEntityPtr_);
532 GenericEventHandler::setAttributes(const SGMLApplication::Attribute *&attributes,
533 const AttributeList &attributeList)
535 size_t nAttributes = attributeList.size();
536 SGMLApplication::Attribute *to
537 = (SGMLApplication::Attribute *)allocate(nAttributes * sizeof(*to));
539 for (size_t i = 0; i < nAttributes; i++) {
540 SGMLApplication::Attribute *p = to + i;
541 setString(p->name, attributeList.name(i));
542 const AttributeValue *value = attributeList.value(i);
544 p->type = SGMLApplication::Attribute::invalid;
547 const StringC *string;
548 switch (value->info(text, string)) {
549 case AttributeValue::implied:
550 p->type = SGMLApplication::Attribute::implied;
552 case AttributeValue::tokenized:
554 if (attributeList.specified(i))
555 p->defaulted = SGMLApplication::Attribute::specified;
556 else if (attributeList.current(i))
557 p->defaulted = SGMLApplication::Attribute::current;
559 p->defaulted = SGMLApplication::Attribute::definition;
560 p->type = SGMLApplication::Attribute::tokenized;
562 p->notation.name.len = 0;
563 p->isId = attributeList.id(i);
564 p->isGroup = (attributeList.getAllowedTokens(i) != 0);
565 setString(p->tokens, *string);
566 const AttributeSemantics *semantics = attributeList.semantics(i);
568 ConstPtr<Notation> notation = semantics->notation();
569 if (!notation.isNull())
570 setNotation(p->notation, *notation);
572 size_t nEntities = semantics->nEntities();
574 SGMLApplication::Entity *v
575 = (SGMLApplication::Entity *)allocate(nEntities * sizeof(*v));
577 p->nEntities = nEntities;
578 for (size_t i = 0; i < nEntities; i++)
579 setEntity(v[i], *semantics->entity(i));
585 case AttributeValue::cdata:
587 p->type = SGMLApplication::Attribute::cdata;
588 if (attributeList.specified(i))
589 p->defaulted = SGMLApplication::Attribute::specified;
590 else if (attributeList.current(i))
591 p->defaulted = SGMLApplication::Attribute::current;
593 p->defaulted = SGMLApplication::Attribute::definition;
600 TextIter iter(*text);
601 while (iter.next(type, s, length, loc))
604 case TextItem::sdata:
605 case TextItem::cdata:
613 = (SGMLApplication::Attribute::CdataChunk *)allocate(nChunks * sizeof(SGMLApplication::Attribute::CdataChunk));
614 p->nCdataChunks = nChunks;
618 for (TextIter iter(*text);
619 iter.next(type, s, length, loc);
623 case TextItem::sdata:
624 case TextItem::cdata:
626 SGMLApplication::Attribute::CdataChunk *chunk
627 = (SGMLApplication::Attribute::CdataChunk *)(p->cdataChunks + i);
628 if (type != TextItem::sdata)
632 setString(chunk->entityName,
633 *loc->origin()->asInputSourceOrigin()->entityName());
636 chunk->data.len = length;
652 void GenericEventHandler::setEntity(SGMLApplication::Entity &to,
655 setString(to.name, from.name());
656 switch (from.declType()) {
657 case Entity::generalEntity:
658 to.declType = SGMLApplication::Entity::general;
660 case Entity::parameterEntity:
661 to.declType = SGMLApplication::Entity::parameter;
663 case Entity::doctype:
664 to.declType = SGMLApplication::Entity::doctype;
666 case Entity::linktype:
667 to.declType = SGMLApplication::Entity::linktype;
672 switch (from.dataType()) {
673 case Entity::sgmlText:
674 to.dataType = SGMLApplication::Entity::sgml;
677 to.dataType = SGMLApplication::Entity::cdata;
680 to.dataType = SGMLApplication::Entity::sdata;
683 to.dataType = SGMLApplication::Entity::ndata;
686 to.dataType = SGMLApplication::Entity::subdoc;
689 to.dataType = SGMLApplication::Entity::pi;
692 const InternalEntity *internal = from.asInternalEntity();
695 setString(to.text, internal->string());
698 const ExternalEntity *external = from.asExternalEntity();
700 setExternalId(to.externalId, external->externalId());
701 const ExternalDataEntity *externalData = from.asExternalDataEntity();
703 setNotation(to.notation, *externalData->notation());
704 to.nAttributes = externalData->attributes().size();
706 setAttributes(to.attributes, externalData->attributes());
709 to.notation.name.len = 0;
716 void GenericEventHandler::setNotation(SGMLApplication::Notation &to,
717 const Notation &from)
719 setString(to.name, from.name());
720 setExternalId(to.externalId, from.externalId());
723 void GenericEventHandler::setExternalId(SGMLApplication::ExternalId &to,
724 const ExternalId &from)
727 str = from.systemIdString();
730 setString(to.systemId, *str);
734 str = from.publicIdString();
737 setString(to.publicId, *str);
741 str = &from.effectiveSystemId();
743 to.haveGeneratedSystemId = 1;
744 setString(to.generatedSystemId, *str);
747 to.haveGeneratedSystemId = 0;
750 MsgGenericEventHandler::MsgGenericEventHandler(SGMLApplication &app,
751 bool generalEntities,
752 MessageReporter &reporter,
753 const bool *messagesInhibitedPtr)
754 : GenericEventHandler(app, generalEntities),
755 reporter_(&reporter),
756 messagesInhibitedPtr_(messagesInhibitedPtr)
760 void MsgGenericEventHandler::reportMessage(const Message &msg, StringC &str)
762 WrapReporter wrap(reporter_);
763 reporter_->dispatchMessage(msg);
764 wrap.strStream.extractString(str);
765 if (!*messagesInhibitedPtr_)
766 *wrap.origStream << str;
769 SpOpenEntity::SpOpenEntity(const ConstPtr<Origin> &origin)
774 SGMLApplication::Location
775 SpOpenEntity::location(SGMLApplication::Position pos) const
777 SGMLApplication::Location loc;
778 const Origin *origin = origin_.pointer();
779 const InputSourceOrigin *inputSourceOrigin;
780 const ExternalInfo *externalInfo;
781 Index index = Index(pos);
785 inputSourceOrigin = origin->asInputSourceOrigin();
786 if (inputSourceOrigin) {
787 externalInfo = inputSourceOrigin->externalInfo();
791 const Location &loc = origin->parent();
793 origin = loc.origin().pointer();
795 const StringC *entityName = inputSourceOrigin->entityName();
797 GenericEventHandler::setString(loc.entityName, *entityName);
798 Offset off = inputSourceOrigin->startOffset(index);
799 loc.entityOffset = off;
800 StorageObjectLocation soLoc;
801 if (!ExtendEntityManager::externalize(externalInfo, off, soLoc))
803 loc.lineNumber = soLoc.lineNumber;
804 GenericEventHandler::setString(loc.filename, soLoc.storageObjectSpec->id);
805 loc.columnNumber = soLoc.columnNumber;
806 loc.byteOffset = soLoc.byteIndex;
807 loc.other = soLoc.storageObjectSpec;