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

View File

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

View File

@ -25,6 +25,8 @@ class PdmObjectFactory;
class PdmFieldHandle;
}
class RicfMessages;
class QTextStream;
//==================================================================================================
@ -39,7 +41,9 @@ public:
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;
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 "RicfFieldHandle.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;
bool readLastArgument = false;
while ( !inputStream.atEnd() && !readLastArgument )
bool isLastArgumentRead = false;
while ( !inputStream.atEnd() && !isLastArgumentRead )
{
// Read field keyword
bool fieldDataFound = true;
bool isEndOfArgumentFound = false;
QString keyword;
{
inputStream.skipWhiteSpace();
@ -69,6 +74,16 @@ void RicfObjectCapability::readFields(QTextStream& inputStream, caf::PdmObjectFa
if ( currentChar != QChar('=') )
{
// 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;
}
@ -84,29 +99,35 @@ void RicfObjectCapability::readFields(QTextStream& inputStream, caf::PdmObjectFa
if ( readFields.count(keyword) )
{
// Warning message: Referenced the same argument several times
errorMessageContainer->addWarning("The argument: \"" + keyword + "\" is referenced several times." );
}
}
// Make field read its data
caf::PdmFieldHandle* fieldHandle = m_owner->findField(keyword);
if ( fieldHandle && fieldHandle->xmlCapability() && fieldHandle->capability<RicfFieldHandle>() )
if (fieldDataFound)
{
caf::PdmXmlFieldHandle* xmlFieldHandle = fieldHandle->xmlCapability();
RicfFieldHandle* rcfField = fieldHandle->capability<RicfFieldHandle>();
// Make field read its data
if ( xmlFieldHandle->isIOReadable() )
caf::PdmFieldHandle* fieldHandle = m_owner->findField(keyword);
if ( fieldHandle && fieldHandle->xmlCapability() && fieldHandle->capability<RicfFieldHandle>() )
{
rcfField->readFieldData(inputStream, objectFactory);
}
caf::PdmXmlFieldHandle* xmlFieldHandle = fieldHandle->xmlCapability();
RicfFieldHandle* rcfField = fieldHandle->capability<RicfFieldHandle>();
}
else
{
// Error message: Unknown argument name
if ( xmlFieldHandle->isIOReadable() )
{
rcfField->readFieldData(inputStream, objectFactory, errorMessageContainer);
}
}
else
{
// Error message: Unknown argument name
errorMessageContainer->addWarning("The argument: \"" + keyword + "\" does not exist.");
}
}
// Skip to end of argument ',' or end of call ')'
if (!(isLastArgumentRead || isEndOfArgumentFound) )
{
QChar currentChar;
bool isOutsideQuotes = true;
@ -122,7 +143,7 @@ void RicfObjectCapability::readFields(QTextStream& inputStream, caf::PdmObjectFa
if ( currentChar == QChar(')') )
{
readLastArgument = true;
isLastArgumentRead = true;
break;
}
if ( currentChar == QChar('\"') )

View File

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

View File

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

View File

@ -3,6 +3,7 @@
#include "RifcCommandFileReader.h"
#include "RicfCommandObject.h"
#include "cafPdmField.h"
#include "RicfMessages.h"
class TestCommand1: public RicfCommandObject
{
@ -63,8 +64,9 @@ TEST(RicfCommands, Test1)
//std::cout << commandString.toStdString() << std::endl;
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());
auto tc2 = dynamic_cast<TestCommand1*>(objects[0]);
@ -89,6 +91,47 @@ TEST(RicfCommands, Test1)
obj->execute();
}
for (auto obj: objects)
{
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);