gem5  v20.1.0.0
inifile.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2005 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "base/inifile.hh"
30 
31 #include <algorithm>
32 #include <fstream>
33 #include <iostream>
34 #include <string>
35 #include <vector>
36 
37 #include "base/str.hh"
38 
39 using namespace std;
40 
42 {}
43 
45 {
46  SectionTable::iterator i = table.begin();
47  SectionTable::iterator end = table.end();
48 
49  while (i != end) {
50  delete (*i).second;
51  ++i;
52  }
53 }
54 
55 bool
56 IniFile::load(const string &file)
57 {
58  ifstream f(file.c_str());
59 
60  if (!f.is_open())
61  return false;
62 
63  return load(f);
64 }
65 
66 
67 const string &
69 {
70  referenced = true;
71  return value;
72 }
73 
74 
75 void
76 IniFile::Section::addEntry(const std::string &entryName,
77  const std::string &value,
78  bool append)
79 {
80  EntryTable::iterator ei = table.find(entryName);
81 
82  if (ei == table.end()) {
83  // new entry
84  table[entryName] = new Entry(value);
85  }
86  else if (append) {
87  // append new reult to old entry
88  ei->second->appendValue(value);
89  }
90  else {
91  // override old entry
92  ei->second->setValue(value);
93  }
94 }
95 
96 
97 bool
98 IniFile::Section::add(const std::string &assignment)
99 {
100  string::size_type offset = assignment.find('=');
101  if (offset == string::npos) {
102  // no '=' found
103  cerr << "Can't parse .ini line " << assignment << endl;
104  return false;
105  }
106 
107  // if "+=" rather than just "=" then append value
108  bool append = (assignment[offset-1] == '+');
109 
110  string entryName = assignment.substr(0, append ? offset-1 : offset);
111  string value = assignment.substr(offset + 1);
112 
113  eat_white(entryName);
114  eat_white(value);
115 
116  addEntry(entryName, value, append);
117  return true;
118 }
119 
120 
122 IniFile::Section::findEntry(const std::string &entryName) const
123 {
124  referenced = true;
125 
126  EntryTable::const_iterator ei = table.find(entryName);
127 
128  return (ei == table.end()) ? NULL : ei->second;
129 }
130 
131 
133 IniFile::addSection(const string &sectionName)
134 {
135  SectionTable::iterator i = table.find(sectionName);
136 
137  if (i != table.end()) {
138  return i->second;
139  }
140  else {
141  // new entry
142  Section *sec = new Section();
143  table[sectionName] = sec;
144  return sec;
145  }
146 }
147 
148 
150 IniFile::findSection(const string &sectionName) const
151 {
152  SectionTable::const_iterator i = table.find(sectionName);
153 
154  return (i == table.end()) ? NULL : i->second;
155 }
156 
157 
158 // Take string of the form "<section>:<parameter>=<value>" and add to
159 // database. Return true if successful, false if parse error.
160 bool
161 IniFile::add(const string &str)
162 {
163  // find ':'
164  string::size_type offset = str.find(':');
165  if (offset == string::npos) // no ':' found
166  return false;
167 
168  string sectionName = str.substr(0, offset);
169  string rest = str.substr(offset + 1);
170 
171  eat_white(sectionName);
172  Section *s = addSection(sectionName);
173 
174  return s->add(rest);
175 }
176 
177 bool
178 IniFile::load(istream &f)
179 {
180  Section *section = NULL;
181 
182  while (!f.eof()) {
183  f >> ws; // Eat whitespace
184  if (f.eof()) {
185  break;
186  }
187 
188  string line;
189  getline(f, line);
190  if (line.size() == 0)
191  continue;
192 
193  eat_end_white(line);
194  int last = line.size() - 1;
195 
196  if (line[0] == '[' && line[last] == ']') {
197  string sectionName = line.substr(1, last - 1);
198  eat_white(sectionName);
199  section = addSection(sectionName);
200  continue;
201  }
202 
203  if (section == NULL)
204  continue;
205 
206  if (!section->add(line))
207  return false;
208  }
209 
210  return true;
211 }
212 
213 bool
214 IniFile::find(const string &sectionName, const string &entryName,
215  string &value) const
216 {
217  Section *section = findSection(sectionName);
218  if (section == NULL)
219  return false;
220 
221  Entry *entry = section->findEntry(entryName);
222  if (entry == NULL)
223  return false;
224 
225  value = entry->getValue();
226 
227  return true;
228 }
229 
230 bool
231 IniFile::entryExists(const string &sectionName, const string &entryName) const
232 {
233  Section *section = findSection(sectionName);
234 
235  if (!section)
236  return false;
237  else
238  return section->findEntry(entryName);
239 }
240 
241 bool
242 IniFile::sectionExists(const string &sectionName) const
243 {
244  return findSection(sectionName) != NULL;
245 }
246 
247 
248 bool
249 IniFile::Section::printUnreferenced(const string &sectionName)
250 {
251  bool unref = false;
252  bool search_unref_entries = false;
253  vector<string> unref_ok_entries;
254 
255  Entry *entry = findEntry("unref_entries_ok");
256  if (entry != NULL) {
257  tokenize(unref_ok_entries, entry->getValue(), ' ');
258  if (unref_ok_entries.size()) {
259  search_unref_entries = true;
260  }
261  }
262 
263  for (EntryTable::iterator ei = table.begin();
264  ei != table.end(); ++ei) {
265  const string &entryName = ei->first;
266  entry = ei->second;
267 
268  if (entryName == "unref_section_ok" ||
269  entryName == "unref_entries_ok")
270  {
271  continue;
272  }
273 
274  if (!entry->isReferenced()) {
275  if (search_unref_entries &&
276  (std::find(unref_ok_entries.begin(), unref_ok_entries.end(),
277  entryName) != unref_ok_entries.end()))
278  {
279  continue;
280  }
281 
282  cerr << "Parameter " << sectionName << ":" << entryName
283  << " not referenced." << endl;
284  unref = true;
285  }
286  }
287 
288  return unref;
289 }
290 
291 
292 void
294 {
295  for (SectionTable::const_iterator i = table.begin();
296  i != table.end(); ++i)
297  {
298  list.push_back((*i).first);
299  }
300 }
301 
302 bool
304 {
305  bool unref = false;
306 
307  for (SectionTable::iterator i = table.begin();
308  i != table.end(); ++i) {
309  const string &sectionName = i->first;
310  Section *section = i->second;
311 
312  if (!section->isReferenced()) {
313  if (section->findEntry("unref_section_ok") == NULL) {
314  cerr << "Section " << sectionName << " not referenced."
315  << endl;
316  unref = true;
317  }
318  }
319  else {
320  if (section->printUnreferenced(sectionName)) {
321  unref = true;
322  }
323  }
324  }
325 
326  return unref;
327 }
328 
329 
330 void
331 IniFile::Section::dump(const string &sectionName)
332 {
333  for (EntryTable::iterator ei = table.begin();
334  ei != table.end(); ++ei) {
335  cout << sectionName << ": " << (*ei).first << " => "
336  << (*ei).second->getValue() << "\n";
337  }
338 }
339 
340 void
342 {
343  for (SectionTable::iterator i = table.begin();
344  i != table.end(); ++i) {
345  i->second->dump(i->first);
346  }
347 }
tokenize
void tokenize(vector< string > &v, const string &s, char token, bool ignore)
Definition: str.cc:67
IniFile::printUnreferenced
bool printUnreferenced()
Print unreferenced entries in object.
Definition: inifile.cc:303
eat_end_white
void eat_end_white(std::string &s)
Definition: str.hh:56
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
IniFile::getSectionNames
void getSectionNames(std::vector< std::string > &list) const
Push all section names into the given vector.
Definition: inifile.cc:293
IniFile::~IniFile
~IniFile()
Destructor.
Definition: inifile.cc:44
IniFile::Section::addEntry
void addEntry(const std::string &entryName, const std::string &value, bool append)
Add an entry to the table.
Definition: inifile.cc:76
IniFile::find
bool find(const std::string &section, const std::string &entry, std::string &value) const
Find value corresponding to given section and entry names.
Definition: inifile.cc:214
std::vector< string >
IniFile::entryExists
bool entryExists(const std::string &section, const std::string &entry) const
Determine whether the entry exists within named section exists in the .ini file.
Definition: inifile.cc:231
IniFile::Section::dump
void dump(const std::string &sectionName)
Print the contents of this section to cout (for debugging).
Definition: inifile.cc:331
IniFile::add
bool add(const std::string &s)
Take string of the form "<section>:<parameter>=<value>" or "<section>:<parameter>+=<value>" and add t...
Definition: inifile.cc:161
str.hh
IniFile::Section::add
bool add(const std::string &assignment)
Add an entry to the table given a string assigment.
Definition: inifile.cc:98
IniFile::Section::findEntry
Entry * findEntry(const std::string &entryName) const
Find the entry with the given name.
Definition: inifile.cc:122
IniFile::Section::printUnreferenced
bool printUnreferenced(const std::string &sectionName)
Print the unreferenced entries in this section to cerr.
Definition: inifile.cc:249
inifile.hh
IniFile::addSection
Section * addSection(const std::string &sectionName)
Look up section with the given name, creating a new section if not found.
Definition: inifile.cc:133
IniFile::Section
A section.
Definition: inifile.hh:90
eat_white
void eat_white(std::string &s)
Definition: str.hh:64
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
IniFile::Entry
A single key/value pair.
Definition: inifile.hh:58
Stats::size_type
unsigned int size_type
Definition: types.hh:54
IniFile::Entry::isReferenced
bool isReferenced()
Has this entry been used?
Definition: inifile.hh:71
IniFile::load
bool load(std::istream &f)
Load parameter settings from given istream.
std::list
STL list class.
Definition: stl.hh:51
ArmISA::s
Bitfield< 4 > s
Definition: miscregs_types.hh:556
IniFile::findSection
Section * findSection(const std::string &sectionName) const
Look up section with the given name.
Definition: inifile.cc:150
IniFile::Section::isReferenced
bool isReferenced()
Has this section been used?
Definition: inifile.hh:106
IniFile::sectionExists
bool sectionExists(const std::string &section) const
Determine whether the named section exists in the .ini file.
Definition: inifile.cc:242
IniFile::IniFile
IniFile()
Constructor.
Definition: inifile.cc:41
IniFile::Entry::getValue
const std::string & getValue() const
Fetch the value.
Definition: inifile.cc:68
ArmISA::f
Bitfield< 6 > f
Definition: miscregs_types.hh:64
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
IniFile::dump
void dump()
Dump contents to cout. For debugging.
Definition: inifile.cc:341

Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17