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