diff --git a/distr/app/UpdateLog.txt b/distr/app/UpdateLog.txt index c51f691..2cdfaf2 100644 --- a/distr/app/UpdateLog.txt +++ b/distr/app/UpdateLog.txt @@ -1,3 +1,5 @@ +30.08.2024 Экстеор 4.9.4 +• исправлена загрузка файлов версий 2017-2020 годов 14.06.2024 Экстеор 4.9.3 • Грамматика: разрешено использование одного аргумента для мультифильтра - Fi1,2[X1*X1](S1) • исправлена ошибка, приводившая к некорректному вычислению типизаций рекурсии с пустым множеством diff --git a/include/Exteor.RC b/include/Exteor.RC index 18c1902..5714b63 100644 --- a/include/Exteor.RC +++ b/include/Exteor.RC @@ -1182,8 +1182,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,9,3,1000 - PRODUCTVERSION 4,9,3,1000 + FILEVERSION 4,9,4,1000 + PRODUCTVERSION 4,9,4,1000 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -1201,13 +1201,13 @@ BEGIN VALUE "Comments", " " VALUE "CompanyName", " " VALUE "FileDescription", " 4.9" - VALUE "FileVersion", "4.9.3.1000" + VALUE "FileVersion", "4.9.4.1000" VALUE "InternalName", " 4.9" VALUE "LegalCopyright", "Copyright NPMP CIHT CONCEPT 1994-2024" VALUE "LegalTrademarks", "" VALUE "OriginalFilename", "Exteor.exe" VALUE "ProductName", " 4.9" - VALUE "ProductVersion", "4.9.3.1000" + VALUE "ProductVersion", "4.9.4.1000" END END BLOCK "VarFileInfo" diff --git a/src/io/TRSLegacyLoader.cpp b/src/io/TRSLegacyLoader.cpp index 5d23594..bc3991b 100644 --- a/src/io/TRSLegacyLoader.cpp +++ b/src/io/TRSLegacyLoader.cpp @@ -4,6 +4,11 @@ #include "xtr/core/Encoder.h" +#include +#include +#include +#include + using ccl::semantic::ConceptRecord; using ccl::semantic::CstType; using ccl::lang::ManagedText; @@ -11,6 +16,40 @@ using ccl::lang::LexicalTerm; namespace xtr::io { +namespace details { + static void FixOldReferences(std::string& target) { + static const std::regex referencePattern(R"(\@\{([A-Z]\d+)\|([A-Z]+)\|([A-Z]+)\|\d+\})"); + std::vector> replacements{}; + std::sregex_iterator iter(target.begin(), target.end(), referencePattern); + std::sregex_iterator end{}; + while (iter != end) { + std::smatch match = *iter; + + std::string part1 = match[1].str(); // e.g., "D4" + std::string part2 = match[2].str(); // e.g., "ABLT" + std::string part3 = match[3].str(); // e.g., "PLUR" + + std::transform(part2.begin(), part2.end(), part2.begin(), + [](unsigned char c) { return static_cast(std::tolower(c)); }); + std::transform(part3.begin(), part3.end(), part3.begin(), + [](unsigned char c) { return static_cast(std::tolower(c)); }); + + std::string newReference = "@{" + part1 + "|" + part2 + "," + part3 + "}"; + + replacements.emplace_back(match.str(), newReference); + + iter++; + } + for (const auto& [oldRef, newRef] : replacements) { + size_t pos = 0; + while ((pos = target.find(oldRef, pos)) != std::string::npos) { + target.replace(pos, oldRef.length(), newRef); + pos += newRef.length(); + } + } + } +} + void LegacyCstLoader::LoadBasicProperties(BOOL oldType) { const auto sName = ar.Load(); auto sComment = ar.Load(); @@ -73,11 +112,14 @@ void LegacyCstLoader::LoadTerms(const BOOL hasTerms, const BOOL multipleTerms) { termRefs.at(0) = terms.at(0); } - cst->term = LexicalTerm{ mfc::ToSTL(termRefs.at(0)), mfc::ToSTL(terms.at(0)) }; + auto termRaw = mfc::ToSTL(termRefs.at(0)); + details::FixOldReferences(termRaw); + cst->term = LexicalTerm{ termRaw, mfc::ToSTL(terms.at(0)) }; for (uint8_t j = 0; j < size(TERM_FORMS); ++j) { - const auto formText = mfc::ToSTL(termForms.at(0).at(j)); - if (!formText.empty()) { - cst->term.SetForm(TERM_FORMS.at(j), formText); + auto manualForm = mfc::ToSTL(termForms.at(0).at(j)); + if (!manualForm.empty()) { + details::FixOldReferences(manualForm); + cst->term.SetForm(TERM_FORMS.at(j), manualForm); } } } @@ -91,7 +133,9 @@ void LegacyCstLoader::LoadInterpretation(const BOOL loadWithRef) { if (needEncoding) { encode::EncodeToUnicode(sInterpretation); } - cst->definition = ManagedText{ mfc::ToSTL(sInterpretationRef), mfc::ToSTL(sInterpretation) }; + auto interpretationRaw = mfc::ToSTL(sInterpretationRef); + details::FixOldReferences(interpretationRaw); + cst->definition = ManagedText{ interpretationRaw, mfc::ToSTL(sInterpretation) }; } void LegacyCstLoader::LoadID() { @@ -120,7 +164,8 @@ void LegacyCoreLoader::DoLoad(ccl::semantic::RSCore& core) { } ccl::lang::ManagedText LegacyCoreLoader::LoadText() { - const auto rawText = ar.Load(); + auto rawText = ar.Load(); + details::FixOldReferences(rawText); const auto cache = ar.Load(); return ccl::lang::ManagedText{ rawText, cache }; } @@ -129,8 +174,9 @@ ccl::lang::LexicalTerm LegacyCoreLoader::LoadTerm() { using ccl::lang::TERM_FORMS; ccl::lang::LexicalTerm term{ LoadText() }; for (uint8_t j = 0; j < size(TERM_FORMS); ++j) { - const auto manualForm = ar.Load(); + auto manualForm = ar.Load(); if (!std::empty(manualForm)) { + details::FixOldReferences(manualForm); term.SetForm(TERM_FORMS.at(j), manualForm); } } diff --git a/test/Data/Model/TestCalculate.rsm b/test/Data/Model/TestCalculate.rsm new file mode 100644 index 0000000..ab4fb8c Binary files /dev/null and b/test/Data/Model/TestCalculate.rsm differ diff --git a/test/Data/Тест_Модели/TestCalculate.rsm b/test/Data/Тест_Модели/TestCalculate.rsm deleted file mode 100644 index 2945315..0000000 Binary files a/test/Data/Тест_Модели/TestCalculate.rsm and /dev/null differ diff --git a/test/src/testDocuments.cpp b/test/src/testDocuments.cpp index 5f38f4f..b86ec12 100644 --- a/test/src/testDocuments.cpp +++ b/test/src/testDocuments.cpp @@ -152,7 +152,7 @@ TEST_F(UTDocuments, RSModelSaveLoad) { TEST_F(UTDocuments, RSModelCalculate) { MockRSModelDoc document{}; - const auto filePath = ::LocalPathToGlobal(LR"(Data\Тест_Модели\TestCalculate.rsm)"); + const auto filePath = ::LocalPathToGlobal(LR"(Data\Model\TestCalculate.rsm)"); ASSERT_TRUE(document.LoadFrom(filePath)); document.model->Calculations().RecalculateAll(); EXPECT_EQ(document.model->Calculations().Count(ccl::semantic::EvalStatus::AXIOM_FAIL), 0U);