gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
39namespace gem5
40{
41
44
45bool
46IniFile::load(const std::string &file)
47{
48 std::ifstream f(file.c_str());
49
50 if (!f.is_open())
51 return false;
52
53 return load(f);
54}
55
56
57const std::string &
59{
60 referenced = true;
61 return value;
62}
63
64
65void
66IniFile::Section::addEntry(const std::string &entryName,
67 const std::string &value,
68 bool append)
69{
70 EntryTable::iterator ei = table.find(entryName);
71
72 if (ei == table.end()) {
73 // new entry
74 table.emplace(entryName, value);
75 }
76 else if (append) {
77 // append new reult to old entry
78 ei->second.appendValue(value);
79 }
80 else {
81 // override old entry
82 ei->second.setValue(value);
83 }
84}
85
86
87bool
88IniFile::Section::add(const std::string &assignment)
89{
90 std::string::size_type offset = assignment.find('=');
91 if (offset == std::string::npos) {
92 // no '=' found
93 std::cerr << "Can't parse .ini line " << assignment << std::endl;
94 return false;
95 }
96
97 // if "+=" rather than just "=" then append value
98 bool append = (assignment[offset-1] == '+');
99
100 std::string entryName = assignment.substr(0, append ? offset-1 : offset);
101 std::string value = assignment.substr(offset + 1);
102
103 eat_white(entryName);
104 eat_white(value);
105
106 addEntry(entryName, value, append);
107 return true;
108}
109
110
112IniFile::Section::findEntry(const std::string &entryName)
113{
114 return const_cast<IniFile::Entry *>(
115 std::as_const(*this).findEntry(entryName));
116}
117
118const IniFile::Entry *
119IniFile::Section::findEntry(const std::string &entryName) const
120{
121 referenced = true;
122
123 auto ei = table.find(entryName);
124
125 return (ei == table.end()) ? nullptr : &ei->second;
126}
127
128
130IniFile::addSection(const std::string &sectionName)
131{
132 return &table[sectionName];
133}
134
136IniFile::findSection(const std::string &sectionName)
137{
138 return const_cast<IniFile::Section*>(
139 std::as_const(*this).findSection(sectionName));
140}
141
142const IniFile::Section *
143IniFile::findSection(const std::string &sectionName) const
144{
145 auto i = table.find(sectionName);
146
147 return (i == table.end()) ? nullptr : &i->second;
148}
149
150
151// Take string of the form "<section>:<parameter>=<value>" and add to
152// database. Return true if successful, false if parse error.
153bool
154IniFile::add(const std::string &str)
155{
156 // find ':'
157 std::string::size_type offset = str.find(':');
158 if (offset == std::string::npos) // no ':' found
159 return false;
160
161 std::string sectionName = str.substr(0, offset);
162 std::string rest = str.substr(offset + 1);
163
164 eat_white(sectionName);
165 Section *s = addSection(sectionName);
166
167 return s->add(rest);
168}
169
170bool
171IniFile::load(std::istream &f)
172{
173 Section *section = NULL;
174
175 while (!f.eof()) {
176 f >> std::ws; // Eat whitespace
177 if (f.eof()) {
178 break;
179 }
180
181 std::string line;
182 getline(f, line);
183 if (line.size() == 0)
184 continue;
185
186 eat_end_white(line);
187 int last = line.size() - 1;
188
189 if (line[0] == '[' && line[last] == ']') {
190 std::string sectionName = line.substr(1, last - 1);
191 eat_white(sectionName);
192 section = addSection(sectionName);
193 continue;
194 }
195
196 if (section == NULL)
197 continue;
198
199 if (!section->add(line))
200 return false;
201 }
202
203 return true;
204}
205
206bool
207IniFile::find(const std::string &sectionName, const std::string &entryName,
208 std::string &value) const
209{
210 auto* section = findSection(sectionName);
211 if (section == NULL)
212 return false;
213
214 auto* entry = section->findEntry(entryName);
215 if (entry == NULL)
216 return false;
217
218 value = entry->getValue();
219
220 return true;
221}
222
223bool
224IniFile::entryExists(const std::string &sectionName,
225 const std::string &entryName) const
226{
227 auto* section = findSection(sectionName);
228
229 if (!section)
230 return false;
231 else
232 return section->findEntry(entryName);
233}
234
235bool
236IniFile::sectionExists(const std::string &sectionName) const
237{
238 return findSection(sectionName) != NULL;
239}
240
241
242bool
243IniFile::Section::printUnreferenced(const std::string &sectionName) const
244{
245 bool unref = false;
246 bool search_unref_entries = false;
247 std::vector<std::string> unref_ok_entries;
248
249 auto* entry = findEntry("unref_entries_ok");
250 if (entry != NULL) {
251 tokenize(unref_ok_entries, entry->getValue(), ' ');
252 if (unref_ok_entries.size()) {
253 search_unref_entries = true;
254 }
255 }
256
257 for (auto& ei: table) {
258 const std::string &entryName = ei.first;
259 entry = &ei.second;
260
261 if (entryName == "unref_section_ok" ||
262 entryName == "unref_entries_ok")
263 {
264 continue;
265 }
266
267 if (!entry->isReferenced()) {
268 if (search_unref_entries &&
269 (std::find(unref_ok_entries.begin(), unref_ok_entries.end(),
270 entryName) != unref_ok_entries.end()))
271 {
272 continue;
273 }
274
275 std::cerr << "Parameter " << sectionName << ":" << entryName
276 << " not referenced." << std::endl;
277 unref = true;
278 }
279 }
280
281 return unref;
282}
283
284
285void
287{
288 for (auto& entry: table) {
289 auto& sectionName = entry.first;
290 list.push_back(sectionName);
291 }
292}
293
294bool
296{
297 bool unref = false;
298
299 for (auto& entry: table) {
300 auto& [sectionName, section] = entry;
301
302 if (!section.isReferenced()) {
303 if (section.findEntry("unref_section_ok") == NULL) {
304 std::cerr << "Section " << sectionName << " not referenced."
305 << std::endl;
306 unref = true;
307 }
308 }
309 else {
310 if (section.printUnreferenced(sectionName)) {
311 unref = true;
312 }
313 }
314 }
315
316 return unref;
317}
318
319
320void
321IniFile::Section::dump(const std::string &sectionName) const
322{
323 for (auto& ei: table) {
324 std::cout << sectionName << ": " << ei.first << " => "
325 << ei.second.getValue() << "\n";
326 }
327}
328
329void
331{
332 for (SectionTable::iterator i = table.begin();
333 i != table.end(); ++i) {
334 i->second.dump(i->first);
335 }
336}
337
338IniFile::Section::EntryTable::const_iterator
340{
341 return table.begin();
342}
343
344IniFile::Section::EntryTable::const_iterator
346{
347 return table.end();
348}
349
350void
351IniFile::visitSection(const std::string &sectionName,
353{
354 const auto& section = table.at(sectionName);
355 for (const auto& pair : section) {
356 cb(pair.first, pair.second.getValue());
357 }
358}
359
360} // namespace gem5
A single key/value pair.
Definition inifile.hh:63
std::string value
The entry value.
Definition inifile.hh:64
const std::string & getValue() const
Fetch the value.
Definition inifile.cc:58
bool referenced
Has this entry been used?
Definition inifile.hh:65
bool printUnreferenced(const std::string &sectionName) const
Print the unreferenced entries in this section to cerr.
Definition inifile.cc:243
void addEntry(const std::string &entryName, const std::string &value, bool append)
Add an entry to the table.
Definition inifile.cc:66
EntryTable::const_iterator end() const
Definition inifile.cc:345
bool add(const std::string &assignment)
Add an entry to the table given a string assigment.
Definition inifile.cc:88
EntryTable::const_iterator begin() const
Definition inifile.cc:339
void dump(const std::string &sectionName) const
Print the contents of this section to cout (for debugging).
Definition inifile.cc:321
Entry * findEntry(const std::string &entryName)
Find the entry with the given name.
Definition inifile.cc:112
bool add(const std::string &s)
Take string of the form "<section>:<parameter>=<value>" or "<section>:<parameter>+=<value>" and add t...
Definition inifile.cc:154
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:207
void visitSection(const std::string &sectionName, VisitSectionCallback cb)
Iterate over key/value pairs of the given section.
Definition inifile.cc:351
std::function< void( const std::string &, const std::string &)> VisitSectionCallback
Visitor callback that receives key/value pairs.
Definition inifile.hh:214
SectionTable table
Hash of section names to Section object pointers.
Definition inifile.hh:150
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:224
void getSectionNames(std::vector< std::string > &list) const
Push all section names into the given vector.
Definition inifile.cc:286
bool load(std::istream &f)
Load parameter settings from given istream.
Definition inifile.cc:171
void dump()
Dump contents to cout. For debugging.
Definition inifile.cc:330
bool printUnreferenced() const
Print unreferenced entries in object.
Definition inifile.cc:295
IniFile()
Constructor.
Definition inifile.cc:42
Section * addSection(const std::string &sectionName)
Look up section with the given name, creating a new section if not found.
Definition inifile.cc:130
bool sectionExists(const std::string &section) const
Determine whether the named section exists in the .ini file.
Definition inifile.cc:236
Section * findSection(const std::string &sectionName)
Look up section with the given name.
Definition inifile.cc:136
STL vector class.
Definition stl.hh:37
Declaration of IniFile object.
Bitfield< 4 > s
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 6 > f
Definition misc_types.hh:68
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
void tokenize(std::vector< std::string > &v, const std::string &s, char token, bool ignore)
Definition str.cc:68
void eat_end_white(std::string &s)
Definition str.hh:60
void eat_white(std::string &s)
Definition str.hh:68

Generated on Tue Jun 18 2024 16:24:00 for gem5 by doxygen 1.11.0