📄 parsesd.cxx
字号:
Boolean givenError; if (referencePublic(id, PublicId::CHARSET, givenError)) found = sdParseExternalCharset(*sdBuilder.sd, baseDesc); else if (!givenError) { found = 0; PublicId::OwnerType ownerType; if (id.getOwnerType(ownerType) && ownerType == PublicId::ISO) { StringC sequence; if (id.getDesignatingSequence(sequence)) { CharsetRegistry::ISORegistrationNumber number = CharsetRegistry::getRegistrationNumber(sequence, sd().internalCharset()); if (number != CharsetRegistry::UNREGISTERED) { Owner<CharsetRegistry::Iter> iter(CharsetRegistry::makeIter(number)); if (iter) { found = 1; WideChar min; WideChar max; UnivChar univ; while (iter->next(min, max, univ)) baseDesc.addRange(min, max, univ); } } } } if (!found) message(ParserMessages::unknownBaseset, StringMessageArg(id.string())); } else found = 0; if (!found) maybeISO646 = 0; decl.addSection(id); if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rDESCSET), parm)) return 0; if (!parseSdParam(AllowedSdParams(SdParam::number), parm)) return 0; do { WideChar min = parm.n; if (!parseSdParam(AllowedSdParams(SdParam::number), parm)) return 0; Number count = parm.n; Number adjCount; if (options().warnSgmlDecl && count == 0) message(ParserMessages::zeroNumberOfCharacters); decl.rangeDeclared(min, count, multiplyDeclared); if (isDocument && count > 0 && (min > charMax || count - 1 > charMax - min)) { message(ParserMessages::documentCharMax, NumberMessageArg(charMax)); adjCount = min > charMax ? 0 : 1 + (charMax - min); maybeISO646 = 0; } else adjCount = count; if (!parseSdParam(AllowedSdParams(SdParam::number, SdParam::minimumLiteral, SdParam::reservedName + Sd::rUNUSED), parm)) return 0; switch (parm.type) { case SdParam::number: decl.addRange(min, count, parm.n); if (found && adjCount > 0) { ISet<WideChar> baseMissing; desc.addBaseRange(baseDesc, min, min + (adjCount - 1), parm.n, baseMissing); if (!baseMissing.isEmpty() && options().warnSgmlDecl) message(ParserMessages::basesetCharsMissing, CharsetMessageArg(baseMissing)); } break; case SdParam::reservedName + Sd::rUNUSED: decl.addRange(min, count); break; case SdParam::minimumLiteral: { UnivChar c = charNameToUniv(*sdBuilder.sd, parm.literalText.string()); if (adjCount > 256) { message(ParserMessages::tooManyCharsMinimumLiteral); adjCount = 256; } for (Number i = 0; i < adjCount; i++) desc.addRange(min + i, min + i, c); } maybeISO646 = 0; decl.addRange(min, count, parm.literalText.string()); break; default: CANNOT_HAPPEN(); } SdParam::Type follow = (isDocument ? SdParam::reservedName + Sd::rCAPACITY : SdParam::reservedName + Sd::rFUNCTION); if (!parseSdParam(AllowedSdParams(SdParam::number, SdParam::reservedName + Sd::rBASESET, follow), parm)) return 0; } while (parm.type == SdParam::number); } while (parm.type == SdParam::reservedName + Sd::rBASESET); if (!multiplyDeclared.isEmpty()) message(ParserMessages::duplicateCharNumbers, CharsetMessageArg(multiplyDeclared)); ISet<WideChar> declaredSet; decl.declaredSet(declaredSet); ISetIter<WideChar> iter(declaredSet); WideChar min, max, lastMax; if (iter.next(min, max)) { ISet<WideChar> holes; lastMax = max; while (iter.next(min, max)) { if (min - lastMax > 1) holes.addRange(lastMax + 1, min - 1); lastMax = max; } if (!holes.isEmpty()) message(ParserMessages::codeSetHoles, CharsetMessageArg(holes)); } if (!isDocument && sdBuilder.sd->scopeInstance()) { // If scope is INSTANCE, syntax reference character set // must be same as reference. UnivCharsetDescIter iter(desc); WideChar descMin, descMax; UnivChar univMin; Char nextDescMin = 0; while (maybeISO646) { if (!iter.next(descMin, descMax, univMin)) { if (nextDescMin != 128) maybeISO646 = 0; break; } if (descMin != nextDescMin || univMin != descMin) maybeISO646 = 0; nextDescMin = descMax + 1; } if (!maybeISO646) message(ParserMessages::scopeInstanceSyntaxCharset); } return 1;}Boolean Parser::sdParseExternalCharset(Sd &sd, UnivCharsetDesc &desc){ SdParam parm; for (;;) { if (!parseSdParam(AllowedSdParams(SdParam::number, SdParam::eE), parm)) break; if (parm.type == SdParam::eE) return 1; WideChar min = parm.n; if (!parseSdParam(AllowedSdParams(SdParam::number), parm)) break; Number count = parm.n; if (!parseSdParam(AllowedSdParams(SdParam::number, SdParam::minimumLiteral, SdParam::reservedName + Sd::rUNUSED), parm)) break; if (parm.type == SdParam::number) { if (count > 0) desc.addRange(min, min + (count - 1), parm.n); } else if (parm.type == SdParam::minimumLiteral) { UnivChar c = charNameToUniv(sd, parm.literalText.string()); if (count > 256) { message(ParserMessages::tooManyCharsMinimumLiteral); count = 256; } for (Number i = 0; i < count; i++) desc.addRange(min + i, min + i, c); } } popInputStack(); return 0;}UnivChar Parser::charNameToUniv(Sd &sd, const StringC &name){ UnivChar univ; if (entityCatalog().lookupChar(name, sd.internalCharset(), messenger(), univ)) return univ; else return sd.nameToUniv(name);}Boolean Parser::sdParseCapacity(SdBuilder &sdBuilder, SdParam &parm){ if (!parseSdParam(sdBuilder.www ? AllowedSdParams(SdParam::reservedName + Sd::rNONE, SdParam::reservedName + Sd::rPUBLIC, SdParam::reservedName + Sd::rSGMLREF) : AllowedSdParams(SdParam::reservedName + Sd::rPUBLIC, SdParam::reservedName + Sd::rSGMLREF), parm)) return 0;#if _MSC_VER == 1100 // Workaround for Visual C++ 5.0 bug int#else Boolean#endif pushed = 0; if (parm.type == SdParam::reservedName + Sd::rNONE) return parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rSCOPE), parm); if (parm.type == SdParam::reservedName + Sd::rPUBLIC) { if (!parseSdParam(AllowedSdParams(SdParam::minimumLiteral), parm)) return 0; PublicId id; PublicId::TextClass textClass; const MessageType1 *err; if (!id.init(parm.literalText, sd().internalCharset(), syntax().space(), err)) sdBuilder.addFormalError(currentLocation(), *err, id.string()); else if (id.getTextClass(textClass) && textClass != PublicId::CAPACITY) sdBuilder.addFormalError(currentLocation(), ParserMessages::capacityTextClass, id.string()); const StringC &str = id.string(); if (str != sd().execToInternal("ISO 8879-1986//CAPACITY Reference//EN") && str != sd().execToInternal("ISO 8879:1986//CAPACITY Reference//EN")) { Boolean givenError; if (referencePublic(id, PublicId::CAPACITY, givenError)) pushed = 1; else if (!givenError) message(ParserMessages::unknownCapacitySet, StringMessageArg(str)); } if (!pushed) return parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rSCOPE), parm); } PackedBoolean capacitySpecified[Sd::nCapacity]; int i; for (i = 0; i < Sd::nCapacity; i++) capacitySpecified[i] = 0; if (!parseSdParam(AllowedSdParams(SdParam::capacityName), parm)) return 0; do { Sd::Capacity capacityIndex = parm.capacityIndex; if (!parseSdParam(AllowedSdParams(SdParam::number), parm)) return 0; if (!capacitySpecified[capacityIndex]) { sdBuilder.sd->setCapacity(capacityIndex, parm.n); capacitySpecified[capacityIndex] = 1; } else if (options().warnSgmlDecl) message(ParserMessages::duplicateCapacity, StringMessageArg(sd().capacityName(i))); int final = pushed ? int(SdParam::eE) : SdParam::reservedName + Sd::rSCOPE; if (!parseSdParam(AllowedSdParams(SdParam::capacityName, final), parm)) return 0; } while (parm.type == SdParam::capacityName); Number totalcap = sdBuilder.sd->capacity(0); for (i = 1; i < Sd::nCapacity; i++) if (sdBuilder.sd->capacity(i) > totalcap) message(ParserMessages::capacityExceedsTotalcap, StringMessageArg(sd().capacityName(i))); if (pushed) return parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rSCOPE), parm); return 1;}Boolean Parser::referencePublic(const PublicId &id, PublicId::TextClass entityType, Boolean &givenError){ givenError = 0; StringC sysid; if (entityCatalog().lookupPublic(id.string(), sd().internalCharset(), messenger(), sysid)) { Location loc = currentLocation(); eventHandler().sgmlDeclEntity(new (eventAllocator()) SgmlDeclEntityEvent(id, entityType, sysid, loc)); Ptr<EntityOrigin> origin(EntityOrigin::make(internalAllocator(), ConstPtr<Entity>(0), loc)); if (currentMarkup()) currentMarkup()->addEntityStart(origin); InputSource *in = entityManager().open(sysid, sd().docCharset(), origin.pointer(), 0, messenger()); if (!in) { givenError = 1; return 0; } pushInput(in); return 1; } return 0;}Boolean Parser::sdParseScope(SdBuilder &sdBuilder, SdParam &parm){ if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rINSTANCE, SdParam::reservedName + Sd::rDOCUMENT), parm)) return 0; if (parm.type == SdParam::reservedName + Sd::rINSTANCE) sdBuilder.sd->setScopeInstance(); return 1;}Boolean Parser::sdParseSyntax(SdBuilder &sdBuilder, SdParam &parm){ if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rSYNTAX), parm)) return 0; if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rSHUNCHAR, SdParam::reservedName + Sd::rPUBLIC), parm)) return 0; if (parm.type == SdParam::reservedName + Sd::rPUBLIC) { if (!parseSdParam(AllowedSdParams(SdParam::minimumLiteral), parm)) return 0; PublicId id; const MessageType1 *err; PublicId::TextClass textClass; if (!id.init(parm.literalText, sd().internalCharset(), syntax().space(), err)) sdBuilder.addFormalError(currentLocation(), *err, id.string()); else if (id.getTextClass(textClass) && textClass != PublicId::SYNTAX) sdBuilder.addFormalError(currentLocation(), ParserMessages::syntaxTextClass, id.string()); if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rFEATURES, SdParam::reservedName + Sd::rSWITCHES), parm)) return 0; Vector<UnivChar> charSwitches; if (parm.type == SdParam::reservedName + Sd::rSWITCHES) { if (!parseSdParam(AllowedSdParams(SdParam::number), parm)) return 0; for (;;) { SyntaxChar c = parm.n; if (!parseSdParam(AllowedSdParams(SdParam::number), parm)) return 0; sdBuilder.switcher.addSwitch(c, parm.n); if (!parseSdParam(AllowedSdParams(SdParam::number, SdParam::reservedName + Sd::rFEATURES), parm)) return 0; if (parm.type != SdParam::number) break; } } const StandardSyntaxSpec *spec = lookupSyntax(id); if (spec) { if (!setStandardSyntax(*sdBuilder.syntax, *spec, sdBuilder.sd->internalCharset(), sdBuilder.switcher, sdBuilder.www)) sdBuilder.valid = 0; } else { Boolean givenError; if (referencePublic(id, PublicId::SYNTAX, givenError)) { sdBuilder.externalSyntax = 1; SdParam parm2; if (!parseSdParam(AllowedSdParams(SdParam::reservedName + Sd::rSHUNCHAR), parm2)) return 0; if (!sdParseExplicitSyntax(sdBuilder, parm2)) return 0; } else { if (!givenError) message(ParserMessages::unknownPublicSyntax, StringMessageArg(id.string())); sdBuilder.valid = 0; } } } else { if (!sdParseExplicitSyntax(sdBuilder, parm)) return 0; } if (!sdBuilder.sd->scopeInstance()) { // we know the significant chars now ISet<WideChar> invalidSgmlChar; sdBuilder.syntax->checkSgmlChar(*sdBuilder.sd, 0, 1, invalidSgmlChar); if (!invalidSgmlChar.isEmpty()) message(ParserMessages::invalidSgmlChar, CharsetMessageArg(invalidSgmlChar)); } checkSyntaxNamelen(*sdBuilder.syntax); checkSwitchesMarkup(sdBuilder.switcher); return 1;}Boolean Parser::sdParseExplicitSyntax(SdBuilder &sdBuilder, SdParam &parm){ typedef Boolean (Parser::*SdParser)(SdBuilder &, SdParam &); static SdParser parsers[] = { &Parser::sdParseShunchar, &Parser::sdParseSyntaxCharset, &Parser::sdParseFunction, &Parser::sdParseNaming, &Parser::sdParseDelim, &Parser::sdParseNames, &Parser::sdParseQuantity }; for (size_t i = 0; i < SIZEOF(parsers); i++) if (!(this->*(parsers[i]))(sdBuilder, parm)) return 0; return 1;}const StandardSyntaxSpec *Parser::lookupSyntax(const PublicId &id){ PublicId::OwnerType ownerType; if (!id.getOwnerType(ownerType) || ownerType != PublicId::ISO) return 0; StringC str; if (!id.getOwner(str)) return 0; if (str != sd().execToInternal("ISO 8879:1986") && str != sd().execToInternal("ISO 8879-1986")) return 0; PublicId::TextClass textClass; if (!id.getTextClass(textClass) || textClass != PublicId::SYNTAX) return 0; if (!id.getDescription(str)) return 0; if (str == sd().execToInternal("Reference")) return &refSyntax; if (str == sd().execToInternal("Core")) return &coreSyntax; return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -