From 247192452f7afd31e13058d220a08929501396ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 12 Nov 2017 21:03:22 +0100 Subject: [PATCH] GUI: Better error handling when library file has unhandled elements --- gui/cppchecklibrarydata.cpp | 22 ++++++++++------- gui/cppchecklibrarydata.h | 11 ++++++++- gui/librarydialog.cpp | 49 +++++++++++++++++++++++-------------- 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/gui/cppchecklibrarydata.cpp b/gui/cppchecklibrarydata.cpp index 1707555e9..57ab5c96c 100644 --- a/gui/cppchecklibrarydata.cpp +++ b/gui/cppchecklibrarydata.cpp @@ -28,6 +28,11 @@ CppcheckLibraryData::CppcheckLibraryData() { } +static std::string unhandledElement(const QXmlStreamReader &xmlReader) +{ + throw std::runtime_error(QObject::tr("line %1: Unhandled element %2").arg(xmlReader.lineNumber()).arg(xmlReader.name().toString()).toStdString()); +} + static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader) { CppcheckLibraryData::Container container; @@ -72,7 +77,7 @@ static CppcheckLibraryData::Container loadContainer(QXmlStreamReader &xmlReader) container.otherFunctions.append(function); } } else { - throw std::runtime_error("Unhandled element " + elementName.toStdString()); + unhandledElement(xmlReader); } } return container; @@ -126,7 +131,7 @@ static CppcheckLibraryData::Function::Arg loadFunctionArg(QXmlStreamReader &xmlR arg.iterator.container = xmlReader.attributes().value("container").toInt(); arg.iterator.type = xmlReader.attributes().value("type").toString(); } else { - throw std::runtime_error("Unhandled element " + elementName.toStdString()); + unhandledElement(xmlReader); } } return arg; @@ -170,7 +175,7 @@ static CppcheckLibraryData::Function loadFunction(QXmlStreamReader &xmlReader, c function.warn.alternatives = xmlReader.attributes().value("alternatives").toString(); function.warn.msg = xmlReader.readElementText(); } else { - throw std::runtime_error("Unhandled element " + elementName.toStdString()); + unhandledElement(xmlReader); } } return function; @@ -196,7 +201,7 @@ static CppcheckLibraryData::MemoryResource loadMemoryResource(QXmlStreamReader & else if (elementName == "use") memoryresource.use.append(xmlReader.readElementText()); else - throw std::runtime_error("Unhandled element " + elementName.toStdString()); + unhandledElement(xmlReader); } return memoryresource; } @@ -210,7 +215,7 @@ static CppcheckLibraryData::PodType loadPodType(const QXmlStreamReader &xmlReade return podtype; } -bool CppcheckLibraryData::open(QIODevice &file) +QString CppcheckLibraryData::open(QIODevice &file) { clear(); QString comments; @@ -239,10 +244,9 @@ bool CppcheckLibraryData::open(QIODevice &file) else if (elementName == "podtype") podtypes.append(loadPodType(xmlReader)); else - return false; + unhandledElement(xmlReader); } catch (std::runtime_error &e) { - const QString what(e.what()); - return false; + return e.what(); } comments.clear(); break; @@ -251,7 +255,7 @@ bool CppcheckLibraryData::open(QIODevice &file) } } - return true; + return QString(); } static void writeContainerFunctions(QXmlStreamWriter &xmlWriter, const QString name, int extra, const QList &functions) diff --git a/gui/cppchecklibrarydata.h b/gui/cppchecklibrarydata.h index ae54f230f..26a65c63a 100644 --- a/gui/cppchecklibrarydata.h +++ b/gui/cppchecklibrarydata.h @@ -159,7 +159,16 @@ public: podtypes.clear(); } - bool open(QIODevice &file); + + void swap(CppcheckLibraryData &other) { + containers.swap(other.containers); + defines.swap(other.defines); + functions.swap(other.functions); + memoryresource.swap(other.memoryresource); + podtypes.swap(other.podtypes); + } + + QString open(QIODevice &file); QString toString() const; QList containers; diff --git a/gui/librarydialog.cpp b/gui/librarydialog.cpp index 28e108ab6..5ed07a7f1 100644 --- a/gui/librarydialog.cpp +++ b/gui/librarydialog.cpp @@ -90,31 +90,44 @@ void LibraryDialog::openCfg() return; QFile file(selectedFile); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - ignoreChanges = true; - data.open(file); - mFileName = selectedFile; - ui->buttonSave->setEnabled(false); - ui->buttonSaveAs->setEnabled(true); - ui->filter->clear(); - ui->functions->clear(); - for (CppcheckLibraryData::Function &function : data.functions) { - ui->functions->addItem(new FunctionListItem(ui->functions, - &function, - false)); - } - ui->sortFunctions->setEnabled(!data.functions.empty()); - ui->filter->setEnabled(!data.functions.empty()); - ui->addFunction->setEnabled(true); - ignoreChanges = false; - } else { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox msg(QMessageBox::Critical, tr("Cppcheck"), tr("Can not open file %1.").arg(selectedFile), QMessageBox::Ok, this); msg.exec(); + return; } + + CppcheckLibraryData tempdata; + const QString errmsg = tempdata.open(file); + if (!errmsg.isNull()) { + QMessageBox msg(QMessageBox::Critical, + tr("Cppcheck"), + tr("Failed to load %1. %2.").arg(selectedFile).arg(errmsg), + QMessageBox::Ok, + this); + msg.exec(); + return; + } + + ignoreChanges = true; + data.swap(tempdata); + mFileName = selectedFile; + ui->buttonSave->setEnabled(false); + ui->buttonSaveAs->setEnabled(true); + ui->filter->clear(); + ui->functions->clear(); + for (CppcheckLibraryData::Function &function : data.functions) { + ui->functions->addItem(new FunctionListItem(ui->functions, + &function, + false)); + } + ui->sortFunctions->setEnabled(!data.functions.empty()); + ui->filter->setEnabled(!data.functions.empty()); + ui->addFunction->setEnabled(true); + ignoreChanges = false; } void LibraryDialog::saveCfg()