xref: /phasta/phSolver/common/Cinput.cc (revision cc72a73fd2b79f4dd0a850fa4af718cd73554811)
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 (unsigned i = 0 ; i < intext->size(); i++) {
132     string textlineALL = (*intext)[i];
133     string textline;
134 
135     // modification introduced so that comments starting midway in a file
136     // can be handled.
137     size_t pos = textlineALL.find_first_of( '#',0);
138     if ( pos != string::npos) {
139       textline = textlineALL.substr(0,pos);
140     }else {
141       textline = textlineALL;
142     }
143     pos = textline.find_first_of( ':', 0);
144     if ( pos != string::npos) {
145 
146       // get the keyphrase
147       string keywd = textline.substr(0,pos);
148       trim_string(&keywd);
149 
150       // get the key-value
151       string keyval = textline.substr( pos+1, textline.length() - pos);
152       trim_string(&keyval);
153 
154       // put the pair into the map
155       (*inmap)[keywd] = keyval;
156 
157     }
158   }
159 }
160 
161 // remove leading and trailing spaces (or tabs)
162 void phSolver::Input::trim_string(string *str)
163 {
164   // check for empty string
165   int length = str->length();
166   if ( length == 0 )
167     return;
168 
169   // erase leading spaces (or tabs)
170   int pos0 = 0;
171   while ( (*str)[pos0] == ' ' || (*str)[pos0] == '\t') {
172     pos0++;
173   }
174   if ( pos0 > 0 ) {
175     str->erase(0,pos0);
176   }
177 
178   length = str->length();
179   pos0 = length-1;
180   // erase trailing spaces (or tabs)
181   while ( (*str)[pos0] == ' ' || (*str)[pos0] == '\t') {
182     pos0--;
183   }
184   if ( pos0 < length-1 ) {
185     str->erase(pos0+1, length-pos0);
186   }
187 
188 }
189