コード例 #1
0
ファイル: init.cpp プロジェクト: guozanhua/Equalizer
bool _parseArguments( const int argc, char** argv )
{
    typedef stde::hash_map< std::string, uint32_t > Flags;
    Flags configFlags;
    configFlags["multiprocess"] = fabric::ConfigParams::FLAG_MULTIPROCESS;
    configFlags["multiprocess_db"] = fabric::ConfigParams::FLAG_MULTIPROCESS_DB;
    configFlags["ethernet"] = fabric::ConfigParams::FLAG_NETWORK_ETHERNET;
    configFlags["infiniband"] = fabric::ConfigParams::FLAG_NETWORK_INFINIBAND;
    configFlags["2D_horizontal"] =
        fabric::ConfigParams::FLAG_LOAD_EQ_HORIZONTAL;
    configFlags["2D_vertical"] =
        fabric::ConfigParams::FLAG_LOAD_EQ_VERTICAL;
    configFlags["2D_tiles"] =
        fabric::ConfigParams::FLAG_LOAD_EQ_2D;

    arg::options_description options( "Equalizer library options" );
    options.add_options()
        ( EQ_HELP, "Display usage information and exit" )
        ( EQ_LOGFILE, arg::value< std::string >(),
          "Redirect log output to given file" )
        ( EQ_SERVER, arg::value< std::string >(), "The server address" )
        ( EQ_CONFIG, arg::value< std::string >(),
          "The config filename or autoconfig session name" )
        ( EQ_CONFIG_FLAGS, arg::value< Strings >()->multitoken(),
          "The autoconfig flags" )
        ( EQ_CONFIG_PREFIXES, arg::value< Strings >()->multitoken(),
          "The network prefix filter(s) in CIDR notation for autoconfig "
          "(white-space separated)" )
        ( EQ_RENDER_CLIENT, arg::value< std::string >(),
          "The render client executable filename" )
    ;

    arg::variables_map vm;
    try
    {
        Strings args;
        for( int i = 0; i < argc; ++i )
        {
            if( strcmp( argv[i], "--" ) != 0 )
                args.push_back( argv[i] );
        }
        arg::store( arg::command_line_parser( args )
                        .options( options ).allow_unregistered().run(), vm );
        arg::notify( vm );
    }
    catch( const std::exception& e )
    {
        LBERROR << "Error in argument parsing: " << e.what() << std::endl;
        return false;
    }

    if( vm.count( EQ_HELP ))
    {
        std::cout << options << std::endl;
        return false;
    }

    if( vm.count( EQ_LOGFILE ))
    {
        const std::string& newFile = vm["eq-logfile"].as< std::string >();
        std::ofstream* oldLog = _logFile;
        std::ofstream* newLog = new std::ofstream( newFile.c_str( ));

        if( newLog->is_open( ))
        {
            _logFile = newLog;
            lunchbox::Log::setOutput( *newLog );

            if( oldLog )
            {
                *oldLog << "Redirected log to " << newFile << std::endl;
                oldLog->close();
                delete oldLog;
            }
            else
                std::cout << "Redirected log to " << newFile << std::endl;
        }
        else
        {
            LBWARN << "Can't open log file " << newFile << ": "
                   << lunchbox::sysError << std::endl;
            delete newLog;
            newLog = 0;
        }
    }

    if( vm.count( EQ_SERVER ))
        Global::setServer( vm[EQ_SERVER].as< std::string >( ));

    if( vm.count( EQ_CONFIG ))
        Global::setConfigFile( vm[EQ_CONFIG].as< std::string >( ));

    if( vm.count( EQ_CONFIG_FLAGS ))
    {
        const Strings& flagStrings = vm[EQ_CONFIG_FLAGS].as< Strings >( );
        uint32_t flags = Global::getFlags();
        for( StringsCIter i = flagStrings.begin(); i != flagStrings.end(); ++i )
        {
            Flags::const_iterator j = configFlags.find( *i );
            if( j != configFlags.end( ))
                flags |= j->second;
            else
                LBWARN << "Unknown argument for --eq-config-flags: " << *i
                       << std::endl;
        }
        Global::setFlags( flags );
    }

    if( vm.count( EQ_CONFIG_PREFIXES ))
    {
        const Strings& prefixes = vm[EQ_CONFIG_PREFIXES].as< Strings >( );
        Global::setPrefixes( prefixes );
    }

    if( vm.count( EQ_CLIENT ))
    {
        const std::string& renderClient = vm[EQ_CLIENT].as< std::string >();
        const boost::filesystem::path path( renderClient );

        Global::setProgramName( renderClient );
        Global::setWorkDir( path.parent_path().string( ));
    }

    return true;
}