xref: /phasta/phSolver/common/Cinput.cc (revision f1ff48b0dc8b3d7cb993a2e35bb9deededfc862f)
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