diff --git a/tools/packchk/include/CheckFiles.h b/tools/packchk/include/CheckFiles.h index b7d9d8dd2..254313c3f 100644 --- a/tools/packchk/include/CheckFiles.h +++ b/tools/packchk/include/CheckFiles.h @@ -51,6 +51,11 @@ class CheckFiles { std::string GetFullFilename(const std::string& fileName); bool GatherIncPathVsAttrConfig(RteItem* item); bool CheckAttrConfigFiles(); + bool CheckCSolutionEntries(RteItem* item); + bool CheckCsolutionLayer(RteItem* item); + bool CheckCsolutionTemplate(RteItem* item); + bool CheckForTag(RteItem* item, const std::list& searchAttributes); + private: std::string m_packagePath; diff --git a/tools/packchk/src/CheckFiles.cpp b/tools/packchk/src/CheckFiles.cpp index 9f84ae64d..2d6e2fa71 100644 --- a/tools/packchk/src/CheckFiles.cpp +++ b/tools/packchk/src/CheckFiles.cpp @@ -45,6 +45,8 @@ VISIT_RESULT CheckFilesVisitor::Visit(RteItem* item) m_checkFiles.CheckDeprecated(item); m_checkFiles.CheckDescription(item); m_checkFiles.GatherIncPathVsAttrConfig(item); + m_checkFiles.CheckCSolutionEntries(item); + return VISIT_RESULT::CONTINUE_VISIT; } @@ -421,6 +423,11 @@ bool CheckFiles::CheckFileExists(const string& fileName, int lineNo, bool associ string checkPath = GetFullFilename(fileName); + if(XmlValueAdjuster::IsAbsolute(fileName)) { + LogMsg("M326", PATH(fileName), lineNo); // error : absolute paths are not permitted + return false; + } + bool ok = true; if(!RteFsUtils::Exists(checkPath)) { if(associated) { @@ -533,7 +540,7 @@ bool CheckFiles::CheckCaseSense(const string& fileName, int lineNo) } else { string errMsg = string("file/folder \"") + seg + "\" not found"; - LogMsg("M103", VAL("REF", errMsg)); + LogMsg("M103", VAL("REF", errMsg), lineNo); return false; } } @@ -899,7 +906,6 @@ bool CheckFiles::CheckFileExtension(RteItem* item) return ok; } - bool CheckFiles::GatherIncPathVsAttrConfig(RteItem* item) { const auto file = dynamic_cast(item); @@ -952,3 +958,100 @@ bool CheckFiles::CheckAttrConfigFiles() return bOk; } +bool CheckFiles::CheckCSolutionEntries(RteItem* item) +{ + if(item->GetTag() != "csolution") { + return true; + } + + bool bOk = true; + const auto lineNo = item->GetLineNumber(); + + const auto& children = item->GetChildren(); + if(children.empty()) { + LogMsg("M100", lineNo); // No entries for %TAG% found + return false; + } + + for(const auto& child : children) { + const auto& tag = child->GetTag(); + if(tag == "clayer") { + CheckCsolutionLayer(child); + } + else if(tag == "template") { + CheckCsolutionTemplate(child); + } + } + + return bOk; +} + +bool CheckFiles::CheckForTag(RteItem* item, const list& searchAttributes) +{ + const auto lineNo = item->GetLineNumber(); + const auto& tag = item->GetTag(); + bool bOk = true; + + for(const auto& searchAttr : searchAttributes) { + if(item->GetAttribute(searchAttr) == "") { + LogMsg("M601", TAG(searchAttr), TAG2(tag), lineNo); // '%TAG%' missing on '%TAG2%' + bOk = false; + } + } + + return bOk; +} + +bool CheckFiles::CheckCsolutionLayer(RteItem* item) +{ + CheckForTag(item, list({"type", "path", "file"})); + + const auto lineNo = item->GetLineNumber(); + const auto& path = item->GetAttribute("path"); + const auto& file = item->GetAttribute("file"); + + if(!path.empty() && !file.empty()) { + const auto fileName = path + "/" + file; + CheckForSpaces(fileName, lineNo); + if(CheckFileExists(fileName, lineNo)) { + CheckCaseSense(fileName, lineNo); + CheckFileIsInPack(fileName, lineNo); + } + } + + + return true; +} + +bool CheckFiles::CheckCsolutionTemplate(RteItem* item) +{ + CheckForTag(item, list({"name", "path", "file"})); + + const auto lineNo = item->GetLineNumber(); + const auto& tag = item->GetTag(); + const auto& children = item->GetChildren(); + const auto& path = item->GetAttribute("path"); + const auto& file = item->GetAttribute("file"); + + if(!path.empty() && !file.empty()) { + const auto fileName = path + "/" + file; + CheckForSpaces(fileName, lineNo); + if(CheckFileExists(fileName, lineNo)) { + CheckCaseSense(fileName, lineNo); + CheckFileIsInPack(fileName, lineNo); + } + } + + bool bFound = false; + for(const auto child : children) { + if(child->GetTag() == "description") { + bFound = true; + } + } + + if(!bFound) { + LogMsg("M601", TAG("description"), TAG2(tag), lineNo); // '%TAG%' missing on '%TAG2%' + } + + return bFound; +} diff --git a/tools/packchk/test/data/CsolutionTag/Files/header1.h b/tools/packchk/test/data/CsolutionTag/Files/header1.h new file mode 100644 index 000000000..5c7e4f187 --- /dev/null +++ b/tools/packchk/test/data/CsolutionTag/Files/header1.h @@ -0,0 +1 @@ +//header 1 diff --git a/tools/packchk/test/data/CsolutionTag/Files/test1.c b/tools/packchk/test/data/CsolutionTag/Files/test1.c new file mode 100644 index 000000000..6904aa08d --- /dev/null +++ b/tools/packchk/test/data/CsolutionTag/Files/test1.c @@ -0,0 +1 @@ +// tests1.c diff --git a/tools/packchk/test/data/CsolutionTag/License.txt b/tools/packchk/test/data/CsolutionTag/License.txt new file mode 100644 index 000000000..86942a801 --- /dev/null +++ b/tools/packchk/test/data/CsolutionTag/License.txt @@ -0,0 +1,2 @@ +License + diff --git a/tools/packchk/test/data/CsolutionTag/TestVendor.CsolutionTag.pdsc b/tools/packchk/test/data/CsolutionTag/TestVendor.CsolutionTag.pdsc new file mode 100644 index 000000000..7fc386865 --- /dev/null +++ b/tools/packchk/test/data/CsolutionTag/TestVendor.CsolutionTag.pdsc @@ -0,0 +1,56 @@ + + + + TestVendor + https://www.testurl.com/pack/ + CsolutionTag + CsolutionTag + License.txt + + + > + Initial release of CsolutionTag. + + + + + TestInvalidPack + + + + + Test Device + + + + + + + TestGlobal + + + + + + + + + + + + + + + + + + + + diff --git a/tools/packchk/test/data/CsolutionTag/boards/myboard/cmsis/layers/baremetal/Board.clayer.yml b/tools/packchk/test/data/CsolutionTag/boards/myboard/cmsis/layers/baremetal/Board.clayer.yml new file mode 100644 index 000000000..0a52ef3c7 --- /dev/null +++ b/tools/packchk/test/data/CsolutionTag/boards/myboard/cmsis/layers/baremetal/Board.clayer.yml @@ -0,0 +1 @@ +//yaml file diff --git a/tools/packchk/test/data/CsolutionTag/boards/myboard/cmsis/templates/Device/Simple/Simple.csolution.yml b/tools/packchk/test/data/CsolutionTag/boards/myboard/cmsis/templates/Device/Simple/Simple.csolution.yml new file mode 100644 index 000000000..0a52ef3c7 --- /dev/null +++ b/tools/packchk/test/data/CsolutionTag/boards/myboard/cmsis/templates/Device/Simple/Simple.csolution.yml @@ -0,0 +1 @@ +//yaml file diff --git a/tools/packchk/test/integtests/src/PackChkIntegTests.cpp b/tools/packchk/test/integtests/src/PackChkIntegTests.cpp index f102868ba..60f34e152 100644 --- a/tools/packchk/test/integtests/src/PackChkIntegTests.cpp +++ b/tools/packchk/test/integtests/src/PackChkIntegTests.cpp @@ -1155,6 +1155,53 @@ TEST_F(PackChkIntegTests, CheckConcurrentComponentFiles) { } } +TEST_F(PackChkIntegTests, CheckCsolutionTag) { + const char* argv[3]; + + string pdscFile = PackChkIntegTestEnv::localtestdata_dir + + "/CsolutionTag/TestVendor.CsolutionTag.pdsc"; + ASSERT_TRUE(RteFsUtils::Exists(pdscFile)); + + argv[0] = (char*)""; + argv[1] = (char*)pdscFile.c_str(); + argv[2] = (char*)"--disable-validation"; + + PackChk packChk; + EXPECT_EQ(1, packChk.Check(3, argv, nullptr)); + + auto errMsgs = ErrLog::Get()->GetLogMessages(); + int M110_foundCnt = 0; + int M500_foundCnt = 0; + int M601_foundCnt = 0; + int M323_foundCnt = 0; + int M326_foundCnt = 0; + int M332_foundCnt = 0; + + for (const string& msg : errMsgs) { + if (msg.find("M110", 0) != string::npos) { + M110_foundCnt++; + } + if (msg.find("M500", 0) != string::npos) { + M500_foundCnt++; + } + if (msg.find("M601", 0) != string::npos) { + M601_foundCnt++; + } + if (msg.find("M323", 0) != string::npos) { + M323_foundCnt++; + } + if (msg.find("M326", 0) != string::npos) { + M326_foundCnt++; + } + if (msg.find("M332", 0) != string::npos) { + M332_foundCnt++; + } + } + + if(M110_foundCnt != 1 || M500_foundCnt != 2 || M601_foundCnt != 7 || M323_foundCnt != 2 || M326_foundCnt != 2 || M332_foundCnt != 2 ) { + FAIL() << "error: Missing messages testing tag"; + } +} TEST_F(PackChkIntegTests, CheckConditionComponentDependency_Pos) { const char* argv[7];