$search
00001 #include "utilmm/configsearch/configuration_finder.hh" 00002 00003 #define WIN32_LEAN_AND_MEAN 00004 #include <boost/program_options.hpp> 00005 #if BOOST_VERSION >= 104600 00006 #include <boost/filesystem.hpp> 00007 #endif 00008 #include <boost/filesystem/fstream.hpp> 00009 #include <boost/filesystem/operations.hpp> 00010 #include <boost/algorithm/string.hpp> 00011 00012 namespace utilmm { 00013 00014 const char* configEnv = "ROCK_CONFIG_PATH"; 00015 00016 00017 std::string ConfigurationFinder::find( const std::string& configFile) 00018 { 00019 return find(configFile, ""); 00020 } 00021 00022 std::string ConfigurationFinder::find( const std::string& configFile, const std::string& packagename) 00023 { 00024 std::string configurationDir = getenv(configEnv) ? getenv(configEnv) : ""; 00025 00026 std::vector<std::string> searchDirectories; 00027 if( configurationDir.empty() ) 00028 { 00029 fprintf(stderr, "WARNING: ConfigurationFinder: environment variable %s is not set\n", configEnv); 00030 } else { 00031 00032 boost::split(searchDirectories, configurationDir, boost::is_any_of(":")); 00033 } 00034 00035 if(packagename != "") 00036 { 00037 // append packagename to configuration files, e.g. if packagename is my-package 00038 // my-package/ will be appended to the searchDirectories 00039 std::vector<std::string>::iterator it = searchDirectories.begin(); 00040 for(;it != searchDirectories.end(); it++) 00041 { 00042 boost::filesystem::path directory(*it); 00043 boost::filesystem::path searchPath = operator/(directory, packagename); 00044 *it = searchPath.string(); 00045 } 00046 } 00047 00048 return search(configFile, searchDirectories); 00049 } 00050 00051 std::string ConfigurationFinder::search(const std::string& file, const std::vector<std::string>& searchDirectories) 00052 { 00053 std::string searchFile(file); 00054 std::string result; 00055 00056 if( searchFile != "") 00057 { 00058 // Check current directory first 00059 if(boost::filesystem::exists(searchFile)) 00060 { 00061 result = boost::filesystem::system_complete( searchFile ).string(); 00062 00063 } else { 00064 // search in given search directories 00065 std::vector<std::string>::const_iterator it = searchDirectories.begin(); 00066 00067 for(; it != searchDirectories.end(); it++) 00068 { 00069 boost::filesystem::path dir(*it); 00070 boost::filesystem::path testPath = operator/(dir,searchFile); 00071 00072 if( boost::filesystem::exists(testPath) ) 00073 { 00074 result = boost::filesystem::system_complete( testPath ).string(); 00075 break; 00076 } 00077 } 00078 } 00079 } 00080 00081 return result; 00082 } 00083 00084 std::string ConfigurationFinder::findSystemConfig(const std::string& file, const std::string& systemId) 00085 { 00086 std::vector<std::string> result; 00087 boost::algorithm::split(result, systemId, boost::algorithm::is_any_of("_")); 00088 00089 if(result.size() != 2) 00090 { 00091 fprintf(stderr, "WARNING: ConfigurationFinder: Invalid systemConfig provided\n"); 00092 fprintf(stderr, "ConfigurationFinder: searching in basedir %s\n", systemId.c_str()); 00093 00094 } 00095 00096 boost::filesystem::path baseDir(result[0]); 00097 boost::filesystem::path systemIdDir = operator/(baseDir, result[1]); 00098 // Split file name, when a <folder>/<file> is given -- allows 00099 // search in given directories of the systemconfiguration directory 00100 // and keeps consistency with the ruby implementation 00101 boost::algorithm::split(result, file, boost::algorithm::is_any_of("/")); 00102 boost::filesystem::path subdir; 00103 00104 std::string searchFile = result.back(); 00105 if(result.size() >= 2) 00106 { 00107 for(size_t i = 0; i < result.size() - 1; ++i) 00108 { 00109 subdir = operator/(subdir, result[i]); 00110 } 00111 00112 } 00113 00114 if(!subdir.string().empty()) 00115 { 00116 systemIdDir = operator/(systemIdDir,subdir); 00117 baseDir = operator/(baseDir,subdir); 00118 } 00119 00120 std::string systemIdConfig = find(searchFile,systemIdDir.string() ); 00121 std::string baseConfig = find(searchFile, baseDir.string()); 00122 00123 if(systemIdConfig != "") 00124 return systemIdConfig; 00125 00126 return baseConfig; 00127 } 00128 00129 } // end namespace rock 00130