| 1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
| 2 | // |
| 3 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 4 | |
| 5 | #include "symbolparser.h" |
| 6 | #include "common/common.h" |
| 7 | #include "clangparser/clangparser.h" |
| 8 | |
| 9 | namespace { |
| 10 | const QString unionparser{"unionparser" }; |
| 11 | } |
| 12 | SymbolParser::SymbolParser(QObject *parent) |
| 13 | : QProcess (parent) |
| 14 | { |
| 15 | setProgram(getPython()); |
| 16 | auto procEnv = env::lang::get(env::lang::User, env::lang::Python, 3); |
| 17 | for (auto val : procEnv.keys()) { |
| 18 | qInfo()<< val << procEnv.value(val); |
| 19 | } |
| 20 | setProcessEnvironment(procEnv); |
| 21 | auto env = processEnvironment().systemEnvironment(); |
| 22 | QObject::connect(this, &QProcess::errorOccurred, |
| 23 | this, &SymbolParser::errorOccurred); |
| 24 | QObject::connect(this, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), |
| 25 | this, &SymbolParser::finished); |
| 26 | QObject::connect(this, &QProcess::readyReadStandardError, |
| 27 | this, &SymbolParser::redirectErr); |
| 28 | QObject::connect(this, &QProcess::readyReadStandardOutput, |
| 29 | this, &SymbolParser::redirectOut); |
| 30 | } |
| 31 | |
| 32 | void SymbolParser::setArgs(const SymbolParseArgs &args) |
| 33 | { |
| 34 | this->processArgs = args; |
| 35 | } |
| 36 | |
| 37 | SymbolParseArgs SymbolParser::args() const |
| 38 | { |
| 39 | return this->processArgs; |
| 40 | } |
| 41 | |
| 42 | void SymbolParser::setStorage(const QString &storage) |
| 43 | { |
| 44 | processArgs.storage = storage; |
| 45 | } |
| 46 | |
| 47 | QString SymbolParser::getStorage() const |
| 48 | { |
| 49 | return processArgs.storage; |
| 50 | } |
| 51 | |
| 52 | void SymbolParser::setWorkspace(const QString &workspace) |
| 53 | { |
| 54 | processArgs.workspace = workspace; |
| 55 | } |
| 56 | |
| 57 | QString SymbolParser::getWorkspace() const |
| 58 | { |
| 59 | return processArgs.workspace; |
| 60 | } |
| 61 | |
| 62 | void SymbolParser::setLanguage(const QString &language) |
| 63 | { |
| 64 | processArgs.language = language; |
| 65 | } |
| 66 | |
| 67 | QString SymbolParser::getLanguage() const |
| 68 | { |
| 69 | return processArgs.language; |
| 70 | } |
| 71 | |
| 72 | void SymbolParser::start() |
| 73 | { |
| 74 | #ifdef __mips__ |
| 75 | // switch to libclang. |
| 76 | ClangParser::parse(processArgs.workspace, processArgs.storage, processArgs.language); |
| 77 | #else |
| 78 | QString scriptPath = CustomPaths::global(CustomPaths::Scripts); |
| 79 | QStringList arguments; |
| 80 | arguments << (scriptPath + "/symbol-parser/main.py" ); |
| 81 | arguments << "-w" << processArgs.workspace; |
| 82 | arguments << "-l" << processArgs.language; |
| 83 | arguments << "-s" << processArgs.storage; |
| 84 | setArguments({arguments}); |
| 85 | QProcess::start(); |
| 86 | #endif |
| 87 | } |
| 88 | |
| 89 | SymbolParseArgs::SymbolParseArgs() |
| 90 | { |
| 91 | |
| 92 | } |
| 93 | |
| 94 | SymbolParseArgs::SymbolParseArgs(const QString &workspace, |
| 95 | const QString &language, |
| 96 | const QString &storage) |
| 97 | : workspace(workspace) |
| 98 | , language(language) |
| 99 | , storage(storage) |
| 100 | { |
| 101 | |
| 102 | } |
| 103 | |
| 104 | SymbolParseArgs::SymbolParseArgs(const SymbolParseArgs &as) |
| 105 | : workspace(as.workspace) |
| 106 | , language(as.language) |
| 107 | , storage(as.storage) |
| 108 | { |
| 109 | |
| 110 | } |
| 111 | |
| 112 | SymbolParseArgs &SymbolParseArgs::operator=(const SymbolParseArgs &as) |
| 113 | { |
| 114 | workspace = as.workspace; |
| 115 | language = as.language; |
| 116 | storage = as.storage; |
| 117 | return *this; |
| 118 | } |
| 119 | |
| 120 | void SymbolParser::errorOccurred(QProcess::ProcessError err) |
| 121 | { |
| 122 | qCritical() << exitCode() << exitStatus() << err; |
| 123 | } |
| 124 | |
| 125 | void SymbolParser::finished(int exitCode, QProcess::ExitStatus status) |
| 126 | { |
| 127 | qCritical() << exitCode << status; |
| 128 | if (exitCode == 0) |
| 129 | parseDone(true); |
| 130 | else |
| 131 | parseDone(false); |
| 132 | } |
| 133 | |
| 134 | void SymbolParser::redirectOut() |
| 135 | { |
| 136 | } |
| 137 | |
| 138 | void SymbolParser::redirectErr() |
| 139 | { |
| 140 | qCritical() << "symbol parser error:" <<QProcess::readAllStandardError(); |
| 141 | } |
| 142 | |
| 143 | QList<QString> findAll(const QString &pattern, const QString &str, bool greedy) |
| 144 | { |
| 145 | QRegExp rxlen(pattern); |
| 146 | rxlen.setMinimal(greedy); |
| 147 | int position = 0; |
| 148 | QList<QString> strList; |
| 149 | while (position >= 0) { |
| 150 | position = rxlen.indexIn(str, position); |
| 151 | if (position < 0) |
| 152 | break; |
| 153 | strList << rxlen.cap(1); |
| 154 | position += rxlen.matchedLength(); |
| 155 | } |
| 156 | return strList; |
| 157 | } |
| 158 | |
| 159 | QString SymbolParser::getPython() |
| 160 | { |
| 161 | if (pythonCmd.isEmpty()) { |
| 162 | QDir dir("/usr/bin" ); |
| 163 | QStringList filter { "Python*.*" }; |
| 164 | dir.setNameFilters(filter); |
| 165 | QStringList pythonList = dir.entryList(); |
| 166 | |
| 167 | QString pattern = "((\\d)|(\\d.\\d))($|\\s)" ; |
| 168 | QStringList versions = findAll(pattern, pythonList.join(" " ), true); |
| 169 | |
| 170 | double newVersion = 0; |
| 171 | for (auto version : versions) { |
| 172 | double v = version.toDouble(); |
| 173 | if (v > newVersion) { |
| 174 | newVersion = v; |
| 175 | } |
| 176 | } |
| 177 | pythonCmd = "python" + QString::number(newVersion); |
| 178 | } |
| 179 | return pythonCmd; |
| 180 | } |
| 181 | |