ParserState.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
// Copyright (c) 1994 James Clark
// See the file COPYING for copying permission.
#pragma ident "%Z%%M% %I% %E% SMI"
#ifndef ParserState_INCLUDED
#define ParserState_INCLUDED 1
#ifdef __GNUG__
#pragma interface
#endif
#include <stddef.h>
#include <signal.h>
#include "Allocator.h"
#include "Attribute.h"
#include "Boolean.h"
#include "Vector.h"
#include "StringC.h"
#include "Dtd.h"
#include "Entity.h"
#include "EntityCatalog.h"
#include "EntityManager.h"
#include "Event.h"
#include "EventQueue.h"
#include "Id.h"
#include "InputSource.h"
#include "IList.h"
#include "IQueue.h"
#include "Location.h"
#include "Message.h"
#include "Mode.h"
#include "OpenElement.h"
#include "OutputState.h"
#include "ParserOptions.h"
#include "Ptr.h"
#include "Recognizer.h"
#include "Sd.h"
#include "Syntax.h"
#include "NCVector.h"
#include "Owner.h"
#include "Lpd.h"
#include "LpdEntityRef.h"
#include "Markup.h"
#include "ContentState.h"
#ifdef SP_NAMESPACE
namespace SP_NAMESPACE {
#endif
class ParserState : public ContentState, public AttributeContext {
public:
enum Phase {
noPhase,
initPhase,
prologPhase,
declSubsetPhase,
instanceStartPhase,
contentPhase
};
ParserState(const Ptr<EntityManager> &,
const ParserOptions &,
unsigned subdocLevel,
Phase finalPhase);
void setHandler(EventHandler *, const volatile sig_atomic_t *cancelPtr);
void unsetHandler();
Boolean inInstance() const;
Boolean hadDtd() const;
void allDone();
void startDtd(const StringC &);
void endDtd();
void startInstance();
unsigned subdocLevel() const;
Boolean haveDefLpd() const;
Dtd &defDtd();
const Ptr<Dtd> &defDtdPointer() const;
Boolean haveCurrentDtd() const;
const Dtd &currentDtd() const;
Dtd &currentDtdNonConst() const;
const ConstPtr<Dtd> &currentDtdPointer() const;
void startLpd(Ptr<Lpd> &lpd);
void endLpd();
Lpd &defLpd();
Ptr<Lpd> &defLpdPointer();
Ptr<ComplexLpd> defComplexLpdPointer();
size_t nActiveLink() const;
const Lpd &activeLpd(size_t i) const;
ComplexLpd &defComplexLpd();
Ptr<Dtd> lookupDtd(const StringC &name);
Ptr<Dtd> baseDtd();
void activateLinkType(const StringC &);
void allLinkTypesActivated();
void setResultAttributeSpecMode();
void clearResultAttributeSpecMode();
Boolean haveApplicableDtd() const;
Boolean hadLpd() const;
Boolean pass2() const;
void setPass2Start();
Boolean maybeStartPass2();
void checkEntityStability();
void noteReferencedEntity(const ConstPtr<Entity> &entity,
Boolean, Boolean);
ConstPtr<Lpd> lookupLpd(const StringC &name) const;
Boolean shouldActivateLink(const StringC &) const;
Char currentChar() const;
const Location &currentLocation() const;
InputSource *currentInput() const;
EntityManager &entityManager() const;
Ptr<EntityManager> entityManagerPtr() const;
const EntityCatalog &entityCatalog() const;
ConstPtr<EntityCatalog> entityCatalogPtr() const;
void setEntityCatalog(const ConstPtr<EntityCatalog> &);
void setSyntax(ConstPtr<Syntax>);
void setSyntaxes(ConstPtr<Syntax>, ConstPtr<Syntax>);
void setSd(ConstPtr<Sd>);
const Syntax &syntax() const;
const Syntax &instanceSyntax() const;
const ConstPtr<Syntax> &syntaxPointer() const;
const ConstPtr<Syntax> &prologSyntaxPointer() const;
const ConstPtr<Syntax> &instanceSyntaxPointer() const;
const Sd &sd() const;
const ConstPtr<Sd> &sdPointer() const;
void setPhase(Phase phase);
Phase phase() const;
Phase finalPhase() const;
Mode currentMode() const;
void setRecognizer(Mode, ConstPtr<Recognizer>);
void setNormalMap(const XcharMap<PackedBoolean> &);
const XcharMap<PackedBoolean> &normalMap() const;
Xchar getChar();
void skipChar();
Token getToken(Mode mode);
StringC currentToken() const;
void getCurrentToken(StringC &) const;
void getCurrentToken(const SubstTable<Char> *, StringC &) const;
unsigned inputLevel() const;
unsigned specialParseInputLevel() const;
unsigned markedSectionLevel() const;
unsigned markedSectionSpecialLevel() const;
unsigned currentInputElementIndex() const;
const Location &currentMarkedSectionStartLocation() const;
Boolean entityIsOpen(const Entity *) const;
void popInputStack();
void pushInput(InputSource *);
Boolean referenceDsEntity(const Location &);
void setDsEntity(const ConstPtr<Entity> &);
Boolean eventQueueEmpty() const;
Event *eventQueueGet();
EventHandler &eventHandler();
void pushElement(OpenElement *);
OpenElement *popSaveElement();
void popElement();
void pcdataRecover();
Boolean pcdataRecovering() const;
ConstPtr<Entity> lookupEntity(Boolean isParameter,
const StringC &name,
const Location &,
Boolean referenced);
ConstPtr<Entity> createUndefinedEntity(const StringC &,
const Location &);
Boolean appendCurrentRank(StringC &, const RankStem *) const;
void setCurrentRank(const RankStem *, const StringC &);
void startMarkedSection(const Location &);
void startSpecialMarkedSection(Mode, const Location &);
void endMarkedSection();
void queueRe(const Location &);
void noteMarkup();
void noteData();
void noteRs();
void noteStartElement(Boolean included);
void noteEndElement(Boolean included);
// size of objects allocated with this must not exceed
// sizeof(StartElementEvent)
Allocator &eventAllocator();
// size of objects allocated with this must not exceed
// sizeof(OpenElement)
Allocator &internalAllocator();
AttributeList *allocAttributeList(const ConstPtr<AttributeDefinitionList> &,
unsigned i);
static void freeEvent(void *);
Boolean wantMarkup() const;
const EventsWanted &eventsWanted() const;
StringC &nameBuffer();
typedef NamedTableIter<Id> IdTableIter;
IdTableIter idTableIter();
const ParserOptions &options() const;
void enableImplydef();
Boolean implydefElement();
Boolean implydefAttlist();
void keepMessages();
void releaseKeptMessages();
void discardKeptMessages();
Messenger &messenger();
Markup *currentMarkup();
const Location &markupLocation() const;
Markup *startMarkup(Boolean, const Location &);
void inheritActiveLinkTypes(const ParserState &parent);
Boolean cancelled() const;
// AFDR extensions
void setHadAfdrDecl();
Boolean hadAfdrDecl() const;
// Implementation of AttributeContext.
Boolean defineId(const StringC &, const Location &, Location &);
void noteIdref(const StringC &, const Location &);
void noteCurrentAttribute(size_t, AttributeValue *);
ConstPtr<AttributeValue> getCurrentAttribute(size_t) const;
ConstPtr<Entity> getAttributeEntity(const StringC &,
const Location &);
ConstPtr<Notation> getAttributeNotation(const StringC &,
const Location &);
const Syntax &attributeSyntax() const;
private:
ParserState(const ParserState &); // undefined
void operator=(const ParserState &); // undefined
void dispatchMessage(Message &);
void dispatchMessage(const Message &);
void initMessage(Message &);
void queueMessage(MessageEvent *);
Id *lookupCreateId(const StringC &);
ParserOptions options_;
EventHandler *handler_;
Pass1EventHandler pass1Handler_;
Boolean allowPass2_;
Offset pass2StartOffset_;
Boolean hadPass2Start_;
EventQueue eventQueue_;
OutputState outputState_;
ConstPtr<Syntax> prologSyntax_;
ConstPtr<Syntax> instanceSyntax_;
ConstPtr<Sd> sd_;
unsigned subdocLevel_;
Ptr<EntityManager> entityManager_;
ConstPtr<EntityCatalog> entityCatalog_;
Phase phase_;
Phase finalPhase_;
Boolean inInstance_;
Ptr<Dtd> defDtd_;
Ptr<Lpd> defLpd_;
Vector<ConstPtr<Lpd> > allLpd_;
Vector<ConstPtr<Lpd> > lpd_; // active LPDs
Vector<StringC> activeLinkTypes_;
Boolean activeLinkTypesSubsted_;
Boolean hadLpd_;
Boolean resultAttributeSpecMode_;
Boolean pass2_;
typedef OwnerTable<LpdEntityRef, LpdEntityRef, LpdEntityRef, LpdEntityRef>
LpdEntityRefSet;
typedef OwnerTableIter<LpdEntityRef, LpdEntityRef, LpdEntityRef, LpdEntityRef>
LpdEntityRefSetIter;
LpdEntityRefSet lpdEntityRefs_;
// external entity to be referenced at the end of the declaration subset
ConstPtr<Entity> dsEntity_;
Allocator eventAllocator_;
Allocator internalAllocator_;
NCVector<Owner<AttributeList> > attributeLists_;
StringC nameBuffer_;
Boolean keepingMessages_;
IQueue<MessageEvent> keptMessages_;
Mode currentMode_;
Boolean pcdataRecovering_;
// if in a special parse (cdata, rcdata, ignore), the input level
// at which the special parse started.
unsigned specialParseInputLevel_;
Mode specialParseMode_;
unsigned markedSectionLevel_;
unsigned markedSectionSpecialLevel_;
Vector<Location> markedSectionStartLocation_;
ConstPtr<Recognizer> recognizers_[nModes];
XcharMap<PackedBoolean> normalMap_;
unsigned inputLevel_;
IList<InputSource> inputStack_;
Vector<unsigned> inputLevelElementIndex_;
Ptr<Dtd> currentDtd_;
ConstPtr<Dtd> currentDtdConst_;
Vector<Ptr<Dtd> > dtd_;
Ptr<Dtd> pass1Dtd_;
ConstPtr<Syntax> syntax_;
Vector<StringC> currentRank_;
NamedTable<Id> idTable_;
NamedResourceTable<Entity> instanceDefaultedEntityTable_;
NamedResourceTable<Entity> undefinedEntityTable_;
Vector<ConstPtr<AttributeValue> > currentAttributes_;
Markup *currentMarkup_;
Markup markup_;
Location markupLocation_;
Boolean hadAfdrDecl_;
Boolean implydefElement_;
Boolean implydefAttlist_;
const volatile sig_atomic_t *cancelPtr_;
static sig_atomic_t dummyCancel_;
static const Location nullLocation_;
};
inline
Messenger &ParserState::messenger()
{
return *this;
}
inline
Boolean ParserState::wantMarkup() const
{
return (inInstance_
? options_.eventsWanted.wantInstanceMarkup()
: options_.eventsWanted.wantPrologMarkup());
}
inline
const EventsWanted &ParserState::eventsWanted() const
{
return options_.eventsWanted;
}
inline
InputSource *ParserState::currentInput() const
{
return inputStack_.head();
}
inline
const Location &ParserState::currentLocation() const
{
InputSource *in = currentInput();
return in ? in->currentLocation() : nullLocation_;
}
inline
Boolean ParserState::pcdataRecovering() const
{
return pcdataRecovering_;
}
inline
unsigned ParserState::inputLevel() const
{
return inputLevel_;
}
inline
unsigned ParserState::specialParseInputLevel() const
{
return specialParseInputLevel_;
}
inline
unsigned ParserState::markedSectionLevel() const
{
return markedSectionLevel_;
}
inline
unsigned ParserState::markedSectionSpecialLevel() const
{
return markedSectionSpecialLevel_;
}
inline
const Location &ParserState::currentMarkedSectionStartLocation() const
{
return markedSectionStartLocation_.back();
}
inline
unsigned ParserState::currentInputElementIndex() const
{
return inputLevelElementIndex_.back();
}
inline
Char ParserState::currentChar() const
{
return currentInput()->currentTokenStart()[0];
}
inline
StringC ParserState::currentToken() const
{
return StringC(currentInput()->currentTokenStart(),
currentInput()->currentTokenLength());
}
inline
void ParserState::getCurrentToken(StringC &str) const
{
InputSource *in = currentInput();
str.assign(in->currentTokenStart(), in->currentTokenLength());
}
inline
void ParserState::setRecognizer(Mode mode, ConstPtr<Recognizer> p)
{
recognizers_[mode] = p;
}
inline
void ParserState::setNormalMap(const XcharMap<PackedBoolean> &map)
{
normalMap_ = map;
}
inline
const XcharMap<PackedBoolean> &ParserState::normalMap() const
{
return normalMap_;
}
inline
Boolean ParserState::haveDefLpd() const
{
return !defLpd_.isNull();
}
inline
Boolean ParserState::haveCurrentDtd() const
{
return !currentDtd_.isNull();
}
inline
Dtd &ParserState::defDtd()
{
return *defDtd_;
}
inline
const Dtd &ParserState::currentDtd() const
{
return *currentDtd_;
}
inline
Dtd &ParserState::currentDtdNonConst() const
{
return *currentDtd_;
}
inline
const Ptr<Dtd> &ParserState::defDtdPointer() const
{
return defDtd_;
}
inline
const ConstPtr<Dtd> &ParserState::currentDtdPointer() const
{
return currentDtdConst_;
}
inline
Boolean ParserState::inInstance() const
{
return inInstance_;
}
inline
const Syntax &ParserState::syntax() const
{
return *syntax_;
}
inline
const Syntax &ParserState::instanceSyntax() const
{
return *instanceSyntax_;
}
inline
const ConstPtr<Syntax> &ParserState::syntaxPointer() const
{
return syntax_;
}
inline
const ConstPtr<Syntax> &ParserState::instanceSyntaxPointer() const
{
return instanceSyntax_;
}
inline
const ConstPtr<Syntax> &ParserState::prologSyntaxPointer() const
{
return prologSyntax_;
}
inline
const Sd &ParserState::sd() const
{
return *sd_;
}
inline
const ConstPtr<Sd> &ParserState::sdPointer() const
{
return sd_;
}
inline
void ParserState::setPhase(Phase phase)
{
phase_ = phase;
}
inline
Mode ParserState::currentMode() const
{
return currentMode_;
}
inline
Xchar ParserState::getChar()
{
return inputStack_.head()->get(messenger());
}
inline
void ParserState::skipChar()
{
(void)getChar();
}
inline
Token ParserState::getToken(Mode mode)
{
return recognizers_[mode]->recognize(inputStack_.head(), messenger());
}
inline
Boolean ParserState::hadDtd() const
{
return dtd_.size() > 0;
}
inline
Boolean ParserState::eventQueueEmpty() const
{
return eventQueue_.empty();
}
inline
Event *ParserState::eventQueueGet()
{
return eventQueue_.get();
}
inline
ParserState::Phase ParserState::phase() const
{
return phase_;
}
inline
ParserState::Phase ParserState::finalPhase() const
{
return finalPhase_;
}
inline
EntityManager &ParserState::entityManager() const
{
return *entityManager_;
}
inline
Ptr<EntityManager> ParserState::entityManagerPtr() const
{
return entityManager_;
}
inline
const EntityCatalog &ParserState::entityCatalog() const
{
return *entityCatalog_;
}
inline
ConstPtr<EntityCatalog> ParserState::entityCatalogPtr() const
{
return entityCatalog_;
}
inline
void ParserState::setEntityCatalog(const ConstPtr<EntityCatalog> &catalog)
{
entityCatalog_ = catalog;
}
inline
void ParserState::setDsEntity(const ConstPtr<Entity> &entity)
{
dsEntity_ = entity;
}
inline
Allocator &ParserState::eventAllocator()
{
return eventAllocator_;
}
inline
Allocator &ParserState::internalAllocator()
{
return internalAllocator_;
}
inline
StringC &ParserState::nameBuffer()
{
return nameBuffer_;
}
inline
void ParserState::setHandler(EventHandler *handler,
const volatile sig_atomic_t *cancelPtr)
{
handler_ = handler;
cancelPtr_ = cancelPtr ? cancelPtr : &dummyCancel_;
}
inline
void ParserState::unsetHandler()
{
handler_ = &eventQueue_;
cancelPtr_ = &dummyCancel_;
}
inline
void ParserState::queueRe(const Location &location)
{
outputState_.handleRe(*handler_, eventAllocator_, options_.eventsWanted,
syntax().standardFunction(Syntax::fRE),
location);
}
inline
void ParserState::noteMarkup()
{
if (inInstance_)
outputState_.noteMarkup(*handler_, eventAllocator_, options_.eventsWanted);
}
inline
void ParserState::noteRs()
{
outputState_.noteRs(*handler_, eventAllocator_, options_.eventsWanted);
}
inline
void ParserState::noteStartElement(Boolean included)
{
outputState_.noteStartElement(included, *handler_, eventAllocator_,
options_.eventsWanted);
}
inline
void ParserState::noteEndElement(Boolean included)
{
outputState_.noteEndElement(included, *handler_, eventAllocator_,
options_.eventsWanted);
}
inline
void ParserState::noteData()
{
outputState_.noteData(*handler_, eventAllocator_, options_.eventsWanted);
}
inline
unsigned ParserState::subdocLevel() const
{
return subdocLevel_;
}
inline
EventHandler &ParserState::eventHandler()
{
return *handler_;
}
inline
ParserState::IdTableIter ParserState::idTableIter()
{
// Avoid use of typedef to work around MSVC 2.0 bug.
return NamedTableIter<Id>(idTable_);
}
inline
const ParserOptions &ParserState::options() const
{
return options_;
}
inline
Boolean ParserState::implydefElement()
{
return implydefElement_;
}
inline
Boolean ParserState::implydefAttlist()
{
return implydefAttlist_;
}
inline
void ParserState::enableImplydef()
{
implydefElement_ = 1;
implydefAttlist_ = 1;
}
inline
void ParserState::keepMessages()
{
keepingMessages_ = 1;
}
inline
Boolean ParserState::haveApplicableDtd() const
{
return !currentDtd_.isNull();
}
inline
Boolean ParserState::hadLpd() const
{
return hadLpd_;
}
inline
Boolean ParserState::pass2() const
{
return pass2_;
}
inline
size_t ParserState::nActiveLink() const
{
return lpd_.size();
}
inline
const Lpd &ParserState::activeLpd(size_t i) const
{
return *lpd_[i];
}
inline
Lpd &ParserState::defLpd()
{
return *defLpd_;
}
inline
Ptr<Lpd> &ParserState::defLpdPointer()
{
return defLpd_;
}
inline
Ptr<ComplexLpd> ParserState::defComplexLpdPointer()
{
return (ComplexLpd *)defLpd_.pointer();
}
inline
ComplexLpd &ParserState::defComplexLpd()
{
return (ComplexLpd &)defLpd();
}
inline
Ptr<Dtd> ParserState::baseDtd()
{
if (dtd_.size() > 0)
return dtd_[0];
else
return Ptr<Dtd>();
}
inline
void ParserState::setResultAttributeSpecMode()
{
resultAttributeSpecMode_ = 1;
}
inline
void ParserState::clearResultAttributeSpecMode()
{
resultAttributeSpecMode_ = 0;
}
inline
Markup *ParserState::currentMarkup()
{
return currentMarkup_;
}
inline
const Location &ParserState::markupLocation() const
{
return markupLocation_;
}
inline
Markup *ParserState::startMarkup(Boolean storing, const Location &loc)
{
markupLocation_ = loc;
if (storing) {
markup_.clear();
return currentMarkup_ = &markup_;
}
else
return currentMarkup_ = 0;
}
inline
Boolean ParserState::cancelled() const
{
return *cancelPtr_ != 0;
}
inline
void ParserState::setHadAfdrDecl()
{
hadAfdrDecl_ = 1;
}
inline
Boolean ParserState::hadAfdrDecl() const
{
return hadAfdrDecl_;
}
#ifdef SP_NAMESPACE
}
#endif
#endif /* not ParserState_INCLUDED */