#1666 CommandFile: Add error messages to reading.

Remove some  reader bugs
This commit is contained in:
Jacob Støren 2017-06-29 16:12:51 +02:00
parent 64bee4bb57
commit c25895bdad
9 changed files with 155 additions and 29 deletions

View File

@ -17,13 +17,15 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
#include "RicfFieldCapability.h" #include "RicfFieldCapability.h"
#include "RicfMessages.h"
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicfFieldReader<QString>::readFieldData(QString& fieldValue, QTextStream& inputStream) void RicfFieldReader<QString>::readFieldData(QString& fieldValue, QTextStream& inputStream, RicfMessages* errorMessageContainer)
{ {
fieldValue = ""; fieldValue = "";
@ -59,6 +61,7 @@ void RicfFieldReader<QString>::readFieldData(QString& fieldValue, QTextStream& i
{ {
// Unexpected start of string, Missing '"' // Unexpected start of string, Missing '"'
// Error message // Error message
errorMessageContainer->addError("String argument does not seem to be quoted. Missing the start '\"'");
// Could interpret as unquoted text // Could interpret as unquoted text
} }

View File

@ -23,12 +23,19 @@
#include <QTextStream> #include <QTextStream>
#include <QString> #include <QString>
class RicfMessages;
template <typename DataType> template <typename DataType>
struct RicfFieldReader struct RicfFieldReader
{ {
static void readFieldData(DataType & fieldValue, QTextStream& inputStream) static void readFieldData(DataType & fieldValue, QTextStream& inputStream, RicfMessages* errorMessageContainer)
{ {
inputStream >> fieldValue; inputStream >> fieldValue;
if (inputStream.status() == QTextStream::ReadCorruptData)
{
errorMessageContainer->addError("Argument value is unreadable");
inputStream.setStatus( QTextStream::Ok);
}
} }
}; };
@ -44,7 +51,7 @@ struct RicfFieldWriter
template <> template <>
struct RicfFieldReader<QString> struct RicfFieldReader<QString>
{ {
static void readFieldData(QString & fieldValue, QTextStream& inputStream); static void readFieldData(QString & fieldValue, QTextStream& inputStream, RicfMessages* errorMessageContainer);
}; };
template <> template <>
@ -68,11 +75,11 @@ public:
// Xml Serializing // Xml Serializing
public: public:
virtual void readFieldData (QTextStream& inputStream, caf::PdmObjectFactory* objectFactory) override virtual void readFieldData (QTextStream& inputStream, caf::PdmObjectFactory* objectFactory, RicfMessages* errorMessageContainer) override
{ {
//m_field->xmlCapability()->assertValid(); //m_field->xmlCapability()->assertValid();
typename FieldType::FieldDataType value; typename FieldType::FieldDataType value;
RicfFieldReader<typename FieldType::FieldDataType>::readFieldData(value, inputStream); RicfFieldReader<typename FieldType::FieldDataType>::readFieldData(value, inputStream, errorMessageContainer);
m_field->setValue(value); m_field->setValue(value);
} }

View File

@ -25,6 +25,8 @@ class PdmObjectFactory;
class PdmFieldHandle; class PdmFieldHandle;
} }
class RicfMessages;
class QTextStream; class QTextStream;
//================================================================================================== //==================================================================================================
@ -39,7 +41,9 @@ public:
virtual ~RicfFieldHandle(); virtual ~RicfFieldHandle();
virtual void readFieldData (QTextStream& inputStream, caf::PdmObjectFactory* objectFactory) = 0; virtual void readFieldData (QTextStream& inputStream,
caf::PdmObjectFactory* objectFactory,
RicfMessages* errorMessageContainer ) = 0;
virtual void writeFieldData(QTextStream& outputStream) const = 0; virtual void writeFieldData(QTextStream& outputStream) const = 0;
private: private:

View File

@ -0,0 +1,38 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <vector>
#include <QString>
class RicfMessages
{
public:
enum MessageType
{
WARNING,
ERROR
};
void addWarning(const QString& message) { m_messages.push_back(std::make_pair(WARNING, message));}
void addError(const QString& message) { m_messages.push_back(std::make_pair(ERROR, message));}
std::vector<std::pair<MessageType, QString> > m_messages;
};

View File

@ -21,6 +21,8 @@
#include <QTextStream> #include <QTextStream>
#include "RicfFieldHandle.h" #include "RicfFieldHandle.h"
#include "cafPdmXmlFieldHandle.h" #include "cafPdmXmlFieldHandle.h"
#include "RicfMessages.h"
@ -44,14 +46,17 @@ RicfObjectCapability::~RicfObjectCapability()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicfObjectCapability::readFields(QTextStream& inputStream, caf::PdmObjectFactory* objectFactory) void RicfObjectCapability::readFields(QTextStream& inputStream,
caf::PdmObjectFactory* objectFactory,
RicfMessages* errorMessageContainer)
{ {
std::set<QString> readFields; std::set<QString> readFields;
bool readLastArgument = false; bool isLastArgumentRead = false;
while ( !inputStream.atEnd() && !readLastArgument ) while ( !inputStream.atEnd() && !isLastArgumentRead )
{ {
// Read field keyword // Read field keyword
bool fieldDataFound = true;
bool isEndOfArgumentFound = false;
QString keyword; QString keyword;
{ {
inputStream.skipWhiteSpace(); inputStream.skipWhiteSpace();
@ -69,6 +74,16 @@ void RicfObjectCapability::readFields(QTextStream& inputStream, caf::PdmObjectFa
if ( currentChar != QChar('=') ) if ( currentChar != QChar('=') )
{ {
// Error message: Missing "=" after argument name // Error message: Missing "=" after argument name
errorMessageContainer->addError("Can't find the '=' after the argument named: \"" + keyword);
fieldDataFound = false;
if (currentChar == QChar(')') )
{
isLastArgumentRead = true;
}
else if (currentChar == QChar(',') )
{
isEndOfArgumentFound = true;
}
} }
break; break;
} }
@ -84,9 +99,12 @@ void RicfObjectCapability::readFields(QTextStream& inputStream, caf::PdmObjectFa
if ( readFields.count(keyword) ) if ( readFields.count(keyword) )
{ {
// Warning message: Referenced the same argument several times // Warning message: Referenced the same argument several times
errorMessageContainer->addWarning("The argument: \"" + keyword + "\" is referenced several times." );
} }
} }
if (fieldDataFound)
{
// Make field read its data // Make field read its data
caf::PdmFieldHandle* fieldHandle = m_owner->findField(keyword); caf::PdmFieldHandle* fieldHandle = m_owner->findField(keyword);
@ -97,16 +115,19 @@ void RicfObjectCapability::readFields(QTextStream& inputStream, caf::PdmObjectFa
if ( xmlFieldHandle->isIOReadable() ) if ( xmlFieldHandle->isIOReadable() )
{ {
rcfField->readFieldData(inputStream, objectFactory); rcfField->readFieldData(inputStream, objectFactory, errorMessageContainer);
} }
} }
else else
{ {
// Error message: Unknown argument name // Error message: Unknown argument name
errorMessageContainer->addWarning("The argument: \"" + keyword + "\" does not exist.");
}
} }
// Skip to end of argument ',' or end of call ')' // Skip to end of argument ',' or end of call ')'
if (!(isLastArgumentRead || isEndOfArgumentFound) )
{ {
QChar currentChar; QChar currentChar;
bool isOutsideQuotes = true; bool isOutsideQuotes = true;
@ -122,7 +143,7 @@ void RicfObjectCapability::readFields(QTextStream& inputStream, caf::PdmObjectFa
if ( currentChar == QChar(')') ) if ( currentChar == QChar(')') )
{ {
readLastArgument = true; isLastArgumentRead = true;
break; break;
} }
if ( currentChar == QChar('\"') ) if ( currentChar == QChar('\"') )

View File

@ -26,6 +26,7 @@ class PdmObjectFactory;
} }
class QTextStream; class QTextStream;
class RicfMessages;
//================================================================================================== //==================================================================================================
// //
@ -39,7 +40,7 @@ public:
virtual ~RicfObjectCapability(); virtual ~RicfObjectCapability();
void readFields(QTextStream& inputStream, caf::PdmObjectFactory* objectFactory); void readFields(QTextStream& inputStream, caf::PdmObjectFactory* objectFactory, RicfMessages* errorMessageContainer);
void writeFields(QTextStream& outputStream) const; void writeFields(QTextStream& outputStream) const;
private: private:

View File

@ -20,6 +20,7 @@
#include "RicfCommandObject.h" #include "RicfCommandObject.h"
#include "RicfObjectCapability.h" #include "RicfObjectCapability.h"
#include "RicfMessages.h"
#include "cafPdmObjectFactory.h" #include "cafPdmObjectFactory.h"
@ -29,7 +30,8 @@
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::vector<RicfCommandObject*> RicfCommandFileReader::readCommands(QTextStream& inputStream, std::vector<RicfCommandObject*> RicfCommandFileReader::readCommands(QTextStream& inputStream,
caf::PdmObjectFactory* objectFactory) caf::PdmObjectFactory* objectFactory,
RicfMessages* errorMessageContainer)
{ {
std::vector<RicfCommandObject*> readCommands; std::vector<RicfCommandObject*> readCommands;
@ -54,6 +56,8 @@ std::vector<RicfCommandObject*> RicfCommandFileReader::readCommands(QTextStream&
if ( isBracket != QChar('(') ) if ( isBracket != QChar('(') )
{ {
// Error, could not find start bracket for command // Error, could not find start bracket for command
errorMessageContainer->addError("Could not find start bracket for command " + commandName);
return readCommands; return readCommands;
} }
break; break;
@ -72,6 +76,8 @@ std::vector<RicfCommandObject*> RicfCommandFileReader::readCommands(QTextStream&
if ( cObj == nullptr ) if ( cObj == nullptr )
{ {
errorMessageContainer->addError("The command: \"" + commandName + "\" does not exist.");
// Error: Unknown command // Error: Unknown command
// Skip to end of command // Skip to end of command
QChar currentChar; QChar currentChar;
@ -108,7 +114,7 @@ std::vector<RicfCommandObject*> RicfCommandFileReader::readCommands(QTextStream&
{ {
readCommands.push_back(cObj); readCommands.push_back(cObj);
auto rcfCap = cObj->capability<RicfObjectCapability>(); auto rcfCap = cObj->capability<RicfObjectCapability>();
rcfCap->readFields(inputStream, objectFactory); rcfCap->readFields(inputStream, objectFactory, errorMessageContainer);
} }
} }

View File

@ -26,6 +26,8 @@ namespace caf
class PdmObjectFactory; class PdmObjectFactory;
} }
class RicfMessages;
//================================================================================================== //==================================================================================================
// //
// //
@ -35,7 +37,8 @@ class RicfCommandFileReader
{ {
public: public:
static std::vector<RicfCommandObject*> readCommands(QTextStream& inputStream, static std::vector<RicfCommandObject*> readCommands(QTextStream& inputStream,
caf::PdmObjectFactory* objectFactory); caf::PdmObjectFactory* objectFactory,
RicfMessages* errorMessageContainer);
static void writeCommands(QTextStream& outputStream, static void writeCommands(QTextStream& outputStream,
const std::vector<RicfCommandObject*>& commandsToWrite); const std::vector<RicfCommandObject*>& commandsToWrite);
}; };

View File

@ -3,6 +3,7 @@
#include "RifcCommandFileReader.h" #include "RifcCommandFileReader.h"
#include "RicfCommandObject.h" #include "RicfCommandObject.h"
#include "cafPdmField.h" #include "cafPdmField.h"
#include "RicfMessages.h"
class TestCommand1: public RicfCommandObject class TestCommand1: public RicfCommandObject
{ {
@ -63,8 +64,9 @@ TEST(RicfCommands, Test1)
//std::cout << commandString.toStdString() << std::endl; //std::cout << commandString.toStdString() << std::endl;
QTextStream inputStream(&commandString); QTextStream inputStream(&commandString);
RicfMessages errors;
auto objects = RicfCommandFileReader::readCommands(inputStream, caf::PdmDefaultObjectFactory::instance()); auto objects = RicfCommandFileReader::readCommands(inputStream, caf::PdmDefaultObjectFactory::instance(), &errors);
EXPECT_EQ(4, objects.size()); EXPECT_EQ(4, objects.size());
auto tc2 = dynamic_cast<TestCommand1*>(objects[0]); auto tc2 = dynamic_cast<TestCommand1*>(objects[0]);
@ -94,3 +96,44 @@ TEST(RicfCommands, Test1)
delete(obj); delete(obj);
} }
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(RicfCommands, ErrorMessages)
{
QString commandString("TesCommand1(IntArgument=3, TextArgument=\"Dette er en tekst, \\\"og\\\" jeg er: (happy)\", DoubleArgument=5.0e3) \n"
"TestCommand1 ( IntArgument = , \n TextA rgument = \"Dette er en tekst, \\\"og\\\" jeg er: (happy)\", \n DoubleArgument ) \n"
" TestCommand1(TextArgument=Litt kortere tekst.\") \n"
"TC3 ( ta = \"Hepp\", ia = 3, da= 0.123)");
//std::cout << commandString.toStdString() << std::endl;
QTextStream inputStream(&commandString);
RicfMessages errors;
auto objects = RicfCommandFileReader::readCommands(inputStream, caf::PdmDefaultObjectFactory::instance(), &errors);
EXPECT_EQ(2, objects.size());
EXPECT_EQ(5, errors.m_messages.size());
for (const auto& msg: errors.m_messages)
{
QString label;
if (msg.first == RicfMessages::ERROR)
{
label = "Error : ";
}
else
{
label = "Warning: ";
}
std::cout << label.toStdString() << msg.second.toStdString() << std::endl;
}
for (auto obj: objects)
{
delete(obj);
}
}