Skip to content

Commit 293058c

Browse files
authored
Merge branch 'main' into main
2 parents 2997d03 + 8a92e99 commit 293058c

73 files changed

Lines changed: 13012 additions & 12504 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ daisuke-chiba
101101
Daniel Friedrich
102102
David Korczynski
103103
Daniel Marjamäki
104+
Daschle Newberry
104105
David Hallas
105106
David Korth
106107
Dávid Slivka

cfg/qt.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5520,7 +5520,7 @@
55205520
<define name="Q_OVERRIDE(x)" value=""/>
55215521
<define name="Q_PLUGIN_METADATA(x)" value=""/>
55225522
<define name="Q_ASSERT(condition)" value="assert(condition)"/>
5523-
<define name="Q_ASSERT_X(condition, where, what)" value="assert(condition)"/>
5523+
<define name="Q_ASSERT_X(condition, where, what)" value="assert(condition); (void)(where); (void)(what)"/>
55245524
<define name="QTC_ASSERT_STRINGIFY_HELPER(x)" value="#x"/>
55255525
<define name="QTC_ASSERT_STRINGIFY(x)" value="QTC_ASSERT_STRINGIFY_HELPER(x)"/>
55265526
<define name="QTC_ASSERT_STRING(cond)" value="::Utils::writeAssertLocation( &quot;\&quot;&quot; cond&quot;\&quot; in file &quot; __FILE__ &quot;, line &quot; QTC_ASSERT_STRINGIFY(__LINE__))"/>

externals/simplecpp/simplecpp.cpp

Lines changed: 201 additions & 61 deletions
Large diffs are not rendered by default.

externals/simplecpp/simplecpp.h

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@
6060
# endif
6161
#endif
6262

63+
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 9
64+
// Hack to workaround GCC bug.
65+
// Details: https://trac.cppcheck.net/ticket/14850
66+
// seen on g++ before 10.x
67+
#define SIMPLECPP_NOEXCEPT
68+
#else
69+
#define SIMPLECPP_NOEXCEPT noexcept
70+
#endif
71+
6372
namespace simplecpp {
6473
/** C code standard */
6574
enum cstd_t : std::int8_t { CUnknown=-1, C89, C99, C11, C17, C23, C2Y };
@@ -238,7 +247,10 @@ namespace simplecpp {
238247
MISSING_HEADER,
239248
INCLUDE_NESTED_TOO_DEEPLY,
240249
SYNTAX_ERROR,
250+
DIRECTIVE_AS_MACRO_PARAMETER,
241251
PORTABILITY_BACKSLASH,
252+
PORTABILITY_LINE_DIRECTIVE,
253+
PORTABILITY_NO_EOF_NEWLINE,
242254
UNHANDLED_CHAR_ERROR,
243255
EXPLICIT_INCLUDE_NOT_FOUND,
244256
FILE_NOT_FOUND,
@@ -251,52 +263,67 @@ namespace simplecpp {
251263

252264
using OutputList = std::list<Output>;
253265

266+
/**
267+
* Command line preprocessor settings.
268+
* On the command line these are configured by -D, -U, -I, --include, -std
269+
*/
270+
struct SIMPLECPP_LIB DUI {
271+
DUI() = default;
272+
std::list<std::string> defines;
273+
std::set<std::string> undefined;
274+
std::list<std::string> includePaths;
275+
std::list<std::string> includes;
276+
std::string std;
277+
bool clearIncludeCache{};
278+
bool removeComments{}; /** remove comment tokens from included files */
279+
};
280+
254281
/** List of tokens. */
255282
class SIMPLECPP_LIB TokenList {
256283
public:
257284
class Stream;
258285

259286
explicit TokenList(std::vector<std::string> &filenames);
260287
/** generates a token list from the given std::istream parameter */
261-
TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr);
288+
TokenList(std::istream &istr, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr);
262289
/** generates a token list from the given buffer */
263290
template<size_t size>
264-
TokenList(const char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
265-
: TokenList(reinterpret_cast<const unsigned char*>(data), size-1, filenames, filename, outputList, 0)
291+
TokenList(const char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
292+
: TokenList(reinterpret_cast<const unsigned char*>(data), size-1, filenames, filename, dui, outputList, 0)
266293
{}
267294
/** generates a token list from the given buffer */
268295
template<size_t size>
269-
TokenList(const unsigned char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
270-
: TokenList(data, size-1, filenames, filename, outputList, 0)
296+
TokenList(const unsigned char (&data)[size], std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
297+
: TokenList(data, size-1, filenames, filename, dui, outputList, 0)
271298
{}
272299
#if SIMPLECPP_TOKENLIST_ALLOW_PTR
273300
/** generates a token list from the given buffer */
274-
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
275-
: TokenList(data, size, filenames, filename, outputList, 0)
301+
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
302+
: TokenList(data, size, filenames, filename, dui, outputList, 0)
276303
{}
277304
/** generates a token list from the given buffer */
278-
TokenList(const char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
279-
: TokenList(reinterpret_cast<const unsigned char*>(data), size, filenames, filename, outputList, 0)
305+
TokenList(const char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
306+
: TokenList(reinterpret_cast<const unsigned char*>(data), size, filenames, filename, dui, outputList, 0)
280307
{}
281308
#endif // SIMPLECPP_TOKENLIST_ALLOW_PTR
282309
/** generates a token list from the given buffer */
283-
TokenList(View data, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
284-
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, outputList, 0)
310+
TokenList(View data, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
311+
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, dui, outputList, 0)
285312
{}
286313
#ifdef __cpp_lib_span
287314
/** generates a token list from the given buffer */
288-
TokenList(std::span<const char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
289-
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, outputList, 0)
315+
TokenList(std::span<const char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
316+
: TokenList(reinterpret_cast<const unsigned char*>(data.data()), data.size(), filenames, filename, dui, outputList, 0)
290317
{}
291318

292319
/** generates a token list from the given buffer */
293-
TokenList(std::span<const unsigned char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), OutputList *outputList = nullptr)
294-
: TokenList(data.data(), data.size(), filenames, filename, outputList, 0)
320+
TokenList(std::span<const unsigned char> data, std::vector<std::string> &filenames, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr)
321+
: TokenList(data.data(), data.size(), filenames, filename, dui, outputList, 0)
295322
{}
296323
#endif // __cpp_lib_span
297324

298325
/** generates a token list from the given filename parameter */
299-
TokenList(const std::string &filename, std::vector<std::string> &filenames, OutputList *outputList = nullptr);
326+
TokenList(const std::string &filename, std::vector<std::string> &filenames, const DUI &dui = {}, OutputList *outputList = nullptr);
300327
TokenList(const TokenList &other);
301328
TokenList(TokenList &&other);
302329
~TokenList();
@@ -312,7 +339,7 @@ namespace simplecpp {
312339
void dump(bool linenrs = false) const;
313340
std::string stringify(bool linenrs = false) const;
314341

315-
void readfile(Stream &stream, const std::string &filename=std::string(), OutputList *outputList = nullptr);
342+
void readfile(Stream &stream, const std::string &filename=std::string(), const DUI &dui = {}, OutputList *outputList = nullptr);
316343
/**
317344
* @throws std::overflow_error thrown on overflow or division by zero
318345
* @throws std::runtime_error thrown on invalid expressions
@@ -376,7 +403,7 @@ namespace simplecpp {
376403
const std::string& file(const Location& loc) const;
377404

378405
private:
379-
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList, int /*unused*/);
406+
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, const DUI &dui, OutputList *outputList, int /*unused*/);
380407

381408
void combineOperators();
382409

@@ -425,21 +452,6 @@ namespace simplecpp {
425452
long long result; // condition result
426453
};
427454

428-
/**
429-
* Command line preprocessor settings.
430-
* On the command line these are configured by -D, -U, -I, --include, -std
431-
*/
432-
struct SIMPLECPP_LIB DUI {
433-
DUI() = default;
434-
std::list<std::string> defines;
435-
std::set<std::string> undefined;
436-
std::list<std::string> includePaths;
437-
std::list<std::string> includes;
438-
std::string std;
439-
bool clearIncludeCache{};
440-
bool removeComments{}; /** remove comment tokens from included files */
441-
};
442-
443455
struct SIMPLECPP_LIB FileData {
444456
/** The canonical filename associated with this data */
445457
std::string filename;
@@ -453,10 +465,10 @@ namespace simplecpp {
453465
~FileDataCache();
454466

455467
FileDataCache(const FileDataCache &) = delete;
456-
FileDataCache(FileDataCache &&) noexcept;
468+
FileDataCache(FileDataCache &&) SIMPLECPP_NOEXCEPT;
457469

458470
FileDataCache &operator=(const FileDataCache &) = delete;
459-
FileDataCache &operator=(FileDataCache &&) noexcept;
471+
FileDataCache &operator=(FileDataCache &&) SIMPLECPP_NOEXCEPT;
460472

461473
/** Get the cached data for a file, or load and then return it if it isn't cached.
462474
* returns the file data and true if the file was loaded, false if it was cached. */
@@ -499,7 +511,7 @@ namespace simplecpp {
499511
return mData.cend();
500512
}
501513

502-
using load_callback_type = std::function<void (FileData &)>;
514+
using load_callback_type = std::function<void (FileData &, bool)>;
503515

504516
void set_load_callback(load_callback_type cb) {
505517
mLoadCallback = std::move(cb);
@@ -512,6 +524,7 @@ namespace simplecpp {
512524
using name_map_type = std::unordered_map<std::string, FileData *>;
513525

514526
std::pair<FileData *, bool> tryload(name_map_type::iterator &name_it, const DUI &dui, std::vector<std::string> &filenames, OutputList *outputList);
527+
std::pair<FileData *, bool> get_private(const std::string &sourcefile, const std::string &header, const DUI &dui, bool systemheader, std::vector<std::string> &filenames, OutputList *outputList);
515528

516529
container_type mData;
517530
name_map_type mNameMap;
@@ -578,9 +591,15 @@ namespace simplecpp {
578591
/** Returns the C version a given standard */
579592
SIMPLECPP_LIB cstd_t getCStd(const std::string &std);
580593

594+
/** Returns the name of a C standard */
595+
SIMPLECPP_LIB const char *getCStdName(cstd_t std);
596+
581597
/** Returns the C++ version a given standard */
582598
SIMPLECPP_LIB cppstd_t getCppStd(const std::string &std);
583599

600+
/** Returns the name of a C++ standard */
601+
SIMPLECPP_LIB const char *getCppStdName(cppstd_t std);
602+
584603
/** Returns the __STDC_VERSION__ value for a given standard */
585604
SIMPLECPP_LIB std::string getCStdString(const std::string &std);
586605
SIMPLECPP_LIB std::string getCStdString(cstd_t std);

gui/manualtest/projectfiledialog.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
Some manual testing in the project file dialog interface
55

66

7+
## Test: Relative paths
8+
9+
Ticket: #14983
10+
11+
1. Configure files/paths in project folder:
12+
* import a projectfile
13+
* add include paths in project folder
14+
* exclude file/folder
15+
16+
2. Save project
17+
18+
EXPECTED: Relative paths should be used in the XML
19+
20+
721
## Test: Platform file pic8.xml
822

923
Ticket: #14489

gui/projectfile.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,15 @@ QStringList ProjectFile::getSearchPaths(const QString& projectPath, const QStrin
11931193
return ret;
11941194
}
11951195

1196+
QString ProjectFile::getRelativePath(const QString &absolutePath) const
1197+
{
1198+
const QDir dir(QFileInfo(mFilename).absolutePath());
1199+
const QString relativePath(dir.relativeFilePath(absolutePath));
1200+
if (relativePath.startsWith("../../..") || absolutePath.length() < relativePath.length())
1201+
return absolutePath;
1202+
return relativePath;
1203+
}
1204+
11961205
QStringList ProjectFile::getSearchPaths(const QString& dir) const {
11971206
const QFileInfo inf(mFilename);
11981207
const QString applicationFilePath = QCoreApplication::applicationFilePath();

gui/projectfile.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,14 @@ class ProjectFile : public QObject {
447447

448448
static QStringList getSearchPaths(const QString& projectPath, const QString& appPath, const QString& datadir, const QString& dir);
449449

450+
/**
451+
* @brief Convert an absolute path to a path relative to this project's directory.
452+
* If the relative path would need to walk up more than 2 parent folders
453+
* (i.e. "../../...") the absolute path is returned unchanged instead.
454+
* @param absolutePath Absolute path to convert.
455+
*/
456+
QString getRelativePath(const QString &absolutePath) const;
457+
450458
/** Set user includes in settings if non-empty */
451459
void setSettingsUserIncludes(Settings &settings) const;
452460

gui/projectfiledialog.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -571,10 +571,7 @@ QString ProjectFileDialog::getExistingDirectory(const QString &caption, bool tra
571571

572572
// Check if the path is relative to project file's path and if so
573573
// make it a relative path instead of absolute path.
574-
const QDir dir(projectPath);
575-
const QString relpath(dir.relativeFilePath(selectedDir));
576-
if (!relpath.startsWith("../.."))
577-
selectedDir = relpath;
574+
selectedDir = mProjectFile->getRelativePath(selectedDir);
578575

579576
// Trailing slash..
580577
if (trailingSlash && !selectedDir.endsWith('/'))
@@ -631,7 +628,7 @@ void ProjectFileDialog::browseImportProject()
631628
dir.canonicalPath(),
632629
toFilterString(filters));
633630
if (!fileName.isEmpty()) {
634-
mUI->mEditImportProject->setText(dir.relativeFilePath(fileName));
631+
mUI->mEditImportProject->setText(mProjectFile->getRelativePath(fileName));
635632
updatePathsAndDefines();
636633
setProjectConfigurations(getProjectConfigs(fileName));
637634
for (int row = 0; row < mUI->mListVsConfigs->count(); ++row) {
@@ -652,7 +649,7 @@ void ProjectFileDialog::browseUserInclude()
652649
dir.canonicalPath(),
653650
toFilterString(filters));
654651
if (!fileName.isEmpty()) {
655-
mUI->mEditUserInclude->setText(dir.relativeFilePath(fileName));
652+
mUI->mEditUserInclude->setText(mProjectFile->getRelativePath(fileName));
656653
}
657654
}
658655

@@ -891,7 +888,9 @@ void ProjectFileDialog::addExcludeFile()
891888
QMap<QString,QString> filters;
892889
filters[tr("Source files")] = "*.c *.cpp";
893890
filters[tr("All files")] = "*.*";
894-
addExcludePath(QFileDialog::getOpenFileName(this, tr("Exclude file"), dir.canonicalPath(), toFilterString(filters)));
891+
QString fileName = QFileDialog::getOpenFileName(this, tr("Exclude file"), dir.canonicalPath(), toFilterString(filters));
892+
if (!fileName.isEmpty())
893+
addExcludePath(mProjectFile->getRelativePath(fileName));
895894
}
896895

897896
void ProjectFileDialog::editExcludePath()

gui/test/projectfile/testprojectfile.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,5 +214,45 @@ void TestProjectFile::emptyUserInclude() const
214214
QCOMPARE(settings.userIncludes.size(), 0);
215215
}
216216

217+
// Absolute path is made relative when it does not require walking up more than 3 parent folders
218+
void TestProjectFile::getRelativePathRelative() const
219+
{
220+
ProjectFile projectFile;
221+
projectFile.setFilename("/some/path/sub/123.cppcheck");
222+
QCOMPARE(projectFile.getRelativePath("/some/path/externals/foo.cpp"), QString("../externals/foo.cpp"));
223+
}
224+
225+
// Absolute path is made relative even when it requires walking up 2 parent folders
226+
void TestProjectFile::getRelativePathTwoUp() const
227+
{
228+
ProjectFile projectFile;
229+
projectFile.setFilename("/some/path/sub/123.cppcheck");
230+
QCOMPARE(projectFile.getRelativePath("/some/externals/foo.cpp"), QString("../../externals/foo.cpp"));
231+
}
232+
233+
// Absolute path is kept as-is when making it relative would require walking up more than 3 parent folders
234+
void TestProjectFile::getRelativePathTooFarUp() const
235+
{
236+
ProjectFile projectFile;
237+
projectFile.setFilename("/some/path/sub/123.cppcheck");
238+
QCOMPARE(projectFile.getRelativePath("/other/deep/foo.cpp"), QString("/other/deep/foo.cpp"));
239+
}
240+
241+
// Absolute path in a subfolder of the project path is made relative without walking up at all
242+
void TestProjectFile::getRelativePathSubfolder() const
243+
{
244+
ProjectFile projectFile;
245+
projectFile.setFilename("/some/path/sub/123.cppcheck");
246+
QCOMPARE(projectFile.getRelativePath("/some/path/sub/src/file1.c"), QString("src/file1.c"));
247+
}
248+
249+
// Absolute path is kept as-is when it is shorter than the relative path, even if it does not require walking up 3 or more parent folders
250+
void TestProjectFile::getRelativePathAbsoluteShorter() const
251+
{
252+
ProjectFile projectFile;
253+
projectFile.setFilename("/ab/path/sub/123.cppcheck");
254+
QCOMPARE(projectFile.getRelativePath("/ab/foo.cpp"), QString("/ab/foo.cpp"));
255+
}
256+
217257
QTEST_MAIN(TestProjectFile)
218258

gui/test/projectfile/testprojectfile.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,10 @@ private slots:
3838
void getCheckingSuppressionsStar() const;
3939

4040
void emptyUserInclude() const;
41+
42+
void getRelativePathRelative() const;
43+
void getRelativePathTwoUp() const;
44+
void getRelativePathTooFarUp() const;
45+
void getRelativePathSubfolder() const;
46+
void getRelativePathAbsoluteShorter() const;
4147
};

0 commit comments

Comments
 (0)