00001 #include "ModulesReader.h"
00002 #include "ModulesFactory.h"
00003 #include "ModulesNavigator.h"
00004 #include "ModulesParser.h"
00005 #include <sstream>
00006 #include <string.h>
00007 #include <stdio.h>
00008
00009 using namespace modules::parser;
00010 using std::endl;
00011 using std::cout;
00012
00013 #include "debug_tools.h"
00014
00015 const char* modules::reader::fGlobalModule="global";
00016
00017 int modules::reader::ReadFile(const char* name){
00018
00019
00020 std::ifstream infile;
00021 int ret = OpenFile(name,infile);
00022 if(ret!=0) return ret;
00023
00024
00025 AddSection(fGlobalModule);
00026
00027
00028 std::string full_line;
00029 std::string section=fGlobalModule, new_section;
00030 Option_t current_opt;
00031 fLineNumber=0;
00032 while(std::getline(infile,full_line)){
00033 fLineNumber++;
00034
00035
00036 std::stringstream line(full_line);
00037
00038
00039 if(isComment(line) ) continue;
00040
00041
00042 new_section=findSectionName(full_line);
00043 if(new_section!="") {
00044 section=new_section;
00045 if(fShouldPrint) std::cout<<"Found new section: '"<<section<<"'"<<std::endl;
00046 if(section!="MODULES") {
00047 AddSection(section);
00048 }
00049 continue;
00050 }
00051
00052 if(section=="MODULES") {
00053
00054 ret=AddModule(full_line);
00055 if(ret!=0) return ret;
00056 }else{
00057
00058 current_opt=SplitOption(full_line);
00059
00060
00061 if(section==fGlobalModule) {
00062 ProcessGlobalOption(current_opt);
00063 } else{
00064 AddOption(section,current_opt);
00065 }
00066 if(fShouldPrint) std::cout<<"Found option: "<<full_line<<std::endl;
00067 }
00068 }
00069
00070
00071 if(fDumpContents) PrintAllOptions();
00072 return 0;
00073 }
00074
00075 int modules::reader::OpenFile(const char* name, std::ifstream& infile){
00076 infile.close();
00077 infile.open(name, std::ifstream::in);
00078 if(!infile.is_open()) {
00079 std::cout<<"Problem opening modules file: "<<name<<std::endl;
00080 return 1;
00081 }
00082 if(fShouldPrint) std::cout<<"Found modules file: "<<name<<std::endl;
00083 return 0;
00084 }
00085
00086 bool modules::reader::isComment( std::stringstream& line){
00087 char word='\0';
00088 line>>word;
00089 if(word=='#' || word =='\0'){
00090 return true;
00091 }
00092 line.clear();
00093 line.seekg(0,std::stringstream::beg);
00094
00095 return false;
00096 }
00097
00098 std::string modules::reader::findSectionName(const std::string& line){
00099
00100 Constructor_t section= modules::parser::ParseConstructor(line,'[',']');
00101 return section.inside;
00102 }
00103
00104 int modules::reader::AddModule(std::string line){
00105 std::string alias, type;
00106
00107
00108
00109
00110
00111 Constructor_t constructor=ParseConstructor(line,'(',')');
00112
00113 std::vector<std::string> name_alias;
00114 TokeniseByDelimiter(constructor.before, name_alias,"=");
00115 if(name_alias.size()>2) {
00116 PrintProblem()<<"Multiple equals signs (=) in line gives an ambiguous alias / alias."<<std::endl;
00117 return 1;
00118 }else if(name_alias.size()==2) {
00119 alias=name_alias[0];
00120 type=name_alias[1];
00121 TrimWhiteSpaceBeforeAfter(alias);
00122 }else if(name_alias.size()==1) type=name_alias[0];
00123 else {
00124 PrintProblem()<<"No module requested"<<std::endl;
00125 return 2;
00126 }
00127 TrimWhiteSpaceBeforeAfter(type);
00128
00129
00130 std::vector<std::string> args;
00131 TokeniseByDelimiter(constructor.inside,args,",");
00132
00133 if(fShouldPrint){
00134 std::cout<<"Adding module: '"<<type<<"'"<<std::endl;
00135 std::cout<<" with alias: '"<<alias<<"'"<<std::endl;
00136 std::cout<<" and "<<args.size()<<" arguments:"<<std::endl;
00137 for(unsigned i=0;i<args.size() ;i++)
00138 std::cout<<" "<<i<<'\t'<<args[i]<<std::endl;
00139 }
00140
00141
00142 modules::options* opts;
00143 if(alias==""){
00144 opts=new modules::options(type);
00145 }else{
00146
00147
00148 if(!AddSection(alias,type)){
00149 PrintProblem()<<" module alias is being reused"<<std::endl;
00150 return 1;
00151 }
00152 opts=fAllOptions[alias];
00153 opts->SetAlias(alias);
00154 }
00155
00156 for(unsigned i=0;i<args.size();i++) {
00157 opts->AddArgument(i,args[i]);
00158 }
00159
00160
00161 fModules.push_back(std::make_pair(type,opts));
00162 fModulesCounts[type]++;
00163
00164
00165 if(fDebugAll) AddOption(opts,"debug");
00166
00167 return 0;
00168 }
00169
00170 modules::reader::Option_t modules::reader::SplitOption( const std::string& line){
00171 Option_t opt;
00172 opt.value="";
00173 opt.mode=kSet;
00174
00175
00176 size_t equ_pos=line.find('=');
00177 if(equ_pos==std::string::npos) {
00178
00179 opt.key=line;
00180 }else if(line[equ_pos-1]=='+'){
00181
00182 opt.key=line.substr(0,equ_pos-1);
00183 opt.value=line.substr(equ_pos+1);
00184 opt.mode=kAppend;
00185 }else{
00186
00187 opt.key=line.substr(0,equ_pos);
00188 opt.value=line.substr(equ_pos+1);
00189 }
00190 return opt;
00191 }
00192
00193 void modules::reader::AddOption(modules::options* options, const Option_t& opt){
00194 bool exists;
00195 switch (opt.mode){
00196 case kSet:
00197 options->SetOption(opt.key,opt.value);
00198 break;
00199 case kAppend:
00200 exists= options->AppendToOption(opt.key,opt.value);
00201 if(!exists &&fShouldPrint){
00202 std::cout<<"Cannot append to '"<<opt.key<<"' as it doesn't already exist"<<std::endl;
00203 }
00204 break;
00205 default:
00206 std::cout<<"modules::reader::AddOption(): That's odd! How did I end up here?"<<std::endl;
00207 break;
00208 }
00209 }
00210
00211 void modules::reader::AddOption(modules::options* options, const std::string& flag){
00212 options->SetOption(flag,"");
00213 }
00214
00215 void modules::reader::PrintAllOptions()const{
00216
00217 SectionsList::const_iterator it_sec=fAllOptions.find(fGlobalModule);
00218 if(it_sec!=fAllOptions.end() && it_sec->second->GetNumOptions()>0){
00219 std::cout<<"== Global otions =="<<std::endl;
00220 it_sec->second->DumpOptions();
00221 std::cout<<std::endl;
00222 }
00223
00224
00225 std::cout<<"== All modules =="<<std::endl;
00226 ModuleList::const_iterator it_mod;
00227 for(it_mod=fModules.begin(); it_mod != fModules.end();it_mod++){
00228 std::cout<<"Module: "<<it_mod->first<<std::endl;
00229 it_mod->second->DumpOptions();
00230 std::cout<<std::endl;
00231 }
00232
00233
00234 std::cout<<"== Unused sections =="<<std::endl;
00235 for(it_sec=fAllOptions.begin(); it_sec != fAllOptions.end();it_sec++){
00236 if(it_sec->first==fGlobalModule) continue;
00237 for(it_mod=fModules.begin(); it_mod != fModules.end();it_mod++){
00238 if(it_sec->second==it_mod->second ) break;
00239 }
00240 if(it_mod!=fModules.end()) continue;
00241 std::cout<<"Section: "<<it_sec->first<<std::endl;
00242 it_sec->second->DumpOptions();
00243 std::cout<<std::endl;
00244 }
00245 }
00246
00247 void modules::reader::SetDebug(){
00248 std::cout<<"Debug mode activated"<<std::endl;
00249 fShouldPrint=true;
00250 modules::factory::Instance()->SetDebug();
00251 }
00252
00253 void modules::reader::SetDebugAll(){
00254
00255 fDebugAll=true;
00256 AddOptionAll("debug");
00257 }
00258
00259 void modules::reader::AddOptionAll(const std::string& key,const std::string& value){
00260 for(SectionsList::iterator it_sec=fAllOptions.begin(); it_sec != fAllOptions.end();it_sec++){
00261 if(it_sec->first==fGlobalModule) continue;
00262 it_sec->second->SetOption(key,value);
00263 }
00264 }
00265
00266 void modules::reader::ProcessGlobalOption(Option_t opt){
00267 if (opt.mode==kAppend) {
00268 if(fShouldPrint) std::cout<<"Warning: over-writing '"<<opt.key<<"' with '"
00269 << opt.value<<"' despite append operator being used"<<std::endl;
00270 }
00271 if (opt.key=="debug"){
00272 std::vector<std::string> args;
00273 modules::parser::TokeniseByWhiteSpace(opt.value,args );
00274 for(unsigned i=0;i<args.size();i++){
00275 if (args[i]=="all"){
00276 SetDebugAll();
00277 }else if (args[i]=="modules_navigator"){
00278 modules::navigator::Instance()->SetDebug();
00279 }else if (args[i]=="modules_reader"){
00280 SetDebug();
00281 }
00282 }
00283 }else if(opt.key=="list_modules"){
00284 modules::factory::Instance()->PrintPossibleModules();
00285 }else if(opt.key=="show_input_data"){
00286 fDumpInputFile=true;
00287 }else if(opt.key=="dump_contents"){
00288 fDumpContents=true;
00289 }else {
00290 if(fShouldPrint) std::cout<<"Warning: Unknown global option given, '"<<opt.key<<"'"<<std::endl;
00291 return;
00292 }
00293 }
00294
00295 std::ostream& modules::reader::PrintProblem(){
00296 return std::cout<<"Problem on line "<<fLineNumber<<": ";
00297 }
00298
00299 int modules::reader::HowMany(const std::string& name)const{
00300 ModuleCounts::const_iterator it=fModulesCounts.find(name);
00301 if(it!=fModulesCounts.end()) return it->second;
00302 return 0;
00303 }
00304