Raise OpmInputError for unbalanced quotes

This commit is contained in:
Joakim Hove 2020-10-14 08:40:10 +02:00
parent 2ebc15e8d4
commit 2d036144cc
6 changed files with 60 additions and 51 deletions

View File

@ -809,7 +809,7 @@ std::unique_ptr<RawKeyword> tryParseKeyword( ParserState& parserState, const Par
std::string_view line_content = { line.begin(), end_pos};
record_buffer = str::update_record_buffer( record_buffer, line_content );
RawRecord record(record_buffer, true);
RawRecord record(record_buffer, rawKeyword->location(), true);
rawKeyword->addRecord(record);
return rawKeyword;
} else
@ -845,11 +845,11 @@ std::unique_ptr<RawKeyword> tryParseKeyword( ParserState& parserState, const Par
record_buffer = str::update_record_buffer(record_buffer, line);
if (is_title) {
if (record_buffer.empty()) {
RawRecord record("opm/flow simulation");
RawRecord record("opm/flow simulation", rawKeyword->location());
rawKeyword->addRecord(record);
} else {
std::size_t size = std::distance(record_buffer.begin(),record_buffer.end());
RawRecord record( std::string_view{ record_buffer.begin(), size });
RawRecord record( std::string_view{ record_buffer.begin(), size }, rawKeyword->location());
rawKeyword->addRecord(record);
}
return rawKeyword;
@ -864,7 +864,7 @@ std::unique_ptr<RawKeyword> tryParseKeyword( ParserState& parserState, const Par
if (str::isTerminatedRecordString(record_buffer)) {
std::size_t size = std::distance(record_buffer.begin(), record_buffer.end()) - 1;
RawRecord record( std::string_view{ record_buffer.begin(), size });
RawRecord record( std::string_view{ record_buffer.begin(), size }, rawKeyword->location());
if (rawKeyword->addRecord(record))
return rawKeyword;

View File

@ -23,6 +23,10 @@
#include <vector>
#include <deque>
#include <fmt/format.h>
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include <opm/common/utility/OpmInputError.hpp>
#include "RawRecord.hpp"
#include "RawConsts.hpp"
@ -77,7 +81,7 @@ inline bool even_quotes( const T& str ) {
}
RawRecord::RawRecord(const std::string_view& singleRecordString, bool text) :
RawRecord::RawRecord(const std::string_view& singleRecordString, const KeywordLocation& location, bool text) :
m_sanitizedRecordString( singleRecordString )
{
@ -86,15 +90,16 @@ inline bool even_quotes( const T& str ) {
else {
this->m_recordItems = splitSingleRecordString( m_sanitizedRecordString );
if( !even_quotes( singleRecordString ) )
throw std::invalid_argument("Input string is not a complete record string, "
"offending string: '" + std::string(singleRecordString) + "'");
if( !even_quotes( singleRecordString ) ) {
std::string error = fmt::format("Quotes are not balanced in: \"{}\"", std::string(singleRecordString));
throw OpmInputError(error, location);
}
}
this->m_max_size = this->m_recordItems.size();
}
RawRecord::RawRecord(const std::string_view& singleRecordString) :
RawRecord(singleRecordString, false)
RawRecord::RawRecord(const std::string_view& singleRecordString, const KeywordLocation& location) :
RawRecord(singleRecordString, location, false)
{}
void RawRecord::push_front( std::string_view tok, std::size_t count ) {

View File

@ -27,6 +27,7 @@
#include <list>
namespace Opm {
class KeywordLocation;
/// Class representing the lowest level of the Raw datatypes, a record. A record is simply
/// a vector containing the record elements, represented as strings. Some logic is present
@ -34,8 +35,8 @@ namespace Opm {
class RawRecord {
public:
RawRecord( const std::string_view&, bool text);
explicit RawRecord( const std::string_view&);
RawRecord( const std::string_view&, const KeywordLocation&, bool text);
explicit RawRecord( const std::string_view&, const KeywordLocation&);
inline std::string_view pop_front();
inline std::string_view front() const;

View File

@ -34,6 +34,7 @@
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParserItem.hpp>
#include <opm/parser/eclipse/Parser/ParserRecord.hpp>
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include "src/opm/parser/eclipse/Parser/raw/RawRecord.hpp"
@ -481,7 +482,7 @@ BOOST_AUTO_TEST_CASE(get_byNameNonExisting_throws) {
BOOST_AUTO_TEST_CASE(StringsWithSpaceOK) {
ParserItem itemString("STRINGITEM1", ParserItem::itype::STRING);
ParserRecord record1;
RawRecord rawRecord( " ' VALUE ' " );
RawRecord rawRecord( " ' VALUE ' ", KeywordLocation("KW", "file", 100) );
ParseContext parseContext;
ErrorGuard errors;
UnitSystem active_unitsystem(UnitSystem::UnitType::UNIT_TYPE_LAB);

View File

@ -23,6 +23,7 @@
#include <opm/json/JsonObject.hpp>
#include <iostream>
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include <opm/parser/eclipse/Utility/Typetools.hpp>
#include <opm/common/utility/OpmInputError.hpp>
#include <opm/common/utility/FileSystem.hpp>
@ -441,7 +442,7 @@ BOOST_AUTO_TEST_CASE(scan_PreMatureTerminator_defaultUsed) {
ParserItem itemInt("ITEM2", INT);
itemInt.setDefault(123);
RawRecord rawRecord1( "" );
RawRecord rawRecord1( "", KeywordLocation("KW", "File", 100) );
UnitSystem unit_system;
const auto defaulted = itemInt.scan(rawRecord1, unit_system, unit_system);
@ -652,7 +653,7 @@ BOOST_AUTO_TEST_CASE(Scan_All_CorrectIntSetInDeckItem) {
auto sizeType = ParserItem::item_size::ALL;
ParserItem itemInt("ITEM", INT); itemInt.setSizeType(sizeType);
RawRecord rawRecord( "100 443 10*77 10*1 25" );
RawRecord rawRecord( "100 443 10*77 10*1 25", KeywordLocation("KW", "File", 100) );
UnitSystem unit_system;
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(23U, deckIntItem.data_size());
@ -666,7 +667,7 @@ BOOST_AUTO_TEST_CASE(Scan_All_WithDefaults) {
ParserItem itemInt("ITEM", INT); itemInt.setSizeType(sizeType);
itemInt.setInputType( ParserItem::itype::INT );
RawRecord rawRecord( "100 10* 10*1 25" );
RawRecord rawRecord( "100 10* 10*1 25", KeywordLocation("KW", "File", 100) );
UnitSystem unit_system;
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(22U, deckIntItem.data_size());
@ -681,7 +682,7 @@ BOOST_AUTO_TEST_CASE(Scan_All_WithDefaults) {
BOOST_AUTO_TEST_CASE(Scan_SINGLE_CorrectIntSetInDeckItem) {
ParserItem itemInt(std::string("ITEM2"), INT);
RawRecord rawRecord("100 44.3 'Heisann'" );
RawRecord rawRecord("100 44.3 'Heisann'", KeywordLocation("KW", "File", 100) );
UnitSystem unit_system;
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(100, deckIntItem.get< int >(0));
@ -692,7 +693,7 @@ BOOST_AUTO_TEST_CASE(Scan_SeveralInts_CorrectIntsSetInDeckItem) {
ParserItem itemInt2(std::string("ITEM2"), INT);
ParserItem itemInt3(std::string("ITEM3"), INT);
RawRecord rawRecord( "100 443 338932 222.33 'Heisann' " );
RawRecord rawRecord( "100 443 338932 222.33 'Heisann' " , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(100, deckIntItem1.get< int >(0));
@ -711,7 +712,7 @@ BOOST_AUTO_TEST_CASE(Scan_SeveralInts_CorrectIntsSetInDeckItem) {
BOOST_AUTO_TEST_CASE(Scan_Multiplier_CorrectIntsSetInDeckItem) {
ParserItem itemInt("ITEM2", INT);
RawRecord rawRecord( "3*4 " );
RawRecord rawRecord( "3*4 " , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
itemInt.setSizeType(ParserItem::item_size::ALL);
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
@ -724,7 +725,7 @@ BOOST_AUTO_TEST_CASE(Scan_StarNoMultiplier_ExceptionThrown) {
ParserItem itemInt("ITEM2", INT);
UnitSystem unit_system;
RawRecord rawRecord( "*45 " );
RawRecord rawRecord( "*45 ", KeywordLocation("KW", "File", 100) );
BOOST_CHECK_THROW(itemInt.scan(rawRecord, unit_system, unit_system), std::invalid_argument);
}
@ -732,7 +733,7 @@ BOOST_AUTO_TEST_CASE(Scan_MultipleItems_CorrectIntsSetInDeckItem) {
ParserItem itemInt1(std::string("ITEM1"), INT);
ParserItem itemInt2(std::string("ITEM2"), INT);
RawRecord rawRecord( "10 20" );
RawRecord rawRecord( "10 20" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem2 = itemInt2.scan(rawRecord, unit_system, unit_system);
@ -745,7 +746,7 @@ BOOST_AUTO_TEST_CASE(Scan_MultipleDefault_CorrectIntsSetInDeckItem) {
ParserItem itemInt1("ITEM1", INT); itemInt1.setDefault(10);
ParserItem itemInt2("ITEM2", INT); itemInt2.setDefault(20);
RawRecord rawRecord( "* * " );
RawRecord rawRecord( "* * " , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem2 = itemInt2.scan(rawRecord, unit_system, unit_system);
@ -758,7 +759,7 @@ BOOST_AUTO_TEST_CASE(Scan_MultipleWithMultiplier_CorrectIntsSetInDeckItem) {
ParserItem itemInt1("ITEM1", INT);
ParserItem itemInt2("ITEM2", INT);
RawRecord rawRecord( "2*30" );
RawRecord rawRecord( "2*30" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem2 = itemInt2.scan(rawRecord, unit_system, unit_system);
@ -771,14 +772,14 @@ BOOST_AUTO_TEST_CASE(Scan_MalformedMultiplier_Throw) {
ParserItem itemInt1("ITEM1", INT);
UnitSystem unit_system;
RawRecord rawRecord( "2.10*30" );
RawRecord rawRecord( "2.10*30" , KeywordLocation("KW", "File", 100));
BOOST_CHECK_THROW(itemInt1.scan(rawRecord, unit_system, unit_system), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(Scan_MalformedMultiplierChar_Throw) {
ParserItem itemInt1("ITEM1", INT);
RawRecord rawRecord( "210X30" );
RawRecord rawRecord( "210X30" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
BOOST_CHECK_THROW(itemInt1.scan(rawRecord, unit_system, unit_system), std::invalid_argument);
}
@ -787,7 +788,7 @@ BOOST_AUTO_TEST_CASE(Scan_MultipleWithMultiplierDefault_CorrectIntsSetInDeckItem
ParserItem itemInt1("ITEM1", INT); itemInt1.setDefault(10);
ParserItem itemInt2("ITEM2", INT); itemInt2.setDefault(20);
RawRecord rawRecord( "2*" );
RawRecord rawRecord( "2*" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem2 = itemInt2.scan(rawRecord, unit_system, unit_system);
@ -800,16 +801,16 @@ BOOST_AUTO_TEST_CASE(Scan_RawRecordErrorInRawData_ExceptionThrown) {
ParserItem itemInt(std::string("ITEM2"), INT);
// Wrong type
RawRecord rawRecord2( "333.2 /" );
RawRecord rawRecord2( "333.2 /" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
BOOST_CHECK_THROW(itemInt.scan(rawRecord2, unit_system, unit_system), std::invalid_argument);
// Wrong type
RawRecord rawRecord3( "100X /" );
RawRecord rawRecord3( "100X /" , KeywordLocation("KW", "File", 100));
BOOST_CHECK_THROW(itemInt.scan(rawRecord3, unit_system, unit_system), std::invalid_argument);
// Wrong type
RawRecord rawRecord5( "astring /" );
RawRecord rawRecord5( "astring /", KeywordLocation("KW", "File", 100) );
BOOST_CHECK_THROW(itemInt.scan(rawRecord5, unit_system, unit_system), std::invalid_argument);
}
@ -837,21 +838,21 @@ BOOST_AUTO_TEST_CASE(InitializeStringItem_FromJsonObject_withDefaultInvalid_thro
BOOST_AUTO_TEST_CASE(init_defaultvalue_defaultset) {
ParserItem itemString(std::string("ITEM1"), STRING);
RawRecord rawRecord0( "'1*'" );
RawRecord rawRecord0( "'1*'" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
itemString.setDefault(std::string("DEFAULT"));
BOOST_CHECK_EQUAL("1*", itemString.scan( rawRecord0, unit_system, unit_system ).get< std::string >(0) );
RawRecord rawRecord1( "13*" );
RawRecord rawRecord1( "13*" , KeywordLocation("KW", "File", 100));
BOOST_CHECK_EQUAL("DEFAULT" , itemString.scan( rawRecord1, unit_system, unit_system ).get< std::string >(0) );
RawRecord rawRecord2( "*" );
RawRecord rawRecord2( "*" , KeywordLocation("KW", "File", 100));
BOOST_CHECK_EQUAL("DEFAULT", itemString.scan( rawRecord2, unit_system, unit_system ).get< std::string >(0) );
}
BOOST_AUTO_TEST_CASE(scan_all_valuesCorrect) {
ParserItem itemString("ITEMWITHMANY", STRING);
RawRecord rawRecord( "'WELL1' FISK BANAN 3*X OPPLEGG_FOR_DATAANALYSE 'Foo$*!% BAR' " );
RawRecord rawRecord( "'WELL1' FISK BANAN 3*X OPPLEGG_FOR_DATAANALYSE 'Foo$*!% BAR' " , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
itemString.setSizeType( ParserItem::item_size::ALL );
const auto deckItem = itemString.scan(rawRecord, unit_system, unit_system);
@ -869,7 +870,7 @@ BOOST_AUTO_TEST_CASE(scan_all_valuesCorrect) {
BOOST_AUTO_TEST_CASE(scan_all_withdefaults) {
ParserItem itemString("ITEMWITHMANY", INT);
RawRecord rawRecord( "10*1 10* 10*2 " );
RawRecord rawRecord( "10*1 10* 10*2 " , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
itemString.setDefault(0);
itemString.setSizeType( ParserItem::item_size::ALL );
@ -895,7 +896,7 @@ BOOST_AUTO_TEST_CASE(scan_all_withdefaults) {
BOOST_AUTO_TEST_CASE(scan_single_dataCorrect) {
ParserItem itemString( "ITEM1", STRING);
RawRecord rawRecord( "'WELL1' 'WELL2'" );
RawRecord rawRecord( "'WELL1' 'WELL2'" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto deckItem = itemString.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL("WELL1", deckItem.get< std::string >(0));
@ -905,7 +906,7 @@ BOOST_AUTO_TEST_CASE(scan_singleWithMixedRecord_dataCorrect) {
ParserItem itemString("ITEM1", STRING);
ParserItem itemInt("ITEM1", INT);
UnitSystem unit_system;
RawRecord rawRecord( "2 'WELL1' /" );
RawRecord rawRecord( "2 'WELL1' /" , KeywordLocation("KW", "File", 100));
itemInt.scan(rawRecord, unit_system, unit_system);
const auto deckItem = itemString.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL("WELL1", deckItem.get< std::string >(0));
@ -913,7 +914,7 @@ BOOST_AUTO_TEST_CASE(scan_singleWithMixedRecord_dataCorrect) {
/******************String and int**********************/
BOOST_AUTO_TEST_CASE(scan_intsAndStrings_dataCorrect) {
RawRecord rawRecord( "'WELL1' 2 2 2*3" );
RawRecord rawRecord( "'WELL1' 2 2 2*3" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
ParserItem itemSingleString(std::string("ITEM1"), STRING);
const auto deckItemWell1 = itemSingleString.scan(rawRecord, unit_system, unit_system);
@ -1055,14 +1056,14 @@ BOOST_AUTO_TEST_CASE(parse_validRecord_noThrow) {
auto record = createSimpleParserRecord();
ParseContext parseContext;
ErrorGuard errors;
RawRecord raw( std::string_view( "100 443" ) );
RawRecord raw( std::string_view( "100 443" ), KeywordLocation("KW", "fle", 100) );
UnitSystem unit_system;
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, raw , unit_system, unit_system, KeywordLocation()) );
}
BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) {
auto record = createSimpleParserRecord();
RawRecord rawRecord( std::string_view( "100 443" ) );
RawRecord rawRecord( std::string_view( "100 443") , KeywordLocation("KW", "fle", 100) );
ParseContext parseContext;
ErrorGuard errors;
UnitSystem unit_system;
@ -1094,7 +1095,7 @@ static ParserRecord createMixedParserRecord() {
BOOST_AUTO_TEST_CASE(parse_validMixedRecord_noThrow) {
auto record = createMixedParserRecord();
RawRecord rawRecord( std::string_view( "1 2 10.0 20.0 4 90.0") );
RawRecord rawRecord( std::string_view( "1 2 10.0 20.0 4 90.0"), KeywordLocation("KW", "fle", 100));
ParseContext parseContext;
ErrorGuard errors;
UnitSystem unit_system;
@ -1144,7 +1145,7 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
// according to the RM, this is invalid ("an asterisk by itself is not sufficient"),
// but it seems to appear in the wild. Thus, we interpret this as "1*"...
{
RawRecord rawRecord( "* " );
RawRecord rawRecord( "* " , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto& deckStringItem = itemString.scan(rawRecord, unit_system, unit_system);
const auto& deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
@ -1156,7 +1157,7 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
}
{
RawRecord rawRecord( "" );
RawRecord rawRecord( "" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto deckStringItem = itemString.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
@ -1169,7 +1170,7 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
{
RawRecord rawRecord( "TRYGVE 10 2.9 " );
RawRecord rawRecord( "TRYGVE 10 2.9 " , KeywordLocation("KW", "File", 100));
// let the raw record be "consumed" by the items. Note that the scan() method
// modifies the rawRecord object!
@ -1185,7 +1186,7 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
// again this is invalid according to the RM, but it is used anyway in the wild...
{
RawRecord rawRecord( "* * *" );
RawRecord rawRecord( "* * *" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto deckStringItem = itemString.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
@ -1197,7 +1198,7 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
}
{
RawRecord rawRecord( "3*" );
RawRecord rawRecord( "3*" , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
const auto deckStringItem = itemString.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
@ -1222,14 +1223,14 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooManyItems_Throws) {
parserRecord.addItem(itemK);
RawRecord rawRecord( "3 3 3 " );
RawRecord rawRecord( "3 3 3 " , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, KeywordLocation()));
RawRecord rawRecordOneExtra( "3 3 3 4 " );
RawRecord rawRecordOneExtra( "3 3 3 4 " , KeywordLocation("KW", "File", 100));
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordOneExtra, unit_system, unit_system, KeywordLocation()), OpmInputError);
RawRecord rawRecordForgotRecordTerminator( "3 3 3 \n 4 4 4 " );
RawRecord rawRecordForgotRecordTerminator( "3 3 3 \n 4 4 4 ", KeywordLocation("KW", "file", 100) );
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordForgotRecordTerminator, unit_system, unit_system, KeywordLocation()), OpmInputError);
}
@ -1247,7 +1248,7 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooFewItems) {
ParseContext parseContext;
ErrorGuard errors;
RawRecord rawRecord( "3 3 " );
RawRecord rawRecord( "3 3 " , KeywordLocation("KW", "File", 100));
UnitSystem unit_system;
KeywordLocation location;
// no default specified for the third item, record can be parsed just fine but trying
@ -1631,7 +1632,7 @@ BOOST_AUTO_TEST_CASE(ParseEmptyRecord) {
UnitSystem unit_system;
BOOST_CHECK_EQUAL( Raw::FIXED , rawkeyword.getSizeType());
rawkeyword.addRecord( RawRecord("") );
rawkeyword.addRecord( RawRecord("", KeywordLocation("KW", "File", 100)) );
record.addItem(item);
tabdimsKeyword.addRecord( record );

View File

@ -21,6 +21,7 @@
#include <cstring>
#include <stdexcept>
#include <boost/test/unit_test.hpp>
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include "src/opm/parser/eclipse/Parser/raw/RawEnums.hpp"
#include "src/opm/parser/eclipse/Parser/raw/RawKeyword.hpp"
@ -46,7 +47,7 @@ BOOST_AUTO_TEST_CASE(RawKeywordConstructor) {
BOOST_AUTO_TEST_CASE(IsFinished) {
std::string storage = "RecordString";
std::string_view line(storage);
RawRecord rec(line);
RawRecord rec(line, KeywordLocation("KW", "file", 100 ));
RawKeyword kw1("NAME", "file", 10, false, Raw::FIXED, 0);
BOOST_CHECK(kw1.isFinished());