pxar
 All Classes Namespaces Functions Variables Typedefs Friends
PixTestParameters.cc
1 #include <fstream>
2 #include <iostream>
3 #include <string>
4 #include <algorithm> /* for 'remove()' */
5 
6 #include "PixTestParameters.hh"
7 #include "log.h"
8 
9 using namespace std;
10 using namespace pxar;
11 
12 
13 // ----------------------------------------------------------------------
14 bool bothAreSpaces(char lhs, char rhs) {
15  return (lhs == rhs) && (lhs == ' ');
16 }
17 
18 
19 // ----------------------------------------------------------------------
20 PixTestParameters::PixTestParameters(string file, bool verbose) {
21  readTestParameterFile(file, verbose);
22 }
23 
24 // ----------------------------------------------------------------------
25 vector<string> PixTestParameters::getTests() {
26  vector<string> a;
27  for (map<string, vector<pair<string, string> > >::iterator imap = fTests.begin(); imap != fTests.end(); ++imap) {
28  a.push_back(imap->first);
29  }
30  return a;
31 }
32 
33 // ----------------------------------------------------------------------
34 bool PixTestParameters::readTestParameterFile(string file, bool verbose) {
35  ifstream is(file.c_str());
36  if (!is.is_open()) {
37  LOG(logDEBUG) << "cannot read " << file;
38  return false;
39  }
40 
41  vector<pair<string, string> > testparameters;
42  string testName, parName, parValString;
43  bool oneTooMuch(false);
44  string line;
45  while (is.good()) {
46  if (!oneTooMuch) {
47  getline(is, line);
48  } else {
49  oneTooMuch = false;
50  }
51 
52  // -- found a new test, read all its parameters until you hit the next '--'
53  if (string::npos != line.find("--")) {
54  int testCnt(0);
55  string::size_type m1 = line.find(" ");
56  if (m1 < line.size()) {
57  testName = line.substr(m1+1);
58  testName.erase (std::remove(testName.begin(), testName.end(), ' '), testName.end());
59  }
60  while (is.good()) {
61  getline(is, line);
62  if (string::npos != line.find("--")) {
63  oneTooMuch = true;
64  break;
65  }
66 
67  // -- parse parameter names and values
68  std::string::iterator new_end = std::unique(line.begin(), line.end(), bothAreSpaces);
69  line.erase(new_end, line.end());
70 
71 
72  string::size_type m1 = line.find(" ");
73  if (m1 < line.size()) {
74  parName = line.substr(0, m1);
75  std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
76  parValString = line.substr(m1+1);
77  testparameters.push_back(make_pair(parName, parValString));
78  ++testCnt;
79  } else {
80  break;
81  }
82  }
83  }
84  // -- add the map to the complete map
85  fTests.insert(make_pair(testName, testparameters));
86  testparameters.clear();
87  }
88 
89  if (verbose) dump();
90 
91  return true;
92 }
93 
94 
95 // ----------------------------------------------------------------------
96 vector<pair<string, string> > PixTestParameters::getTestParameters(string testName) {
97  return fTests[testName];
98 }
99 
100 
101 // ----------------------------------------------------------------------
102 void PixTestParameters::dump() {
103  for (map<string, vector<pair<string, string> > >::iterator imap = fTests.begin(); imap != fTests.end(); ++imap) {
104  LOG(logDEBUG) << "PixTestParameters: ->" << imap->first << "<-";
105  vector<pair<string, string> > pars = imap->second;
106  for (vector<pair<string, string> >::iterator imap2 = pars.begin(); imap2 != pars.end(); ++imap2) {
107  LOG(logDEBUG) << " " << imap2->first << ": " << imap2->second;
108  }
109  }
110 
111 }
112 
113 
114 // ----------------------------------------------------------------------
115 bool PixTestParameters::setTestParameter(string testname, string parname, string value) {
116 
117  for (map<string, vector<pair<string, string> > >::iterator imap = fTests.begin(); imap != fTests.end(); ++imap) {
118  if (imap->first.compare(testname)) continue;
119  LOG(logDEBUG) << "PixTestParameters: ->" << imap->first << "<-";
120  // vector<pair<string, string> > pars = imap->second;
121  for (unsigned int i = 0; i < imap->second.size(); ++i) {
122  if (!imap->second[i].first.compare(parname)) {
123  imap->second[i].second = value;
124  LOG(logDEBUG) << " setting " << imap->second[i].first << " to new value " << imap->second[i].second;
125  return true;
126  }
127  }
128  }
129 
130  return false;
131 }
132 
133 
134 // ----------------------------------------------------------------------
135 bool PixTestParameters::addTestParameter(string testname, string parname, string value) {
136 
137  for (map<string, vector<pair<string, string> > >::iterator imap = fTests.begin(); imap != fTests.end(); ++imap) {
138  if (imap->first.compare(testname)) continue;
139  LOG(logDEBUG) << "PixTestParameters: ->" << imap->first << "<- adding parameter " << parname;
140  vector<pair<string, string> > pars = imap->second;
141  // -- avoid adding a second identical parameter value (e.g. for PIX)
142  bool alreadyIn(false);
143  for (unsigned int i = 0; i < pars.size(); ++i) {
144  if (!pars[i].first.compare(parname)) {
145  if (!pars[i].second.compare(value)) alreadyIn = true;
146  break;
147  }
148  }
149  if (!alreadyIn) {
150  pars.push_back(make_pair(parname, value));
151  LOG(logDEBUG) << " adding " << parname << " with value " << value;
152  }
153 
154  return true;
155  }
156 
157  return false;
158 }
159 
160 
161 // ----------------------------------------------------------------------
162 bool PixTestParameters::setTestParameters(string testname, vector<std::pair<std::string, std::string> > v) {
163 
164  for (map<string, vector<pair<string, string> > >::iterator imap = fTests.begin(); imap != fTests.end(); ++imap) {
165  if (imap->first.compare(testname)) continue;
166  imap->second = v;
167  return true;
168  }
169 
170  return false;
171 }
172 
173 
174 // ----------------------------------------------------------------------
175 bool PixTestParameters::setTestParameters(string testname, string testParameters) {
176 
177  for (map<string, vector<pair<string, string> > >::iterator imap = fTests.begin(); imap != fTests.end(); ++imap) {
178  string ltname = imap->first;
179  if (!ltname.compare(testname)) {
180  vector<pair<string, string> > v = splitStringIntoParameters(testParameters);
181  for (unsigned int i = 0; i < v.size(); ++i) {
182  setTestParameter(testname, v[i].first, v[i].second);
183  }
184  return true;
185  }
186  }
187 
188  return false;
189 }
190 
191 // ----------------------------------------------------------------------
192 vector<pair<string, string> > PixTestParameters::splitStringIntoParameters(string testParameters) {
193  vector<pair<string, string> > v;
194 
195  replaceAll(testParameters, " ", "");
196  replaceAll(testParameters, "\t", "");
197  string::size_type m0 = 0;
198  string::size_type m1 = testParameters.find("=");
199  string::size_type m2 = testParameters.find(";");
200  if (m2 == string::npos) {
201  m2 = testParameters.size();
202  }
203  string var, val;
204  do {
205  var = testParameters.substr(m0, m1-m0);
206  val = testParameters.substr(m1+1, m2-m1-1);
207  v.push_back(make_pair(var, val));
208  if (m2 == testParameters.size()) break;
209  m0 = m2+1;
210  m1 = testParameters.find("=", m0);
211  m2 = testParameters.find(";", m0);
212  if (m2 == string::npos) m2 = testParameters.size();
213  } while (m1 < testParameters.size());
214 
215  return v;
216 }
217 
218 
219 // ----------------------------------------------------------------------
220 void PixTestParameters::replaceAll(string& str, const string& from, const string& to) {
221  if (from.empty()) return;
222  size_t start_pos = 0;
223  while((start_pos = str.find(from, start_pos)) != string::npos) {
224  str.replace(start_pos, from.length(), to);
225  start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
226  }
227 }