Merge pull request #1722 from joakim-hove/raw-string-quote
Raw string quote
This commit is contained in:
commit
0f5fddc470
@ -39,6 +39,7 @@ namespace Opm {
|
||||
|
||||
DeckItem() = default;
|
||||
DeckItem( const std::string&, int);
|
||||
DeckItem( const std::string&, RawString);
|
||||
DeckItem( const std::string&, std::string);
|
||||
DeckItem( const std::string&, double) = delete;
|
||||
DeckItem( const std::string&, UDAValue) = delete;
|
||||
@ -80,6 +81,7 @@ namespace Opm {
|
||||
void push_back( int );
|
||||
void push_back( double );
|
||||
void push_back( std::string );
|
||||
void push_back( RawString );
|
||||
void push_back( UDAValue, size_t );
|
||||
void push_back( int, size_t );
|
||||
void push_back( double, size_t );
|
||||
@ -88,6 +90,7 @@ namespace Opm {
|
||||
void push_backDefault( int );
|
||||
void push_backDefault( double );
|
||||
void push_backDefault( std::string );
|
||||
void push_backDefault( RawString );
|
||||
// trying to access the data of a "dummy default item" will raise an exception
|
||||
|
||||
template <typename T>
|
||||
@ -145,6 +148,7 @@ namespace Opm {
|
||||
mutable std::vector< double > dval;
|
||||
std::vector< int > ival;
|
||||
std::vector< std::string > sval;
|
||||
std::vector< RawString > rsval;
|
||||
std::vector< UDAValue > uval;
|
||||
|
||||
type_tag type = type_tag::unknown;
|
||||
|
@ -106,6 +106,7 @@ namespace Opm {
|
||||
double dval;
|
||||
int ival;
|
||||
std::string sval;
|
||||
RawString rsval;
|
||||
UDAValue uval;
|
||||
std::vector< std::string > m_dimensions;
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
#ifndef OPM_TYPETOOLS_HPP
|
||||
#define OPM_TYPETOOLS_HPP
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@ -8,17 +11,49 @@ enum class type_tag {
|
||||
unknown = 0,
|
||||
integer = 1,
|
||||
string = 2,
|
||||
fdouble = 3,
|
||||
uda = 4,
|
||||
raw_string = 3,
|
||||
fdouble = 4,
|
||||
uda = 5,
|
||||
};
|
||||
|
||||
/*
|
||||
The RawString class itself is just a glorified std::string, it does not have
|
||||
any additional data nor behavior which differentiates it from std::string, but
|
||||
the use of a separate string class allows the compiler to differentiate
|
||||
between different behavior for normal strings and raw strings. The special
|
||||
behavior for raw strings is:
|
||||
|
||||
1. The input data is terminated on the *last* '/' and not the first - to allow
|
||||
'/' as part of the input.
|
||||
|
||||
2. '* is not treated as a multiplier/default, but rather as a normal token.
|
||||
|
||||
3. Quotes are not removed from the input, and when writing quotes are not
|
||||
added.
|
||||
|
||||
*/
|
||||
|
||||
class RawString : public std::string
|
||||
{
|
||||
public:
|
||||
|
||||
static std::vector<std::string> strings(const std::vector<RawString>& raw_strings) {
|
||||
std::vector<std::string> std_strings;
|
||||
for (const auto& rstring : raw_strings)
|
||||
std_strings.push_back( rstring );
|
||||
return std_strings;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline std::string tag_name( type_tag x ) {
|
||||
switch( x ) {
|
||||
case type_tag::integer: return "int";
|
||||
case type_tag::string: return "std::string";
|
||||
case type_tag::fdouble: return "double";
|
||||
case type_tag::uda: return "UDAValue";
|
||||
case type_tag::unknown: return "unknown";
|
||||
case type_tag::integer: return "int";
|
||||
case type_tag::string: return "std::string";
|
||||
case type_tag::raw_string: return "RawString";
|
||||
case type_tag::fdouble: return "double";
|
||||
case type_tag::uda: return "UDAValue";
|
||||
case type_tag::unknown: return "unknown";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
@ -37,6 +72,10 @@ template<> inline type_tag get_type< std::string >() {
|
||||
return type_tag::string;
|
||||
}
|
||||
|
||||
template<> inline type_tag get_type< RawString >() {
|
||||
return type_tag::raw_string;
|
||||
}
|
||||
|
||||
template<> inline type_tag get_type<UDAValue>() {
|
||||
return type_tag::uda;
|
||||
}
|
||||
|
@ -61,6 +61,14 @@ const std::vector< std::string >& DeckItem::value_ref< std::string >() const {
|
||||
return this->sval;
|
||||
}
|
||||
|
||||
template<>
|
||||
const std::vector< RawString >& DeckItem::value_ref< RawString >() const {
|
||||
if( this->type != get_type< RawString >() )
|
||||
throw std::invalid_argument( "DeckItem::value_ref<RawString> Item of wrong type. this->type: " + tag_name(this->type) + " " + this->name());
|
||||
|
||||
return this->rsval;
|
||||
}
|
||||
|
||||
template<>
|
||||
const std::vector< UDAValue >& DeckItem::value_ref< UDAValue >() const {
|
||||
if( this->type != get_type< UDAValue >() )
|
||||
@ -82,6 +90,13 @@ DeckItem::DeckItem( const std::string& nm, std::string) :
|
||||
{
|
||||
}
|
||||
|
||||
DeckItem::DeckItem( const std::string& nm, RawString) :
|
||||
type( get_type< RawString >() ),
|
||||
item_name( nm )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DeckItem::DeckItem( const std::string& nm, double, const std::vector<Dimension>& active_dim, const std::vector<Dimension>& default_dim) :
|
||||
type( get_type< double >() ),
|
||||
item_name( nm ),
|
||||
@ -200,6 +215,10 @@ void DeckItem::push_back( std::string x ) {
|
||||
this->push( std::move( x ) );
|
||||
}
|
||||
|
||||
void DeckItem::push_back( RawString x ) {
|
||||
this->push( std::move( x ) );
|
||||
}
|
||||
|
||||
void DeckItem::push_back( UDAValue x ) {
|
||||
this->push( std::move( x ) );
|
||||
}
|
||||
@ -251,6 +270,10 @@ void DeckItem::push_backDefault( std::string x ) {
|
||||
this->push_default( std::move( x ) );
|
||||
}
|
||||
|
||||
void DeckItem::push_backDefault( RawString x ) {
|
||||
this->push_default( std::move( x ) );
|
||||
}
|
||||
|
||||
void DeckItem::push_backDefault( UDAValue x ) {
|
||||
this->push_default( std::move( x ) );
|
||||
}
|
||||
@ -356,6 +379,9 @@ void DeckItem::write(DeckOutput& stream) const {
|
||||
case type_tag::string:
|
||||
this->write_vector( stream, this->sval );
|
||||
break;
|
||||
case type_tag::raw_string:
|
||||
this->write_vector( stream, this->rsval );
|
||||
break;
|
||||
case type_tag::uda:
|
||||
this->write_vector( stream, this->uval );
|
||||
break;
|
||||
@ -493,13 +519,16 @@ bool DeckItem::to_bool(std::string string_value) {
|
||||
template int DeckItem::get< int >( size_t ) const;
|
||||
template double DeckItem::get< double >( size_t ) const;
|
||||
template std::string DeckItem::get< std::string >( size_t ) const;
|
||||
template RawString DeckItem::get< RawString >( size_t ) const;
|
||||
|
||||
template void DeckItem::push_backDummyDefault<int>();
|
||||
template void DeckItem::push_backDummyDefault<double>();
|
||||
template void DeckItem::push_backDummyDefault<std::string>();
|
||||
template void DeckItem::push_backDummyDefault<RawString>();
|
||||
template void DeckItem::push_backDummyDefault<UDAValue>();
|
||||
|
||||
template const std::vector< int >& DeckItem::getData< int >() const;
|
||||
template const std::vector< UDAValue >& DeckItem::getData< UDAValue >() const;
|
||||
template const std::vector< std::string >& DeckItem::getData< std::string >() const;
|
||||
template const std::vector<RawString>& DeckItem::getData<RawString>() const;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <opm/parser/eclipse/Deck/DeckOutput.hpp>
|
||||
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
|
||||
#include <opm/parser/eclipse/Utility/Typetools.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
@ -73,6 +74,11 @@ namespace Opm {
|
||||
this->os << "'" << value << "'";
|
||||
}
|
||||
|
||||
template <>
|
||||
void DeckOutput::write_value( const RawString& value ) {
|
||||
this->os << value;
|
||||
}
|
||||
|
||||
template <>
|
||||
void DeckOutput::write_value( const int& value ) {
|
||||
this->os << value;
|
||||
@ -143,5 +149,6 @@ namespace Opm {
|
||||
template void DeckOutput::write( const int& value);
|
||||
template void DeckOutput::write( const double& value);
|
||||
template void DeckOutput::write( const std::string& value);
|
||||
template void DeckOutput::write( const RawString& value);
|
||||
template void DeckOutput::write( const UDAValue& value);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <opm/parser/eclipse/Utility/Typetools.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionValue.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
|
||||
@ -65,7 +66,7 @@ ActionX::ActionX(const DeckKeyword& kw, std::time_t start_time) :
|
||||
std::vector<std::string> tokens;
|
||||
for (size_t record_index = 1; record_index < kw.size(); record_index++) {
|
||||
const auto& record = kw.getRecord(record_index);
|
||||
const auto& cond_tokens = record.getItem("CONDITION").getData<std::string>();
|
||||
const auto& cond_tokens = RawString::strings( record.getItem("CONDITION").getData<RawString>() );
|
||||
|
||||
for (const auto& token : cond_tokens)
|
||||
tokens.push_back(token);
|
||||
|
@ -241,7 +241,7 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
|
||||
}
|
||||
}
|
||||
|
||||
throw std::invalid_argument("Should not be here ... this->type: " + std::to_string(static_cast<int>(this->type)));
|
||||
throw std::invalid_argument("Should not be here ... this->type: " + std::to_string(static_cast<int>(this->type)) + " string_value: <" + this->string_value + ">");
|
||||
}
|
||||
|
||||
void UDQASTNode::func_tokens(std::set<UDQTokenType>& tokens) const {
|
||||
|
@ -117,9 +117,9 @@ namespace Opm {
|
||||
|
||||
|
||||
void UDQConfig::add_record(const DeckRecord& record) {
|
||||
auto action = UDQ::actionType(record.getItem("ACTION").get<std::string>(0));
|
||||
auto action = UDQ::actionType(record.getItem("ACTION").get<RawString>(0));
|
||||
const auto& quantity = record.getItem("QUANTITY").get<std::string>(0);
|
||||
const auto& data = record.getItem("DATA").getData<std::string>();
|
||||
const auto& data = RawString::strings( record.getItem("DATA").getData<RawString>() );
|
||||
|
||||
if (action == UDQAction::UPDATE)
|
||||
throw std::invalid_argument("The UDQ action UPDATE is not yet implemented in opm/flow");
|
||||
|
@ -41,7 +41,7 @@ type_tag get_data_type_json( const std::string& str ) {
|
||||
if( str == "INT" ) return type_tag::integer;
|
||||
if( str == "DOUBLE" ) return type_tag::fdouble;
|
||||
if( str == "STRING" ) return type_tag::string;
|
||||
if( str == "RAW_STRING") return type_tag::string;
|
||||
if( str == "RAW_STRING") return type_tag::raw_string;
|
||||
if( str == "UDA") return type_tag::uda;
|
||||
throw std::invalid_argument( str + " cannot be converted to enum 'tag'" );
|
||||
}
|
||||
@ -98,10 +98,16 @@ template<> const double& ParserItem::value_ref< double >() const {
|
||||
|
||||
template<> const std::string& ParserItem::value_ref< std::string >() const {
|
||||
if( this->data_type != get_type< std::string >() )
|
||||
throw std::invalid_argument( "ValueRef<String> Wrong type." );
|
||||
throw std::invalid_argument( "ValueRef<std::string> Wrong type." );
|
||||
return this->sval;
|
||||
}
|
||||
|
||||
template<> const RawString& ParserItem::value_ref< RawString >() const {
|
||||
if( this->data_type != get_type<RawString>() )
|
||||
throw std::invalid_argument( "ValueRef<RawString> Wrong type." );
|
||||
return this->rsval;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
T& ParserItem::value_ref() {
|
||||
return const_cast< T& >(
|
||||
@ -194,7 +200,7 @@ void ParserItem::setInputType(ParserItem::itype input_type_arg) {
|
||||
this->setDataType( std::string() );
|
||||
|
||||
else if (input_type == itype::RAW_STRING)
|
||||
this->setDataType( std::string() );
|
||||
this->setDataType( RawString() );
|
||||
|
||||
else if (input_type == itype::UDA)
|
||||
this->setDataType( UDAValue(0) );
|
||||
@ -255,9 +261,9 @@ void ParserItem::push_backDimension( const std::string& dim ) {
|
||||
}
|
||||
|
||||
|
||||
type_tag ParserItem::dataType() const {
|
||||
return this->data_type;
|
||||
}
|
||||
type_tag ParserItem::dataType() const {
|
||||
return this->data_type;
|
||||
}
|
||||
|
||||
|
||||
ParserItem::item_size ParserItem::sizeType() const {
|
||||
@ -294,7 +300,8 @@ type_tag ParserItem::dataType() const {
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
bool ParserItem::operator==( const ParserItem& rhs ) const {
|
||||
|
||||
bool ParserItem::operator==( const ParserItem& rhs ) const {
|
||||
if( !( this->data_type == rhs.data_type
|
||||
&& this->m_name == rhs.m_name
|
||||
&& this->m_description == rhs.m_description
|
||||
@ -322,6 +329,10 @@ bool ParserItem::operator==( const ParserItem& rhs ) const {
|
||||
if( this->sval != rhs.sval ) return false;
|
||||
break;
|
||||
|
||||
case type_tag::raw_string:
|
||||
if( this->rsval != rhs.rsval ) return false;
|
||||
break;
|
||||
|
||||
case type_tag::uda:
|
||||
if( this->uval != rhs.uval ) return false;
|
||||
break;
|
||||
@ -423,6 +434,10 @@ std::string ParserItem::createCode(const std::string& indent) const {
|
||||
stream << "std::string(\"" << this->getDefault< std::string >() << "\")";
|
||||
break;
|
||||
|
||||
case type_tag::raw_string:
|
||||
stream << "RawString(\"" << this->getDefault< RawString >() << "\")";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::logic_error( "Item of unknown type." );
|
||||
}
|
||||
@ -448,7 +463,8 @@ void scan_item( DeckItem& deck_item, const ParserItem& parser_item, RawRecord& r
|
||||
if (parse_raw) {
|
||||
while (record.size()) {
|
||||
auto token = record.pop_front();
|
||||
deck_item.push_back( token.string() );
|
||||
auto raw_string = RawString{ token.string() };
|
||||
deck_item.push_back( raw_string );
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -499,7 +515,9 @@ void scan_item( DeckItem& deck_item, const ParserItem& parser_item, RawRecord& r
|
||||
}
|
||||
|
||||
if (parse_raw) {
|
||||
deck_item.push_back( record.pop_front().string());
|
||||
auto token = record.pop_front();
|
||||
auto raw_string = RawString{ token.string() };
|
||||
deck_item.push_back( raw_string );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -573,6 +591,13 @@ DeckItem ParserItem::scan( RawRecord& record, UnitSystem& active_unitsystem, Uni
|
||||
return item;
|
||||
}
|
||||
break;
|
||||
case type_tag::raw_string:
|
||||
{
|
||||
DeckItem item(this->name(), RawString());
|
||||
scan_item<RawString>( item, *this, record );
|
||||
return item;
|
||||
}
|
||||
break;
|
||||
case type_tag::uda:
|
||||
{
|
||||
std::vector<Dimension> active_dimensions;
|
||||
|
@ -39,6 +39,7 @@ namespace Opm {
|
||||
explicit RawRecord( const string_view&);
|
||||
|
||||
inline string_view pop_front();
|
||||
inline string_view front() const;
|
||||
void push_front( string_view token );
|
||||
void prepend( size_t count, string_view token );
|
||||
inline size_t size() const;
|
||||
@ -63,6 +64,10 @@ namespace Opm {
|
||||
return front;
|
||||
}
|
||||
|
||||
string_view RawRecord::front() const {
|
||||
return this->m_recordItems.front();
|
||||
}
|
||||
|
||||
size_t RawRecord::size() const {
|
||||
return m_recordItems.size();
|
||||
}
|
||||
|
@ -119,6 +119,12 @@ namespace Opm {
|
||||
return view.substr( 1, view.size() - 2 );
|
||||
}
|
||||
|
||||
template <>
|
||||
RawString readValueToken<RawString>( string_view view ) {
|
||||
return { view.string() };
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
UDAValue readValueToken< UDAValue >( string_view view ) {
|
||||
double n = 0;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/Utility/Stringview.hpp>
|
||||
#include <opm/parser/eclipse/Utility/Typetools.hpp>
|
||||
|
||||
namespace Opm {
|
||||
bool isStarToken(const string_view& token,
|
||||
|
@ -6,7 +6,7 @@
|
||||
"items": [
|
||||
{
|
||||
"name": "ACTION",
|
||||
"value_type": "STRING"
|
||||
"value_type": "RAW_STRING"
|
||||
},
|
||||
{
|
||||
"name": "QUANTITY",
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <opm/json/JsonObject.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <opm/parser/eclipse/Utility/Typetools.hpp>
|
||||
#include <opm/common/utility/FileSystem.hpp>
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
@ -1920,22 +1921,25 @@ AQUTAB
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ParseRAW_STRING) {
|
||||
const std::string deck_string = R"(
|
||||
UDQ
|
||||
DEFINE WUBHP 'P*X*' /
|
||||
DEFINE WUBHP 'P*X*' 5*(1 + LOG(WBHP)) /
|
||||
const std::string deck_string = R"(UDQ
|
||||
DEFINE 'WUBHP' 'P*X*' /
|
||||
DEFINE 'WUBHP' 'P*X*' 5*(1 + LOG(WBHP)) /
|
||||
/
|
||||
)";
|
||||
Parser parser;
|
||||
const auto deck = parser.parseString( deck_string);
|
||||
const auto& udq = deck.getKeyword("UDQ");
|
||||
const auto& data0 = udq.getRecord(0).getItem("DATA").getData<std::string>();
|
||||
const auto& data1 = udq.getRecord(1).getItem("DATA").getData<std::string>();
|
||||
const std::vector<std::string> expected0 = {"'P*X*'"};
|
||||
const std::vector<std::string> expected1 = {"'P*X*'", "5*(1", "+", "LOG(WBHP))"};
|
||||
const auto& data0 = RawString::strings( udq.getRecord(0).getItem("DATA").getData<RawString>() );
|
||||
const auto& data1 = RawString::strings( udq.getRecord(1).getItem("DATA").getData<RawString>() );
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( data0.begin(), data0.end(), expected0.begin(), expected0.end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( data1.begin(), data1.end(), expected1.begin(), expected1.end());
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << udq;
|
||||
BOOST_CHECK_EQUAL(ss.str(), deck_string);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ParseThreePhaseRelpermModels) {
|
||||
|
@ -16,6 +16,7 @@ Copyright 2018 Statoil ASA.
|
||||
#define BOOST_TEST_MODULE UDQTests
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Utility/Typetools.hpp>
|
||||
#include <opm/parser/eclipse/Python/Python.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
@ -484,7 +485,7 @@ UDQ
|
||||
const auto& udq = deck.getKeyword("UDQ");
|
||||
const auto& record = udq.getRecord(0);
|
||||
const auto& data_item = record.getItem("DATA");
|
||||
const auto& data = data_item.getData<std::string>();
|
||||
const auto& data = RawString::strings( data_item.getData<RawString>() );
|
||||
std::vector<std::string> exp = {"WWPR", "/", "(", "WWPR", "+", "WOPR", ")"};
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(data.begin(), data.end(),
|
||||
exp.begin(), exp.end());
|
||||
|
Loading…
Reference in New Issue
Block a user