xref: /phasta/phSolver/common/Cinput.cc (revision 1bfea4388fd063fa9512a81921163a8af7623428)
159599516SKenneth E. Jansen #include <stdio.h>
259599516SKenneth E. Jansen #include <fstream>
359599516SKenneth E. Jansen #include "Input.h"
459599516SKenneth E. Jansen #include "ValType.h"
559599516SKenneth E. Jansen #include <stdexcept>
6*1bfea438SCameron Smith #include <sstream>
759599516SKenneth E. Jansen //MR CHANGE
859599516SKenneth E. Jansen #include <cstdlib>
959599516SKenneth E. Jansen //MR CHANGE END
1059599516SKenneth E. Jansen 
1159599516SKenneth E. Jansen // return a given key value (if it's in the map)
1259599516SKenneth E. Jansen ValType Input::GetValue(const string &str) const
1359599516SKenneth E. Jansen {
1459599516SKenneth E. Jansen   if (input_map->find(str) != input_map->end()) {
1559599516SKenneth E. Jansen     if ( (*input_map)[str] == "NODEFAULT" ) {
16*1bfea438SCameron Smith       stringstream ost;
1759599516SKenneth E. Jansen       ost << "required input variable not set: " << str << ends;
1859599516SKenneth E. Jansen       throw invalid_argument( ost.str() );
1959599516SKenneth E. Jansen     }
2059599516SKenneth E. Jansen   } else {
21*1bfea438SCameron Smith     stringstream ost;
2259599516SKenneth E. Jansen     ost << "required input variable not set: " << str << ends;
2359599516SKenneth E. Jansen     throw invalid_argument( ost.str() );
2459599516SKenneth E. Jansen   }
2559599516SKenneth E. Jansen 
2659599516SKenneth E. Jansen   return ValType( (*input_map)[str] );
2759599516SKenneth E. Jansen }
2859599516SKenneth E. Jansen 
2959599516SKenneth E. Jansen 
3059599516SKenneth E. Jansen Input::Input(const string &fname, const string &default_fname)
3159599516SKenneth E. Jansen {
3259599516SKenneth E. Jansen   // open the input file
3359599516SKenneth E. Jansen   ifstream infile( fname.c_str(), ios::in);
3459599516SKenneth E. Jansen 
3559599516SKenneth E. Jansen   if(!infile || infile.eof()){
3659599516SKenneth E. Jansen     cerr<<" Input file does not exist or is empty or perhaps you forgot mpirun? "<<endl;
3759599516SKenneth E. Jansen     exit(-2);
3859599516SKenneth E. Jansen   }
3959599516SKenneth E. Jansen 
4059599516SKenneth E. Jansen   // allocate memory
4159599516SKenneth E. Jansen   input_text   = new vector<string>;
4259599516SKenneth E. Jansen   input_map    = new map<string,string>;
4359599516SKenneth E. Jansen 
4459599516SKenneth E. Jansen   // get the lines of text from the input file
4559599516SKenneth E. Jansen   get_input_lines(input_text, infile);
4659599516SKenneth E. Jansen   build_map(input_map, input_text);
4759599516SKenneth E. Jansen 
4859599516SKenneth E. Jansen   // build and merge with default map ( if desired )
4959599516SKenneth E. Jansen   if (!default_fname.empty()) {
5059599516SKenneth E. Jansen     ifstream infile2( default_fname.c_str(), ios::in);
5159599516SKenneth E. Jansen 
5259599516SKenneth E. Jansen     map<string,string> *default_map  = new map<string,string>;
5359599516SKenneth E. Jansen     vector<string> *default_text = new vector<string>;
5459599516SKenneth E. Jansen 
5559599516SKenneth E. Jansen     get_input_lines(default_text, infile2);
5659599516SKenneth E. Jansen     build_map(default_map, default_text);
5759599516SKenneth E. Jansen 
5859599516SKenneth E. Jansen     // merge the two maps
5959599516SKenneth E. Jansen     map<string,string>::const_iterator iter = default_map->begin();
6059599516SKenneth E. Jansen     for ( ; iter != default_map->end(); ++iter ) {
6159599516SKenneth E. Jansen       string defkey = iter->first;
6259599516SKenneth E. Jansen       string defval = iter->second;
6359599516SKenneth E. Jansen       if ( input_map->find(defkey) == input_map->end() ) {
6459599516SKenneth E. Jansen 	(*input_map)[defkey] = defval;
6559599516SKenneth E. Jansen       }
6659599516SKenneth E. Jansen     }
6759599516SKenneth E. Jansen     infile2.close();
6859599516SKenneth E. Jansen 
6959599516SKenneth E. Jansen     delete default_map;
7059599516SKenneth E. Jansen     delete default_text;
7159599516SKenneth E. Jansen 
7259599516SKenneth E. Jansen   } else  {
7359599516SKenneth E. Jansen     cerr << "Input warning: no input.config file found." << endl;
7459599516SKenneth E. Jansen     cerr << "Get one from source directory." << endl;
7559599516SKenneth E. Jansen     exit(-2);
7659599516SKenneth E. Jansen   }
7759599516SKenneth E. Jansen 
7859599516SKenneth E. Jansen   infile.close();
7959599516SKenneth E. Jansen 
8059599516SKenneth E. Jansen }
8159599516SKenneth E. Jansen 
8259599516SKenneth E. Jansen Input::~Input()
8359599516SKenneth E. Jansen {
8459599516SKenneth E. Jansen   delete input_text;
8559599516SKenneth E. Jansen   delete input_map;
8659599516SKenneth E. Jansen }
8759599516SKenneth E. Jansen 
8859599516SKenneth E. Jansen 
8959599516SKenneth E. Jansen // return the input map
9059599516SKenneth E. Jansen map<string,string> Input::InputMap() const
9159599516SKenneth E. Jansen {
9259599516SKenneth E. Jansen   return *input_map;
9359599516SKenneth E. Jansen }
9459599516SKenneth E. Jansen 
9559599516SKenneth E. Jansen // echo the entire map
9659599516SKenneth E. Jansen void Input::EchoInputMap(const ostream &ofile)
9759599516SKenneth E. Jansen {
9859599516SKenneth E. Jansen   map<string,string>::const_iterator iter = input_map->begin();
9959599516SKenneth E. Jansen   for ( ; iter != input_map->end(); ++iter ) {
10059599516SKenneth E. Jansen     cout << "Keyphrase: " << iter->first << endl
10159599516SKenneth E. Jansen 	 << "Keyvalue:  " << iter->second << endl << endl;
10259599516SKenneth E. Jansen   }
10359599516SKenneth E. Jansen }
10459599516SKenneth E. Jansen 
10559599516SKenneth E. Jansen // read the input text from the given stream
10659599516SKenneth E. Jansen void Input::get_input_lines(vector<string> *text, ifstream &infile)
10759599516SKenneth E. Jansen {
10859599516SKenneth E. Jansen   string textline;
10959599516SKenneth E. Jansen   while ( getline( infile, textline, '\n' ) ) {
11059599516SKenneth E. Jansen     // ignore everything on a comment line
11159599516SKenneth E. Jansen     if ( textline[0] != '#' ) {
11259599516SKenneth E. Jansen       text->push_back( textline );
11359599516SKenneth E. Jansen     }
11459599516SKenneth E. Jansen   }
11559599516SKenneth E. Jansen }
11659599516SKenneth E. Jansen 
11759599516SKenneth E. Jansen 
11859599516SKenneth E. Jansen //
11959599516SKenneth E. Jansen void Input::build_map(map<string,string> *inmap,
12059599516SKenneth E. Jansen 		      vector<string>     *intext)
12159599516SKenneth E. Jansen {
12259599516SKenneth E. Jansen   // iterate through input_text of text and separate at :'s
12359599516SKenneth E. Jansen   for (int i = 0 ; i < intext->size(); i++) {
12459599516SKenneth E. Jansen     string textlineALL = (*intext)[i];
12559599516SKenneth E. Jansen     string textline;
12659599516SKenneth E. Jansen     int pos  = 0;
12759599516SKenneth E. Jansen 
12859599516SKenneth E. Jansen     // modification introduced so that comments starting midway in a file
12959599516SKenneth E. Jansen     // can be handled.
13059599516SKenneth E. Jansen 
13159599516SKenneth E. Jansen     if ( (pos = textlineALL.find_first_of( '#',pos)) != string::npos) {
13259599516SKenneth E. Jansen       textline = textlineALL.substr(0,pos);
13359599516SKenneth E. Jansen     }else {
13459599516SKenneth E. Jansen       textline = textlineALL;
13559599516SKenneth E. Jansen     }
13659599516SKenneth E. Jansen     pos = 0;
13759599516SKenneth E. Jansen     if ( (pos = textline.find_first_of( ':',pos)) != string::npos) {
13859599516SKenneth E. Jansen 
13959599516SKenneth E. Jansen       // get the keyphrase
14059599516SKenneth E. Jansen       string keywd = textline.substr(0,pos);
14159599516SKenneth E. Jansen       trim_string(&keywd);
14259599516SKenneth E. Jansen 
14359599516SKenneth E. Jansen       // get the key-value
14459599516SKenneth E. Jansen       string keyval = textline.substr( pos+1, textline.length() - pos);
14559599516SKenneth E. Jansen       trim_string(&keyval);
14659599516SKenneth E. Jansen 
14759599516SKenneth E. Jansen       // put the pair into the map
14859599516SKenneth E. Jansen       (*inmap)[keywd] = keyval;
14959599516SKenneth E. Jansen 
15059599516SKenneth E. Jansen     }
15159599516SKenneth E. Jansen   }
15259599516SKenneth E. Jansen }
15359599516SKenneth E. Jansen 
15459599516SKenneth E. Jansen // remove leading and trailing spaces (or tabs)
15559599516SKenneth E. Jansen void Input::trim_string(string *str)
15659599516SKenneth E. Jansen {
15759599516SKenneth E. Jansen   // check for empty string
15859599516SKenneth E. Jansen   int length = str->length();
15959599516SKenneth E. Jansen   if ( length == 0 )
16059599516SKenneth E. Jansen     return;
16159599516SKenneth E. Jansen 
16259599516SKenneth E. Jansen   // erase leading spaces (or tabs)
16359599516SKenneth E. Jansen   int pos0 = 0;
16459599516SKenneth E. Jansen   while ( (*str)[pos0] == ' ' || (*str)[pos0] == '\t') {
16559599516SKenneth E. Jansen     pos0++;
16659599516SKenneth E. Jansen   }
16759599516SKenneth E. Jansen   if ( pos0 > 0 ) {
16859599516SKenneth E. Jansen     str->erase(0,pos0);
16959599516SKenneth E. Jansen   }
17059599516SKenneth E. Jansen 
17159599516SKenneth E. Jansen   length = str->length();
17259599516SKenneth E. Jansen   pos0 = length-1;
17359599516SKenneth E. Jansen   // erase trailing spaces (or tabs)
17459599516SKenneth E. Jansen   while ( (*str)[pos0] == ' ' || (*str)[pos0] == '\t') {
17559599516SKenneth E. Jansen     pos0--;
17659599516SKenneth E. Jansen   }
17759599516SKenneth E. Jansen   if ( pos0 < length-1 ) {
17859599516SKenneth E. Jansen     str->erase(pos0+1, length-pos0);
17959599516SKenneth E. Jansen   }
18059599516SKenneth E. Jansen 
18159599516SKenneth E. Jansen }
182