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
9namespace {
10const QString unionparser{"unionparser"};
11}
12SymbolParser::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
32void SymbolParser::setArgs(const SymbolParseArgs &args)
33{
34 this->processArgs = args;
35}
36
37SymbolParseArgs SymbolParser::args() const
38{
39 return this->processArgs;
40}
41
42void SymbolParser::setStorage(const QString &storage)
43{
44 processArgs.storage = storage;
45}
46
47QString SymbolParser::getStorage() const
48{
49 return processArgs.storage;
50}
51
52void SymbolParser::setWorkspace(const QString &workspace)
53{
54 processArgs.workspace = workspace;
55}
56
57QString SymbolParser::getWorkspace() const
58{
59 return processArgs.workspace;
60}
61
62void SymbolParser::setLanguage(const QString &language)
63{
64 processArgs.language = language;
65}
66
67QString SymbolParser::getLanguage() const
68{
69 return processArgs.language;
70}
71
72void 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
89SymbolParseArgs::SymbolParseArgs()
90{
91
92}
93
94SymbolParseArgs::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
104SymbolParseArgs::SymbolParseArgs(const SymbolParseArgs &as)
105 : workspace(as.workspace)
106 , language(as.language)
107 , storage(as.storage)
108{
109
110}
111
112SymbolParseArgs &SymbolParseArgs::operator=(const SymbolParseArgs &as)
113{
114 workspace = as.workspace;
115 language = as.language;
116 storage = as.storage;
117 return *this;
118}
119
120void SymbolParser::errorOccurred(QProcess::ProcessError err)
121{
122 qCritical() << exitCode() << exitStatus() << err;
123}
124
125void 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
134void SymbolParser::redirectOut()
135{
136}
137
138void SymbolParser::redirectErr()
139{
140 qCritical() << "symbol parser error:" <<QProcess::readAllStandardError();
141}
142
143QList<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
159QString 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