TIVI-153: Add as dependency for iputils
[profile/ivi/opensp.git] / lib / GenericEventHandler.cxx
1 // Copyright (c) 1996 James Clark
2 // See the file COPYING for copying permission.
3
4 #ifdef __GNUG__
5 #pragma implementation
6 #endif
7
8 #include "splib.h"
9 #include "GenericEventHandler.h"
10 #include "macros.h"
11 #include "ExtendEntityManager.h"
12
13 #ifdef SP_NAMESPACE
14 namespace SP_NAMESPACE {
15 #endif
16
17 class SpOpenEntity : public SGMLApplication::OpenEntity {
18 public:
19   SpOpenEntity(const ConstPtr<Origin> &origin);
20   SGMLApplication::Location location(SGMLApplication::Position) const;
21 private:
22   ConstPtr<Origin> origin_;
23   StorageObjectLocation soLoc_;
24 };
25
26 inline
27 void GenericEventHandler::freeAll()
28 {
29   if (allocBlocks_)
30     freeAll1();
31 }
32
33 inline
34 void GenericEventHandler::clearNotation(SGMLApplication::Notation &to)
35 {
36   clearString(to.name);
37 }
38
39 inline
40 void GenericEventHandler::setLocation(SGMLApplication::Position &pos,
41                                   const Location &loc)
42 {
43   if (lastOrigin_ != loc.origin())
44     setLocation1(pos, loc);
45   else
46     pos = loc.index();
47 }
48
49 GenericEventHandler::GenericEventHandler(SGMLApplication &app,
50                                          bool generalEntities)
51 : app_(&app), generalEntities_(generalEntities),
52   freeBlocks_(0), allocBlocks_(0), firstBlockSpare_(0), firstBlockUsed_(0)
53 {
54 }
55
56 GenericEventHandler::~GenericEventHandler()
57 {
58   freeAll();
59   while (freeBlocks_) {
60     Block *tem = freeBlocks_;
61     freeBlocks_ = freeBlocks_->next;
62     delete [] tem->mem;
63     delete tem;
64   }
65 }
66
67 void GenericEventHandler::freeAll1()
68 {
69   Block **p;
70   for (p = &allocBlocks_; *p; p = &(*p)->next)
71     ;
72   *p = freeBlocks_;
73   freeBlocks_ = allocBlocks_;
74   allocBlocks_ = 0;
75   if (freeBlocks_)
76     firstBlockSpare_ = freeBlocks_->size;
77   else
78     firstBlockSpare_ = 0;
79   firstBlockUsed_ = 0;
80 }
81
82 void *GenericEventHandler::allocate(size_t n)
83 {
84   if (n == 0)
85     return 0;
86   // round up to avoid alignment problems
87   n = (n + sizeof(char *) - 1) & ~(sizeof(char *) - 1);
88   enum { BIG = 1024 };
89   if (n > firstBlockSpare_) {
90     if (freeBlocks_ && firstBlockUsed_) {
91       Block *tem = freeBlocks_;
92       freeBlocks_ = freeBlocks_->next;
93       tem->next = allocBlocks_;
94       allocBlocks_ = tem;
95     }
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_;
101       freeBlocks_ = tem;
102     }
103     firstBlockUsed_ = 0;
104     firstBlockSpare_ = freeBlocks_->size;
105   }
106   char *tem = freeBlocks_->mem + firstBlockUsed_;
107   firstBlockUsed_ += n;
108   firstBlockSpare_ -= n;
109   return tem;
110 }
111
112 void GenericEventHandler::startElement(StartElementEvent *event)
113 {
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:
119     appEvent.contentType
120       = (def->compiledModelGroup()->containsPcdata()
121          ? SGMLApplication::StartElementEvent::mixed
122          : SGMLApplication::StartElementEvent::element);
123     break;
124   case ElementDefinition::any:
125     appEvent.contentType = SGMLApplication::StartElementEvent::mixed;
126     break;
127   case ElementDefinition::cdata:
128     appEvent.contentType = SGMLApplication::StartElementEvent::cdata;
129     break;
130   case ElementDefinition::rcdata:
131     appEvent.contentType = SGMLApplication::StartElementEvent::rcdata;
132     break;
133   case ElementDefinition::empty:
134     appEvent.contentType = SGMLApplication::StartElementEvent::empty;
135     break;
136   }
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());
143   }
144   setLocation(appEvent.pos, event->location());
145   app_->startElement(appEvent);
146   freeAll();
147   delete event;
148 }
149
150 void GenericEventHandler::endElement(EndElementEvent *event)
151 {
152   SGMLApplication::EndElementEvent appEvent;
153   setString(appEvent.gi, event->name());
154   setLocation(appEvent.pos, event->location());
155   app_->endElement(appEvent);
156   delete event;
157 }
158
159 void GenericEventHandler::data(DataEvent *event)
160 {
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);
166   delete event;
167 }
168
169 void GenericEventHandler::pi(PiEvent *event)
170 {
171   SGMLApplication::PiEvent appEvent;
172   appEvent.data.ptr = event->data();
173   appEvent.data.len = event->dataLength();
174   const Entity *entity = event->entity();
175   if (entity)
176     setString(appEvent.entityName, entity->name());
177   else
178     appEvent.entityName.len = 0;
179   setLocation(appEvent.pos, event->location());
180   app_->pi(appEvent);
181   delete event;
182 }
183
184 void GenericEventHandler::sdataEntity(SdataEntityEvent *event)
185 {
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);
193   delete event;
194 }
195
196 void GenericEventHandler::externalDataEntity(ExternalDataEntityEvent *event)
197 {
198   SGMLApplication::ExternalDataEntityRefEvent appEvent;
199   setEntity(appEvent.entity, *event->entity());
200   setLocation(appEvent.pos, event->location());
201   app_->externalDataEntityRef(appEvent);
202   freeAll();
203   delete event;
204 }
205
206 void GenericEventHandler::subdocEntity(SubdocEntityEvent *event)
207 {
208   SGMLApplication::SubdocEntityRefEvent appEvent;
209   setEntity(appEvent.entity, *event->entity());
210   setLocation(appEvent.pos, event->location());
211   app_->subdocEntityRef(appEvent);
212   freeAll();
213   delete event;
214 }
215
216 void GenericEventHandler::nonSgmlChar(NonSgmlCharEvent *event)
217 {
218   SGMLApplication::NonSgmlCharEvent appEvent;
219   appEvent.c = event->character();
220   setLocation(appEvent.pos, event->location());
221   app_->nonSgmlChar(appEvent);
222   delete event;
223 }
224
225 void GenericEventHandler::startDtd(StartDtdEvent *event)
226 {
227   SGMLApplication::StartDtdEvent appEvent;
228   setString(appEvent.name, event->name());
229   const Entity *entity = event->entity().pointer();
230   if (entity) {
231     appEvent.haveExternalId = 1;
232     setExternalId(appEvent.externalId,
233                   entity->asExternalEntity()->externalId());
234   }
235   else
236     appEvent.haveExternalId = 0;
237   setLocation(appEvent.pos, event->location());
238   app_->startDtd(appEvent);
239   freeAll();
240   delete event;
241 }
242
243 void GenericEventHandler::endDtd(EndDtdEvent *event)
244 {
245   SGMLApplication::EndDtdEvent appEvent;
246   setString(appEvent.name, event->dtd().name());
247   setLocation(appEvent.pos, event->location());
248   app_->endDtd(appEvent);
249   delete event;
250 }
251
252 void GenericEventHandler::endProlog(EndPrologEvent *event)
253 {
254   if (generalEntities_) {
255     SGMLApplication::GeneralEntityEvent entityEvent;
256     const Dtd &dtd = event->dtd();
257     Dtd::ConstEntityIter iter(dtd.generalEntityIter());
258     for (;;) {
259       const Entity *entity = iter.nextTemp();
260       if (!entity)
261         break;
262       setEntity(entityEvent.entity, *entity);
263       app_->generalEntity(entityEvent);
264     }
265     freeAll();
266   }
267   SGMLApplication::EndPrologEvent appEvent;
268   setLocation(appEvent.pos, event->location());
269   app_->endProlog(appEvent);
270   delete event;
271 }
272
273 void GenericEventHandler::entityDefaulted(EntityDefaultedEvent *event)
274 {
275   if (generalEntities_) {
276     SGMLApplication::GeneralEntityEvent appEvent;
277     setEntity(appEvent.entity, event->entity());
278     app_->generalEntity(appEvent);
279   }
280   delete event;
281 }
282
283 void GenericEventHandler::appinfo(AppinfoEvent *event)
284 {
285   SGMLApplication::AppinfoEvent appEvent;
286   const StringC *str;
287   if (event->literal(str)) {
288     setString(appEvent.string, *str);
289     appEvent.none = 0;
290   }
291   else
292     appEvent.none = 1;
293   setLocation(appEvent.pos, event->location());
294   app_->appinfo(appEvent);
295   delete event;
296 }
297
298 void GenericEventHandler::commentDecl(CommentDeclEvent *event)
299 {
300   SGMLApplication::CommentDeclEvent appEvent;
301   appEvent.nComments = 0;
302   {
303     for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
304       if (iter.type() == Markup::comment)
305         appEvent.nComments++;
306   }
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;
312   size_t i = 0;
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]);
319       i++;
320       break;
321     case Markup::s:
322       comments[appEvent.nComments + i - 1].ptr = iter.charsPointer();
323       comments[appEvent.nComments + i - 1].len = iter.charsLength();
324       break;
325     default:
326       break;
327     }
328   setLocation(appEvent.pos, event->location());
329   app_->commentDecl(appEvent);
330   freeAll();
331   delete event;
332 }
333
334 void GenericEventHandler::markedSectionStart(MarkedSectionStartEvent *event)
335 {
336   SGMLApplication::MarkedSectionStartEvent appEvent;
337   unsigned depth = 0;
338   appEvent.nParams = 0;
339   {
340     for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
341       switch (iter.type()) {
342       case Markup::reservedName:
343         if (!depth)
344           appEvent.nParams++;
345         break;
346       case Markup::entityStart:
347         if (!depth)
348           appEvent.nParams++;
349         depth++;
350         break;
351       case Markup::entityEnd:
352         depth--;
353         break;
354       default:
355         break;
356       }
357   }
358   SGMLApplication::MarkedSectionStartEvent::Param *params
359     = (SGMLApplication::MarkedSectionStartEvent::Param *)
360       allocate(appEvent.nParams * sizeof(appEvent.params[0]));
361   appEvent.params = params;
362   size_t i = 0;
363   for (MarkupIter iter(event->markup()); iter.valid(); iter.advance())
364     switch (iter.type()) {
365     case Markup::reservedName:
366       if (!depth) {
367         switch (iter.reservedName()) {
368         case Syntax::rTEMP:
369           params[i].type
370             = SGMLApplication::MarkedSectionStartEvent::Param::temp;
371           break;
372         case Syntax::rINCLUDE:
373           params[i].type
374             = SGMLApplication::MarkedSectionStartEvent::Param::include;
375           break;
376         case Syntax::rRCDATA:
377           params[i].type
378             = SGMLApplication::MarkedSectionStartEvent::Param::rcdata;
379           break;
380         case Syntax::rCDATA:
381           params[i].type
382             = SGMLApplication::MarkedSectionStartEvent::Param::cdata;
383           break;
384         case Syntax::rIGNORE:
385           params[i].type
386             = SGMLApplication::MarkedSectionStartEvent::Param::ignore;
387           break;
388         default:
389           CANNOT_HAPPEN();
390         }
391         clearString(params[i].entityName);
392         i++;
393       }
394       break;
395     case Markup::entityStart:
396       if (!depth) {
397         params[i].type
398           = SGMLApplication::MarkedSectionStartEvent::Param::entityRef;
399         setString(params[i].entityName,
400                   iter.entityOrigin()->entity()->name());
401         i++;
402       }
403       depth++;
404       break;
405     case Markup::entityEnd:
406       depth--;
407       break;
408     default:
409       break;
410     }
411   switch (event->status()) {
412   case MarkedSectionEvent::include:
413     appEvent.status = SGMLApplication::MarkedSectionStartEvent::include;
414     break;
415   case MarkedSectionEvent::rcdata:
416     appEvent.status = SGMLApplication::MarkedSectionStartEvent::rcdata;
417     break;
418   case MarkedSectionEvent::cdata:
419     appEvent.status = SGMLApplication::MarkedSectionStartEvent::cdata;
420     break;
421   case MarkedSectionEvent::ignore:
422     appEvent.status = SGMLApplication::MarkedSectionStartEvent::ignore;
423     break;
424   }
425   setLocation(appEvent.pos, event->location());
426   app_->markedSectionStart(appEvent);
427   freeAll();
428   delete event;
429 }
430
431 void GenericEventHandler::ignoredChars(IgnoredCharsEvent *event)
432 {
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);
438   delete event;
439 }
440
441 void GenericEventHandler::markedSectionEnd(MarkedSectionEndEvent *event)
442 {
443   SGMLApplication::MarkedSectionEndEvent appEvent;
444   switch (event->status()) {
445   case MarkedSectionEvent::include:
446     appEvent.status = SGMLApplication::MarkedSectionEndEvent::include;
447     break;
448   case MarkedSectionEvent::rcdata:
449     appEvent.status = SGMLApplication::MarkedSectionEndEvent::rcdata;
450     break;
451   case MarkedSectionEvent::cdata:
452     appEvent.status = SGMLApplication::MarkedSectionEndEvent::cdata;
453     break;
454   case MarkedSectionEvent::ignore:
455     appEvent.status = SGMLApplication::MarkedSectionEndEvent::ignore;
456     break;
457   }
458   setLocation(appEvent.pos, event->location());
459   app_->markedSectionEnd(appEvent);
460   delete event;
461 }
462
463 void GenericEventHandler::message(MessageEvent *event)
464 {
465   SGMLApplication::ErrorEvent appEvent;
466   switch (event->message().type->severity()) {
467   case MessageType::quantityError:
468     appEvent.type = SGMLApplication::ErrorEvent::quantity;
469     break;
470   case MessageType::idrefError:
471     appEvent.type = SGMLApplication::ErrorEvent::idref;
472     break;
473   case MessageType::error:
474     appEvent.type = SGMLApplication::ErrorEvent::otherError;
475     break;
476   case MessageType::info:
477     appEvent.type = SGMLApplication::ErrorEvent::info;
478     break;
479   case MessageType::warning:
480     appEvent.type = SGMLApplication::ErrorEvent::warning;
481     break;
482   }
483   setLocation(appEvent.pos, event->message().loc);
484   StringC str;
485   reportMessage(event->message(), str);
486   setString(appEvent.message, str);
487   app_->error(appEvent);
488   ErrorCountEventHandler::message(event);
489 }
490
491 void GenericEventHandler::setLocation1(SGMLApplication::Position &pos,
492                                    const Location &loc)
493 {
494   const Location *locp = &loc;
495   for (;;) {
496     if (locp->origin().isNull()) {
497       lastOrigin_.clear();
498       openEntityPtr_ = (SpOpenEntity *)0;
499       return;
500     }
501     const InputSourceOrigin *origin = locp->origin()->asInputSourceOrigin();
502     if (origin && origin->externalInfo())
503       break;
504     locp = &locp->origin()->parent();
505   }
506   lastOrigin_ = locp->origin();
507   pos = locp->index();
508   openEntityPtr_ = new SpOpenEntity(locp->origin());
509   app_->openEntityChange(openEntityPtr_);
510 }
511
512 void 
513 GenericEventHandler::setAttributes(const SGMLApplication::Attribute *&attributes,
514                                const AttributeList &attributeList)
515 {
516   size_t nAttributes = attributeList.size();
517   SGMLApplication::Attribute *to
518     = (SGMLApplication::Attribute *)allocate(nAttributes * sizeof(*to));
519   attributes = 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);
524     if (!value)
525       p->type = SGMLApplication::Attribute::invalid;
526     else {
527       const Text *text;
528       const StringC *string;
529       switch (value->info(text, string)) {
530       case AttributeValue::implied:
531         p->type = SGMLApplication::Attribute::implied;
532         break;
533       case AttributeValue::tokenized:
534         {
535           if (attributeList.specified(i))
536             p->defaulted = SGMLApplication::Attribute::specified;
537           else if (attributeList.current(i))
538             p->defaulted = SGMLApplication::Attribute::current;
539           else
540             p->defaulted = SGMLApplication::Attribute::definition;
541           p->type = SGMLApplication::Attribute::tokenized;
542           p->nEntities = 0;
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);
548           if (semantics) {
549             ConstPtr<Notation> notation = semantics->notation();
550             if (!notation.isNull())
551               setNotation(p->notation, *notation);
552             else {
553               size_t nEntities = semantics->nEntities();
554               if (nEntities) {
555                 SGMLApplication::Entity *v
556                   = (SGMLApplication::Entity *)allocate(nEntities * sizeof(*v));
557                 p->entities = v;
558                 p->nEntities = nEntities;
559                 for (size_t i = 0; i < nEntities; i++)
560                   setEntity(v[i], *semantics->entity(i));
561               }
562             }
563           }
564         }
565         break;
566       case AttributeValue::cdata:
567         {
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;
573           else
574             p->defaulted = SGMLApplication::Attribute::definition;
575           TextItem::Type type;
576           const Char *s;
577           size_t length;
578           const Location *loc;
579           size_t nChunks = 0;
580           {
581             TextIter iter(*text);
582             while (iter.next(type, s, length, loc))
583               switch (type) {
584               case TextItem::data:
585               case TextItem::sdata:
586               case TextItem::cdata:
587               case TextItem::nonSgml:
588                 nChunks++;
589                 break;
590               default:
591                 break;
592               }
593           }
594           p->cdataChunks
595             = (SGMLApplication::Attribute::CdataChunk *)allocate(nChunks * sizeof(SGMLApplication::Attribute::CdataChunk));
596           p->nCdataChunks = nChunks;
597
598           {
599             size_t i = 0;
600             for (TextIter iter(*text); iter.next(type, s, length, loc);) {
601               switch (type) {
602               case TextItem::data:
603               case TextItem::sdata:
604               case TextItem::cdata:
605                 {
606                   SGMLApplication::Attribute::CdataChunk *chunk
607                     = (SGMLApplication::Attribute::CdataChunk *)(p->cdataChunks + i++);
608                   if (type != TextItem::sdata) {
609                     chunk->isSdata = 0;
610                     chunk->isNonSgml = 0;
611                   }
612                   else {
613                     chunk->isSdata = 1;
614                     setString(chunk->entityName,
615                               *loc->origin()->asInputSourceOrigin()->entityName());
616                   }
617                   chunk->data.ptr = s;
618                   chunk->data.len = length;
619                 }
620                 break;
621               case TextItem::nonSgml:
622                 {
623                   SGMLApplication::Attribute::CdataChunk *chunk
624                     = (SGMLApplication::Attribute::CdataChunk *)(p->cdataChunks + i++);
625                   chunk->isSdata = 0;
626                   chunk->isNonSgml = 1;
627                   chunk->nonSgmlChar = *s;
628                   chunk->data.len = 0;
629                   chunk->data.ptr = 0;
630                 }
631                 break;
632               default:
633                 break;
634               }
635             }
636           }
637         }
638         break;
639       }
640     }
641   }
642 }
643
644
645 void GenericEventHandler::setEntity(SGMLApplication::Entity &to,
646                                 const Entity &from)
647 {
648   setString(to.name, from.name());
649   switch (from.declType()) {
650   case Entity::generalEntity:
651     to.declType = SGMLApplication::Entity::general;
652     break;
653   case Entity::parameterEntity:
654     to.declType = SGMLApplication::Entity::parameter;
655     break;
656   case Entity::doctype:
657     to.declType = SGMLApplication::Entity::doctype;
658     break;
659   case Entity::linktype:
660     to.declType = SGMLApplication::Entity::linktype;
661     break;
662   default:
663     CANNOT_HAPPEN();
664   }
665   switch (from.dataType()) {
666   case Entity::sgmlText:
667     to.dataType = SGMLApplication::Entity::sgml;
668     break;
669   case Entity::cdata:
670     to.dataType = SGMLApplication::Entity::cdata;
671     break;
672   case Entity::sdata:
673     to.dataType = SGMLApplication::Entity::sdata;
674     break;
675   case Entity::ndata:
676     to.dataType = SGMLApplication::Entity::ndata;
677     break;
678   case Entity::subdoc:
679     to.dataType = SGMLApplication::Entity::subdoc;
680     break;
681   case Entity::pi:
682     to.dataType = SGMLApplication::Entity::pi;
683     break;
684   }
685   const InternalEntity *internal = from.asInternalEntity();
686   if (internal) {
687     to.isInternal = 1;
688     setString(to.text, internal->string());
689   }
690   else {
691     const ExternalEntity *external = from.asExternalEntity();
692     to.isInternal = 0;
693     setExternalId(to.externalId, external->externalId());
694     const ExternalDataEntity *externalData = from.asExternalDataEntity();
695     if (externalData) {
696       setNotation(to.notation, *externalData->notation());
697       to.nAttributes = externalData->attributes().size();
698       if (to.nAttributes)
699         setAttributes(to.attributes, externalData->attributes());
700     }
701     else {
702       to.notation.name.len = 0;
703       to.nAttributes = 0;
704     }
705   }
706 }
707
708
709 void GenericEventHandler::setNotation(SGMLApplication::Notation &to,
710                                       const Notation &from)
711 {
712   setString(to.name, from.name());
713   setExternalId(to.externalId, from.externalId());
714 }
715
716 void GenericEventHandler::setExternalId(SGMLApplication::ExternalId &to,
717                                         const ExternalId &from)
718 {
719   const StringC *str;
720   str = from.systemIdString();
721   if (str) {
722     to.haveSystemId = 1;
723     setString(to.systemId, *str);
724   }
725   else
726     to.haveSystemId = 0;
727   str = from.publicIdString();
728   if (str) {
729     to.havePublicId = 1;
730     setString(to.publicId, *str);
731   }
732   else
733     to.havePublicId = 0;
734   str = &from.effectiveSystemId();
735   if (str->size()) {
736     to.haveGeneratedSystemId = 1;
737     setString(to.generatedSystemId, *str);
738   }
739   else
740     to.haveGeneratedSystemId = 0;
741 }
742
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)
750 {
751 }
752
753 void MsgGenericEventHandler::reportMessage(const Message &msg, StringC &str)
754 {
755   WrapReporter wrap(reporter_);
756   reporter_->dispatchMessage(msg);
757   wrap.strStream.extractString(str);
758   if (!*messagesInhibitedPtr_)
759     *wrap.origStream << str;
760 }
761
762 SpOpenEntity::SpOpenEntity(const ConstPtr<Origin> &origin)
763 : origin_(origin)
764 {
765 }
766
767 SGMLApplication::Location
768 SpOpenEntity::location(SGMLApplication::Position pos) const
769 {
770   SGMLApplication::Location loc;
771   const Origin *origin = origin_.pointer();
772   const InputSourceOrigin *inputSourceOrigin;
773   const ExternalInfo *externalInfo;
774   Index index = Index(pos);
775   for (;;) {
776     if (!origin)
777       return loc;
778     inputSourceOrigin = origin->asInputSourceOrigin();
779     if (inputSourceOrigin) {
780       externalInfo = inputSourceOrigin->externalInfo();
781       if (externalInfo)
782         break;
783     }
784     // Qualifier is for CodeWarrior
785     const ::SP_NAMESPACE_SCOPE Location &loc = origin->parent();
786     index = loc.index();
787     origin = loc.origin().pointer();
788   }
789   const StringC *entityName = inputSourceOrigin->entityName();
790   if (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_))
795     return loc;
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;
801   return loc;
802 }
803
804 #ifdef SP_NAMESPACE
805 }
806 #endif