arcengine.cxx

来自「SP是一个基于GNU C++编译器」· CXX 代码 · 共 1,758 行 · 第 1/4 页

CXX
1,758
字号
	      Messenger::message(ArcEngineMessages::invalidArcAuto,				 StringMessageArg(supportAtts_[i]));	    break;	  case rArcIndr:	    docSyntax_->generalSubstTable()->subst(supportAtts_[i]);	    if (supportAtts_[i] == docSd_->execToInternal("ARCINDR")) {	      Messenger::setNextLocation(textP->charLocation(0));	      Messenger::message(ArcEngineMessages::arcIndrNotSupported);	    }	    else if (supportAtts_[i] != docSd_->execToInternal("NARCINDR")) {	      Messenger::setNextLocation(textP->charLocation(0));	      Messenger::message(ArcEngineMessages::invalidArcIndr,				 StringMessageArg(supportAtts_[i]));	    }	    break;	  case rArcFormA:	  case rArcNamrA:	  case rArcSuprA:	  case rArcIgnDA:	    docSyntax_->generalSubstTable()->subst(supportAtts_[i]);	    break;	  case rArcDocF:	  case rArcSuprF:	  case rArcBridF:	  case rArcDataF:	    metaSyntax_->generalSubstTable()->subst(supportAtts_[i]);	    break;	  case rArcDTD:	    {	      const StringC &pero = docSyntax_->delimGeneral(Syntax::dPERO);	      if (supportAtts_[i].size() >= pero.size()) {		StringC tem(supportAtts_[i].data(), pero.size());		docSyntax_->generalSubstTable()->subst(tem);		if (tem == pero) {		  arcDtdIsParam_ = 1;		  tem.assign(supportAtts_[i].data() + pero.size(),			     supportAtts_[i].size() - pero.size());		  tem.swap(supportAtts_[i]);		}	      }	      docSyntax_->entitySubstTable()->subst(supportAtts_[i]);	    }	    break;	  }	}      }    }  }  processArcOpts(atts);}void ArcProcessor::processArcOpts(const AttributeList &atts){  StringC attName(docSd_->execToInternal("ArcOptSA"));  docSyntax_->generalSubstTable()->subst(attName);  unsigned ind;  Vector<StringC> arcOptA;  Vector<size_t> arcOptAPos;  const Text *arcOptAText = 0;  if (atts.attributeIndex(attName, ind)) {    const AttributeValue *value = atts.value(ind);    if (value) {      arcOptAText = value->text();      if (arcOptAText)	split(*arcOptAText, docSyntax_->space(), arcOptA, arcOptAPos);    }  }  if (!arcOptAText)    arcOptA.push_back(docSd_->execToInternal("ArcOpt"));  for (size_t i = 0; i < arcOptA.size(); i++) {    docSyntax_->generalSubstTable()->subst(arcOptA[i]);    if (atts.attributeIndex(arcOptA[i], ind)) {      const AttributeValue *value = atts.value(ind);      if (value) {	const Text *textP = value->text();	if (textP) {	  Vector<StringC> opts;	  Vector<size_t> optsPos;	  split(*textP, docSyntax_->space(), opts, optsPos);	  arcOpts_.insert(arcOpts_.begin(),			  opts.begin(), opts.begin() + opts.size());	}      }    }  }}void ArcProcessor::processArcQuant(const Text &text){  Ptr<Syntax> newMetaSyntax;  Vector<StringC> tokens;  Vector<size_t> tokensPos;  split(text, docSyntax_->space(), tokens, tokensPos);  for (size_t i = 0; i < tokens.size(); i++) {    docSyntax_->generalSubstTable()->subst(tokens[i]);    Syntax::Quantity quantityName;    if (!docSd_->lookupQuantityName(tokens[i], quantityName)) {      setNextLocation(text.charLocation(tokensPos[i]));      Messenger::message(ArcEngineMessages::invalidQuantity,			 StringMessageArg(tokens[i]));    }    else if (i + 1 >= tokens.size()) {      setNextLocation(text.charLocation(tokensPos[i]));      Messenger::message(ArcEngineMessages::missingQuantityValue,			 StringMessageArg(tokens[i]));    }    else {      i++;      unsigned long val = 0;      if (tokens[i].size() > 8) {	setNextLocation(text.charLocation(tokensPos[i] + 8));	Messenger::message(ArcEngineMessages::quantityValueTooLong,			   StringMessageArg(tokens[i]));	tokens[i].resize(8);      }      for (size_t j = 0; j < tokens[i].size(); j++) {	int weight = docSd_->digitWeight(tokens[i][j]);	if (weight < 0) {	  setNextLocation(text.charLocation(tokensPos[i] + j));	  Char c = tokens[i][j];	  Messenger::message(ArcEngineMessages::invalidDigit,			     StringMessageArg(StringC(&c, 1)));	  val = 0;	  break;	}	else {	  val *= 10;	  val += weight;	}      }      if (val > docSyntax_->quantity(quantityName)) {	if (newMetaSyntax.isNull())	  newMetaSyntax = new Syntax(*docSyntax_);	newMetaSyntax->setQuantity(quantityName, val);      }    }  }  if (!newMetaSyntax.isNull())    metaSyntax_ = newMetaSyntax;}Boolean ArcProcessor::processStartElement(const StartElementEvent &event,					  const AttributeList *linkAttributes,					  const Text *content,					  Allocator &alloc){  unsigned suppressFlags = (openElementFlags_.size() > 0			    ? (openElementFlags_.back() & ~isArc)			    : (unsigned)condIgnoreData);  if ((suppressFlags & suppressForm)      && (suppressFlags & suppressSupr)) {    // Make this case efficient.    openElementFlags_.push_back(suppressFlags);    return 1;  }  const AttributeList &atts = event.attributes();  const MetaMap &map = buildMetaMap(event.elementType(),				    0,				    atts,				    linkAttributes,				    suppressFlags);  const ElementType *metaType;  ConstPtr<AttributeValue> arcContent;  if (map.attributed == 0) {    if (!(tagLevel() == 0	  && !currentElement().isFinished())) {      if (!arcContent.isNull()	  && (currentElement().declaredEmpty()	      || !currentElement().tryTransitionPcdata()))	Messenger::message(ArcEngineMessages::invalidArcContent);      openElementFlags_.push_back(map.suppressFlags);      return 1;    }    metaType = metaDtd_->documentElementType();    mgr_->message(ArcEngineMessages::documentElementNotArc,		  StringMessageArg(metaType->name()));    attributeList_.init(metaType->attributeDef());    attributeList_.finish(*this);  }  else {    if (!mapAttributes(atts, linkAttributes, content, attributeList_,		       arcContent, map))      return 0;    metaType = (const ElementType *)map.attributed;    suppressFlags = map.suppressFlags;  }  StartElementEvent *genEvent    = new (alloc) StartElementEvent(metaType,					metaDtd_,					&attributeList_,					event.location(),					0);  if (metaType->definition()->undefined())    Messenger::message(ArcEngineMessages::undefinedElement,		       StringMessageArg(metaType->name()));  else if (elementIsExcluded(metaType))    Messenger::message(ArcEngineMessages::elementExcluded,		       StringMessageArg(metaType->name()));  else if (elementIsIncluded(metaType))    genEvent->setIncluded();  else if (!currentElement().tryTransition(metaType))    Messenger::message(ArcEngineMessages::invalidElement,		       StringMessageArg(metaType->name()));		         pushElement(new (alloc) OpenElement(metaType,					  0,					  genEvent->included(),					  0,					  event.location()));  docHandler_->startElement(genEvent);  if (attributeList_.conref())    currentElement().setConref();  if (!arcContent.isNull() && arcContent->text() != 0) {    if (currentElement().declaredEmpty()	|| !currentElement().tryTransitionPcdata())      Messenger::message(ArcEngineMessages::invalidArcContent);    else      emitArcContent(*arcContent->text(), docHandler(), alloc);    suppressFlags |= (suppressForm|suppressSupr|ignoreData);  }  suppressFlags &= ~recoverData;  openElementFlags_.push_back(suppressFlags | isArc);  return 1;}void ArcProcessor::emitArcContent(const Text &text,				  EventHandler &handler,				  Allocator &alloc){  TextIter iter(text);  TextItem::Type type;  const Char *s;  size_t n;  const Location *loc;  while (iter.next(type, s, n, loc))    switch (type) {    case TextItem::data:    case TextItem::cdata:      // +1 because first dataEvent is the non-architectural data.      if (type == TextItem::data)	handler.data(new (alloc) ImmediateDataEvent(Event::characterData,							s,							n,							*loc,							0));      else			  	handler.data(new (alloc)		     CdataEntityEvent(loc->origin()->asEntityOrigin()				      ->entity()->asInternalEntity(),				      loc->origin()));      break;    case TextItem::sdata:		           handler.sdataEntity(new (alloc)			  SdataEntityEvent(loc->origin()->asEntityOrigin()					   ->entity()->asInternalEntity(),					   loc->origin()));      break;    default:      break;    }}Boolean ArcProcessor::processData(){  if (openElementFlags_.size() > 0      && (openElementFlags_.back() & ignoreData))    return 0;  if (!currentElement().declaredEmpty()      && currentElement().tryTransitionPcdata())    return 1;  else if (openElementFlags_.size() > 0	   && (openElementFlags_.back() & condIgnoreData))    return 0;  else {    // Only give this error once per element    if (openElementFlags_.size() > 0) {      if (openElementFlags_.back() & recoverData)	return 1;      openElementFlags_.back() |= recoverData;    }    Messenger::message(ArcEngineMessages::invalidData);    return 1;  }}Boolean ArcProcessor::mapAttributes(const AttributeList &from,				    const AttributeList *fromLink,				    const Text *content,				    AttributeList &to,				    ConstPtr<AttributeValue> &arcContent,				    const MetaMap &map){  if (map.attributed)    to.init(map.attributed->attributeDef());  for (size_t i = 0; i < map.attMapFrom.size(); i++) {    unsigned fromIndex = map.attMapFrom[i];    const AttributeList *fromList = &from;    if (fromIndex != contentPseudoAtt && fromIndex >= fromList->size()) {      fromList = fromLink;      fromIndex -= from.size();    }    if (map.attMapTo[i] == contentPseudoAtt) {      if (fromIndex != contentPseudoAtt)	arcContent = fromList->valuePointer(fromIndex);    }    else {      const Text *fromText = 0;      Boolean fromTextTokenized = 0;      if (map.attMapFrom[i] == contentPseudoAtt) {	if (!content)	  return 0;	fromText = content;      }      else {	const AttributeValue *value = fromList->value(fromIndex);	if (value) {	  fromText = value->text();	  fromTextTokenized = fromList->tokenized(fromIndex);	  if (fromText	      && fromList == &from	      && !from.specified(fromIndex)	      && (map.attributed->attributeDef()->def(map.attMapTo[i])		  ->missingValueWouldMatch(*fromText, *this)))	    fromText = 0;	}      }      if (fromText) {	unsigned specLength = 0;	Text tem;	if (!fromTextTokenized && to.tokenized(map.attMapTo[i]))	  fromText->tokenize(docSyntax_->space(), tem);	else	  tem = *fromText;	to.setSpec(map.attMapTo[i], *this);	to.setValue(map.attMapTo[i], tem, *this, specLength);      }    }  }  if (map.attributed)    to.finish(*this);  return 1;}const ArcProcessor::MetaMap &ArcProcessor::buildMetaMap(const ElementType *docElementType,			   const Notation *notation,			   const AttributeList &atts,			   const AttributeList *linkAtts,			   unsigned suppressFlags){  Boolean isNotation;  const Attributed *attributed = docElementType;  const StringC *nameP;  if (!attributed) {    attributed = notation;    isNotation = 1;    nameP = &notation->name();  }  else {    isNotation = 0;    nameP = &docElementType->name();  }  // Try to use cached entry.  Boolean inhibitCache = 0;  size_t cacheIndex;  if (isNotation || docElementType->definition()->undefined()) {    inhibitCache = 1;    cacheIndex = (unsigned)-1;  }  else {    cacheIndex = docElementType->index();    const MetaMapCache *cache = metaMapCache_[cacheIndex].pointer();    if (cache	&& cache->suppressFlags == suppressFlags	&& cache->linkAtts == linkAtts) {      for (int i = 0;; i++) {	if (i == MetaMapCache::nNoSpec)	  return cache->map;	unsigned attIndex = cache->noSpec[i];	if (attIndex != invalidAtt && atts.specified(attIndex))	  break;      }    }  }  // no valid cached MetaMap  // Handle suppression.  unsigned oldSuppressFlags = suppressFlags;  unsigned newSuppressFlags = suppressFlags;  unsigned arcSuprIndex;  if (!isNotation)    considerSupr(atts, linkAtts, suppressFlags, newSuppressFlags, inhibitCache,		 arcSuprIndex);  else    arcSuprIndex = invalidAtt;  // Handle ArcIgnD  unsigned arcIgnDIndex;  if (!isNotation)    considerIgnD(atts, linkAtts, suppressFlags, newSuppressFlags, inhibitCache,		 arcIgnDIndex);  else    arcIgnDIndex = invalidAtt;  // Handle ArcForm.  unsigned arcFormIndex;  const Attributed *metaAttributed    = considerForm(atts, linkAtts, *nameP, isNotation,		   suppressFlags, newSuppressFlags,		   inhibitCache, arcFormIndex);  // See if there's a renamer that will inhibit cacheing.  unsigned arcNamerIndex;  const Text *namerText;  if (metaAttributed)    namerText = considerNamer(atts, inhibitCache, arcNamerIndex);  else {    arcNamerIndex = invalidAtt;    namerText = 0;  }  MetaMap *mapP;  if (inhibitCache) {    noCacheMetaMap_.clear();    mapP = &noCacheMetaMap_;  }  else {    MetaMapCache *cache = metaMapCache_[cacheIndex].pointer();    if (cache)      cache->clear();    else {      cache = new MetaMapCache;      metaMapCache_[cacheIndex] = cache;    }    cache->noSpec[0] = arcFormIndex;    cache->noSpec[1] = arcNamerIndex;    cache->noSpec[2] = arcSuprIndex;    cache->noSpec[3] = arcIgnDIndex;    cache->suppressFlags = oldSuppressFlags;    cache->linkAtts = linkAtts;    mapP = &cache->map;  }  mapP->attributed = metaAttributed;

⌨️ 快捷键说明

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