Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion libs/rtefsutils/include/RteFsUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
/******************************************************************************/
/*
* Copyright (c) 2020-2024 Arm Limited. All rights reserved.
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -84,6 +84,15 @@ class RteFsUtils
* @return true if copying file is processed
*/
static bool CopyMergeFile(const std::string& src, const std::string& dst, int nInstance, bool backup);

/**
* @brief compare files content with normalized line endings
* @param fileName1 name of first file to be compared
* @param fileName2 name of second file to be compared
* @return true if files are equal
*/
static bool CmpFiles(const std::string& fileName1, const std::string& fileName2);

/**
* @brief compare file content with given string 'buffer'
* @param fileName name of file to be compared
Expand Down
12 changes: 11 additions & 1 deletion libs/rtefsutils/src/RteFsUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
/******************************************************************************/
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -104,6 +104,16 @@ bool RteFsUtils::ReadFile(const string& fileName, string& buffer) {
return true;
}

bool RteFsUtils::CmpFiles(const string& fileName1, const string& fileName2) {

// Open files and read content
string fileBuffer1, fileBuffer2;
if (!ReadFile(fileName1, fileBuffer1) || !ReadFile(fileName2, fileBuffer2)) {
return false;
}
// Compare buffer contents with normalized line endings
return RteUtils::EnsureLf(fileBuffer1) == RteUtils::EnsureLf(fileBuffer2);
}

bool RteFsUtils::CmpFileMem(const string& fileName, const string& buffer) {

Expand Down
21 changes: 20 additions & 1 deletion libs/rtefsutils/test/src/RteFsUtilsTest.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -165,6 +165,25 @@ TEST_F(RteFsUtilsTest, BackupFile) {
RteFsUtils::RemoveFile(filenameRegular);
}

TEST_F(RteFsUtilsTest, CmpFiles) {
// Test files with same content
RteFsUtils::CreateTextFile(filenameRegular, bufferFoo);
RteFsUtils::CreateTextFile(filenameRegularCopy, bufferFoo);
EXPECT_TRUE(RteFsUtils::CmpFiles(filenameRegular, filenameRegularCopy));

// Test files with different content
RteFsUtils::CreateTextFile(filenameRegularCopy, bufferBar);
EXPECT_FALSE(RteFsUtils::CmpFiles(filenameRegular, filenameRegularCopy));

// Test missing file2
RteFsUtils::RemoveFile(filenameRegularCopy);
EXPECT_FALSE(RteFsUtils::CmpFiles(filenameRegular, filenameRegularCopy));

// Test missing file1
RteFsUtils::RemoveFile(filenameRegular);
EXPECT_FALSE(RteFsUtils::CmpFiles(filenameRegular, filenameRegularCopy));
}

TEST_F(RteFsUtilsTest, CmpFileMem) {
bool ret;

Expand Down
15 changes: 12 additions & 3 deletions libs/rtemodel/src/RteProject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
/******************************************************************************/
/*
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -696,8 +696,17 @@ void RteProject::UpdateConfigFileBackups(RteFileInstance* fi, RteItem* f)
// copy current file if version differs
string updateFile = RteUtils::AppendFileUpdateVersion(absPath, updateVersion);
if (!baseFile.empty() && baseVersion != updateVersion) { // only copy update if base exists
RteFsUtils::CopyMergeFile(src, updateFile, fi->GetInstanceIndex(), false);
RteFsUtils::SetFileReadOnly(updateFile, true);
if (RteFsUtils::CmpFiles(baseFile, src)) {
// if base and update contents are equal, rebase it
const string rebaseFile = RteUtils::AppendFileBaseVersion(absPath, updateVersion);
RteFsUtils::MoveFileExAutoRetry(baseFile, rebaseFile);
fi->SetAttribute("version", updateVersion.c_str());
baseFile = rebaseFile;
updateFile.clear();
} else {
RteFsUtils::CopyMergeFile(src, updateFile, fi->GetInstanceIndex(), false);
RteFsUtils::SetFileReadOnly(updateFile, true);
}
} else {
updateFile.clear(); // no need in that
}
Expand Down
7 changes: 4 additions & 3 deletions libs/rtemodel/test/src/RteModelTest.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -714,10 +714,11 @@ TEST_F(RteModelPrjTest, LoadCprjConfigVer) {

const string deviceDir = rteDir + "Device/RteTest_ARMCM3/";
EXPECT_TRUE(RteFsUtils::Exists(deviceDir + "ARMCM3_ac6.sct"));
EXPECT_TRUE(RteFsUtils::Exists(deviceDir + "ARMCM3_ac6.sct.base@1.0.0"));
// content of update file is equal to the base file, rebase the version to 1.2.0
EXPECT_TRUE(RteFsUtils::Exists(deviceDir + "ARMCM3_ac6.sct.base@1.2.0"));
// check if file version is taken from base file (project contains "5.5.5")
RteFileInstance* fi = loadedCprjProject->GetFileInstance("CONFIG_FOLDER/Device/RteTest_ARMCM3/ARMCM3_ac6.sct");
EXPECT_TRUE(fi && fi->GetVersionString() == "1.0.0");
EXPECT_TRUE(fi && fi->GetVersionString() == "1.2.0");

EXPECT_TRUE(RteFsUtils::Exists(deviceDir + "startup_ARMCM3.c.base@2.0.3"));
EXPECT_TRUE(RteFsUtils::Exists(deviceDir + "system_ARMCM3.c.base@1.0.1"));
Expand Down
9 changes: 1 addition & 8 deletions tools/projmgr/include/ProjMgrUtils.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -314,13 +314,6 @@ class ProjMgrUtils {
*/
static const std::string FileTypeFromExtension(const std::string& file);

/**
* @brief normalize line endings for consistent string comparison
* @param input string
* @return output normalized string
*/
static const std::string NormalizeLineEndings(const std::string& in);

/**
* @brief convert board string to west board string
* @param board string
Expand Down
15 changes: 1 addition & 14 deletions tools/projmgr/src/ProjMgrUtils.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -486,19 +486,6 @@ const string ProjMgrUtils::FileTypeFromExtension(const string& file) {
return RteUtils::EMPTY_STRING;
}

const std::string ProjMgrUtils::NormalizeLineEndings(const std::string& in) {
string out = in;
size_t pos = 0;
while ((pos = out.find("\r\n", pos)) != std::string::npos) {
out.replace(pos++, 2, "\n");
}
pos = 0;
while ((pos = out.find("\r", pos)) != std::string::npos) {
out.replace(pos, 1, "\n");
}
return out;
}

const std::string ProjMgrUtils::GetWestBoard(const std::string& board) {
string westBoard = RteUtils::StripSuffix(RteUtils::StripPrefix(board, "::"));
std::transform(westBoard.begin(), westBoard.end(), westBoard.begin(),
Expand Down
6 changes: 3 additions & 3 deletions tools/projmgr/src/ProjMgrYamlEmitter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2024 Arm Limited. All rights reserved.
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -94,8 +94,8 @@ bool ProjMgrYamlEmitter::CompareFile(const string& filename, const YAML::Node& r
}
YAML::Emitter emitter;
const auto& outBuffer = string((emitter << rootNode).c_str()) + '\n';
return ProjMgrUtils::NormalizeLineEndings(inBuffer) ==
ProjMgrUtils::NormalizeLineEndings(outBuffer);
return RteUtils::EnsureLf(inBuffer) ==
RteUtils::EnsureLf(outBuffer);
}

bool ProjMgrYamlEmitter::CompareNodes(const YAML::Node& lhs, const YAML::Node& rhs) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* Dummy file */
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/******************************************************************************
* @file startup_ARMCM3.c
* @brief CMSIS-Core(M) Device Startup File for a Cortex-M3 Device
* @version V2.0.3
* @date 31. March 2020
******************************************************************************/
/*
* Copyright (c) 2009-2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#if defined (ARMCM3)
#include "ARMCM3.h"
#else
#error device not specified!
#endif


#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
#endif

/*----------------------------------------------------------------------------
Reset Handler called on controller reset
*----------------------------------------------------------------------------*/
void Reset_Handler(void)
{
}

/*----------------------------------------------------------------------------
Hard Fault Handler
*----------------------------------------------------------------------------*/
void HardFault_Handler(void)
{
while(1);
}

/*----------------------------------------------------------------------------
Default Handler for Exceptions / Interrupts
*----------------------------------------------------------------------------*/
void Default_Handler(void)
{
while(1);
}

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic pop
#endif

Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ solution:
- type: Patch
- type: Minor
- type: Major
- type: BaseUnknown
- type: BaseUnknown
- type: Missing
- type: Rebase

target-types:
- type: RteTest_ARMCM3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/******************************************************************************
* @file startup_ARMCM0.c
* @brief CMSIS-Core(M) Device Startup File for a Cortex-M0 Device
* @version V2.0.3
* @version V2.0.2
* @date 31. March 2020
******************************************************************************/
/*
Expand Down
15 changes: 15 additions & 0 deletions tools/projmgr/test/src/ProjMgrUnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6627,6 +6627,21 @@ TEST_F(ProjMgrUnitTests, ConfigFilesUpdate) {
}
}

TEST_F(ProjMgrUnitTests, ConfigFilesUpdateRebase) {
StdStreamRedirect streamRedirect;
char* argv[6];
const string& csolution = testinput_folder + "/TestSolution/ConfigFilesUpdate/config.csolution.yml";
argv[1] = (char*)"convert";
argv[2] = (char*)csolution.c_str();
argv[3] = (char*)"-c";
argv[4] = (char*)".Rebase";
EXPECT_EQ(0, RunProjMgr(5, argv, m_envp));
EXPECT_TRUE(RteFsUtils::Exists(testinput_folder + "/TestSolution/ConfigFilesUpdate/Rebase/Device/RteTest_ARMCM3/startup_ARMCM3.c.base@2.0.3"));
EXPECT_FALSE(RteFsUtils::Exists(testinput_folder + "/TestSolution/ConfigFilesUpdate/Rebase/Device/RteTest_ARMCM3/startup_ARMCM3.c.base@1.0.0"));
auto errStr = streamRedirect.GetErrorString();
EXPECT_FALSE(regex_search(errStr, regex("startup_ARMCM3")));
}

TEST_F(ProjMgrUnitTests, RegionsFileGeneration) {
char* argv[3];
const string& csolution = testinput_folder + "/TestMemoryRegions/regions.csolution.yml";
Expand Down
10 changes: 1 addition & 9 deletions tools/projmgr/test/src/ProjMgrUtilsUnitTests.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -531,11 +531,3 @@ TEST_F(ProjMgrUtilsUnitTests, ULLToHex) {
EXPECT_EQ("0xDEADBEEF", ProjMgrUtils::ULLToHex(3735928559));
EXPECT_EQ("0xFFFFFFFF", ProjMgrUtils::ULLToHex(4294967295));
}

TEST_F(ProjMgrUtilsUnitTests, NormalizeLineEndings) {
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\r\ndef\r\n"));
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\rdef\r"));
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\rdef\n"));
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\ndef\r"));
EXPECT_EQ("abc\ndef\n", ProjMgrUtils::NormalizeLineEndings("abc\ndef\n"));
}
Loading