in cli/mparser.cpp [272:422]
bool CModelData::readParamSet( wstring& line )
{
const wstring STD_MSG = L"Submodel definition is incorrect: " + line;
wstringstream ist( line );
// it's always in a form of { paramName1 @ N, paramName2 @ N, ... } @ N but "@ N" is optional
wstring s;
ist >> s;
wstring::iterator next = line.begin();
// {
wstring::iterator begin = findFirstNonWhitespace( next, line.end() );
if( begin == line.end() || *begin != SET_BEGIN )
{
PrintMessage( InputDataError, STD_MSG.data() );
return( false );
}
++begin;
// find }
wstring::iterator end;
end = find( begin, line.end(), SET_END );
if ( end == line.end() )
{
PrintMessage( InputDataError, STD_MSG.data() );
return( false );
}
// params in the middle
wstring setp;
setp.assign( begin, end );
setp = trim( setp );
if ( setp.empty() )
{
PrintMessage( InputDataError, STD_MSG.data() );
return( false );
}
//
// Two attempts to resolve submodel names:
// 1. Use a comma as a separator
// 2. If 1 fails to produce matching names, use ModelData.ValuesDelim as a separator
//
// first figure out whether "," or a delimiter specified by /d option applies
wstrings setParams;
split( setp, SET_SEP, setParams );
transform( setParams.begin(), setParams.end(), setParams.begin(), trim );
wstrings unmatched;
getUnmatchedParameterNames( setParams, unmatched );
if( !unmatched.empty() )
{
setParams.clear();
unmatched.clear();
split( setp, ValuesDelim, setParams );
transform( setParams.begin(), setParams.end(), setParams.begin(), trim );
getUnmatchedParameterNames( setParams, unmatched );
if( !unmatched.empty() )
{
PrintMessage( InputDataWarning, L"Submodel defintion", trim( line ).data(), L"contains unknown parameter. Skipping..." );
return( true ); // just a warning so don't exit
}
}
// remove duplicates
sort( setParams.begin(), setParams.end(), stringCaseInsensitiveLess );
wstrings::iterator newEnd = unique( setParams.begin(), setParams.end(), stringCaseInsensitiveEquals );
if( setParams.end() != newEnd )
{
PrintMessage( InputDataWarning, L"Submodel defintion", trim( line ).data(), L"contains duplicate parameters. Removing duplicates..." );
setParams.erase( newEnd, setParams.end() );
}
CModelSubmodel submodel;
// match to names, set up the structure
for( auto & cparam : setParams )
{
bool found = false;
unsigned int index = 0;
for( auto & param : Parameters )
{
if ( 0 == stringCompare( cparam, param.Name, CaseSensitive ))
{
found = true;
break;
}
++index;
}
// at this point we should always match the name
assert( found );
submodel.Parameters.push_back( index );
}
// @
++end;
wstring::iterator at = findFirstNonWhitespace( end, line.end() );
// anything other than @, quit
if ( at != line.end() && *at != SET_ORDER )
{
PrintMessage( InputDataError, STD_MSG.data() );
return( false );
}
if ( at == line.end() )
{
// if this is the end then order will be assigned later
NOOP
}
else
{
++at;
// number
wstring numberText;
numberText.assign( at, line.end() );
double number;
bool ret = stringToNumber( numberText, number );
int order = 0;
if( ret )
{
order = static_cast<int> (number);
if( order <= 0 )
{
order = 0;
ret = false;
}
}
if ( !ret )
{
PrintMessage( InputDataError, STD_MSG.data() );
return( false );
}
submodel.Order = order;
}
Submodels.push_back( submodel );
return ( true );
}