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 libraries 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: Entity.C /main/1 1996/07/29 16:49:46 cde-hp $ */
24 // Copyright (c) 1994 James Clark
25 // See the file COPYING for copying permission.
28 #pragma implementation
32 #include "ParserState.h"
34 #include "InternalInputSource.h"
35 #include "MessageArg.h"
36 #include "ParserMessages.h"
39 namespace SP_NAMESPACE {
42 Entity::Entity(const StringC &name, DeclType declType, DataType dataType,
43 const Location &defLocation)
44 : EntityDecl(name, declType, dataType, defLocation),
45 used_(0), defaulted_(0)
49 void Entity::generateSystemId(ParserState &)
53 InternalEntity::InternalEntity(const StringC &name,
56 const Location &defLocation,
58 : Entity(name, declType, dataType, defLocation)
63 PiEntity::PiEntity(const StringC &name, DeclType declType,
64 const Location &defLocation, Text &text)
65 : InternalEntity(name, declType, pi, defLocation, text)
69 Entity *PiEntity::copy() const
71 return new PiEntity(*this);
74 InternalDataEntity::InternalDataEntity(const StringC &name, DataType dataType,
75 const Location &defLocation, Text &text)
76 : InternalEntity(name, generalEntity, dataType, defLocation, text)
81 InternalCdataEntity::InternalCdataEntity(const StringC &name,
82 const Location &defLocation,
84 : InternalDataEntity(name, cdata, defLocation, text)
88 Entity *InternalCdataEntity::copy() const
90 return new InternalCdataEntity(*this);
93 InternalSdataEntity::InternalSdataEntity(const StringC &name,
94 const Location &defLocation,
96 : InternalDataEntity(name, sdata, defLocation, text)
100 Entity *InternalSdataEntity::copy() const
102 return new InternalSdataEntity(*this);
105 InternalTextEntity::InternalTextEntity(const StringC &name, DeclType declType,
106 const Location &defLocation, Text &text,
108 : InternalEntity(name, declType, sgmlText, defLocation, text),
109 bracketed_(bracketed)
113 Entity *InternalTextEntity::copy() const
115 return new InternalTextEntity(*this);
119 ExternalEntity::ExternalEntity(const StringC &name,
122 const Location &defLocation,
123 const ExternalId &id)
124 : Entity(name, declType, dataType, defLocation), externalId_(id)
128 const ExternalEntity *ExternalEntity::asExternalEntity() const
133 const StringC *ExternalEntity::systemIdPointer() const
135 return externalId_.systemIdString();
138 const StringC *ExternalEntity::effectiveSystemIdPointer() const
140 if (externalId_.effectiveSystemId().size() > 0)
141 return &externalId_.effectiveSystemId();
145 const StringC *ExternalEntity::publicIdPointer() const
147 return externalId_.publicIdString();
150 void ExternalEntity::generateSystemId(ParserState &parser)
153 if (parser.entityCatalog().lookup(*this,
155 parser.sd().docCharset(),
158 externalId_.setEffectiveSystem(str);
159 else if (externalId_.publicIdString())
160 parser.message(ParserMessages::cannotGenerateSystemIdPublic,
161 StringMessageArg(*externalId_.publicIdString()));
163 switch (declType()) {
165 parser.message(ParserMessages::cannotGenerateSystemIdGeneral,
166 StringMessageArg(name()));
168 case parameterEntity:
169 parser.message(ParserMessages::cannotGenerateSystemIdParameter,
170 StringMessageArg(name()));
173 parser.message(ParserMessages::cannotGenerateSystemIdDoctype,
174 StringMessageArg(name()));
177 parser.message(ParserMessages::cannotGenerateSystemIdLinktype,
178 StringMessageArg(name()));
186 ExternalTextEntity::ExternalTextEntity(const StringC &name,
188 const Location &defLocation,
189 const ExternalId &id)
190 : ExternalEntity(name, declType, sgmlText, defLocation, id)
194 Entity *ExternalTextEntity::copy() const
196 return new ExternalTextEntity(*this);
199 ExternalNonTextEntity::ExternalNonTextEntity(const StringC &name,
201 const Location &defLocation,
202 const ExternalId &id)
203 : ExternalEntity(name, generalEntity, dataType, defLocation, id)
207 ExternalDataEntity::ExternalDataEntity(const StringC &name,
209 const Location &defLocation,
210 const ExternalId &id,
211 const ConstPtr<Notation> &nt,
213 AttributeList &attributes)
214 : ExternalNonTextEntity(name, dataType, defLocation, id),
217 attributes.swap(attributes_);
220 void ExternalDataEntity::setNotation(const ConstPtr<Notation> ¬ation,
221 AttributeList &attributes)
223 notation_ = notation;
224 attributes.swap(attributes_);
227 Entity *ExternalDataEntity::copy() const
229 return new ExternalDataEntity(*this);
232 SubdocEntity::SubdocEntity(const StringC &name,
233 const Location &defLocation,
234 const ExternalId &id)
235 : ExternalNonTextEntity(name, subdoc, defLocation, id)
239 Entity *SubdocEntity::copy() const
241 return new SubdocEntity(*this);
244 Boolean Entity::isDataOrSubdoc() const
249 Boolean Entity::isCharacterData() const
254 const ExternalEntity *Entity::asExternalEntity() const
259 const ExternalDataEntity *Entity::asExternalDataEntity() const
264 const SubdocEntity *Entity::asSubdocEntity() const
269 const InternalEntity *Entity::asInternalEntity() const
274 void Entity::dsReference(ParserState &parser,
275 const Ptr<EntityOrigin> &origin)
278 normalReference(parser, origin, 1);
281 void Entity::declReference(ParserState &parser,
282 const Ptr<EntityOrigin> &origin)
285 normalReference(parser, origin, 0);
286 if (parser.currentMarkup())
287 parser.currentMarkup()->addEntityStart(origin);
290 void Entity::contentReference(ParserState &parser,
291 const Ptr<EntityOrigin> &origin)
294 normalReference(parser, origin, 1);
297 void Entity::rcdataReference(ParserState &parser,
298 const Ptr<EntityOrigin> &origin)
301 normalReference(parser, origin, 1);
304 void Entity::litReference(Text &, ParserState &parser,
305 const Ptr<EntityOrigin> &origin,
309 normalReference(parser, origin, 0);
312 const InternalEntity *InternalEntity::asInternalEntity() const
317 void PiEntity::litReference(Text &, ParserState &parser,
318 const Ptr<EntityOrigin> &,
321 parser.message(ParserMessages::piEntityReference);
324 void PiEntity::normalReference(ParserState &parser,
325 const Ptr<EntityOrigin> &origin,
329 parser.eventHandler().pi(new (parser.eventAllocator())
330 PiEntityEvent(this, origin.pointer()));
333 void PiEntity::declReference(ParserState &parser,
334 const Ptr<EntityOrigin> &) const
336 parser.message(ParserMessages::piEntityReference);
339 void PiEntity::rcdataReference(ParserState &parser,
340 const Ptr<EntityOrigin> &) const
342 parser.message(ParserMessages::piEntityRcdata);
345 void InternalDataEntity::declReference(ParserState &parser,
346 const Ptr<EntityOrigin> &) const
348 parser.message(ParserMessages::internalDataEntityReference);
351 Boolean InternalDataEntity::isDataOrSubdoc() const
356 void InternalCdataEntity::normalReference(ParserState &parser,
357 const Ptr<EntityOrigin> &origin,
361 if (string().size() > 0) {
363 parser.eventHandler().data(new (parser.eventAllocator())
364 CdataEntityEvent(this, origin.pointer()));
368 Boolean InternalCdataEntity::isCharacterData() const
370 return string().size() > 0;
373 void InternalCdataEntity::litReference(Text &text,
375 const Ptr<EntityOrigin> &origin,
376 Boolean squeeze) const
380 Location loc(origin.pointer(), 0);
381 text.addEntityStart(loc);
382 text.addCharsTokenize(text_.string(), loc, parser.syntax().space());
384 text.addEntityEnd(loc);
387 text.addCdata(this, origin.pointer());
391 void InternalSdataEntity::normalReference(ParserState &parser,
392 const Ptr<EntityOrigin> &origin,
397 parser.eventHandler().sdataEntity(new (parser.eventAllocator())
398 SdataEntityEvent(this,
402 Boolean InternalSdataEntity::isCharacterData() const
407 void InternalSdataEntity::litReference(Text &text,
409 const Ptr<EntityOrigin> &origin,
410 Boolean squeeze) const
414 Location loc(origin.pointer(), 0);
415 text.addEntityStart(loc);
416 text.addCharsTokenize(text_.string(), loc, parser.syntax().space());
418 text.addEntityEnd(loc);
421 text.addSdata(this, origin.pointer());
424 void InternalTextEntity::normalReference(ParserState &parser,
425 const Ptr<EntityOrigin> &origin,
426 Boolean generateEvent) const
429 if (checkNotOpen(parser)) {
430 if (generateEvent && parser.wantMarkup())
431 parser.eventHandler().entityStart(new (parser.eventAllocator())
432 EntityStartEvent(origin));
433 parser.pushInput(new (parser.internalAllocator())
434 InternalInputSource(text_.string(), origin.pointer()));
438 void InternalTextEntity::litReference(Text &text,
440 const Ptr<EntityOrigin> &origin,
443 text.addEntityStart(Location(origin.pointer(), 0));
444 normalReference(parser, origin, 0);
447 void ExternalTextEntity::normalReference(ParserState &parser,
448 const Ptr<EntityOrigin> &origin,
449 Boolean generateEvent) const
452 if (checkNotOpen(parser)) {
453 if (generateEvent && parser.wantMarkup())
454 parser.eventHandler().entityStart(new (parser.eventAllocator())
455 EntityStartEvent(origin));
456 if (externalId().effectiveSystemId().size())
457 parser.pushInput(parser.entityManager()
458 .open(externalId().effectiveSystemId(),
459 parser.sd().docCharset(),
462 parser.messenger()));
464 parser.message(ParserMessages::nonExistentEntityRef,
465 StringMessageArg(name()),
470 void ExternalTextEntity::litReference(Text &text,
472 const Ptr<EntityOrigin> &origin,
475 text.addEntityStart(Location(origin.pointer(), 0));
476 normalReference(parser, origin, 0);
479 const ExternalDataEntity *ExternalDataEntity::asExternalDataEntity() const
484 void ExternalDataEntity::contentReference(ParserState &parser,
485 const Ptr<EntityOrigin> &origin) const
489 parser.eventHandler().externalDataEntity(new (parser.eventAllocator())
490 ExternalDataEntityEvent(this, origin.pointer()));
493 Boolean ExternalNonTextEntity::isDataOrSubdoc() const
498 Boolean ExternalNonTextEntity::isCharacterData() const
504 void ExternalNonTextEntity::normalReference(ParserState &parser,
505 const Ptr<EntityOrigin> &,
508 parser.message(ParserMessages::externalNonTextEntityReference);
511 void ExternalNonTextEntity::litReference(Text &,
513 const Ptr<EntityOrigin> &,
516 parser.message(ParserMessages::externalNonTextEntityRcdata);
519 void ExternalNonTextEntity::rcdataReference(ParserState &parser,
520 const Ptr<EntityOrigin> &) const
522 parser.message(ParserMessages::externalNonTextEntityRcdata);
525 void SubdocEntity::contentReference(ParserState &parser,
526 const Ptr<EntityOrigin> &origin) const
530 parser.eventHandler().subdocEntity(new (parser.eventAllocator())
531 SubdocEntityEvent(this, origin.pointer()));
534 const SubdocEntity *SubdocEntity::asSubdocEntity() const
539 IgnoredEntity::IgnoredEntity(const StringC &name, DeclType declType)
540 : Entity(name, declType, sgmlText, Location())
544 Entity *IgnoredEntity::copy() const
546 return new IgnoredEntity(*this);
549 void IgnoredEntity::declReference(ParserState &parser,
550 const Ptr<EntityOrigin> &origin)
553 if (parser.currentMarkup()) {
554 parser.currentMarkup()->addEntityStart(origin);
555 parser.currentMarkup()->addEntityEnd();
559 void IgnoredEntity::litReference(Text &text,
561 const Ptr<EntityOrigin> &origin,
564 text.addEntityStart(Location(origin.pointer(), 0));
565 text.addEntityEnd(Location(origin.pointer(), 0));
568 void IgnoredEntity::normalReference(ParserState &parser,
569 const Ptr<EntityOrigin> &origin,
570 Boolean generateEvent) const
572 if (generateEvent && parser.wantMarkup()) {
573 parser.eventHandler().entityStart(new (parser.eventAllocator())
574 EntityStartEvent(origin));
575 Location loc(origin.pointer(), 0);
576 parser.eventHandler().entityEnd(new (parser.eventAllocator())
577 EntityEndEvent(loc));
581 void Entity::checkEntlvl(ParserState &parser)
583 // -1 because document entity isn't counted
584 if (parser.inputLevel() - 1 == parser.syntax().entlvl())
585 parser.message(ParserMessages::entlvl);
588 Boolean Entity::checkNotOpen(ParserState &parser) const
590 if (parser.entityIsOpen(this)) {
591 parser.message(ParserMessages::recursiveEntityReference,
592 StringMessageArg(name()));
598 EntityOrigin::EntityOrigin()
603 EntityOrigin::EntityOrigin(const Location &refLocation)
604 : InputSourceOrigin(refLocation), refLength_(0)
608 EntityOrigin::EntityOrigin(const ConstPtr<Entity> &entity,
609 const Location &refLocation)
610 : InputSourceOrigin(refLocation), refLength_(0), entity_(entity)
614 EntityOrigin::EntityOrigin(const ConstPtr<Entity> &entity,
615 const Location &refLocation,
617 Owner<Markup> &markup)
618 : InputSourceOrigin(refLocation), refLength_(refLength), entity_(entity)
620 markup.swap(markup_);
623 EntityOrigin::~EntityOrigin()
627 InputSourceOrigin *EntityOrigin::copy() const
631 m = new Markup(*markup_);
632 return new EntityOrigin(entity_, parent(), refLength_, m);
635 const StringC *EntityOrigin::entityName() const
637 if (entity_.isNull())
639 return entity_->namePointer();
642 Index EntityOrigin::refLength() const
647 const EntityOrigin *EntityOrigin::asEntityOrigin() const
652 Boolean EntityOrigin::defLocation(Offset off, Location &loc) const
654 if (entity_.isNull())
656 const InternalEntity *internal = entity_->asInternalEntity();
659 loc = internal->text().charLocation(off);
663 const EntityDecl *EntityOrigin::entityDecl() const
665 return entity_.pointer();