diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp index 0984889be9..c146839d68 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp @@ -17,13 +17,15 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RicfFieldCapability.h" +#include "RicfMessages.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfFieldReader::readFieldData(QString& fieldValue, QTextStream& inputStream) +void RicfFieldReader::readFieldData(QString& fieldValue, QTextStream& inputStream, RicfMessages* errorMessageContainer) { fieldValue = ""; @@ -59,6 +61,7 @@ void RicfFieldReader::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 } diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h index 908cec0e47..30b4ed32a5 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h @@ -23,12 +23,19 @@ #include #include +class RicfMessages; + template 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 { - 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::readFieldData(value, inputStream); + RicfFieldReader::readFieldData(value, inputStream, errorMessageContainer); m_field->setValue(value); } diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h b/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h index 5d01fb0b8d..9879eadace 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h @@ -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: diff --git a/ApplicationCode/CommandFileInterface/Core/RicfMessages.h b/ApplicationCode/CommandFileInterface/Core/RicfMessages.h new file mode 100644 index 0000000000..4b90e88b9b --- /dev/null +++ b/ApplicationCode/CommandFileInterface/Core/RicfMessages.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include + +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 > m_messages; +}; + + diff --git a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp index 78f9ba57ba..a39533e344 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp @@ -21,6 +21,8 @@ #include #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 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() ) + if (fieldDataFound) { - caf::PdmXmlFieldHandle* xmlFieldHandle = fieldHandle->xmlCapability(); - RicfFieldHandle* rcfField = fieldHandle->capability(); + // Make field read its data - if ( xmlFieldHandle->isIOReadable() ) + caf::PdmFieldHandle* fieldHandle = m_owner->findField(keyword); + if ( fieldHandle && fieldHandle->xmlCapability() && fieldHandle->capability() ) { - rcfField->readFieldData(inputStream, objectFactory); - } + caf::PdmXmlFieldHandle* xmlFieldHandle = fieldHandle->xmlCapability(); + RicfFieldHandle* rcfField = fieldHandle->capability(); - } - 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('\"') ) diff --git a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h index ba15514438..8d85319d07 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h @@ -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: diff --git a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp index fcacaaee60..38db987d2b 100644 --- a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp @@ -20,6 +20,7 @@ #include "RicfCommandObject.h" #include "RicfObjectCapability.h" +#include "RicfMessages.h" #include "cafPdmObjectFactory.h" @@ -29,7 +30,8 @@ /// //-------------------------------------------------------------------------------------------------- std::vector RicfCommandFileReader::readCommands(QTextStream& inputStream, - caf::PdmObjectFactory* objectFactory) + caf::PdmObjectFactory* objectFactory, + RicfMessages* errorMessageContainer) { std::vector readCommands; @@ -54,6 +56,8 @@ std::vector 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 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 RicfCommandFileReader::readCommands(QTextStream& { readCommands.push_back(cObj); auto rcfCap = cObj->capability(); - rcfCap->readFields(inputStream, objectFactory); + rcfCap->readFields(inputStream, objectFactory, errorMessageContainer); } } diff --git a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.h b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.h index f1b5c6de2e..9c15cd7022 100644 --- a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.h +++ b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.h @@ -26,6 +26,8 @@ namespace caf class PdmObjectFactory; } +class RicfMessages; + //================================================================================================== // // @@ -35,7 +37,8 @@ class RicfCommandFileReader { public: static std::vector readCommands(QTextStream& inputStream, - caf::PdmObjectFactory* objectFactory); + caf::PdmObjectFactory* objectFactory, + RicfMessages* errorMessageContainer); static void writeCommands(QTextStream& outputStream, const std::vector& commandsToWrite); }; diff --git a/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp b/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp index 1b9f186a00..0749787b2b 100644 --- a/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp +++ b/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp @@ -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(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);