-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
greatly improved Settings::loadCppcheckCfg()
error handling
#5712
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,40 +40,87 @@ Settings::Settings() | |
setCheckLevelNormal(); | ||
} | ||
|
||
// TODO: report error when the config is invalid | ||
void Settings::loadCppcheckCfg() | ||
std::string Settings::loadCppcheckCfg() | ||
{ | ||
std::string fileName = Path::getPathFromFilename(exename) + "cppcheck.cfg"; | ||
static const std::string cfgFilename = "cppcheck.cfg"; | ||
std::string fileName; | ||
#ifdef FILESDIR | ||
if (Path::isFile(FILESDIR "/cppcheck.cfg")) | ||
fileName = FILESDIR "/cppcheck.cfg"; | ||
if (Path::isFile(Path::join(FILESDIR, cfgFilename))) | ||
fileName = Path::join(FILESDIR, cfgFilename); | ||
#endif | ||
// cppcheck-suppress knownConditionTrueFalse | ||
if (fileName.empty()) { | ||
fileName = Path::getPathFromFilename(exename) + cfgFilename; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Oh right. That again. I ran into his in another context as well. Will take a look later today. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I may. I'm already working on it in a separate ticket and was just asking you to help me clarify your thought process behind this particular change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. I would have just hot fixed this this for now. As it would have also tied into my upcoming changes to fix https://trac.cppcheck.net/ticket/12240 and #4424 I would have done any more refactoring within that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay hot fix it is |
||
if (!Path::isFile(fileName)) | ||
return ""; | ||
} | ||
|
||
std::ifstream fin(fileName); | ||
if (!fin.is_open()) | ||
return; | ||
return "could not open file"; | ||
picojson::value json; | ||
fin >> json; | ||
if (!picojson::get_last_error().empty()) | ||
return; | ||
picojson::object obj = json.get<picojson::object>(); | ||
if (obj.count("productName") && obj["productName"].is<std::string>()) | ||
cppcheckCfgProductName = obj["productName"].get<std::string>(); | ||
if (obj.count("about") && obj["about"].is<std::string>()) | ||
cppcheckCfgAbout = obj["about"].get<std::string>(); | ||
if (obj.count("addons") && obj["addons"].is<picojson::array>()) { | ||
for (const picojson::value &v : obj["addons"].get<picojson::array>()) { | ||
const std::string &s = v.get<std::string>(); | ||
if (!Path::isAbsolute(s)) | ||
addons.emplace(Path::getPathFromFilename(fileName) + s); | ||
else | ||
addons.emplace(s); | ||
{ | ||
const std::string& lastErr = picojson::get_last_error(); | ||
if (!lastErr.empty()) | ||
return "not a valid JSON - " + lastErr; | ||
} | ||
const picojson::object& obj = json.get<picojson::object>(); | ||
{ | ||
const picojson::object::const_iterator it = obj.find("productName"); | ||
if (it != obj.cend()) { | ||
const auto& v = it->second; | ||
if (!v.is<std::string>()) | ||
return "'productName' is not a string"; | ||
cppcheckCfgProductName = v.get<std::string>(); | ||
} | ||
} | ||
if (obj.count("suppressions") && obj["suppressions"].is<picojson::array>()) { | ||
for (const picojson::value &v : obj["suppressions"].get<picojson::array>()) | ||
nomsg.addSuppressionLine(v.get<std::string>()); | ||
{ | ||
const picojson::object::const_iterator it = obj.find("about"); | ||
if (it != obj.cend()) { | ||
const auto& v = it->second; | ||
if (!v.is<std::string>()) | ||
return "'about' is not a string"; | ||
cppcheckCfgAbout = v.get<std::string>(); | ||
} | ||
} | ||
{ | ||
const picojson::object::const_iterator it = obj.find("addons"); | ||
if (it != obj.cend()) { | ||
const auto& entry = it->second; | ||
if (!entry.is<picojson::array>()) | ||
return "'addons' is not an array"; | ||
for (const picojson::value &v : entry.get<picojson::array>()) | ||
{ | ||
if (!v.is<std::string>()) | ||
return "'addons' array entry is not a string"; | ||
const std::string &s = v.get<std::string>(); | ||
if (!Path::isAbsolute(s)) | ||
addons.emplace(Path::join(Path::getPathFromFilename(fileName), s)); | ||
else | ||
addons.emplace(s); | ||
} | ||
} | ||
} | ||
{ | ||
const picojson::object::const_iterator it = obj.find("suppressions"); | ||
if (it != obj.cend()) { | ||
const auto& entry = it->second; | ||
if (!entry.is<picojson::array>()) | ||
return "'suppressions' is not an array"; | ||
for (const picojson::value &v : entry.get<picojson::array>()) | ||
{ | ||
if (!v.is<std::string>()) | ||
return "'suppressions' array entry is not a string"; | ||
const std::string &s = v.get<std::string>(); | ||
const std::string err = nomsg.addSuppressionLine(s); | ||
if (!err.empty()) | ||
return "could not parse suppression '" + s + "' - " + err; | ||
} | ||
} | ||
} | ||
|
||
return ""; | ||
} | ||
|
||
std::string Settings::parseEnabled(const std::string &str, std::tuple<SimpleEnableGroup<Severity>, SimpleEnableGroup<Checks>> &groups) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@firewave May I ask you why do we need to create the local settings here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we do not accidentally load the config multiple times times. That should be done in a deterministic way once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay agree on that one. But you only creating local variable so it's not working.
adding
static
to it will help though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is not working? We only need to compare s single string from the object. Also this is only done during the parsing of the command-line options.
What? The method or the object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both but as you've already marked the method you need to add it only here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the object it would not help as it still requires the function call.
I think I did look at the method but I am not sure. It is also just a limited usage.