⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 config_file_iterator.cpp

📁 C++的一个好库。。。现在很流行
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//____________________________________________________________________________//

boost::optional<cstring>
config_file_iterator::Impl::get_macro_value( cstring macro_name, bool ignore_missing )
{
    symbol_table_t::const_iterator it = m_symbols_table.find( macro_name );

    if( it == m_symbols_table.end() ) {
        boost::optional<cstring> macro_value; // !! variable actually may have different type

        env::get( macro_name, macro_value );

        BOOST_RT_PARAM_VALIDATE_LOGIC( macro_value || ignore_missing || !m_detect_missing_macro, 
            BOOST_RT_PARAM_LITERAL( "Unknown macro \"" ) << macro_name << BOOST_RT_PARAM_LITERAL( "\"" ) );
        
        if( !macro_value ) {
            if( !ignore_missing )
                macro_value = cstring();
        }
        else 
            m_symbols_table.add( macro_name, *macro_value );

        return macro_value;
    }

    return boost::optional<cstring>( cstring( it->second ) );
}

//____________________________________________________________________________//

void
config_file_iterator::Impl::process_command_line( cstring line )
{
    line.trim_left( m_command_delimeter.size() );

    unit_test::string_token_iterator tit( line, unit_test::max_tokens = 2 );

    command_handler_map::const_iterator it = m_command_handler_map.find( *tit );

    BOOST_RT_PARAM_VALIDATE_LOGIC( it != m_command_handler_map.end(), BOOST_RT_PARAM_LITERAL( "Invalid command " ) << *tit );

    ++tit;

    (it->second)( *tit );
}

//____________________________________________________________________________//

void
config_file_iterator::Impl::process_include( cstring line )
{
    using namespace unit_test;

    if( !is_active_line() )
        return;

    string_token_iterator tit( line, kept_delimeters = dt_none );

    BOOST_RT_PARAM_VALIDATE_LOGIC( tit != string_token_iterator(),
                                   BOOST_RT_PARAM_LITERAL( "include file name missing" ) );

    cstring include_file_name = *tit;

    BOOST_RT_PARAM_VALIDATE_LOGIC( ++tit == string_token_iterator(),
                                   BOOST_RT_PARAM_LITERAL( "unexpected tokens at the end of include command" ) );

    substitute_macros( include_file_name );

    m_curr_level.reset( new include_level( include_file_name, m_path_separators, m_curr_level.release() ) );
}

//____________________________________________________________________________//

void
config_file_iterator::Impl::process_define( cstring line )
{
    using namespace unit_test;

    if( !is_active_line() )
        return;

    string_token_iterator tit( line, (kept_delimeters = dt_none, max_tokens = 2 ));

    cstring macro_name = *tit;
    BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
                                   BOOST_RT_PARAM_LITERAL( "invalid macro name" ) );

    cstring macro_value = *(++tit);
    substitute_macros( macro_value );

    m_symbols_table.add( macro_name, macro_value );
}

//____________________________________________________________________________//

void
config_file_iterator::Impl::process_undef( cstring line )
{
    if( !is_active_line() )
        return;

    cstring macro_name = line;
    BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
                                   BOOST_RT_PARAM_LITERAL( "invalid macro name" ) );

    m_symbols_table.remove( macro_name );
}

//____________________________________________________________________________//

void
config_file_iterator::Impl::process_ifdef( cstring line )
{
    m_conditional_states.push_back( true );
    if( !is_active_line() )
        return;

    cstring macro_name = line;
    BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
                                   BOOST_RT_PARAM_LITERAL( "invalid macro name" ) );

    if( !get_macro_value( macro_name ) )
        m_inactive_ifdef_level = m_conditional_states.size();
}

//____________________________________________________________________________//

void
config_file_iterator::Impl::process_ifndef( cstring line )
{
    m_conditional_states.push_back( true );
    if( !is_active_line() )
        return;

    cstring macro_name = line;
    BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ),
                                   BOOST_RT_PARAM_LITERAL( "invalid macro name" ) );

    if( get_macro_value( macro_name ) )
        m_inactive_ifdef_level = m_conditional_states.size();
}

//____________________________________________________________________________//

void
config_file_iterator::Impl::process_else( cstring line )
{
    BOOST_RT_PARAM_VALIDATE_LOGIC( m_conditional_states.size() > 0 && m_conditional_states.back(),
                                   BOOST_RT_PARAM_LITERAL( "else without matching if" ) );

    m_inactive_ifdef_level = m_conditional_states.size() == m_inactive_ifdef_level ? 0 : m_conditional_states.size();

    BOOST_RT_PARAM_VALIDATE_LOGIC( line.is_empty(), BOOST_RT_PARAM_LITERAL( "unexpected tokens at the end of else command" ) );
}

//____________________________________________________________________________//

void
config_file_iterator::Impl::process_endif( cstring line )
{
    BOOST_RT_PARAM_VALIDATE_LOGIC( m_conditional_states.size() > 0, BOOST_RT_PARAM_LITERAL( "endif without matching if" ) );

    if( m_conditional_states.size() == m_inactive_ifdef_level )
        m_inactive_ifdef_level = 0;

    m_conditional_states.pop_back();
    BOOST_RT_PARAM_VALIDATE_LOGIC( line.is_empty(), BOOST_RT_PARAM_LITERAL( "unexpected tokens at the end of endif command" ) );
}

//____________________________________________________________________________//

void
config_file_iterator::Impl::substitute_macros( cstring& where )
{
    m_post_subst_line.clear();
    cstring::size_type pos;

    while( (pos = where.find( m_macro_ref_begin )) != cstring::npos ) {
        m_post_subst_line.append( where.begin(), pos );

        where.trim_left( where.begin() + pos + m_macro_ref_begin.size() );

        pos = where.find( m_macro_ref_end );

        BOOST_RT_PARAM_VALIDATE_LOGIC( pos != cstring::npos, BOOST_RT_PARAM_LITERAL( "incomplete macro reference" ) );

        cstring value = *get_macro_value( where.substr( 0, pos ), false );
        m_post_subst_line.append( value.begin(), value.size() );

        where.trim_left( where.begin() + pos + m_macro_ref_end.size() );
    }

    if( !m_post_subst_line.empty() ) {
        m_post_subst_line.append( where.begin(), where.size() );
        where = m_post_subst_line;
    }
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************      runtime::file::config_file_iterator      ************** //
// ************************************************************************** //

void
config_file_iterator::construct()
{
    m_pimpl.reset( new Impl );
}

//____________________________________________________________________________//

void
config_file_iterator::load( cstring file_name )
{
    m_pimpl->m_curr_level.reset( new include_level( file_name, m_pimpl->m_path_separators ) );
    m_pimpl->m_buffer.reset( new char[m_pimpl->m_buffer_size] );

    register_command_handler( m_pimpl->m_include_kw, bind( &Impl::process_include, m_pimpl.get(), _1 ) );
    register_command_handler( m_pimpl->m_define_kw, bind( &Impl::process_define, m_pimpl.get(), _1 ) );
    register_command_handler( m_pimpl->m_undef_kw, bind( &Impl::process_undef, m_pimpl.get(), _1 ) );
    register_command_handler( m_pimpl->m_ifdef_kw, bind( &Impl::process_ifdef, m_pimpl.get(), _1 ) );
    register_command_handler( m_pimpl->m_ifndef_kw, bind( &Impl::process_ifndef, m_pimpl.get(), _1 ) );
    register_command_handler( m_pimpl->m_else_kw, bind( &Impl::process_else, m_pimpl.get(), _1 ) );
    register_command_handler( m_pimpl->m_endif_kw, bind( &Impl::process_endif, m_pimpl.get(), _1 ) );

    init();
}

//____________________________________________________________________________//

location const&
config_file_iterator::curr_location()
{
    return m_pimpl->m_curr_level->m_curr_location;
}

//____________________________________________________________________________//

void
config_file_iterator::register_command_handler( cstring command_kw, command_handler const& ch )
{
    m_pimpl->m_command_handler_map.add( command_kw, ch );
}

//____________________________________________________________________________//

bool
config_file_iterator::get()
{
    return m_pimpl->get_next_line( m_value );
}

//____________________________________________________________________________//

void
config_file_iterator::set_parameter( rtti::id_t id, cstring value )
{
    BOOST_RTTI_SWITCH( id ) {
        BOOST_RTTI_CASE( cfg_detail::path_separators_t ) 
            assign_op( m_pimpl->m_path_separators        , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::sl_comment_delimeter_t ) 
            assign_op( m_pimpl->m_sl_comment_delimeter   , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::command_delimeter_t ) 
            assign_op( m_pimpl->m_command_delimeter      , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::line_beak_t ) 
            assign_op( m_pimpl->m_line_beak              , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::macro_ref_begin_t ) 
            assign_op( m_pimpl->m_macro_ref_begin        , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::macro_ref_end_t ) 
            assign_op( m_pimpl->m_macro_ref_end          , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::include_kw_t ) 
            assign_op( m_pimpl->m_include_kw             , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::define_kw_t ) 
            assign_op( m_pimpl->m_define_kw              , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::undef_kw_t ) 
            assign_op( m_pimpl->m_undef_kw               , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::ifdef_kw_t ) 
            assign_op( m_pimpl->m_ifdef_kw               , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::ifndef_kw_t ) 
            assign_op( m_pimpl->m_ifndef_kw              , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::else_kw_t ) 
            assign_op( m_pimpl->m_else_kw                , value, 0 );
        BOOST_RTTI_CASE( cfg_detail::endif_kw_t ) 
            assign_op( m_pimpl->m_endif_kw               , value, 0 );
    }
}

//____________________________________________________________________________//

void
config_file_iterator::set_parameter( rtti::id_t id, bool value )
{
    BOOST_RTTI_SWITCH( id ) {
        BOOST_RTTI_CASE( cfg_detail::trim_leading_spaces_t ) 
            m_pimpl->m_trim_leading_spaces  = value;
        BOOST_RTTI_CASE( cfg_detail::trim_trailing_spaces_t )
            m_pimpl->m_trim_trailing_spaces = value;
        BOOST_RTTI_CASE( cfg_detail::skip_empty_lines_t )
            m_pimpl->m_skip_empty_lines     = value;
        BOOST_RTTI_CASE( cfg_detail::detect_missing_macro_t )
            m_pimpl->m_detect_missing_macro = value;
    }
}

//____________________________________________________________________________//

void
config_file_iterator::set_parameter( rtti::id_t id, char_type value )
{
    BOOST_RTTI_SWITCH( id ) {
        BOOST_RTTI_CASE( cfg_detail::line_delimeter_t ) 
            m_pimpl->m_line_delimeter       = value;
    }
}

//____________________________________________________________________________//

void
config_file_iterator::set_parameter( rtti::id_t id, std::size_t value )
{
    BOOST_RTTI_SWITCH( id ) {
        BOOST_RTTI_CASE( cfg_detail::buffer_size_t ) 
            m_pimpl->m_buffer_size          = value;
    }
}

//____________________________________________________________________________//

} // namespace file

} // namespace BOOST_RT_PARAM_NAMESPACE

} // namespace boost

// ************************************************************************** //
//   Revision History:
//
//   $Log: config_file_iterator.cpp,v $
//   Revision 1.1  2005/04/12 06:42:44  rogeeff
//   Runtime.Param library initial commit
//
// ************************************************************************** //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -