TuttleOFX
1
|
00001 #include <sam/common/utility.hpp> 00002 #include <sam/common/options.hpp> 00003 00004 #include <tuttle/common/exceptions.hpp> 00005 #include <tuttle/common/utils/applicationPath.hpp> 00006 00007 #include <tuttle/host/Core.hpp> 00008 00009 #include <boost/program_options.hpp> 00010 #include <boost/filesystem.hpp> 00011 #include <boost/foreach.hpp> 00012 #include <boost/throw_exception.hpp> 00013 00014 #include <climits> 00015 00016 namespace sam { 00017 00018 namespace bfs = boost::filesystem; 00019 namespace bpo = boost::program_options; 00020 00021 bfs::path retrieveToolFullPath(const std::string& toolName, const std::vector<bfs::path>& searchPaths) 00022 { 00023 const std::string toolFilename(std::string("sam-") + toolName); 00024 00025 BOOST_FOREACH( const bfs::path& p, searchPaths ) 00026 { 00027 const bfs::path toolFullPath = p / toolFilename; 00028 if (bfs::exists(toolFullPath)) 00029 { 00030 return toolFullPath; 00031 } 00032 } 00033 00034 /// @todo exception ? 00035 TUTTLE_LOG_ERROR( "Sam command \"" << toolName << "\" not found." ); 00036 // displayAvailableCommands(); 00037 exit(255); 00038 } 00039 00040 std::vector<bfs::path> retrieveSearchPaths(const bfs::path& samDirectory) 00041 { 00042 std::vector<bfs::path> searchPaths; 00043 if( const char* env_ptr = std::getenv( "SAM_PATH" ) ) 00044 { 00045 const std::string env(env_ptr); 00046 const std::vector<std::string> paths = bpo::split_unix(env, ":;"); 00047 searchPaths.insert(searchPaths.end(), paths.begin(), paths.end()); 00048 } 00049 00050 searchPaths.push_back(samDirectory / "sam"); 00051 searchPaths.push_back(samDirectory); 00052 00053 return searchPaths; 00054 } 00055 00056 std::vector<bfs::path> retrieveAllSamCommands(const bfs::path& dir) 00057 { 00058 std::vector<bfs::path> res; 00059 if( !bfs::is_directory( dir ) ) 00060 return res; 00061 00062 bfs::directory_iterator dir_iter(dir), dir_end; 00063 for( ; dir_iter != dir_end; ++dir_iter ) 00064 { 00065 bfs::path cmd = *dir_iter; 00066 if( boost::starts_with(cmd.filename().string(), "sam-" ) ) 00067 { 00068 res.push_back( cmd ); 00069 } 00070 } 00071 return res; 00072 } 00073 00074 std::vector<bfs::path> retrieveAllSamCommands(const std::vector<bfs::path>& dirs) 00075 { 00076 typedef std::map<bfs::path, bfs::path> PathMap; 00077 PathMap allRes; 00078 BOOST_FOREACH( const bfs::path& dir, dirs ) 00079 { 00080 std::vector<bfs::path> dirRes = retrieveAllSamCommands(dir); 00081 BOOST_FOREACH( const bfs::path& cmd, dirRes ) 00082 { 00083 if( allRes.find( cmd.filename() ) == allRes.end() ) 00084 { 00085 allRes[cmd.filename()] = cmd; 00086 } 00087 } 00088 } 00089 std::vector<bfs::path> res; 00090 res.reserve(allRes.size()); 00091 BOOST_FOREACH( PathMap::const_reference p, allRes ) 00092 { 00093 res.push_back( p.second ); 00094 } 00095 return res; 00096 } 00097 00098 } 00099 00100 int main( int argc, char** argv ) 00101 { 00102 signal(SIGINT, signal_callback_handler); 00103 00104 using namespace tuttle::common; 00105 using namespace sam; 00106 00107 boost::shared_ptr<formatters::Formatter> formatter( formatters::Formatter::get() ); 00108 boost::shared_ptr<Color> color( Color::get() ); 00109 00110 formatter->init_logging(); 00111 00112 try 00113 { 00114 std::vector<std::string> cl_options; 00115 for (int i = 1; i < argc; ++i) 00116 { 00117 const std::string s(argv[i]); 00118 if (!boost::starts_with(s, "-")) 00119 { 00120 break; 00121 } 00122 cl_options.push_back(s); 00123 } 00124 00125 // Declare the supported options. 00126 bpo::options_description infoOptions; 00127 infoOptions.add_options() 00128 ( kHelpOptionString, kHelpOptionMessage ) 00129 ( kVersionOptionString, kVersionOptionMessage ) // which version? 00130 ( kCommandsOptionString, kCommandsOptionMessage ) 00131 ( kColorOptionString, kColorOptionMessage ); 00132 00133 // describe hidden options 00134 bpo::options_description hidden; 00135 hidden.add_options() 00136 ( kCommandsListOptionString, kCommandsListOptionMessage ) 00137 ( kBinariesListOptionString, kBinariesListOptionMessage ) 00138 ( kEnableColorOptionString, bpo::value<std::string>(), kEnableColorOptionMessage ); 00139 00140 bpo::options_description all_options; 00141 all_options.add(infoOptions).add(hidden); 00142 00143 bpo::variables_map sam_vm; 00144 00145 //parse the command line, and put the result in vm 00146 bpo::store(bpo::command_line_parser(cl_options).options(all_options).run(), sam_vm); 00147 // get environment options and parse them 00148 if( const char* env_sam_options = std::getenv( "SAM_OPTIONS" ) ) 00149 { 00150 const std::vector<std::string> envOptions = bpo::split_unix(env_sam_options, " "); 00151 bpo::store(bpo::command_line_parser(envOptions).options(all_options).run(), sam_vm); 00152 } 00153 bpo::notify(sam_vm); 00154 00155 if( sam_vm.count( kColorOptionLongName ) ) 00156 { 00157 color->enable(); 00158 } 00159 00160 if( sam_vm.count( kEnableColorOptionLongName ) ) 00161 { 00162 const std::string str = sam_vm[kEnableColorOptionLongName].as<std::string>(); 00163 if( string_to_boolean(str) ) 00164 { 00165 color->enable(); 00166 } 00167 else 00168 { 00169 color->disable(); 00170 } 00171 } 00172 00173 bfs::path fullsam = tuttle::common::applicationFilepath( argv[0] ); 00174 00175 bfs::path samDirectory( fullsam.parent_path() ); 00176 const std::vector<bfs::path> searchPaths = retrieveSearchPaths( samDirectory ); 00177 00178 if( ( sam_vm.count( kHelpOptionLongName ) || ( argc == 1 ) ) 00179 || ( ( argc == 2 ) && (strstr( argv[1], kColorOptionLongName ) != NULL ) ) ) 00180 { 00181 TUTTLE_LOG_INFO( color->_blue << "TuttleOFX project [" << kUrlTuttleofxProject << "]" << color->_std ); 00182 TUTTLE_LOG_INFO( "" ); 00183 TUTTLE_LOG_INFO( color->_blue << "NAME" << color->_std ); 00184 TUTTLE_LOG_INFO( color->_green <<"\tsam - A set of command line tools." << color->_std ); 00185 TUTTLE_LOG_INFO( "" ); 00186 TUTTLE_LOG_INFO( color->_blue << "SYNOPSIS" << color->_std ); 00187 TUTTLE_LOG_INFO( color->_green << "\tsam COMMAND [options]..." << color->_std ); 00188 TUTTLE_LOG_INFO( "" ); 00189 TUTTLE_LOG_INFO( color->_blue << "COMMANDS" << color->_std ); 00190 const std::vector<bfs::path> cmds = retrieveAllSamCommands( searchPaths ); 00191 BOOST_FOREACH( const bfs::path& c, cmds ) 00192 { 00193 std::cout << std::left << "\t" << std::setw(10) << c.filename().string().substr(4) << std::flush; 00194 system((c.string() + " --brief").c_str()); 00195 std::cout << std::flush; 00196 } 00197 TUTTLE_LOG_INFO( "" ); 00198 TUTTLE_LOG_INFO( color->_blue << "DESCRIPTION" << color->_std ); 00199 TUTTLE_LOG_INFO( "Sam is the TuttleOFX command line tool to manage image processing." ); 00200 TUTTLE_LOG_INFO( "" ); 00201 TUTTLE_LOG_INFO( color->_blue << "OPTIONS" << color->_std ); 00202 TUTTLE_LOG_INFO( infoOptions ); 00203 exit( 0 ); 00204 } 00205 00206 if( sam_vm.count( kVersionOptionLongName ) ) 00207 { 00208 TUTTLE_LOG_INFO( "TuttleOFX Host - version " << TUTTLE_HOST_VERSION_STR); 00209 exit(0); 00210 } 00211 00212 if( sam_vm.count(kCommandsOptionLongName ) ) 00213 { 00214 TUTTLE_LOG_INFO( "" ); 00215 TUTTLE_LOG_INFO( color->_blue << "COMMANDS" << color->_std ); 00216 00217 const std::vector<bfs::path> cmds = retrieveAllSamCommands(searchPaths); 00218 BOOST_FOREACH( const bfs::path& c, cmds ) 00219 { 00220 std::cout << std::left << "\t" << std::setw(10) << c.filename().string().substr(4) << std::flush; 00221 system((c.string() + " --brief").c_str()); 00222 std::cout << std::flush; 00223 } 00224 TUTTLE_LOG_INFO( "" ); 00225 00226 exit(0); 00227 } 00228 if( sam_vm.count( kBinariesListOptionLongName ) ) 00229 { 00230 const std::vector<bfs::path> cmds = retrieveAllSamCommands( searchPaths ); 00231 BOOST_FOREACH( const bfs::path& c, cmds ) 00232 { 00233 TUTTLE_LOG_INFO( c.string()); 00234 } 00235 exit(0); 00236 } 00237 if( sam_vm.count( kCommandsListOptionLongName ) ) 00238 { 00239 const std::vector<bfs::path> cmds = retrieveAllSamCommands( searchPaths ); 00240 BOOST_FOREACH( const bfs::path& c, cmds ) 00241 { 00242 TUTTLE_LOG_INFO( c.filename().string().substr(4) ); 00243 } 00244 exit(0); 00245 } 00246 00247 const std::string sam_tool(argv[cl_options.size() + 1]); 00248 std::vector<std::string> sam_cmd; 00249 for( int i = cl_options.size() + 2; i < argc; ++i ) 00250 { 00251 static const std::string quote("\""); 00252 const std::string s(argv[i]); 00253 sam_cmd.push_back(quote + s + quote); 00254 } 00255 00256 bfs::path toolFullPath = retrieveToolFullPath(sam_tool, searchPaths); 00257 00258 const std::string fullcmd( toolFullPath.string() + " " + boost::algorithm::join( sam_cmd, " " ) ); 00259 00260 // TUTTLE_TLOG_VAR( TUTTLE_INFO, fullcmd ); 00261 int returnCode = system( fullcmd.c_str() ); 00262 // TUTTLE_CLOG_VAR( TUTTLE_INFO, UINT_MAX - returnCode ); 00263 return returnCode>>8; 00264 } 00265 catch( const bpo::error& e ) 00266 { 00267 TUTTLE_LOG_ERROR( "Error in command line: " << e.what() ); 00268 exit(254); 00269 } 00270 catch( ... ) 00271 { 00272 TUTTLE_LOG_ERROR( "Error in command line: " << boost::current_exception_diagnostic_information() ); 00273 exit(254); 00274 } 00275 00276 return 0; 00277 } 00278