📄 parserstate.cxx
字号:
// Copyright (c) 1994 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "splib.h"#include "ParserState.h"#include "InternalInputSource.h"#include "MessageArg.h"#include "macros.h"#include "SgmlParser.h"#include "IListIter.h"#include "ParserMessages.h"#include "Undo.h"#include "Trie.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifconst Location ParserState::nullLocation_;sig_atomic_t ParserState::dummyCancel_ = 0;static const size_t eventSizes[] = {#define EVENT(c, f) sizeof(c),#include "events.h"#undef EVENT};static const size_t internalSizes[] = { sizeof(InternalInputSource), sizeof(OpenElement), sizeof(UndoStartTag), sizeof(UndoEndTag), sizeof(UndoTransition)};staticsize_t maxSize(const size_t *v, size_t n, size_t max = 0){ for (size_t i = 0; i < n; i++) { if (v[i] > max) max = v[i]; } return max;}ParserState::ParserState(const Ptr<EntityManager> &em, const ParserOptions &opt, unsigned subdocLevel, Phase finalPhase): entityManager_(em), options_(opt), inInstance_(0), keepingMessages_(0), eventAllocator_(maxSize(eventSizes, SIZEOF(eventSizes)), 50), internalAllocator_(maxSize(internalSizes, SIZEOF(internalSizes), EntityOrigin::allocSize), 50), handler_(&eventQueue_), subdocLevel_(subdocLevel), inputLevel_(0), specialParseInputLevel_(0), markedSectionLevel_(0), markedSectionSpecialLevel_(0), currentMode_(proMode), hadLpd_(0), resultAttributeSpecMode_(0), pass2_(0), activeLinkTypesSubsted_(0), allowPass2_(0), hadPass2Start_(0), pcdataRecovering_(0), currentMarkup_(0), cancelPtr_(&dummyCancel_), finalPhase_(finalPhase), hadAfdrDecl_(0){}void ParserState::inheritActiveLinkTypes(const ParserState &parent){ activeLinkTypes_ = parent.activeLinkTypes_; activeLinkTypesSubsted_ = parent.activeLinkTypesSubsted_;}void ParserState::allDone(){ phase_ = noPhase;}void ParserState::setPass2Start(){ ASSERT(inputLevel_ == 1); if (hadPass2Start_) return; hadPass2Start_ = 1; if (!pass2() && sd().link() && activeLinkTypes_.size() > 0) { allowPass2_ = 1; pass1Handler_.init(handler_); handler_ = &pass1Handler_; const InputSourceOrigin *p = currentLocation().origin()->asInputSourceOrigin(); pass2StartOffset_= p->startOffset(currentLocation().index()); } else { allowPass2_ = 0; currentInput()->willNotRewind(); }}void ParserState::allLinkTypesActivated(){ if (activeLinkTypes_.size() == 0 && inputLevel_ == 1) currentInput()->willNotRewind();}Boolean ParserState::maybeStartPass2(){ if (pass2_ || !allowPass2_) return 0; handler_ = pass1Handler_.origHandler(); if (!nActiveLink() || pass1Handler_.hadError()) { while (!pass1Handler_.empty()) { if (cancelled()) return 0; pass1Handler_.get()->handle(*handler_); } InputSource *top = 0; for (IListIter<InputSource> iter(inputStack_); !iter.done(); iter.next()) top = iter.cur(); if (top) top->willNotRewind(); return 0; } pass1Handler_.clear(); while (inputLevel_ > 1) { InputSource *p = inputStack_.get(); inputLevel_--; delete p; } // Caller will call allDone() if inputLevel_ is 0. if (inputLevel_ == 0) return 0; if (!inputStack_.head()->rewind(*this)) { inputLevel_ = 0; delete inputStack_.get(); return 0; } inputStack_.head()->willNotRewind(); for (; pass2StartOffset_ > 0; pass2StartOffset_--) if (inputStack_.head()->get(messenger()) == InputSource::eE) { message(ParserMessages::pass2Ee); inputLevel_ = 0; delete inputStack_.get(); return 0; } specialParseInputLevel_ = 0; markedSectionLevel_ = 0; markedSectionSpecialLevel_ = 0; currentMode_ = proMode; hadLpd_ = 0; allowPass2_ = 0; hadPass2Start_ = 0; currentMarkup_ = 0; inputLevel_ = 1; inInstance_ = 0; defDtd_.clear(); defLpd_.clear(); dtd_[0].swap(pass1Dtd_); dtd_.clear(); dsEntity_.clear(); currentDtd_.clear(); currentDtdConst_.clear(); phase_ = noPhase; pass2_ = 1; lpd_.clear(); allLpd_.clear(); return 1;}Boolean ParserState::referenceDsEntity(const Location &loc){ if (dsEntity_.isNull()) return 0; Ptr<EntityOrigin> origin = EntityOrigin::make(internalAllocator(), dsEntity_, loc); dsEntity_->dsReference(*this, origin); dsEntity_.clear(); return inputLevel() > 1;}void ParserState::startDtd(const StringC &name){ defDtd_ = new Dtd(name, dtd_.size() == 0); defLpd_.clear(); for (size_t i = 0; i < options().includes.size(); i++) { StringC name = options().includes[i]; const SubstTable<Char> *subst = syntax().entitySubstTable(); for (size_t j = 0; j < name.size(); j++) subst->subst(name[j]); Text text; text.addChars(syntax().reservedName(Syntax::rINCLUDE), Location()); Entity *entity = new InternalTextEntity(name, Entity::parameterEntity, Location(), text, InternalTextEntity::none); entity->setUsed(); defDtd_->insertEntity(entity); } size_t nEntities = instanceSyntax_->nEntities(); for (size_t i = 0; i < nEntities; i++) { Text text; text.addChar(instanceSyntax_->entityChar(i), Location()); Entity *entity = new InternalCdataEntity(instanceSyntax_->entityName(i), Location(), text); defDtd_->insertEntity(entity); } currentDtd_ = defDtd_; currentDtdConst_ = defDtd_; currentMode_ = dsMode;}void ParserState::endDtd(){ dtd_.push_back(defDtd_); defDtd_.clear(); currentDtd_.clear(); currentDtdConst_.clear(); currentMode_ = proMode;}void ParserState::startLpd(Ptr<Lpd> &lpd){ defLpd_ = lpd; defDtd_ = defLpd_->sourceDtd(); currentDtd_ = defLpd_->sourceDtd(); currentDtdConst_ = defLpd_->sourceDtd(); currentMode_ = dsMode;}void ParserState::endLpd(){ hadLpd_ = 1; if (defLpd_->active()) lpd_.push_back(defLpd_); allLpd_.push_back(defLpd_); defLpd_.clear(); currentDtd_.clear(); currentDtdConst_.clear(); currentMode_ = proMode;}void ParserState::popInputStack(){ ASSERT(inputLevel_ > 0); InputSource *p = inputStack_.get(); inputLevel_--; delete p; if (specialParseInputLevel_ > 0 && inputLevel_ == specialParseInputLevel_) currentMode_ = specialParseMode_; if (currentMode_ == dsiMode && inputLevel_ == 1 && markedSectionLevel_ == 0) currentMode_ = dsMode; if (inputLevelElementIndex_.size()) inputLevelElementIndex_.resize(inputLevelElementIndex_.size() - 1);}void ParserState::setSd(ConstPtr<Sd> sd){ sd_ = sd; mayDefaultAttribute_ = (sd_->omittag() || sd_->attributeDefault()); validate_ = sd_->typeValid(); implydefElement_ = sd_->implydefElement(); implydefAttlist_ = sd_->implydefAttlist();}void ParserState::setSyntax(ConstPtr<Syntax> syntax){ syntax_ = syntax; prologSyntax_ = syntax; instanceSyntax_ = syntax;}void ParserState::setSyntaxes(ConstPtr<Syntax> prologSyntax, ConstPtr<Syntax> instanceSyntax){ syntax_ = prologSyntax; prologSyntax_ = prologSyntax; instanceSyntax_ = instanceSyntax;}void ParserState::pushInput(InputSource *in){ if (!in) return; if (!syntax_.isNull() && syntax_->multicode()) in->setMarkupScanTable(syntax_->markupScanTable()); inputStack_.insert(in); inputLevel_++; if (specialParseInputLevel_ > 0 && inputLevel_ > specialParseInputLevel_) currentMode_ = rcconeMode; // mode for rcdata in an entity else if (currentMode_ == dsMode) currentMode_ = dsiMode; if (inInstance_ && sd().integrallyStored()) inputLevelElementIndex_.push_back(tagLevel() ? currentElement().index() : 0);}void ParserState::startMarkedSection(const Location &loc){ markedSectionLevel_++; markedSectionStartLocation_.push_back(loc); if (currentMode_ == dsMode) currentMode_ = dsiMode; if (markedSectionSpecialLevel_) markedSectionSpecialLevel_++;}void ParserState::startSpecialMarkedSection(Mode mode, const Location &loc){ markedSectionLevel_++; markedSectionStartLocation_.push_back(loc); specialParseInputLevel_ = inputLevel_; markedSectionSpecialLevel_ = 1; specialParseMode_ = currentMode_ = mode;}void ParserState::endMarkedSection(){ ASSERT(markedSectionLevel_ > 0); markedSectionLevel_--; markedSectionStartLocation_.resize(markedSectionStartLocation_.size() - 1); if (markedSectionSpecialLevel_ > 0) { markedSectionSpecialLevel_--; if (markedSectionSpecialLevel_ > 0) return; // remain in imsMode specialParseInputLevel_ = 0; if (inInstance_) currentMode_ = contentMode(); else currentMode_ = dsiMode; } if (currentMode_ == dsiMode && inputLevel_ == 1 && markedSectionLevel_ == 0) currentMode_ = dsMode;}void ParserState::pushElement(OpenElement *e){ ContentState::pushElement(e); pcdataRecovering_ = 0; // the start tag of this element may have been implied by data // inside a cdata or rcdata marked section if (markedSectionSpecialLevel_ == 0) { currentMode_ = contentMode(); if (e->requiresSpecialParse()) { specialParseMode_ = currentMode_; specialParseInputLevel_ = inputLevel_; } }}// PCDATA was encountered somewhere where it was not allowed.// Change the current mode to improve recovery.void ParserState::pcdataRecover(){ switch (currentMode_) { case econMode: currentMode_ = mconMode; break; case econnetMode: currentMode_ = mconnetMode; break; default: break; } pcdataRecovering_ = 1;}OpenElement *ParserState::popSaveElement(){ OpenElement *e = ContentState::popSaveElement(); // the end tag of this element may have been implied by data // inside a cdata or rcdata marked section if (markedSectionSpecialLevel_ == 0) { currentMode_ = contentMode(); specialParseInputLevel_ = 0; } pcdataRecovering_ = 0; return e;}void ParserState::popElement(){ delete popSaveElement();} Boolean ParserState::entityIsOpen(const EntityDecl *entityDecl) const{ for (IListIter<InputSource> iter(inputStack_); !iter.done(); iter.next()) if (iter.cur()->currentLocation().origin()->entityDecl() == entityDecl) return 1; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -