⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sgmlgenerator.cxx

📁 SP是一个基于GNU C++编译器
💻 CXX
字号:
// Copyright (c) 1995 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "config.h"#include "SGMLGenerator.h"const SGMLApplication::Char RE = '\r';const SGMLApplication::Char RS = '\n';const SGMLApplication::Char TAB = '\t';inlineSP_NAMESPACE_SCOPE OutputCharStream &operator<<(SP_NAMESPACE_SCOPE OutputCharStream &os,	   const SGMLApplication::CharString &str){  return os.write(str.ptr, str.len);}inlinebool operator==(const SGMLApplication::CharString &str1,		const SGMLApplication::CharString &str2){  return (str1.len == str2.len	  && (str1.len == 0	      || memcmp(str1.ptr,			str2.ptr,			str1.len*sizeof(SGMLApplication::Char)) == 0));}inlinebool operator!=(const SGMLApplication::CharString &str1,		const SGMLApplication::CharString &str2){  return !(str1 == str2);} inlineSP_NAMESPACE_SCOPE OutputCharStream &SGMLGenerator::os(){  return *os_;}inlinevoid SGMLGenerator::outputRe(){  os().put(RE);}inlinevoid SGMLGenerator::flushRe(){  if (outputState_ == pendingRe) {    outputRe();    outputState_ = other;  }}inlinebool SGMLGenerator::isSgmlChar(Char c){  return c >= 256 || !nonSgml_[c];}staticvoid escape(SP_NAMESPACE_SCOPE OutputCharStream &s, SP_NAMESPACE_SCOPE Char c){  s << "&#" << (unsigned long)c << ";";}SGMLGenerator::SGMLGenerator(SP_NAMESPACE_SCOPE OutputCharStream *os,			     unsigned flags): os_(os), parseMode_(normalMode), outputState_(other), mustOmitEndTag_(0),  inInstance_(0), flags_(flags){  os_->setEscaper(escape);  for (size_t i = 0; i < 256; i++)    switch (i) {    case RE:    case RS:    case TAB:      nonSgml_[i] = 0;      break;    case 255:      nonSgml_[i] = 1;      break;    default:      nonSgml_[i] = (i < 32 || (i >= 127 && i < 160));      break;    }}SGMLGenerator::~SGMLGenerator(){  outputRe();  delete os_;}void SGMLGenerator::startDtd(const StartDtdEvent &event){  if (!(flags_ & generateDtd))    return;  if (event.haveExternalId) {    os() << "<!DOCTYPE " << event.name << ' ';    if (event.externalId.havePublicId)      os() << "PUBLIC \"" << event.externalId.publicId << '\"';    else      os() << "SYSTEM";    if (event.externalId.haveSystemId) {      const CharString &str = event.externalId.systemId;      bool useLit = 1;      bool useLita = 1;      for (size_t i = 0; i < str.len; i++)	if (str.ptr[i] == '"')	  useLit = 0;	else if (str.ptr[i] == '\'')	  useLita = 0;      if (useLit)	os() << " \"" << event.externalId.systemId << '"';      else if (useLita)	os() << " '" << event.externalId.systemId << '\'';    }    os() << '>';    os().put(RE);  }}void SGMLGenerator::startElement(const StartElementEvent &event){  // This can happen with OMITTAG.  if (parseMode_ != normalMode)    os() << "]]><![ INCLUDE [";  // The output is more readable if, within element content,  // tags begin on a new line.  if (isElementContentStack_.size() > 0      && isElementContentStack_[isElementContentStack_.size() - 1])    outputRe();  isElementContentStack_    += char(event.contentType == StartElementEvent::element);  if (event.included) {    if (outputState_ == pendingRe) {      numCharRef(RE);		// would be moved otherwise      outputState_ = other;    }    outputStateStack_ += char(outputState_);  }  else {    outputStateStack_ += char(other);    flushRe();  }  switch (event.contentType) {  case StartElementEvent::cdata:    parseMode_ = cdataMode;    break;  case StartElementEvent::rcdata:    parseMode_ = rcdataMode;    break;  default:    parseMode_ = normalMode;    break;  }  outputState_ = afterStartTag;  os() << '<' << event.gi;  for (size_t i = 0; i < event.nAttributes; i++) {    const Attribute &a = event.attributes[i];    switch (a.type) {    case Attribute::cdata:      if (a.defaulted != Attribute::definition) {	os() << ' ' << a.name << '=' << '"';	for (size_t j = 0; j < a.nCdataChunks; j++)	  if (a.cdataChunks[j].isSdata)	    entityRef(a.cdataChunks[j].entityName);	  else if (a.cdataChunks[j].isNonSgml)	    numCharRefNum(a.cdataChunks[j].nonSgmlChar);	  else	    attributeChars(a.cdataChunks[j].data);	os() << '"';      }      break;    case Attribute::tokenized:      if (a.defaulted != Attribute::definition) {	if (a.isGroup && a.name == a.tokens)	  os() << ' ' << a.tokens;	else	  os() << ' ' << a.name << '=' << '"' << a.tokens << '"';      }      break;    default:      break;    }  }  os() << '>';  mustOmitEndTag_ = (event.contentType == StartElementEvent::empty);}void SGMLGenerator::attributeChars(const CharString &str){  const Char *p = str.ptr;  for (size_t n = str.len; n > 0; n--, p++)    switch (*p) {    case '"':    case '&':    case RS:    case RE:    case TAB:      numCharRef(*p);      break;    default:      if (isSgmlChar(*p))	os().put(*p);      else	numCharRef(*p);      break;    }}void SGMLGenerator::endElement(const EndElementEvent &event){  if (mustOmitEndTag_)    mustOmitEndTag_ = 0;  else {    if (outputState_ == pendingRe) {      outputRe();      outputRe();    }    else if (isElementContentStack_[isElementContentStack_.size() - 1])      outputRe();    os() << "</" << event.gi << '>';  }  outputState_ = outputStateStack_[outputStateStack_.size() - 1];  outputStateStack_.resize(outputStateStack_.size() - 1);  parseMode_ = normalMode;  isElementContentStack_.resize(isElementContentStack_.size() - 1);}void SGMLGenerator::data(const DataEvent &event){  const Char *p = event.data.ptr;  for (size_t len = event.data.len; len > 0; len--, p++) {    switch (*p) {    case RE:      flushRe();      if (outputState_ == afterStartTag)	outputRe();      outputState_ = pendingRe;      break;    case '&':    case '<':    case '>':			// prevents recognition of MSE      flushRe();      outputState_ = other;      if (parseMode_ == cdataMode)	os().put(*p);      else	numCharRef(*p);      break;    default:      flushRe();      outputState_ = other;      if (isSgmlChar(*p))	os().put(*p);      else if (parseMode_ == cdataMode) {	// The output will not be valid, but I don't think this	// situation can arise with valid SGML source.	os().put(*p);      }      else	numCharRef(*p);      break;    }  }}void SGMLGenerator::nonSgmlChar(const NonSgmlCharEvent &event){  flushRe();  outputState_ = other;  numCharRefNum(event.c);}void SGMLGenerator::sdata(const SdataEvent &event){  flushRe();  entityRef(event.entityName);}void SGMLGenerator::pi(const PiEvent &event){  if (!inInstance_)    return;  if (outputState_ == pendingRe) {    numCharRef(RE);		// would be moved otherwise    outputState_ = other;  }  if (event.entityName.len)    entityRef(event.entityName);  else    os() << "<?" << event.data << '>';}void SGMLGenerator::externalDataEntityRef(const ExternalDataEntityRefEvent &event){  flushRe();  entityRef(event.entity.name);}void SGMLGenerator::subdocEntityRef(const SubdocEntityRefEvent &event){  flushRe();  entityRef(event.entity.name);}void SGMLGenerator::endProlog(const EndPrologEvent &){  inInstance_ = 1;}void SGMLGenerator::commentDecl(const CommentDeclEvent &event){  if (!inInstance_)    return;  if (outputState_ == pendingRe) {    numCharRef(RE);		// would be moved otherwise    outputState_ = other;  }  os() << "<!";  for (size_t i = 0; i < event.nComments; i++) {    os() << "--" << event.comments[i] << "--";    if (i + 1 < event.nComments)      os() << event.seps[i];	// ensure comment declarations end with -->  }  os() << '>';}void SGMLGenerator::markedSectionStart(const MarkedSectionStartEvent &event){  if (outputState_ == pendingRe) {    numCharRef(RE);		// would be moved otherwise    outputState_ = other;  }  os() << "<![";  for (size_t i = 0; i < event.nParams; i++)    switch (event.params[i].type) {    case MarkedSectionStartEvent::Param::temp:      os() << " TEMP";      break;    case MarkedSectionStartEvent::Param::include:      os() << " INCLUDE";      break;    case MarkedSectionStartEvent::Param::rcdata:      os() << " RCDATA";      break;    case MarkedSectionStartEvent::Param::cdata:      os() << " CDATA";      break;    case MarkedSectionStartEvent::Param::ignore:      os() << " IGNORE";      break;    case MarkedSectionStartEvent::Param::entityRef:      os() << " %" << event.params[i].entityName << ";";      break;    }  switch (event.status) {  case MarkedSectionStartEvent::cdata:    parseMode_ = cdataMode;    break;  case MarkedSectionStartEvent::rcdata:    parseMode_ = rcdataMode;    break;  default:    break;  }  os() << " [";}void SGMLGenerator::markedSectionEnd(const MarkedSectionEndEvent &){  if (outputState_ == pendingRe) {    numCharRef(RE);		// would be moved otherwise    outputState_ = other;  }  os() << "]]>";  parseMode_ = normalMode;}void SGMLGenerator::ignoredChars(const IgnoredCharsEvent &event){  os() << event.data;}void SGMLGenerator::entityRef(const CharString &name){  os() << '&' << name << ';';}void SGMLGenerator::numCharRef(Char c){  const SP_NAMESPACE_SCOPE StringC *name = charEntityName(c);  if (name && name->size())    os() << '&' << *name << ';';  else    numCharRefNum(c);}void SGMLGenerator::numCharRefNum(unsigned long n){  os() << "&#" << n << ';';}void SGMLGenerator::generalEntity(const GeneralEntityEvent &event){  if (event.entity.isInternal      && event.entity.text.len == 1      && event.entity.dataType != Entity::sdata) {    SP_NAMESPACE_SCOPE StringC *p = charEntityName(event.entity.text.ptr[0]);    if (p)      p->assign(event.entity.name.ptr, event.entity.name.len);  }}SP_NAMESPACE_SCOPE StringC *SGMLGenerator::charEntityName(Char c){  switch (c) {  case '<':    return &lt_;  case '>':    return &gt_;  case '&':    return &amp_;  case '"':    return &quot_;  default:    break;  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -