1 /*
2  * Config.cpp
3  *
4  * Copyright Notice: see copyright.txt
5  *
6  * Date: 3/8/2012 (D/M/Y)
7  * Author: Dmitrij Lioubartsev
8  * Email: dmitrijl42@gmail.com
9  *
10  * For config file specifications of parameters and syntax, see readme.txt.
11  */
12 
13 #include "Config.h"
14 #include <fstream>
15 #include <iostream>
16 #include <cstdlib>
17 using namespace std;
18 
19 #define WHITE_SPACE(x) ((x == ' ') || (x == '\t') || (x == '\n')|| (x == '=') || (x == ':') || (x == '#') || (x == '\r'))
20 
Config()21 Config::Config() {
22 	//set default values
23 	output = "default";
24 	xmol = false;
25 	r_min = 20;
26 	// ratios.insert(std::pair<string,double>("Si",1.0)); <- this is empty as well.
27 	// eliminate.push_back("nothing"); <- this should be empty
28 	ff_file = "default";
29 	charge_tot = 0;
30 	car = false;
31 
32 	//other
33 	fixCharge = false;
34 }
35 
36 /*
37  * Read the specified config file. See readme.txt fore more info
38  * about the file syntax.
39  */
readFile(const char * configFile)40 bool Config::readFile(const char * configFile) {
41 	ifstream conFile(configFile);
42 	if(conFile) { //if file exists
43 		while(!conFile.eof()) {
44 			if(skipWhiteSpace(conFile)) //skip whitespaces
45 				break;
46 
47 			string token("");
48 			if(getWord(conFile,token))  //get word
49 				break;
50 
51 			if(skipWhiteSpace(conFile)) //skip whitespaces after
52 				break;
53 
54 			string value("");
55 			getWord(conFile,value); //get value
56 
57 			if(token == "output") {
58 				output = value;
59 			} else if(token == "make_xmol") {
60 				xmol = atoi(value.c_str());
61 			} else if(token == "R_min" || token == "r_min") {
62 				r_min = atof(value.c_str());
63 			} else if(token == "substitute" || token == "substitution") {
64 				for(int i = 0; i < atoi(value.c_str()); i++) {
65 					if(skipWhiteSpace(conFile)) //skip whitespaces
66 						break;
67 					string name("");
68 					if(getWord(conFile,name)) //get element
69 						break;
70 					if(skipWhiteSpace(conFile)) //skip whitespaces
71 						break;
72 					string ratioStr("");
73 					getWord(conFile,ratioStr); //get its ratio
74 					double ratio = atof(ratioStr.c_str());
75 					ratios.push_back(pair<string,double>(name,ratio));
76 				}
77 			} else if(token == "exclude" || token == "exclusion") {
78 				for(int i = 0; i < atoi(value.c_str()); i++) {
79 					if(skipWhiteSpace(conFile)) //skip whitespaces
80 						break;
81 					string formula("");
82 					getWord(conFile,formula);
83 					exclude.push_back(formula);
84 				}
85 			} else if(token == "force_field") {
86 				ff_file = value;
87 			} else if(token == "charge_tot") {
88 				fixCharge = true;
89 				charge_tot = atof(value.c_str());
90 			} else if(token == "make_car") {
91 				car = atoi(value.c_str());
92 			} //else do nothing
93 		}
94 		return true;
95 	} else {
96 		return false;
97 	}
98 }
99 
~Config()100 Config::~Config() {
101 	// do nothing
102 }
103 
104 /*
105  * Skips all whitespace characters.
106  * Return true if eof reached.
107  */
skipWhiteSpace(ifstream & stream)108 bool Config::skipWhiteSpace(ifstream& stream) {
109 	char c = ' ';
110 
111 	bool eof = false;
112 	while(WHITE_SPACE(c)) {
113 		stream.get(c);
114 		if(stream.eof()) {
115 			eof = true;
116 			break; //reached end of file, stop
117 		}
118 		if(c == '#')  {//comment
119 			stream.ignore(256, '\n');
120 			if(stream.eof()) {
121 				eof = true;
122 				break;
123 			}
124 		}
125 	}
126 	stream.unget();
127 	return eof;
128 }
129 
130 /*
131  * Get the next word, and place it in parameter word.
132  * Returns true in case of eof.
133  */
getWord(ifstream & stream,string & word)134 bool Config::getWord(ifstream& stream, string& word) {
135 	word = "";
136 	char c;
137 	bool eof = false;
138 
139 	while(!(WHITE_SPACE(c))) {
140 		stream.get(c);
141 		if(stream.eof()) {
142 			eof = true;
143 			break; //reached end of file, stop
144 		}
145 		word.append(1,c);
146 	}
147 	if(!eof) {
148 		stream.unget();
149 		word.erase(word.length()-1,1);
150 	}
151 	return eof;
152 }
153 
154 /*
155  * Creates a configuration file with the current values.
156  */
createConf()157 void Config::createConf() {
158 	ofstream conFile("input.cfg");
159 
160 	//first create some explanation comments
161 	conFile << "##################################################################" << endl
162 			<< "# This is an auto-generated configration file with default values." << endl
163 			<< "# This is generated when no input configuration file is specified, and" << endl
164 			<< "# the default \"input.cfg\" does not exist." << endl
165 			<< "# For file syntax and parameters, see readme.txt" << endl
166 			<< "##################################################################" << endl << endl << endl;
167 
168 	//now put values
169 	conFile << "output = " << output << endl;
170 	conFile << "make_xmol = " << xmol << endl;
171 	conFile << "make_car = " << car << endl;
172 	conFile << "R_min = " << r_min << endl;
173 	conFile << "substitute = " << ratios.size() << endl;
174 	vector<pair<string,double> >::iterator it;
175 	for(it = ratios.begin(); it != ratios.end();it++) {
176 		conFile << "   " << (it->first) << " : " << (it->second) << endl;
177 	}
178 	conFile << "exclude = " << exclude.size() << endl;
179 	vector<string>::iterator iter;
180 	for(iter = exclude.begin(); iter != exclude.end();iter++) {
181 		conFile << "   " << (*iter) << endl;
182 	}
183 	conFile << "force_field = " << ff_file << endl;
184 	conFile << "# charge_tot = " << charge_tot << endl;
185 
186 	conFile.close();
187 }
188 
189 
190 
191 #undef WHITE_SPACE
192 
193