bool CModelData::readParameter()

in cli/mparser.cpp [119:244]


bool CModelData::readParameter( wstring& line )
{
    CModelParameter parameter;

    // param name can be separated by : or ,
    wstring::size_type paramSep = line.find( PARAMNAME_SEP );
    if( paramSep == wstring::npos )
    {
        paramSep = line.find( ValuesDelim );
        if( paramSep == wstring::npos )
        {
            PrintMessage( InputDataError, L"Parameter", line.c_str(), L"should have at least one value defined" );
            return( false );
        }
    }

    wstring name = trim( line.substr( 0, paramSep ));
    
    unsigned int order = UNDEFINED_ORDER;
    
    //check if this param has custom-order defined
    wstrings nameAndOrder;
    split( name, PARAM_ORDER, nameAndOrder );

    double d;
    if( nameAndOrder.size() == 2 && stringToNumber( nameAndOrder[ 1 ], d ))
    {
        name  = trim( nameAndOrder[ 0 ]);
        if( d > 0 )
        {
            order = static_cast< unsigned int >( d );
        }
    }

    parameter.Name  = name;
    parameter.Order = order;

    if ( ! parameter.Name.empty() && parameter.Name[ 0 ] == RESULT_PARAM_PREFIX )
    {
        parameter.IsResultParameter = true;
    }

    // now get the values
    wstring rawValues = line.substr( paramSep + 1, line.length() - paramSep - 1 );

    wstrings values;
    split( rawValues, ValuesDelim, values );

    for( wstrings::iterator i_val = values.begin(); i_val != values.end(); i_val++ )
    {
        *i_val = trim( *i_val );

        //
        // if it is in a form <text> it is a reference to another parameter
        // find an existing parameter and add all its values here instead
        //
        vector< CModelParameter >::iterator refParam;
        if ( ! i_val->empty() 
          && *(i_val->begin())  == PARAM_REF_BEGIN
          && *(i_val->rbegin()) == PARAM_REF_END
          &&( refParam = FindParameterByName( i_val->substr( 1, i_val->length() - 2 ))) !=
                         Parameters.end() )
        {
            __push_back( parameter.Values, refParam->Values.begin(), refParam->Values.end() );
        }
        else
        {
            //
            // value weight
            // Param: Val1 (3), Val21|Val22 (2), Val3
            //
            int weight = 1;
            
            size_t weightBegin = i_val->find_last_of( WEIGHT_BEGIN );
            size_t weightEnd   = i_val->find_last_of( WEIGHT_END );
            
            // '(' must exist, ')' must be the last character
            if ( weightBegin != wstring::npos && weightEnd == i_val->length() - 1 )
            {
                wstring weightStr = trim( i_val->substr( weightBegin + 1, weightEnd - weightBegin - 1 ));
                double weightDbl = 0;

                // anything after @ must be a positive integer
                if ( stringToNumber( weightStr, weightDbl ) && ( static_cast< unsigned int > (weightDbl) ) > 0 )
                {
                    weight = static_cast< unsigned int > (weightDbl);

                    // trim the weight off the value
                    i_val->erase( weightBegin, wstring::npos );
                    *i_val = trim( *i_val );
                }
            }

            //
            // names
            //
            wstrings names;
            split( *i_val, NamesDelim, names );

            bool positive = true;
            for ( wstrings::iterator i_name = names.begin(); i_name != names.end(); i_name++ )
            {
                *i_name = trim( *i_name );
                
                // only the first name determines the negativity of a value
                if ( i_name->length() > 0
                 &&  i_name == names.begin()
                 &&(*i_name)[ 0 ] == InvalidPrefix )
                {
                    positive = false;
                    *i_name = trim( i_name->substr( 1, i_name->length() - 1 ));
                }
            }

            if ( ! positive ) 
            {
                m_hasNegativeValues = true;
            }
            CModelValue value( names, weight, positive );
            parameter.Values.push_back( value );
        }
    }

    Parameters.push_back( parameter );
    return( true );
}