/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* $XConsortium: Entity.C /main/1 1996/07/29 16:49:46 cde-hp $ */ // Copyright (c) 1994 James Clark // See the file COPYING for copying permission. #ifdef __GNUG__ #pragma implementation #endif #include "splib.h" #include "Entity.h" #include "ParserState.h" #include "macros.h" #include "InternalInputSource.h" #include "MessageArg.h" #include "ParserMessages.h" #ifdef SP_NAMESPACE namespace SP_NAMESPACE { #endif Entity::Entity(const StringC &name, DeclType declType, DataType dataType, const Location &defLocation) : EntityDecl(name, declType, dataType, defLocation), used_(0), defaulted_(0) { } void Entity::generateSystemId(ParserState &) { } InternalEntity::InternalEntity(const StringC &name, DeclType declType, DataType dataType, const Location &defLocation, Text &text) : Entity(name, declType, dataType, defLocation) { text.swap(text_); } PiEntity::PiEntity(const StringC &name, DeclType declType, const Location &defLocation, Text &text) : InternalEntity(name, declType, pi, defLocation, text) { } Entity *PiEntity::copy() const { return new PiEntity(*this); } InternalDataEntity::InternalDataEntity(const StringC &name, DataType dataType, const Location &defLocation, Text &text) : InternalEntity(name, generalEntity, dataType, defLocation, text) { } InternalCdataEntity::InternalCdataEntity(const StringC &name, const Location &defLocation, Text &text) : InternalDataEntity(name, cdata, defLocation, text) { } Entity *InternalCdataEntity::copy() const { return new InternalCdataEntity(*this); } InternalSdataEntity::InternalSdataEntity(const StringC &name, const Location &defLocation, Text &text) : InternalDataEntity(name, sdata, defLocation, text) { } Entity *InternalSdataEntity::copy() const { return new InternalSdataEntity(*this); } InternalTextEntity::InternalTextEntity(const StringC &name, DeclType declType, const Location &defLocation, Text &text, Bracketed bracketed) : InternalEntity(name, declType, sgmlText, defLocation, text), bracketed_(bracketed) { } Entity *InternalTextEntity::copy() const { return new InternalTextEntity(*this); } ExternalEntity::ExternalEntity(const StringC &name, DeclType declType, DataType dataType, const Location &defLocation, const ExternalId &id) : Entity(name, declType, dataType, defLocation), externalId_(id) { } const ExternalEntity *ExternalEntity::asExternalEntity() const { return this; } const StringC *ExternalEntity::systemIdPointer() const { return externalId_.systemIdString(); } const StringC *ExternalEntity::effectiveSystemIdPointer() const { if (externalId_.effectiveSystemId().size() > 0) return &externalId_.effectiveSystemId(); return 0; } const StringC *ExternalEntity::publicIdPointer() const { return externalId_.publicIdString(); } void ExternalEntity::generateSystemId(ParserState &parser) { StringC str; if (parser.entityCatalog().lookup(*this, parser.syntax(), parser.sd().docCharset(), parser.messenger(), str)) externalId_.setEffectiveSystem(str); else if (externalId_.publicIdString()) parser.message(ParserMessages::cannotGenerateSystemIdPublic, StringMessageArg(*externalId_.publicIdString())); else { switch (declType()) { case generalEntity: parser.message(ParserMessages::cannotGenerateSystemIdGeneral, StringMessageArg(name())); break; case parameterEntity: parser.message(ParserMessages::cannotGenerateSystemIdParameter, StringMessageArg(name())); break; case doctype: parser.message(ParserMessages::cannotGenerateSystemIdDoctype, StringMessageArg(name())); break; case linktype: parser.message(ParserMessages::cannotGenerateSystemIdLinktype, StringMessageArg(name())); break; default: CANNOT_HAPPEN(); } } } ExternalTextEntity::ExternalTextEntity(const StringC &name, DeclType declType, const Location &defLocation, const ExternalId &id) : ExternalEntity(name, declType, sgmlText, defLocation, id) { } Entity *ExternalTextEntity::copy() const { return new ExternalTextEntity(*this); } ExternalNonTextEntity::ExternalNonTextEntity(const StringC &name, DataType dataType, const Location &defLocation, const ExternalId &id) : ExternalEntity(name, generalEntity, dataType, defLocation, id) { } ExternalDataEntity::ExternalDataEntity(const StringC &name, DataType dataType, const Location &defLocation, const ExternalId &id, const ConstPtr &nt, AttributeList &attributes) : ExternalNonTextEntity(name, dataType, defLocation, id), notation_(nt) { attributes.swap(attributes_); } void ExternalDataEntity::setNotation(const ConstPtr ¬ation, AttributeList &attributes) { notation_ = notation; attributes.swap(attributes_); } Entity *ExternalDataEntity::copy() const { return new ExternalDataEntity(*this); } SubdocEntity::SubdocEntity(const StringC &name, const Location &defLocation, const ExternalId &id) : ExternalNonTextEntity(name, subdoc, defLocation, id) { } Entity *SubdocEntity::copy() const { return new SubdocEntity(*this); } Boolean Entity::isDataOrSubdoc() const { return 0; } Boolean Entity::isCharacterData() const { return 0; } const ExternalEntity *Entity::asExternalEntity() const { return 0; } const ExternalDataEntity *Entity::asExternalDataEntity() const { return 0; } const SubdocEntity *Entity::asSubdocEntity() const { return 0; } const InternalEntity *Entity::asInternalEntity() const { return 0; } void Entity::dsReference(ParserState &parser, const Ptr &origin) const { normalReference(parser, origin, 1); } void Entity::declReference(ParserState &parser, const Ptr &origin) const { normalReference(parser, origin, 0); if (parser.currentMarkup()) parser.currentMarkup()->addEntityStart(origin); } void Entity::contentReference(ParserState &parser, const Ptr &origin) const { normalReference(parser, origin, 1); } void Entity::rcdataReference(ParserState &parser, const Ptr &origin) const { normalReference(parser, origin, 1); } void Entity::litReference(Text &, ParserState &parser, const Ptr &origin, Boolean) const { normalReference(parser, origin, 0); } const InternalEntity *InternalEntity::asInternalEntity() const { return this; } void PiEntity::litReference(Text &, ParserState &parser, const Ptr &, Boolean) const { parser.message(ParserMessages::piEntityReference); } void PiEntity::normalReference(ParserState &parser, const Ptr &origin, Boolean) const { parser.noteMarkup(); parser.eventHandler().pi(new (parser.eventAllocator()) PiEntityEvent(this, origin.pointer())); } void PiEntity::declReference(ParserState &parser, const Ptr &) const { parser.message(ParserMessages::piEntityReference); } void PiEntity::rcdataReference(ParserState &parser, const Ptr &) const { parser.message(ParserMessages::piEntityRcdata); } void InternalDataEntity::declReference(ParserState &parser, const Ptr &) const { parser.message(ParserMessages::internalDataEntityReference); } Boolean InternalDataEntity::isDataOrSubdoc() const { return 1; } void InternalCdataEntity::normalReference(ParserState &parser, const Ptr &origin, Boolean) const { checkEntlvl(parser); if (string().size() > 0) { parser.noteData(); parser.eventHandler().data(new (parser.eventAllocator()) CdataEntityEvent(this, origin.pointer())); } } Boolean InternalCdataEntity::isCharacterData() const { return string().size() > 0; } void InternalCdataEntity::litReference(Text &text, ParserState &parser, const Ptr &origin, Boolean squeeze) const { checkEntlvl(parser); if (squeeze) { Location loc(origin.pointer(), 0); text.addEntityStart(loc); text.addCharsTokenize(text_.string(), loc, parser.syntax().space()); loc += text_.size(); text.addEntityEnd(loc); } else text.addCdata(this, origin.pointer()); } void InternalSdataEntity::normalReference(ParserState &parser, const Ptr &origin, Boolean) const { checkEntlvl(parser); parser.noteData(); parser.eventHandler().sdataEntity(new (parser.eventAllocator()) SdataEntityEvent(this, origin.pointer())); } Boolean InternalSdataEntity::isCharacterData() const { return 1; } void InternalSdataEntity::litReference(Text &text, ParserState &parser, const Ptr &origin, Boolean squeeze) const { checkEntlvl(parser); if (squeeze) { Location loc(origin.pointer(), 0); text.addEntityStart(loc); text.addCharsTokenize(text_.string(), loc, parser.syntax().space()); loc += text_.size(); text.addEntityEnd(loc); } else text.addSdata(this, origin.pointer()); } void InternalTextEntity::normalReference(ParserState &parser, const Ptr &origin, Boolean generateEvent) const { checkEntlvl(parser); if (checkNotOpen(parser)) { if (generateEvent && parser.wantMarkup()) parser.eventHandler().entityStart(new (parser.eventAllocator()) EntityStartEvent(origin)); parser.pushInput(new (parser.internalAllocator()) InternalInputSource(text_.string(), origin.pointer())); } } void InternalTextEntity::litReference(Text &text, ParserState &parser, const Ptr &origin, Boolean) const { text.addEntityStart(Location(origin.pointer(), 0)); normalReference(parser, origin, 0); } void ExternalTextEntity::normalReference(ParserState &parser, const Ptr &origin, Boolean generateEvent) const { checkEntlvl(parser); if (checkNotOpen(parser)) { if (generateEvent && parser.wantMarkup()) parser.eventHandler().entityStart(new (parser.eventAllocator()) EntityStartEvent(origin)); if (externalId().effectiveSystemId().size()) parser.pushInput(parser.entityManager() .open(externalId().effectiveSystemId(), parser.sd().docCharset(), origin.pointer(), 0, parser.messenger())); else parser.message(ParserMessages::nonExistentEntityRef, StringMessageArg(name()), defLocation()); } } void ExternalTextEntity::litReference(Text &text, ParserState &parser, const Ptr &origin, Boolean) const { text.addEntityStart(Location(origin.pointer(), 0)); normalReference(parser, origin, 0); } const ExternalDataEntity *ExternalDataEntity::asExternalDataEntity() const { return this; } void ExternalDataEntity::contentReference(ParserState &parser, const Ptr &origin) const { checkEntlvl(parser); parser.noteData(); parser.eventHandler().externalDataEntity(new (parser.eventAllocator()) ExternalDataEntityEvent(this, origin.pointer())); } Boolean ExternalNonTextEntity::isDataOrSubdoc() const { return 1; } Boolean ExternalNonTextEntity::isCharacterData() const { return 1; } void ExternalNonTextEntity::normalReference(ParserState &parser, const Ptr &, Boolean) const { parser.message(ParserMessages::externalNonTextEntityReference); } void ExternalNonTextEntity::litReference(Text &, ParserState &parser, const Ptr &, Boolean) const { parser.message(ParserMessages::externalNonTextEntityRcdata); } void ExternalNonTextEntity::rcdataReference(ParserState &parser, const Ptr &) const { parser.message(ParserMessages::externalNonTextEntityRcdata); } void SubdocEntity::contentReference(ParserState &parser, const Ptr &origin) const { checkEntlvl(parser); parser.noteData(); parser.eventHandler().subdocEntity(new (parser.eventAllocator()) SubdocEntityEvent(this, origin.pointer())); } const SubdocEntity *SubdocEntity::asSubdocEntity() const { return this; } IgnoredEntity::IgnoredEntity(const StringC &name, DeclType declType) : Entity(name, declType, sgmlText, Location()) { } Entity *IgnoredEntity::copy() const { return new IgnoredEntity(*this); } void IgnoredEntity::declReference(ParserState &parser, const Ptr &origin) const { if (parser.currentMarkup()) { parser.currentMarkup()->addEntityStart(origin); parser.currentMarkup()->addEntityEnd(); } } void IgnoredEntity::litReference(Text &text, ParserState &, const Ptr &origin, Boolean) const { text.addEntityStart(Location(origin.pointer(), 0)); text.addEntityEnd(Location(origin.pointer(), 0)); } void IgnoredEntity::normalReference(ParserState &parser, const Ptr &origin, Boolean generateEvent) const { if (generateEvent && parser.wantMarkup()) { parser.eventHandler().entityStart(new (parser.eventAllocator()) EntityStartEvent(origin)); Location loc(origin.pointer(), 0); parser.eventHandler().entityEnd(new (parser.eventAllocator()) EntityEndEvent(loc)); } } void Entity::checkEntlvl(ParserState &parser) { // -1 because document entity isn't counted if (parser.inputLevel() - 1 == parser.syntax().entlvl()) parser.message(ParserMessages::entlvl); } Boolean Entity::checkNotOpen(ParserState &parser) const { if (parser.entityIsOpen(this)) { parser.message(ParserMessages::recursiveEntityReference, StringMessageArg(name())); return 0; } return 1; } EntityOrigin::EntityOrigin() : refLength_(0) { } EntityOrigin::EntityOrigin(const Location &refLocation) : InputSourceOrigin(refLocation), refLength_(0) { } EntityOrigin::EntityOrigin(const ConstPtr &entity, const Location &refLocation) : InputSourceOrigin(refLocation), refLength_(0), entity_(entity) { } EntityOrigin::EntityOrigin(const ConstPtr &entity, const Location &refLocation, Index refLength, Owner &markup) : InputSourceOrigin(refLocation), refLength_(refLength), entity_(entity) { markup.swap(markup_); } EntityOrigin::~EntityOrigin() { } InputSourceOrigin *EntityOrigin::copy() const { Owner m; if (markup_) m = new Markup(*markup_); return new EntityOrigin(entity_, parent(), refLength_, m); } const StringC *EntityOrigin::entityName() const { if (entity_.isNull()) return 0; return entity_->namePointer(); } Index EntityOrigin::refLength() const { return refLength_; } const EntityOrigin *EntityOrigin::asEntityOrigin() const { return this; } Boolean EntityOrigin::defLocation(Offset off, Location &loc) const { if (entity_.isNull()) return 0; const InternalEntity *internal = entity_->asInternalEntity(); if (!internal) return 0; loc = internal->text().charLocation(off); return 1; } const EntityDecl *EntityOrigin::entityDecl() const { return entity_.pointer(); } #ifdef SP_NAMESPACE } #endif