00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <iostream>
00010 #include <fstream>
00011
00012
00013
00014 #include <boost/filesystem/operations.hpp>
00015 #include <boost/tokenizer.hpp>
00016 #include <boost/regex.hpp>
00017 #include <boost/algorithm/string.hpp>
00018 #include <boost/format.hpp>
00019
00020
00021
00022 #include "ParserUtils.h"
00023 #include "ParserGrammar.h"
00024 #include "GaudiKernel/System.h"
00025
00026 namespace fs = boost::filesystem;
00027 using namespace std;
00028
00029
00040
00041 StatusCode Gaudi::Parsers::parse
00042 ( Gaudi::Parsers::Parser parser ,
00043 const std::string& fileName ,
00044 std::vector<Gaudi::Parsers::Message>& msgs )
00045 {
00046 StatusCode res = parser.parse(fileName);
00047 msgs = parser.messages();
00048 return res;
00049 }
00050
00051 StatusCode Gaudi::Parsers::parse
00052 ( const string& filename,
00053 const vector<string>& searchPath,
00054 Gaudi::Parsers::Catalogue& catalogue,
00055 std::vector<std::string>& included,
00056 vector<Gaudi::Parsers::Message>& msgs)
00057 {
00058 return parse
00059 ( Gaudi::Parsers::Parser(catalogue, included, searchPath) ,
00060 filename , msgs ) ;
00061 }
00062
00063 StatusCode Gaudi::Parsers::parse
00064 ( const string& filename,
00065 const string& searchPath,
00066 Gaudi::Parsers::Catalogue& catalogue,
00067 std::vector<std::string>& included,
00068 vector<Gaudi::Parsers::Message>& msgs)
00069 {
00070 return parse
00071 ( Gaudi::Parsers::Parser (catalogue , included, searchPath ) ,
00072 filename , msgs ) ;
00073 }
00074
00075 StatusCode Gaudi::Parsers::parse
00076 ( const string& filename,
00077 Gaudi::Parsers::Catalogue& catalogue,
00078 std::vector<std::string>& included,
00079 vector<Gaudi::Parsers::Message>& msgs){
00080 return parse
00081 (Gaudi::Parsers::Parser(catalogue,included),filename,msgs);
00082 }
00083
00084 StatusCode Gaudi::Parsers::Utils::getEnv
00085 ( const std::string& envName , std::string& envValue )
00086 {
00087 return (System::getEnv(envName, envValue)) ? StatusCode::SUCCESS : StatusCode::FAILURE;
00088 }
00089
00090 std::string
00091 Gaudi::Parsers::Utils::removeEnvironment(const std::string& input){
00092 std::string result=input;
00093
00094 const char* re = "\\$(([A-Za-z0-9_]+)|\\(([A-Za-z0-9_]+)\\))";
00095 std::string::const_iterator start, end;
00096 boost::regex expression(re);
00097 start = input.begin();
00098 end = input.end();
00099 boost::match_results<std::string::const_iterator> what;
00100 boost::match_flag_type flags = boost::match_default;
00101 while ( boost::regex_search(start, end, what, expression, flags ) )
00102 {
00103 std::string var,env;
00104 std::string matched(what[0].first,what[0].second);
00105 std::string v1(what[2].first,what[2].second);
00106 std::string v2(what[3].first,what[3].second);
00107
00108 if ( v1.length()>0){ var = v1; }
00109 else { var = v2; }
00110
00111 StatusCode ok = getEnv(var, env);
00112 if(ok.isSuccess())
00113 { boost::algorithm::replace_first(result,matched, env); }
00114 start = what[0].second;
00115
00116 flags |= boost::match_prev_avail;
00117 flags |= boost::match_not_bob;
00118 }
00119 return result;
00120 }
00121
00122 StatusCode Gaudi::Parsers::Utils::searchFile
00123 ( const std::string& fileInput ,
00124 bool addCurrent ,
00125 const std::vector<std::string>& dirs ,
00126 std::string& fileOutput )
00127 {
00128 std::string result;
00129 try {
00130 fs::path givenPath(removeEnvironment(fileInput),fs::native);
00131
00132 fs::path currentPath = givenPath;
00133 std::vector<std::string> sdirs = dirs;
00134 if(addCurrent){
00135 sdirs.insert(sdirs.begin(),
00136 fs::initial_path().native_directory_string());
00137 }
00138 std::vector<std::string>::const_iterator current =
00139 sdirs.begin(),end=sdirs.end();
00140 while(1) {
00141 if(fs::exists(currentPath)) {
00142 fileOutput = currentPath.native_directory_string();
00143 return StatusCode::SUCCESS;
00144 }
00145 if(current!=end) {
00146 std::string _n = *current;
00147 currentPath = fs::path(_n, fs::native)/givenPath;
00148 }else{
00149 return StatusCode::FAILURE;
00150 }
00151 ++current;
00152 }
00153 }catch(...) {}
00154 return StatusCode::FAILURE;
00155 }
00156
00157 StatusCode Gaudi::Parsers::Utils::readFile
00158 (const std::string& name , std::string& result)
00159 {
00160 std::ifstream in(name.c_str());
00161 if (!in.is_open()) { return StatusCode::FAILURE; }
00162 char c;
00163 while (!in.get(c).eof()) { result += c; }
00164 return StatusCode::SUCCESS;
00165 }
00166
00167 bool Gaudi::Parsers::Utils::isWin()
00168 {
00169 #ifdef _WIN32
00170 return true;
00171 #else
00172 return false;
00173 #endif
00174 }
00175
00176 std::string Gaudi::Parsers::Utils::pathSeparator()
00177 { return Gaudi::Parsers::Utils::isWin()?";":":"; }
00178
00179 std::vector<std::string> Gaudi::Parsers::Utils::extractPath
00180 ( const std::string& input, bool removeEnv )
00181 {
00182 std::string in = removeEnv?removeEnvironment(input):input;
00183 std::string separator = ","+pathSeparator();
00184 typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
00185 std::vector<std::string> result;
00186 Tokenizer tok(in, boost::char_separator<char>(separator.c_str()));
00187 Tokenizer::iterator it =tok.begin();
00188 while(it!=tok.end())
00189 {
00190 if(it->length()>0){ result.push_back(*it); }
00191 it++;
00192 }
00193 return result;
00194 }
00195
00196 StatusCode Gaudi::Parsers::Utils::parseValue
00197 ( const string& input ,
00198 std::string& stringResult ,
00199 std::vector<std::string>& vectorResult )
00200 {
00201
00202 typedef
00203 boost::spirit::position_iterator<std::string::const_iterator> IteratorT;
00204
00205 Gaudi::Parsers::ValueGrammar grValue;
00206 Gaudi::Parsers::SkipperGrammar grSkipper;
00207 IteratorT beginpos(input.begin(), input.end(), "");
00208 IteratorT endpos;
00209 boost::tuple<std::string, std::vector<std::string> > result;
00210 boost::spirit::parse_info<IteratorT> info =
00211 boost::spirit::parse
00212 (beginpos, endpos, grValue[var(result)=arg1] ,grSkipper);
00213 if (!info.full){ return StatusCode::FAILURE; }
00214 stringResult = result.get<0>();
00215 vectorResult = result.get<1>();
00216 return StatusCode::SUCCESS;
00217 }
00218
00219
00220
00221
00222
00223