ISIS Core Library 0.7.2 (api 3.0.0)

/scr/tee1/isis/lib/Core/CoreUtils/application.cpp

Go to the documentation of this file.
00001 /****************************************************************
00002  *
00003  * Copyright (C) ISIS Dev-Team
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 3
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018  *
00019  * Author: Enrico Reimer, <reimer@cbs.mpg.de>, 2010
00020  *
00021  *****************************************************************/
00022 
00023 #include "application.hpp"
00024 #include <boost/foreach.hpp>
00025 
00026 #define STR(s) _xstr_(s)
00027 #define _xstr_(s) std::string(#s)
00028 
00029 namespace isis
00030 {
00031 namespace util
00032 {
00033 
00034 Application::Application( const char name[] ): m_name( name )
00035 {
00036     addLogging<CoreLog>( "Core" );
00037     addLogging<CoreDebug>( "Core" );
00038     addLogging<DataLog>( "Data" );
00039     addLogging<DataDebug>( "Data" );
00040     addLogging<ImageIoLog>( "ImageIO" );
00041     addLogging<ImageIoDebug>( "ImageIO" );
00042 
00043     parameters["help"] = false;
00044     parameters["help"].setDescription( "Print help" );
00045     parameters["help"].needed() = false;
00046 }
00047 Application::~Application() {}
00048 
00049 void Application::addLoggingParameter( std::string name )
00050 {
00051     static const Selection dbg_levels( "error,warning,notice,info,verbose_info", "notice" );
00052 
00053     if( parameters.find( std::string( "d" ) + name ) == parameters.end() ) { //only add the parameter if it does not exist yet
00054         parameters[std::string( "d" )+name] = dbg_levels;
00055 
00056         if( name.empty() )
00057             parameters[std::string( "d" )+name].setDescription( "Log level for \"" + m_name + "\" itself" );
00058         else
00059             parameters[std::string( "d" )+name].setDescription( "Log level for the \"" + name + "\" module(s)" );
00060 
00061         parameters[std::string( "d" )+name].hidden() = true;
00062         parameters[std::string( "d" )+name].needed() = false;
00063     }
00064 }
00065 void Application::removeLogging( std::string name )
00066 {
00067     parameters.erase( name );
00068     logs.erase( name );
00069 }
00070 
00071 void Application::addExample ( std::string params, std::string desc )
00072 {
00073     m_examples.push_back( std::make_pair( params, desc ) );
00074 }
00075 
00076 bool Application::init( int argc, char **argv, bool exitOnError )
00077 {
00078     typedef const std::pair< const std::string, std::list< setLogFunction > > & logger_ref;
00079     bool err = false;
00080     m_filename = boost::filesystem::path( argv[0] ).leaf();//@todo switch to filename() as soon as we drop support for boost < 1.44
00081 
00082     if ( parameters.parse( argc, argv ) ) {
00083         if ( parameters["help"] ) {
00084             printHelp( true );
00085             exit( 0 );
00086         }
00087     } else {
00088         LOG( Runtime, error ) << "Failed to parse the command line";
00089         err = true;
00090     }
00091 
00092     BOOST_FOREACH( logger_ref ref, logs ) {
00093         const std::string dname = std::string( "d" ) + ref.first;
00094         assert( !parameters[dname].isEmpty() ); // this must have been set by addLoggingParameter (called via addLogging)
00095         const LogLevel level = ( LogLevel )( uint16_t )parameters[dname].as<Selection>();
00096         BOOST_FOREACH( setLogFunction setter, ref.second ) {
00097             ( this->*setter )( level );
00098         }
00099     }
00100 
00101     if ( ! parameters.isComplete() ) {
00102         std::cerr << "Missing parameters: ";
00103 
00104         for ( ParameterMap::iterator iP = parameters.begin(); iP != parameters.end(); iP++ ) {
00105             if ( iP->second.isNeeded() ) {std::cerr << "-" << iP->first << "  ";}
00106         }
00107 
00108         std::cerr << std::endl;
00109         err = true;
00110     }
00111 
00112     if ( err ) {
00113         printHelp();
00114 
00115         if( exitOnError ) {
00116             std::cerr << "Exiting..." << std::endl;
00117             exit( 1 );
00118         }
00119     }
00120 
00121     return ! err;
00122 }
00123 void Application::printHelp( bool withHidden )const
00124 {
00125     typedef std::list<std::pair<std::string, std::string> >::const_reference example_type;
00126     std::cerr << this->m_name << " (using isis " << getCoreVersion() << ")" << std::endl;
00127     std::cerr << "Usage: " << this->m_filename << " <options>" << std::endl << "Where <options> includes:" << std::endl;;
00128 
00129     for ( ParameterMap::const_iterator iP = parameters.begin(); iP != parameters.end(); iP++ ) {
00130         std::string pref;
00131 
00132         if ( iP->second.isNeeded() ) {
00133             pref = ". Required.";
00134         } else if( iP->second.isHidden() ) {
00135             if( !withHidden )
00136                 continue; // if its hidden, not needed, and wie want the short version skip this parameter
00137         }
00138 
00139         if ( ! iP->second.isNeeded() ) {
00140             pref = ". Default: \"" + iP->second.toString() + "\".";
00141         }
00142 
00143         std::cerr
00144                 << "\t-" << iP->first << " <" << iP->second.getTypeName() << ">" << std::endl
00145                 << "\t\t" << iP->second.description() << pref << std::endl;
00146 
00147         if ( iP->second.is<Selection>() ) {
00148             const Selection &ref = iP->second.castTo<Selection>();
00149             const std::list< istring > entries = ref.getEntries();
00150             std::list< istring >::const_iterator i = entries.begin();
00151             std::cerr << "\t\tOptions are: \"" << *i << "\"";
00152 
00153             for( i++ ; i != entries.end(); i++ ) {
00154                 std::list< istring >::const_iterator dummy = i;
00155                 std::cout << ( ( ++dummy ) != entries.end() ? ", " : " or " ) << "\"" << *i << "\"";
00156             }
00157 
00158             std::cerr << "." << std::endl;
00159         }
00160     }
00161 
00162     if( !m_examples.empty() ) {
00163         std::cout << "Examples:" << std::endl;
00164 
00165         BOOST_FOREACH( example_type ex, m_examples ) {
00166             std::cout << '\t' << m_filename + " " + ex.first << '\t' << ex.second << std::endl;
00167         }
00168     }
00169 }
00170 
00171 boost::shared_ptr< MessageHandlerBase > Application::getLogHandler( std::string /*module*/, isis::LogLevel level )const
00172 {
00173     return boost::shared_ptr< MessageHandlerBase >( level ? new util::DefaultMsgPrint( level ) : 0 );
00174 }
00175 const std::string Application::getCoreVersion( void )
00176 {
00177 #ifdef ISIS_RCS_REVISION
00178     return STR( _ISIS_VERSION_MAJOR ) + "." + STR( _ISIS_VERSION_MINOR ) + "." + STR( _ISIS_VERSION_PATCH ) + " [" + STR( ISIS_RCS_REVISION ) + "]";
00179 #else
00180     return STR( _ISIS_VERSION_MAJOR ) + "." + STR( _ISIS_VERSION_MINOR ) + "." + STR( _ISIS_VERSION_PATCH );
00181 #endif
00182 }
00183 
00184 }
00185 }
00186 #undef STR
00187 #undef _xstr_
00188