bpp-core3  3.0.0
AttributesTools.cpp
Go to the documentation of this file.
1 //
2 // File: AttributesTools.cpp
3 // Authors:
4 // Julien Dutheil
5 // Created: 2003-10-07 00:00:00
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
10 
11  This software is a computer program whose purpose is to provide basal and
12  utilitary classes. This file belongs to the Bio++ Project.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39 */
40 
41 
42 
43 // From the STL:
44 #include <cstdlib>
45 #include <string>
46 #include <iostream>
47 #include <fstream>
48 #include <algorithm>
49 
50 
51 using namespace std;
52 
53 #include "AttributesTools.h"
54 #include "../App/ApplicationTools.h"
55 #include "../Text/TextTools.h"
56 #include "../Io/FileTools.h"
57 
58 using namespace bpp;
59 
60 std::vector<std::string> AttributesTools::vParam_;
61 
62 /******************************************************************************/
63 
64 std::vector<std::string> AttributesTools::getVector(int argc, char* argv[])
65 {
66  size_t n = static_cast<size_t>(argc);
67  vector<string> result(n);
68  for (size_t i = 1; i < n; ++i)
69  {
70  result[i] = string(argv[i]);
71  }
72  // Ignore first argc which is the program name!
73  return result;
74 }
75 
76 /******************************************************************************/
77 
78 std::map<std::string, std::string> AttributesTools::getAttributesMap(
79  const std::vector<std::string>& argv,
80  const std::string& delimiter)
81 {
82  map<string, string> am;
83  getAttributesMap(argv, am, delimiter);
84  return am;
85 }
86 
87 /******************************************************************************/
88 
89 void AttributesTools::getAttributesMap(
90  const std::vector<std::string>& argv,
91  std::map<std::string, std::string>& am,
92  const std::string& delimiter)
93 {
94  vector<string> argv2(argv.size());
95  // First make a few cleaning:
96  for (size_t i = 0; i < argv.size(); i++)
97  {
98  // Make a few corrections first:
99  string arg = removeComments(argv[i], string("#"), string("\n")); // remove shell comments.
100  arg = removeComments(arg, string("//"), string("\n")); // remove C simple comments.
101  arg = removeComments(arg, string("/*"), string("*/")); // remove C multiple comments.
102  arg = TextTools::removeWhiteSpaces(arg);
103  argv2[i] = arg;
104  }
105  // Now parse arguments:
106  for (size_t i = 0; i < argv.size(); i++)
107  {
108  string arg = argv2[i];
109  if (arg == "")
110  continue; // Skipping void line.
111  while (arg[arg.size() - 1] == '\\')
112  {
113  // Splitted line
114  i++;
115  arg = arg.substr(0, arg.length() - 1) + argv2[i];
116  }
117  // Parsing:
118  string::size_type limit = arg.find(delimiter, 0);
119  if (limit == string::npos)
120  {
121  // Invalid parameter
122  (*ApplicationTools::warning << "WARNING!!! Parameter '" << arg << "' has been ignored.").endLine();
123  }
124  else
125  {
126  string name = string(arg.begin(), arg.begin() + static_cast<ptrdiff_t>(limit));
127  string value = string(arg.begin() + static_cast<ptrdiff_t>(limit + delimiter.size()), arg.end());
128  // if ((name == "param") || (name == "params"))
129  // {
130  // if (std::find(vParam_.begin(),vParam_.end(),value)!=vParam_.end())
131  // throw Exception("Param name " + value + " already seen.");
132 
133  // //Recursive inclusion:
134  // getAttributesMapFromFile(value, am, delimiter);
135  // vParam_.push_back(value);
136  // }
137  // else
138  am[name] = value;
139  }
140  }
141 }
142 
143 /******************************************************************************/
144 
145 void AttributesTools::getAttributesMapFromFile(
146  const std::string& file,
147  std::map<std::string, std::string>& params,
148  const std::string& delimiter)
149 {
150  cout << "Parsing file " << file << " for options." << endl;
151  ifstream input(file.c_str(), ios::in);
152  vector<string> lines = FileTools::putStreamIntoVectorOfStrings(input);
153  getAttributesMap(lines, params, delimiter);
154 }
155 
156 /******************************************************************************/
157 
158 std::map<std::string, std::string> AttributesTools::getAttributesMapFromFile(
159  const std::string& file,
160  const std::string& delimiter)
161 {
162  map<string, string> params;
163  getAttributesMapFromFile(file, params, delimiter);
164  return params;
165 }
166 
167 /******************************************************************************/
168 
169 void AttributesTools::actualizeAttributesMap(
170  std::map<std::string, std::string>& attMap,
171  const std::map<std::string, std::string>& atts)
172 {
173  for (map<string, string>::const_iterator i = atts.begin(); i != atts.end(); i++)
174  {
175  attMap[i->first] = i->second;
176  }
177 }
178 
179 /******************************************************************************/
180 
181 void AttributesTools::resolveVariables(
182  std::map<std::string, std::string>& am,
183  char varCode,
184  char varBeg,
185  char varEnd)
186 {
187  // Now resolve any variable:
188  for (map<string, string>::iterator it = am.begin(); it != am.end(); it++)
189  {
190  string value = it->second;
191  string::size_type index1 = value.find(TextTools::toString(varCode) + TextTools::toString(varBeg));
192  while (index1 != string::npos)
193  {
194  string::size_type index2 = value.find(TextTools::toString(varEnd), index1);
195  if (index2 != string::npos)
196  {
197  string varName = value.substr(index1 + 2, index2 - index1 - 2);
198  map<string, string>::iterator varIt = am.find(varName);
199  string varValue = "";
200  if (varIt == am.end())
201  {
202  if (ApplicationTools::error)
203  (*ApplicationTools::error << "Variable '" << varName << "' is undefined and was ignored.").endLine();
204  }
205  else
206  {
207  varValue = varIt->second;
208  }
209  // Modify original field:
210  string newValue = value.substr(0, index1) + varValue + value.substr(index2 + 1);
211  it->second = newValue;
212  }
213  else
214  throw Exception("Syntax error, variable name is not closed.");
215  value = it->second;
216  index1 = value.find(TextTools::toString(varCode) + TextTools::toString(varBeg));
217  }
218  }
219 }
220 
221 /******************************************************************************/
222 
223 std::string AttributesTools::removeComments(
224  const std::string& s,
225  const std::string& begin,
226  const std::string& end)
227 {
228  string r = s;
229  string::size_type last = 0;
230  do
231  {
232  string::size_type first = r.find(begin, last);
233  if (first == string::npos)
234  return r; // No shell comment.
235  // else:
236  last = r.find(end, first);
237  if (last == string::npos)
238  {
239  r.erase(r.begin() + static_cast<ptrdiff_t>(first), r.end());
240  }
241  else
242  {
243  r.erase(r.begin() + static_cast<ptrdiff_t>(first), r.begin() + static_cast<ptrdiff_t>(last));
244  }
245  }
246  while (last != string::npos);
247  return r;
248 }
249 
250 /******************************************************************************/
251 
252 std::map<std::string, std::string> AttributesTools::parseOptions(int args, char** argv)
253 {
254  // Get the parameters from command line:
255  map<string, string> cmdParams = AttributesTools::getAttributesMap(
256  AttributesTools::getVector(args, argv), "=");
257 
258 
259  // Look for a specified file with parameters:
260  resolveVariables(cmdParams);
261  map<string, string> params;
262 
263  while (cmdParams.find("param") != cmdParams.end() || cmdParams.find("params") != cmdParams.end())
264  {
265  string file = (cmdParams.find("param") != cmdParams.end()) ? cmdParams["param"] : cmdParams["params"];
266 
267  if (std::find(vParam_.begin(), vParam_.end(), file) != vParam_.end())
268  throw Exception("Param name " + file + " already seen.");
269 
270  if (!FileTools::fileExists(file))
271  throw Exception("AttributesTools::parseOptions(). Parameter file not found.: " + file);
272 
273  params = getAttributesMapFromFile(file, "=");
274  // Actualize attributes with ones passed to command line:
275  if (cmdParams.find("param") != cmdParams.end())
276  cmdParams.erase("param");
277  else
278  cmdParams.erase("params");
279 
280  actualizeAttributesMap(params, cmdParams);
281 
282  cmdParams = params;
283  resolveVariables(cmdParams);
284 
285  vParam_.push_back(file);
286  }
287 
288  return cmdParams;
289 }
290 
291 /******************************************************************************/
Exception base class. Overload exception constructor (to control the exceptions mechanism)....
Definition: Exceptions.h:59
std::string removeWhiteSpaces(const std::string &s)
Remove all white spaces characters in a string.
Definition: TextTools.cpp:95
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:153