DriveHQ Start Menu
Cloud Drive Mapping
Folder Sync
Cloud Backup
True Drop Box
FTP/SFTP Hosting
Group Account
DriveHQ Start Menu
Online File Server
My Storage
|
Manage Shares
|
Publishes
|
Drop Boxes
|
Group Account
WebDAV Drive Mapping
Cloud Drive Home
|
WebDAV Guide
|
Drive Mapping Tool
|
Drive Mapping URL
Complete Data Backup
Backup Guide
|
Online Backup Tool
|
Cloud-to-Cloud Backup
FTP, Email & Web Service
FTP Home
|
FTP Hosting FAQ
|
Email Hosting
|
EmailManager
|
Web Hosting
Help & Resources
About
|
Enterprise Service
|
Partnership
|
Comparisons
|
Support
Quick Links
Security and Privacy
Download Software
Service Manual
Use Cases
Group Account
Online Help
Blog
Contact
Cloud Surveillance
Sign Up
Login
Features
Business Features
Online File Server
FTP Hosting
Cloud Drive Mapping
Cloud File Backup
Email Backup & Hosting
Cloud File Sharing
Folder Synchronization
Group Management
True Drop Box
Full-text Search
AD Integration/SSO
Mobile Access
IP Camera & DVR Solution
More...
Personal Features
Personal Cloud Drive
Backup All Devices
Mobile APPs
Personal Web Hosting
Sub-Account (for Kids)
Home/PC/Kids Monitoring
More...
Software
DriveHQ Drive Mapping Tool
DriveHQ FileManager
DriveHQ Online Backup
DriveHQ Mobile Apps
Pricing
Business Plans & Pricing
Personal Plans & Pricing
Price Comparison with Others
Feature Comparison with Others
Install Mobile App
Sign up
Creating account...
Invalid character in username! Only 0-9, a-z, A-Z, _, -, . allowed.
Username is required!
Invalid email address!
E-mail is required!
Password is required!
Password is invalid!
Password and confirmation do not match.
Confirm password is required!
I accept
Membership Agreement
Please read the Membership Agreement and check "I accept"!
Free Quick Sign-up
Sign-up Page
Log in
Signing in...
Username or e-mail address is required!
Password is required!
Keep me logged in
Quick Login
Forgot Password
Up
Upload
Download
Share
Publish
New Folder
New File
Copy
Cut
Delete
Paste
Rate
Upgrade
Rotate
Effect
Edit
Slide
History
// (C) Copyright Gennadiy Rozental 2005-2007. // Use, modification, and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/test for the library home page. // // File : $RCSfile$ // // Version : $Revision: 43798 $ // // Description : flexible configuration file iterator implementation // *************************************************************************** // Boost.Runtime.Parameter #include
#include
#include
#include
// Boost #include
#include
#include
// Boost.Test #include
#include
#include
#include
// STL #include
#include
#include
#include
#include
#include
#include
namespace boost { namespace BOOST_RT_PARAM_NAMESPACE { namespace file { // ************************************************************************** // // ************** symbol_to_value_map ************** // // ************************************************************************** // template
struct symbol_to_value_map : std::map
{ template
void add( cstring name, ParamType const& value ) { using namespace unit_test; m_name_store.push_back( dstring() ); assign_op( m_name_store.back(), name, 0 ); assign_op( (*this)[m_name_store.back()], value, 0 ); } void remove( cstring name ) { std::list
::iterator it = std::find( m_name_store.begin(), m_name_store.end(), name ); m_name_store.erase( it ); erase( name ); } private: std::list
m_name_store; }; // ************************************************************************** // // ************** symbol_table_t ************** // // ************************************************************************** // typedef symbol_to_value_map
symbol_table_t; // ************************************************************************** // // ************** command_handler_map ************** // // ************************************************************************** // typedef symbol_to_value_map
command_handler_map; // ************************************************************************** // // ************** is_valid_identifier ************** // // ************************************************************************** // static bool is_valid_identifier( cstring const& source ) { if( source.is_empty() ) return false; cstring::const_iterator it = source.begin(); if( !std::isalpha( *it ) ) return false; while( ++it < source.end() ) { if( !std::isalnum( *it ) && *it != BOOST_RT_PARAM_LITERAL( '_' ) && *it != BOOST_RT_PARAM_LITERAL( '-' ) ) return false; } return true; } // ************************************************************************** // // ************** include_level ************** // // ************************************************************************** // struct include_level; typedef std::auto_ptr
include_level_ptr; struct include_level : noncopyable { // Constructor explicit include_level( cstring file_name, cstring path_separators, include_level* parent = 0 ); // Data members std::ifstream m_stream; location m_curr_location; include_level_ptr m_parent; }; //____________________________________________________________________________// include_level::include_level( cstring file_name, cstring path_separators, include_level* parent_ ) : m_parent( parent_ ) { if( file_name.is_empty() ) return; assign_op( m_curr_location.first, file_name, 0 ); m_curr_location.second = 0; m_stream.open( m_curr_location.first.c_str() ); if( !m_stream.is_open() && !!m_parent.get() ) { cstring parent_path = m_parent->m_curr_location.first; cstring::iterator it = unit_test::find_last_of( parent_path.begin(), parent_path.end(), path_separators.begin(), path_separators.end() ); if( it != parent_path.end() ) { assign_op( m_curr_location.first, cstring( parent_path.begin(), it+1 ), 0 ); m_curr_location.first.append( file_name.begin(), file_name.end() ); m_stream.clear(); m_stream.open( m_curr_location.first.c_str() ); } } BOOST_RT_PARAM_VALIDATE_LOGIC( m_stream.is_open(), BOOST_RT_PARAM_LITERAL( "couldn't open file " ) << file_name ); } //____________________________________________________________________________// // ************************************************************************** // // ************** config_file_iterator::Impl ************** // // ************************************************************************** // struct config_file_iterator::Impl : noncopyable { // Constructor Impl(); bool get_next_line( cstring& next_line ); void process_command_line( cstring line ); void process_include( cstring line ); void process_define( cstring line ); void process_undef( cstring line ); void process_ifdef( cstring line ); void process_ifndef( cstring line ); void process_else( cstring line ); void process_endif( cstring line ); boost::optional
get_macro_value( cstring macro_name, bool ignore_missing = true ); void substitute_macros( cstring& where ); bool is_active_line() { return m_inactive_ifdef_level == 0; } static bool match_front( cstring str, cstring pattern ) { return str.size() >= pattern.size() && str.substr( 0, pattern.size() ) == pattern; } static bool match_back( cstring str, cstring pattern ) { return str.size() >= pattern.size() && str.substr( str.size() - pattern.size() ) == pattern; } // Configurable parameters dstring m_path_separators; char_type m_line_delimeter; dstring m_sl_comment_delimeter; dstring m_command_delimeter; dstring m_line_beak; dstring m_macro_ref_begin; dstring m_macro_ref_end; dstring m_include_kw; dstring m_define_kw; dstring m_undef_kw; dstring m_ifdef_kw; dstring m_ifndef_kw; dstring m_else_kw; dstring m_endif_kw; std::size_t m_buffer_size; bool m_trim_trailing_spaces; bool m_trim_leading_spaces; bool m_skip_empty_lines; bool m_detect_missing_macro; // Data members dstring m_post_subst_line; scoped_array
m_buffer; include_level_ptr m_curr_level; symbol_table_t m_symbols_table; std::vector
m_conditional_states; std::size_t m_inactive_ifdef_level; command_handler_map m_command_handler_map; }; //____________________________________________________________________________// config_file_iterator::Impl::Impl() : m_path_separators( BOOST_RT_PARAM_LITERAL( "/\\" ) ) , m_line_delimeter( BOOST_RT_PARAM_LITERAL( '\n' ) ) , m_sl_comment_delimeter( BOOST_RT_PARAM_LITERAL( "#" ) ) , m_command_delimeter( BOOST_RT_PARAM_LITERAL( "$" ) ) , m_line_beak( BOOST_RT_PARAM_LITERAL( "\\" ) ) , m_macro_ref_begin( BOOST_RT_PARAM_LITERAL( "$" ) ) , m_macro_ref_end( BOOST_RT_PARAM_LITERAL( "$" ) ) , m_include_kw( BOOST_RT_PARAM_LITERAL( "include" ) ) , m_define_kw( BOOST_RT_PARAM_LITERAL( "define" ) ) , m_undef_kw( BOOST_RT_PARAM_LITERAL( "undef" ) ) , m_ifdef_kw( BOOST_RT_PARAM_LITERAL( "ifdef" ) ) , m_ifndef_kw( BOOST_RT_PARAM_LITERAL( "ifndef" ) ) , m_else_kw( BOOST_RT_PARAM_LITERAL( "else" ) ) , m_endif_kw( BOOST_RT_PARAM_LITERAL( "endif" ) ) , m_buffer_size( 8192 ) , m_trim_trailing_spaces( true ) , m_trim_leading_spaces( false ) , m_skip_empty_lines( true ) , m_detect_missing_macro( true ) , m_inactive_ifdef_level( 0 ) {} //____________________________________________________________________________// bool config_file_iterator::Impl::get_next_line( cstring& line ) { bool broken_line = false; line.clear(); while( !m_curr_level->m_stream.eof() || !!m_curr_level->m_parent.get() ) { // 10. Switch to upper include level if current one is finished // 20. Read/append next file line // 30. Increment line number // 40. Remove comments // 50. Remove trailing and leading spaces // 60. Skip empty string // 70. Concatenate broken lines if needed. Put the result into line // 80. If line is not completed, try to finish it by reading the next line // 90. Process command line // 100. Substitute macros references with their definitions // 110. Next line found. if( m_curr_level->m_stream.eof() ) { // 10 // m_curr_level = m_curr_level->m_parent; continue; } std::ifstream& input = m_curr_level->m_stream; char_type* buffer_insert_pos = broken_line ? m_buffer.get() + line.size() : m_buffer.get(); input.getline( buffer_insert_pos, (std::streamsize)(m_buffer_size - line.size()), // 20 // m_line_delimeter ); cstring next_line( buffer_insert_pos, input.gcount() > 0 ? buffer_insert_pos + (input.eof() ? input.gcount() : (input.gcount()-1)) : buffer_insert_pos ); m_curr_level->m_curr_location.second++; // 30 // cstring::size_type comment_pos = next_line.find( m_sl_comment_delimeter ); if( comment_pos != cstring::npos ) next_line.trim_right( next_line.begin()+comment_pos ); // 40 // if( m_trim_trailing_spaces ) // 50 // next_line.trim_right(); if( m_trim_leading_spaces && !broken_line ) next_line.trim_left(); if( next_line.is_empty() ) { // 60 // if( m_skip_empty_lines ) continue; else next_line.assign( buffer_insert_pos, buffer_insert_pos ); } line = broken_line ? cstring( line.begin(), next_line.end() ) : next_line; // 70 // broken_line = match_back( line, m_line_beak ); if( broken_line ) { // 80 // line.trim_right( 1 ); continue; } if( match_front( line, m_command_delimeter ) ) { // 90 // process_command_line( line ); continue; } if( !is_active_line() ) continue; substitute_macros( line ); // 100 // return true; // 110 // } BOOST_RT_PARAM_VALIDATE_LOGIC( !broken_line, BOOST_RT_PARAM_LITERAL( "broken line is not completed" ) ); BOOST_RT_PARAM_VALIDATE_LOGIC( m_conditional_states.size() == 0, BOOST_RT_PARAM_LITERAL( "matching endif command is missing" ) ); return false; } //____________________________________________________________________________// boost::optional
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
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( 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 // EOF
config_file_iterator.cpp
Page URL
File URL
Prev
3/4
Next
Download
( 24 KB )
Note: The DriveHQ service banners will NOT be displayed if the file owner is a paid member.
Comments
Total ratings:
0
Average rating:
Not Rated
Would you like to comment?
Join DriveHQ
for a free account, or
Logon
if you are already a member.