1 #include <stdio.h> 2 #include <fstream> 3 #include "Input.h" 4 #include "ValType.h" 5 #include <stdexcept> 6 #include <sstream> 7 //MR CHANGE 8 #include <cstdlib> 9 //MR CHANGE END 10 11 // return a given key value (if it's in the map) 12 ValType Input::GetValue(const string &str) const 13 { 14 if (input_map->find(str) != input_map->end()) { 15 if ( (*input_map)[str] == "NODEFAULT" ) { 16 stringstream ost; 17 ost << "required input variable not set: " << str << ends; 18 throw invalid_argument( ost.str() ); 19 } 20 } else { 21 stringstream ost; 22 ost << "required input variable not set: " << str << ends; 23 throw invalid_argument( ost.str() ); 24 } 25 26 return ValType( (*input_map)[str] ); 27 } 28 29 30 Input::Input(const string &fname, const string &default_fname) 31 { 32 // open the input file 33 ifstream infile( fname.c_str(), ios::in); 34 35 if(!infile || infile.eof()){ 36 cerr<<" Input file does not exist or is empty or perhaps you forgot mpirun? "<<endl; 37 exit(-2); 38 } 39 40 // allocate memory 41 input_text = new vector<string>; 42 input_map = new map<string,string>; 43 44 // get the lines of text from the input file 45 get_input_lines(input_text, infile); 46 build_map(input_map, input_text); 47 48 // build and merge with default map ( if desired ) 49 if (!default_fname.empty()) { 50 ifstream infile2( default_fname.c_str(), ios::in); 51 52 map<string,string> *default_map = new map<string,string>; 53 vector<string> *default_text = new vector<string>; 54 55 get_input_lines(default_text, infile2); 56 build_map(default_map, default_text); 57 58 // merge the two maps 59 map<string,string>::const_iterator iter = default_map->begin(); 60 for ( ; iter != default_map->end(); ++iter ) { 61 string defkey = iter->first; 62 string defval = iter->second; 63 if ( input_map->find(defkey) == input_map->end() ) { 64 (*input_map)[defkey] = defval; 65 } 66 } 67 infile2.close(); 68 69 delete default_map; 70 delete default_text; 71 72 } else { 73 cerr << "Input warning: no input.config file found." << endl; 74 cerr << "Get one from source directory." << endl; 75 exit(-2); 76 } 77 78 infile.close(); 79 80 } 81 82 Input::~Input() 83 { 84 delete input_text; 85 delete input_map; 86 } 87 88 89 // return the input map 90 map<string,string> Input::InputMap() const 91 { 92 return *input_map; 93 } 94 95 // echo the entire map 96 void Input::EchoInputMap(const ostream &ofile) 97 { 98 map<string,string>::const_iterator iter = input_map->begin(); 99 for ( ; iter != input_map->end(); ++iter ) { 100 cout << "Keyphrase: " << iter->first << endl 101 << "Keyvalue: " << iter->second << endl << endl; 102 } 103 } 104 105 // read the input text from the given stream 106 void Input::get_input_lines(vector<string> *text, ifstream &infile) 107 { 108 string textline; 109 while ( getline( infile, textline, '\n' ) ) { 110 // ignore everything on a comment line 111 if ( textline[0] != '#' ) { 112 text->push_back( textline ); 113 } 114 } 115 } 116 117 118 // 119 void Input::build_map(map<string,string> *inmap, 120 vector<string> *intext) 121 { 122 // iterate through input_text of text and separate at :'s 123 for (int i = 0 ; i < intext->size(); i++) { 124 string textlineALL = (*intext)[i]; 125 string textline; 126 int pos = 0; 127 128 // modification introduced so that comments starting midway in a file 129 // can be handled. 130 131 if ( (pos = textlineALL.find_first_of( '#',pos)) != string::npos) { 132 textline = textlineALL.substr(0,pos); 133 }else { 134 textline = textlineALL; 135 } 136 pos = 0; 137 if ( (pos = textline.find_first_of( ':',pos)) != string::npos) { 138 139 // get the keyphrase 140 string keywd = textline.substr(0,pos); 141 trim_string(&keywd); 142 143 // get the key-value 144 string keyval = textline.substr( pos+1, textline.length() - pos); 145 trim_string(&keyval); 146 147 // put the pair into the map 148 (*inmap)[keywd] = keyval; 149 150 } 151 } 152 } 153 154 // remove leading and trailing spaces (or tabs) 155 void Input::trim_string(string *str) 156 { 157 // check for empty string 158 int length = str->length(); 159 if ( length == 0 ) 160 return; 161 162 // erase leading spaces (or tabs) 163 int pos0 = 0; 164 while ( (*str)[pos0] == ' ' || (*str)[pos0] == '\t') { 165 pos0++; 166 } 167 if ( pos0 > 0 ) { 168 str->erase(0,pos0); 169 } 170 171 length = str->length(); 172 pos0 = length-1; 173 // erase trailing spaces (or tabs) 174 while ( (*str)[pos0] == ' ' || (*str)[pos0] == '\t') { 175 pos0--; 176 } 177 if ( pos0 < length-1 ) { 178 str->erase(pos0+1, length-pos0); 179 } 180 181 } 182