File indexing completed on 2024-05-05 04:39:28
0001 /* 0002 SPDX-FileCopyrightText: 2018, 2020 Friedrich W. H. Kossebau <kossebau@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "compileanalyzeutils.h" 0008 0009 // lib 0010 #include <debug.h> 0011 // KDevPlatform 0012 #include <util/path.h> 0013 // KF 0014 #include <KLocalizedString> 0015 // Qt 0016 #include <QStandardPaths> 0017 #include <QUrl> 0018 #include <QFile> 0019 #include <QFileInfo> 0020 #include <QJsonDocument> 0021 #include <QJsonArray> 0022 #include <QJsonObject> 0023 0024 namespace KDevelop 0025 { 0026 0027 namespace Utils 0028 { 0029 0030 QString findExecutable(const QString& fallbackExecutablePath) 0031 { 0032 const QString executablePath = QStandardPaths::findExecutable(fallbackExecutablePath); 0033 return executablePath.isEmpty() ? fallbackExecutablePath : executablePath; 0034 } 0035 0036 QStringList filesFromCompilationDatabase(const KDevelop::Path& buildPath, 0037 const QUrl& urlToCheck, bool allFiles, 0038 QString& error) 0039 { 0040 QStringList result; 0041 0042 const auto commandsFilePath = KDevelop::Path(buildPath, QStringLiteral("compile_commands.json")).toLocalFile(); 0043 0044 if (!QFile::exists(commandsFilePath)) { 0045 error = i18n("Compilation database file not found: '%1'", commandsFilePath); 0046 return result; 0047 } 0048 0049 const auto pathToCheck = urlToCheck.toLocalFile(); 0050 if (pathToCheck.isEmpty()) { 0051 error = i18n("Nothing to check: compilation database file '%1' contains no matching items.", commandsFilePath); 0052 return result; 0053 } 0054 0055 QFile commandsFile(commandsFilePath); 0056 if (!commandsFile.open(QFile::ReadOnly | QFile::Text)) { 0057 error = i18n("Could not open compilation database file for reading: '%1'", commandsFilePath); 0058 return result; 0059 } 0060 0061 QJsonParseError jsonError; 0062 const auto commandsDocument = QJsonDocument::fromJson(commandsFile.readAll(), &jsonError); 0063 0064 if (jsonError.error) { 0065 error = i18n("JSON error during parsing compilation database file '%1': %2", commandsFilePath, jsonError.errorString()); 0066 return result; 0067 } 0068 0069 if (!commandsDocument.isArray()) { 0070 error = i18n("JSON error during parsing compilation database file '%1': document is not an array.", commandsFilePath); 0071 return result; 0072 } 0073 0074 const auto pathToCheckInfo = QFileInfo(pathToCheck); 0075 const bool isPathToCheckAFile = pathToCheckInfo.isFile(); 0076 const auto canonicalPathToCheck = pathToCheckInfo.canonicalFilePath(); 0077 0078 const auto fileDataArray = commandsDocument.array(); 0079 for (const auto& value : fileDataArray) { 0080 if (!value.isObject()) { 0081 continue; 0082 } 0083 0084 const auto entry = value.toObject(); 0085 const auto it = entry.find(QLatin1String("file")); 0086 if (it != entry.end()) { 0087 // using the original path from the commands file 0088 // but matching the canonical ones 0089 const auto path = it->toString(); 0090 const auto pathInfo = QFileInfo(path); 0091 if (pathInfo.exists()) { 0092 if (allFiles) { 0093 result += path; 0094 } else { 0095 const auto canonicalPath = pathInfo.canonicalFilePath(); 0096 if (isPathToCheckAFile) { 0097 if (canonicalPath == canonicalPathToCheck) { 0098 result = QStringList{path}; 0099 break; 0100 } 0101 } else if (canonicalPath.startsWith(canonicalPathToCheck)) { 0102 result.append(path); 0103 } 0104 } 0105 } 0106 } 0107 } 0108 0109 if (result.isEmpty()) { 0110 error = i18n("Nothing to check: compilation database file '%1' contains no matching items.", commandsFilePath); 0111 } 0112 0113 return result; 0114 } 0115 0116 } 0117 0118 }