Skip to content

Commit 45d78ed

Browse files
committed
extracted AddonInfo into separate file / minor AddonInfo interface cleanup
1 parent f10851d commit 45d78ed

File tree

6 files changed

+299
-236
lines changed

6 files changed

+299
-236
lines changed

Makefile

Lines changed: 122 additions & 118 deletions
Large diffs are not rendered by default.

lib/addoninfo.cpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* Cppcheck - A tool for static C/C++ code analysis
3+
* Copyright (C) 2007-2023 Cppcheck team.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include "addoninfo.h"
20+
21+
#include "path.h"
22+
#include "utils.h"
23+
24+
#include <fstream>
25+
#include <sstream>
26+
#include <string>
27+
28+
#define PICOJSON_USE_INT64
29+
#include <picojson.h>
30+
31+
static std::string getFullPath(const std::string &fileName, const std::string &exename) {
32+
if (Path::fileExists(fileName))
33+
return fileName;
34+
35+
const std::string exepath = Path::getPathFromFilename(exename);
36+
if (Path::fileExists(exepath + fileName))
37+
return exepath + fileName;
38+
if (Path::fileExists(exepath + "addons/" + fileName))
39+
return exepath + "addons/" + fileName;
40+
41+
#ifdef FILESDIR
42+
if (Path::fileExists(FILESDIR + ("/" + fileName)))
43+
return FILESDIR + ("/" + fileName);
44+
if (Path::fileExists(FILESDIR + ("/addons/" + fileName)))
45+
return FILESDIR + ("/addons/" + fileName);
46+
#endif
47+
return "";
48+
}
49+
50+
static std::string parseAddonInfo(AddonInfo& addoninfo, const picojson::value &json, const std::string &fileName, const std::string &exename) {
51+
const std::string& json_error = picojson::get_last_error();
52+
if (!json_error.empty()) {
53+
return "Loading " + fileName + " failed. " + json_error;
54+
}
55+
if (!json.is<picojson::object>())
56+
return "Loading " + fileName + " failed. Bad json.";
57+
picojson::object obj = json.get<picojson::object>();
58+
if (obj.count("args")) {
59+
if (!obj["args"].is<picojson::array>())
60+
return "Loading " + fileName + " failed. args must be array.";
61+
for (const picojson::value &v : obj["args"].get<picojson::array>())
62+
addoninfo.args += " " + v.get<std::string>();
63+
}
64+
65+
if (obj.count("ctu")) {
66+
// ctu is specified in the config file
67+
if (!obj["ctu"].is<bool>())
68+
return "Loading " + fileName + " failed. ctu must be boolean.";
69+
addoninfo.ctu = obj["ctu"].get<bool>();
70+
} else {
71+
addoninfo.ctu = false;
72+
}
73+
74+
if (obj.count("python")) {
75+
// Python was defined in the config file
76+
if (obj["python"].is<picojson::array>()) {
77+
return "Loading " + fileName +" failed. python must not be an array.";
78+
}
79+
addoninfo.python = obj["python"].get<std::string>();
80+
} else {
81+
addoninfo.python = "";
82+
}
83+
84+
if (obj.count("executable")) {
85+
if (!obj["executable"].is<std::string>())
86+
return "Loading " + fileName + " failed. executable must be a string.";
87+
addoninfo.executable = getFullPath(obj["executable"].get<std::string>(), fileName);
88+
return "";
89+
}
90+
91+
return addoninfo.getAddonInfo(obj["script"].get<std::string>(), exename);
92+
}
93+
94+
std::string AddonInfo::getAddonInfo(const std::string &fileName, const std::string &exename) {
95+
if (fileName[0] == '{') {
96+
std::istringstream in(fileName);
97+
picojson::value json;
98+
in >> json;
99+
return parseAddonInfo(*this, json, fileName, exename);
100+
}
101+
if (fileName.find('.') == std::string::npos)
102+
return getAddonInfo(fileName + ".py", exename);
103+
104+
if (endsWith(fileName, ".py")) {
105+
scriptFile = getFullPath(fileName, exename);
106+
if (scriptFile.empty())
107+
return "Did not find addon " + fileName;
108+
109+
std::string::size_type pos1 = scriptFile.rfind('/');
110+
if (pos1 == std::string::npos)
111+
pos1 = 0;
112+
else
113+
pos1++;
114+
std::string::size_type pos2 = scriptFile.rfind('.');
115+
if (pos2 < pos1)
116+
pos2 = std::string::npos;
117+
name = scriptFile.substr(pos1, pos2 - pos1);
118+
119+
runScript = getFullPath("runaddon.py", exename);
120+
121+
return "";
122+
}
123+
124+
if (!endsWith(fileName, ".json"))
125+
return "Failed to open addon " + fileName;
126+
127+
std::ifstream fin(fileName);
128+
if (!fin.is_open())
129+
return "Failed to open " + fileName;
130+
picojson::value json;
131+
fin >> json;
132+
return parseAddonInfo(*this, json, fileName, exename);
133+
}

lib/addoninfo.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Cppcheck - A tool for static C/C++ code analysis
3+
* Copyright (C) 2007-2023 Cppcheck team.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#ifndef addonInfoH
20+
#define addonInfoH
21+
22+
#include <string>
23+
24+
struct AddonInfo {
25+
std::string name;
26+
std::string scriptFile; // addon script
27+
std::string executable; // addon executable
28+
std::string args; // special extra arguments
29+
std::string python; // script interpreter
30+
bool ctu = false;
31+
std::string runScript;
32+
33+
std::string getAddonInfo(const std::string &fileName, const std::string &exename);
34+
};
35+
36+
#endif // addonInfoH

lib/cppcheck.cpp

Lines changed: 2 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
* You should have received a copy of the GNU General Public License
1616
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
18+
1819
#include "cppcheck.h"
1920

21+
#include "addoninfo.h"
2022
#include "check.h"
2123
#include "checkunusedfunctions.h"
2224
#include "clangimport.h"
@@ -89,122 +91,6 @@ static TimerResults s_timerResults;
8991
// CWE ids used
9092
static const CWE CWE398(398U); // Indicator of Poor Code Quality
9193

92-
namespace {
93-
struct AddonInfo {
94-
std::string name;
95-
std::string scriptFile; // addon script
96-
std::string executable; // addon executable
97-
std::string args; // special extra arguments
98-
std::string python; // script interpreter
99-
bool ctu = false;
100-
std::string runScript;
101-
102-
static std::string getFullPath(const std::string &fileName, const std::string &exename) {
103-
if (Path::fileExists(fileName))
104-
return fileName;
105-
106-
const std::string exepath = Path::getPathFromFilename(exename);
107-
if (Path::fileExists(exepath + fileName))
108-
return exepath + fileName;
109-
if (Path::fileExists(exepath + "addons/" + fileName))
110-
return exepath + "addons/" + fileName;
111-
112-
#ifdef FILESDIR
113-
if (Path::fileExists(FILESDIR + ("/" + fileName)))
114-
return FILESDIR + ("/" + fileName);
115-
if (Path::fileExists(FILESDIR + ("/addons/" + fileName)))
116-
return FILESDIR + ("/addons/" + fileName);
117-
#endif
118-
return "";
119-
}
120-
121-
std::string parseAddonInfo(const picojson::value &json, const std::string &fileName, const std::string &exename) {
122-
const std::string& json_error = picojson::get_last_error();
123-
if (!json_error.empty()) {
124-
return "Loading " + fileName + " failed. " + json_error;
125-
}
126-
if (!json.is<picojson::object>())
127-
return "Loading " + fileName + " failed. Bad json.";
128-
picojson::object obj = json.get<picojson::object>();
129-
if (obj.count("args")) {
130-
if (!obj["args"].is<picojson::array>())
131-
return "Loading " + fileName + " failed. args must be array.";
132-
for (const picojson::value &v : obj["args"].get<picojson::array>())
133-
args += " " + v.get<std::string>();
134-
}
135-
136-
if (obj.count("ctu")) {
137-
// ctu is specified in the config file
138-
if (!obj["ctu"].is<bool>())
139-
return "Loading " + fileName + " failed. ctu must be boolean.";
140-
ctu = obj["ctu"].get<bool>();
141-
} else {
142-
ctu = false;
143-
}
144-
145-
if (obj.count("python")) {
146-
// Python was defined in the config file
147-
if (obj["python"].is<picojson::array>()) {
148-
return "Loading " + fileName +" failed. python must not be an array.";
149-
}
150-
python = obj["python"].get<std::string>();
151-
} else {
152-
python = "";
153-
}
154-
155-
if (obj.count("executable")) {
156-
if (!obj["executable"].is<std::string>())
157-
return "Loading " + fileName + " failed. executable must be a string.";
158-
executable = getFullPath(obj["executable"].get<std::string>(), fileName);
159-
return "";
160-
}
161-
162-
return getAddonInfo(obj["script"].get<std::string>(), exename);
163-
}
164-
165-
std::string getAddonInfo(const std::string &fileName, const std::string &exename) {
166-
if (fileName[0] == '{') {
167-
std::istringstream in(fileName);
168-
picojson::value json;
169-
in >> json;
170-
return parseAddonInfo(json, fileName, exename);
171-
}
172-
if (fileName.find('.') == std::string::npos)
173-
return getAddonInfo(fileName + ".py", exename);
174-
175-
if (endsWith(fileName, ".py")) {
176-
scriptFile = getFullPath(fileName, exename);
177-
if (scriptFile.empty())
178-
return "Did not find addon " + fileName;
179-
180-
std::string::size_type pos1 = scriptFile.rfind('/');
181-
if (pos1 == std::string::npos)
182-
pos1 = 0;
183-
else
184-
pos1++;
185-
std::string::size_type pos2 = scriptFile.rfind('.');
186-
if (pos2 < pos1)
187-
pos2 = std::string::npos;
188-
name = scriptFile.substr(pos1, pos2 - pos1);
189-
190-
runScript = getFullPath("runaddon.py", exename);
191-
192-
return "";
193-
}
194-
195-
if (!endsWith(fileName, ".json"))
196-
return "Failed to open addon " + fileName;
197-
198-
std::ifstream fin(fileName);
199-
if (!fin.is_open())
200-
return "Failed to open " + fileName;
201-
picojson::value json;
202-
fin >> json;
203-
return parseAddonInfo(json, fileName, exename);
204-
}
205-
};
206-
}
207-
20894
static std::string cmdFileName(std::string f)
20995
{
21096
f = Path::toNativeSeparators(f);

lib/cppcheck.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
<ItemGroup Label="SourceFiles">
3737
<ClCompile Include="..\externals\simplecpp\simplecpp.cpp" />
3838
<ClCompile Include="..\externals\tinyxml2\tinyxml2.cpp" />
39+
<ClCompile Include="addoninfo.cpp" />
3940
<ClCompile Include="analyzerinfo.cpp" />
4041
<ClCompile Include="astutils.cpp" />
4142
<ClCompile Include="check.cpp">
@@ -109,6 +110,7 @@
109110
<ItemGroup Label="HeaderFiles">
110111
<ClInclude Include="..\externals\simplecpp\simplecpp.h" />
111112
<ClInclude Include="..\externals\tinyxml2\tinyxml2.h" />
113+
<ClInclude Include="addoninfo.h" />
112114
<ClInclude Include="analyzer.h" />
113115
<ClInclude Include="analyzerinfo.h" />
114116
<ClInclude Include="astutils.h" />

lib/lib.pri

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
include($$PWD/pcrerules.pri)
44
include($$PWD/../externals/externals.pri)
55
INCLUDEPATH += $$PWD
6-
HEADERS += $${PWD}/analyzer.h \
6+
HEADERS += $${PWD}/addoninfo.h \
7+
$${PWD}/analyzer.h \
78
$${PWD}/analyzerinfo.h \
89
$${PWD}/astutils.h \
910
$${PWD}/calculate.h \
@@ -73,7 +74,8 @@ HEADERS += $${PWD}/analyzer.h \
7374
$${PWD}/version.h \
7475
$${PWD}/vfvalue.h
7576

76-
SOURCES += $${PWD}/analyzerinfo.cpp \
77+
SOURCES += $${PWD}/addoninfo.cpp \
78+
$${PWD}/analyzerinfo.cpp \
7779
$${PWD}/astutils.cpp \
7880
$${PWD}/check.cpp \
7981
$${PWD}/check64bit.cpp \

0 commit comments

Comments
 (0)