Library: Better error reporting when loading fails
This commit is contained in:
parent
1cb14f687f
commit
ed78d3e148
|
@ -504,8 +504,35 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
|
|
||||||
// --library
|
// --library
|
||||||
else if (std::strncmp(argv[i], "--library=", 10) == 0) {
|
else if (std::strncmp(argv[i], "--library=", 10) == 0) {
|
||||||
if (!_settings->library.load(argv[0], argv[i]+10)) {
|
Library::Error err = _settings->library.load(argv[0], argv[i]+10);
|
||||||
PrintMessage("cppcheck: Failed to load library configuration file '" + std::string(argv[i]+10) + "'");
|
std::string errmsg;
|
||||||
|
switch (err.errorcode) {
|
||||||
|
case Library::ErrorCode::OK:
|
||||||
|
break;
|
||||||
|
case Library::ErrorCode::FILE_NOT_FOUND:
|
||||||
|
errmsg = "File not found";
|
||||||
|
break;
|
||||||
|
case Library::ErrorCode::BAD_XML:
|
||||||
|
errmsg = "Bad XML";
|
||||||
|
break;
|
||||||
|
case Library::ErrorCode::BAD_ELEMENT:
|
||||||
|
errmsg = "Unexpected element";
|
||||||
|
break;
|
||||||
|
case Library::ErrorCode::MISSING_ATTRIBUTE:
|
||||||
|
errmsg = "Missing attribute";
|
||||||
|
break;
|
||||||
|
case Library::ErrorCode::BAD_ATTRIBUTE:
|
||||||
|
errmsg = "Bad attribute";
|
||||||
|
break;
|
||||||
|
case Library::ErrorCode::BAD_ATTRIBUTE_VALUE:
|
||||||
|
errmsg = "Bad attribute value";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!err.reason.empty())
|
||||||
|
errmsg += " '" + err.reason + "'";
|
||||||
|
|
||||||
|
if (!errmsg.empty()) {
|
||||||
|
PrintMessage("cppcheck: Failed to load library configuration file '" + std::string(argv[i]+10) + "'. " + errmsg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -480,10 +480,10 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha
|
||||||
{
|
{
|
||||||
Settings& settings = cppcheck.settings();
|
Settings& settings = cppcheck.settings();
|
||||||
_settings = &settings;
|
_settings = &settings;
|
||||||
bool std = settings.library.load(argv[0], "std.cfg");
|
bool std = (settings.library.load(argv[0], "std.cfg").errorcode == Library::ErrorCode::OK);
|
||||||
bool posix = true;
|
bool posix = true;
|
||||||
if (settings.standards.posix)
|
if (settings.standards.posix)
|
||||||
posix = settings.library.load(argv[0], "posix.cfg");
|
posix = (settings.library.load(argv[0], "posix.cfg").errorcode == Library::ErrorCode::OK);
|
||||||
|
|
||||||
if (!std || !posix) {
|
if (!std || !posix) {
|
||||||
const std::list<ErrorLogger::ErrorMessage::FileLocation> callstack;
|
const std::list<ErrorLogger::ErrorMessage::FileLocation> callstack;
|
||||||
|
|
|
@ -518,23 +518,23 @@ bool MainWindow::LoadLibrary(Library *library, QString filename)
|
||||||
// Try to load the library from the project folder..
|
// Try to load the library from the project folder..
|
||||||
if (mProject) {
|
if (mProject) {
|
||||||
QString path = QFileInfo(mProject->GetProjectFile()->GetFilename()).canonicalPath();
|
QString path = QFileInfo(mProject->GetProjectFile()->GetFilename()).canonicalPath();
|
||||||
if (library->load(NULL, (path+"/"+filename).toLatin1()))
|
if (library->load(NULL, (path+"/"+filename).toLatin1()).errorcode == Library::ErrorCode::OK)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to load the library from the application folder..
|
// Try to load the library from the application folder..
|
||||||
const QString appPath = QFileInfo(QCoreApplication::applicationFilePath()).canonicalPath();
|
const QString appPath = QFileInfo(QCoreApplication::applicationFilePath()).canonicalPath();
|
||||||
if (library->load(NULL, (appPath+"/"+filename).toLatin1()))
|
if (library->load(NULL, (appPath+"/"+filename).toLatin1()).errorcode == Library::ErrorCode::OK)
|
||||||
return true;
|
return true;
|
||||||
if (library->load(NULL, (appPath+"/cfg/"+filename).toLatin1()))
|
if (library->load(NULL, (appPath+"/cfg/"+filename).toLatin1()).errorcode == Library::ErrorCode::OK)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Try to load the library from the cfg subfolder..
|
// Try to load the library from the cfg subfolder..
|
||||||
const QString datadir = mSettings->value("DATADIR", QString()).toString();
|
const QString datadir = mSettings->value("DATADIR", QString()).toString();
|
||||||
if (!datadir.isEmpty()) {
|
if (!datadir.isEmpty()) {
|
||||||
if (library->load(NULL, (datadir+"/"+filename).toLatin1()))
|
if (library->load(NULL, (datadir+"/"+filename).toLatin1()).errorcode == Library::ErrorCode::OK)
|
||||||
return true;
|
return true;
|
||||||
if (library->load(NULL, (datadir+"/cfg/"+filename).toLatin1()))
|
if (library->load(NULL, (datadir+"/cfg/"+filename).toLatin1()).errorcode == Library::ErrorCode::OK)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,19 +30,20 @@ Library::Library() : allocid(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Library::load(const char exename[], const char path[])
|
Library::Error Library::load(const char exename[], const char path[])
|
||||||
{
|
{
|
||||||
if (std::strchr(path,',') != nullptr) {
|
if (std::strchr(path,',') != nullptr) {
|
||||||
bool ret = true;
|
|
||||||
std::string p(path);
|
std::string p(path);
|
||||||
while (p.find(",") != std::string::npos) {
|
while (p.find(",") != std::string::npos) {
|
||||||
const std::string::size_type pos = p.find(",");
|
const std::string::size_type pos = p.find(",");
|
||||||
ret &= load(exename, p.substr(0,pos).c_str());
|
const Error &e = load(exename, p.substr(0,pos).c_str());
|
||||||
|
if (e.errorcode != ErrorCode::OK)
|
||||||
|
return e;
|
||||||
p = p.substr(pos+1);
|
p = p.substr(pos+1);
|
||||||
}
|
}
|
||||||
if (!p.empty())
|
if (!p.empty())
|
||||||
ret &= load(exename, p.c_str());
|
return load(exename, p.c_str());
|
||||||
return ret;
|
return Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
// open file..
|
// open file..
|
||||||
|
@ -62,7 +63,7 @@ bool Library::load(const char exename[], const char path[])
|
||||||
const std::string cfgfolder(CFGDIR);
|
const std::string cfgfolder(CFGDIR);
|
||||||
#else
|
#else
|
||||||
if (!exename)
|
if (!exename)
|
||||||
return false;
|
return Error(ErrorCode::FILE_NOT_FOUND);
|
||||||
const std::string cfgfolder(Path::fromNativeSeparators(Path::getPathFromFilename(exename)) + "cfg");
|
const std::string cfgfolder(Path::fromNativeSeparators(Path::getPathFromFilename(exename)) + "cfg");
|
||||||
#endif
|
#endif
|
||||||
const char *sep = (!cfgfolder.empty() && cfgfolder[cfgfolder.size()-1U]=='/' ? "" : "/");
|
const char *sep = (!cfgfolder.empty() && cfgfolder[cfgfolder.size()-1U]=='/' ? "" : "/");
|
||||||
|
@ -71,24 +72,24 @@ bool Library::load(const char exename[], const char path[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (error == tinyxml2::XML_NO_ERROR) && load(doc);
|
return (error == tinyxml2::XML_NO_ERROR) ? load(doc) : Error(ErrorCode::BAD_XML);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Library::loadxmldata(const char xmldata[], std::size_t len)
|
bool Library::loadxmldata(const char xmldata[], std::size_t len)
|
||||||
{
|
{
|
||||||
tinyxml2::XMLDocument doc;
|
tinyxml2::XMLDocument doc;
|
||||||
return (tinyxml2::XML_NO_ERROR == doc.Parse(xmldata, len)) && load(doc);
|
return (tinyxml2::XML_NO_ERROR == doc.Parse(xmldata, len)) && (load(doc).errorcode == ErrorCode::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Library::load(const tinyxml2::XMLDocument &doc)
|
Library::Error Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
{
|
{
|
||||||
const tinyxml2::XMLElement * const rootnode = doc.FirstChildElement();
|
const tinyxml2::XMLElement * const rootnode = doc.FirstChildElement();
|
||||||
|
|
||||||
if (rootnode == nullptr)
|
if (rootnode == nullptr)
|
||||||
return false;
|
return Error(ErrorCode::BAD_XML);
|
||||||
|
|
||||||
if (strcmp(rootnode->Name(),"def") != 0)
|
if (strcmp(rootnode->Name(),"def") != 0)
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, rootnode->Name());
|
||||||
|
|
||||||
for (const tinyxml2::XMLElement *node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) {
|
for (const tinyxml2::XMLElement *node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) {
|
||||||
if (strcmp(node->Name(),"memory")==0 || strcmp(node->Name(),"resource")==0) {
|
if (strcmp(node->Name(),"memory")==0 || strcmp(node->Name(),"resource")==0) {
|
||||||
|
@ -124,17 +125,17 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
else if (strcmp(memorynode->Name(),"use")==0)
|
else if (strcmp(memorynode->Name(),"use")==0)
|
||||||
use.insert(memorynode->GetText());
|
use.insert(memorynode->GetText());
|
||||||
else
|
else
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, memorynode->Name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(node->Name(),"define")==0) {
|
else if (strcmp(node->Name(),"define")==0) {
|
||||||
const char *name = node->Attribute("name");
|
const char *name = node->Attribute("name");
|
||||||
if (name == nullptr)
|
if (name == nullptr)
|
||||||
return false;
|
return Error(ErrorCode::MISSING_ATTRIBUTE, "name");
|
||||||
const char *value = node->Attribute("value");
|
const char *value = node->Attribute("value");
|
||||||
if (value == nullptr)
|
if (value == nullptr)
|
||||||
return false;
|
return Error(ErrorCode::MISSING_ATTRIBUTE, "value");
|
||||||
defines.push_back(std::string("#define ") +
|
defines.push_back(std::string("#define ") +
|
||||||
name +
|
name +
|
||||||
" " +
|
" " +
|
||||||
|
@ -145,7 +146,7 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
else if (strcmp(node->Name(),"function")==0) {
|
else if (strcmp(node->Name(),"function")==0) {
|
||||||
const char *name = node->Attribute("name");
|
const char *name = node->Attribute("name");
|
||||||
if (name == nullptr)
|
if (name == nullptr)
|
||||||
return false;
|
return Error(ErrorCode::MISSING_ATTRIBUTE, "name");
|
||||||
|
|
||||||
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
|
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
|
||||||
if (strcmp(functionnode->Name(),"noreturn")==0)
|
if (strcmp(functionnode->Name(),"noreturn")==0)
|
||||||
|
@ -181,7 +182,7 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
// Validate the validation expression
|
// Validate the validation expression
|
||||||
const char *p = argnode->GetText();
|
const char *p = argnode->GetText();
|
||||||
if (!std::isdigit(*p))
|
if (!std::isdigit(*p))
|
||||||
return false;
|
return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, argnode->GetText());
|
||||||
for (; *p; p++) {
|
for (; *p; p++) {
|
||||||
if (std::isdigit(*p))
|
if (std::isdigit(*p))
|
||||||
continue;
|
continue;
|
||||||
|
@ -189,7 +190,7 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
continue;
|
continue;
|
||||||
if (*p == ',' && *(p+1) != ',')
|
if (*p == ',' && *(p+1) != ',')
|
||||||
continue;
|
continue;
|
||||||
return false;
|
return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, argnode->GetText());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set validation expression
|
// Set validation expression
|
||||||
|
@ -197,7 +198,7 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
return false;
|
return Error(ErrorCode::BAD_ATTRIBUTE, argnode->Name());
|
||||||
}
|
}
|
||||||
argumentChecks[name][nr].notbool = notbool;
|
argumentChecks[name][nr].notbool = notbool;
|
||||||
argumentChecks[name][nr].notnull = notnull;
|
argumentChecks[name][nr].notnull = notnull;
|
||||||
|
@ -212,18 +213,18 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
const tinyxml2::XMLAttribute* secure = functionnode->FindAttribute("secure");
|
const tinyxml2::XMLAttribute* secure = functionnode->FindAttribute("secure");
|
||||||
_formatstr[name] = std::make_pair(scan && scan->BoolValue(), secure && secure->BoolValue());
|
_formatstr[name] = std::make_pair(scan && scan->BoolValue(), secure && secure->BoolValue());
|
||||||
} else
|
} else
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, functionnode->Name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(node->Name(), "reflection") == 0) {
|
else if (strcmp(node->Name(), "reflection") == 0) {
|
||||||
for (const tinyxml2::XMLElement *reflectionnode = node->FirstChildElement(); reflectionnode; reflectionnode = reflectionnode->NextSiblingElement()) {
|
for (const tinyxml2::XMLElement *reflectionnode = node->FirstChildElement(); reflectionnode; reflectionnode = reflectionnode->NextSiblingElement()) {
|
||||||
if (strcmp(reflectionnode->Name(), "call") != 0)
|
if (strcmp(reflectionnode->Name(), "call") != 0)
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, reflectionnode->Name());
|
||||||
|
|
||||||
const char * const argString = reflectionnode->Attribute("arg");
|
const char * const argString = reflectionnode->Attribute("arg");
|
||||||
if (!argString)
|
if (!argString)
|
||||||
return false;
|
return Error(ErrorCode::MISSING_ATTRIBUTE, "arg");
|
||||||
|
|
||||||
_reflection[reflectionnode->GetText()] = atoi(argString);
|
_reflection[reflectionnode->GetText()] = atoi(argString);
|
||||||
}
|
}
|
||||||
|
@ -232,7 +233,7 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
else if (strcmp(node->Name(), "markup") == 0) {
|
else if (strcmp(node->Name(), "markup") == 0) {
|
||||||
const char * const extension = node->Attribute("ext");
|
const char * const extension = node->Attribute("ext");
|
||||||
if (!extension)
|
if (!extension)
|
||||||
return false;
|
return Error(ErrorCode::MISSING_ATTRIBUTE, "ext");
|
||||||
_markupExtensions.insert(extension);
|
_markupExtensions.insert(extension);
|
||||||
|
|
||||||
const char * const reporterrors = node->Attribute("reporterrors");
|
const char * const reporterrors = node->Attribute("reporterrors");
|
||||||
|
@ -246,18 +247,18 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
if (strcmp(librarynode->Name(), "keyword") == 0)
|
if (strcmp(librarynode->Name(), "keyword") == 0)
|
||||||
_keywords[extension].insert(librarynode->Attribute("name"));
|
_keywords[extension].insert(librarynode->Attribute("name"));
|
||||||
else
|
else
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, librarynode->Name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(markupnode->Name(), "exported") == 0) {
|
else if (strcmp(markupnode->Name(), "exported") == 0) {
|
||||||
for (const tinyxml2::XMLElement *exporter = markupnode->FirstChildElement(); exporter; exporter = exporter->NextSiblingElement()) {
|
for (const tinyxml2::XMLElement *exporter = markupnode->FirstChildElement(); exporter; exporter = exporter->NextSiblingElement()) {
|
||||||
if (strcmp(exporter->Name(), "exporter") != 0)
|
if (strcmp(exporter->Name(), "exporter") != 0)
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, exporter->Name());
|
||||||
|
|
||||||
const char * const prefix = exporter->Attribute("prefix");
|
const char * const prefix = exporter->Attribute("prefix");
|
||||||
if (!prefix)
|
if (!prefix)
|
||||||
return false;
|
return Error(ErrorCode::MISSING_ATTRIBUTE, "prefix");
|
||||||
|
|
||||||
for (const tinyxml2::XMLElement *e = exporter->FirstChildElement(); e; e = e->NextSiblingElement()) {
|
for (const tinyxml2::XMLElement *e = exporter->FirstChildElement(); e; e = e->NextSiblingElement()) {
|
||||||
if (strcmp(e->Name(), "prefix") == 0)
|
if (strcmp(e->Name(), "prefix") == 0)
|
||||||
|
@ -265,7 +266,7 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
else if (strcmp(e->Name(), "suffix") == 0)
|
else if (strcmp(e->Name(), "suffix") == 0)
|
||||||
_exporters[prefix].addSuffix(e->GetText());
|
_exporters[prefix].addSuffix(e->GetText());
|
||||||
else
|
else
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, e->Name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,7 +276,7 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
if (strcmp(librarynode->Name(), "importer") == 0)
|
if (strcmp(librarynode->Name(), "importer") == 0)
|
||||||
_importers[extension].insert(librarynode->GetText());
|
_importers[extension].insert(librarynode->GetText());
|
||||||
else
|
else
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, librarynode->Name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,19 +298,19 @@ bool Library::load(const tinyxml2::XMLDocument &doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, blocknode->Name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, markupnode->Name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
return false;
|
return Error(ErrorCode::BAD_ELEMENT, node->Name());
|
||||||
}
|
}
|
||||||
return true;
|
return Error(ErrorCode::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Library::isargvalid(const std::string &functionName, int argnr, const MathLib::bigint argvalue) const
|
bool Library::isargvalid(const std::string &functionName, int argnr, const MathLib::bigint argvalue) const
|
||||||
|
|
|
@ -46,9 +46,22 @@ class CPPCHECKLIB Library {
|
||||||
public:
|
public:
|
||||||
Library();
|
Library();
|
||||||
|
|
||||||
bool load(const char exename [], const char path []);
|
enum ErrorCode { OK, FILE_NOT_FOUND, BAD_XML, BAD_ELEMENT, MISSING_ATTRIBUTE, BAD_ATTRIBUTE, BAD_ATTRIBUTE_VALUE };
|
||||||
|
|
||||||
|
class Error {
|
||||||
|
public:
|
||||||
|
Error() : errorcode(ErrorCode::OK) , reason("") {}
|
||||||
|
explicit Error(ErrorCode e) : errorcode(e) , reason("") {}
|
||||||
|
Error(ErrorCode e, const std::string &r) : errorcode(e), reason(r) {}
|
||||||
|
ErrorCode errorcode;
|
||||||
|
std::string reason;
|
||||||
|
};
|
||||||
|
|
||||||
|
Error load(const char exename [], const char path []);
|
||||||
|
Error load(const tinyxml2::XMLDocument &doc);
|
||||||
|
|
||||||
|
/** this is primarily meant for unit tests. it only returns true/false */
|
||||||
bool loadxmldata(const char xmldata[], std::size_t len);
|
bool loadxmldata(const char xmldata[], std::size_t len);
|
||||||
bool load(const tinyxml2::XMLDocument &doc);
|
|
||||||
|
|
||||||
/** get allocation id for function by name */
|
/** get allocation id for function by name */
|
||||||
int alloc(const char name[]) const {
|
int alloc(const char name[]) const {
|
||||||
|
|
|
@ -493,7 +493,7 @@ private:
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
Settings settings;
|
Settings settings;
|
||||||
if (!settings.library.load("./testrunner", "../cfg/std.cfg") && !settings.library.load("./testrunner", "cfg/std.cfg")) {
|
if ((settings.library.load("./testrunner", "../cfg/std.cfg").errorcode != Library::ErrorCode::OK) && (settings.library.load("./testrunner", "cfg/std.cfg").errorcode != Library::ErrorCode::OK)) {
|
||||||
complainMissingLib("std.cfg");
|
complainMissingLib("std.cfg");
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,9 +85,9 @@ public:
|
||||||
#define REGISTER_TEST( CLASSNAME ) namespace { CLASSNAME instance; }
|
#define REGISTER_TEST( CLASSNAME ) namespace { CLASSNAME instance; }
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define LOAD_LIB_2( LIB, NAME ) { if (!(LIB).load("./testrunner", "../cfg/" NAME) && !(LIB).load("./testrunner", "cfg/" NAME)) { complainMissingLib(NAME); return; } }
|
#define LOAD_LIB_2( LIB, NAME ) { if (((LIB).load("./testrunner", "../cfg/" NAME).errorcode != Library::ErrorCode::OK) && ((LIB).load("./testrunner", "cfg/" NAME).errorcode != Library::ErrorCode::OK)) { complainMissingLib(NAME); return; } }
|
||||||
#else
|
#else
|
||||||
#define LOAD_LIB_2( LIB, NAME ) { if (!(LIB).load("./testrunner", "cfg/" NAME)) { complainMissingLib(NAME); return; } }
|
#define LOAD_LIB_2( LIB, NAME ) { if ((LIB).load("./testrunner", "cfg/" NAME).errorcode != Library::ErrorCode::OK) { complainMissingLib(NAME); return; } }
|
||||||
#endif
|
#endif
|
||||||
#define LOAD_LIB( NAME ) { LOAD_LIB_2(_lib, NAME); }
|
#define LOAD_LIB( NAME ) { LOAD_LIB_2(_lib, NAME); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue