inifile.hh revision 2665
111527Sdavid.guillen@arm.com/* 211527Sdavid.guillen@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 311527Sdavid.guillen@arm.com * All rights reserved. 411527Sdavid.guillen@arm.com * 511527Sdavid.guillen@arm.com * Redistribution and use in source and binary forms, with or without 611527Sdavid.guillen@arm.com * modification, are permitted provided that the following conditions are 711527Sdavid.guillen@arm.com * met: redistributions of source code must retain the above copyright 811527Sdavid.guillen@arm.com * notice, this list of conditions and the following disclaimer; 911527Sdavid.guillen@arm.com * redistributions in binary form must reproduce the above copyright 1011527Sdavid.guillen@arm.com * notice, this list of conditions and the following disclaimer in the 1111527Sdavid.guillen@arm.com * documentation and/or other materials provided with the distribution; 1211527Sdavid.guillen@arm.com * neither the name of the copyright holders nor the names of its 1311527Sdavid.guillen@arm.com * contributors may be used to endorse or promote products derived from 1411527Sdavid.guillen@arm.com * this software without specific prior written permission. 1511527Sdavid.guillen@arm.com * 1611527Sdavid.guillen@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711527Sdavid.guillen@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811527Sdavid.guillen@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911527Sdavid.guillen@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011527Sdavid.guillen@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111527Sdavid.guillen@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211527Sdavid.guillen@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311527Sdavid.guillen@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411527Sdavid.guillen@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511527Sdavid.guillen@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611527Sdavid.guillen@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711527Sdavid.guillen@arm.com * 2811527Sdavid.guillen@arm.com * Authors: Nathan Binkert 2911527Sdavid.guillen@arm.com * Steve Reinhardt 3011527Sdavid.guillen@arm.com */ 3111527Sdavid.guillen@arm.com 3211527Sdavid.guillen@arm.com#ifndef __INIFILE_HH__ 3311527Sdavid.guillen@arm.com#define __INIFILE_HH__ 3411527Sdavid.guillen@arm.com 3511527Sdavid.guillen@arm.com#include <fstream> 3611527Sdavid.guillen@arm.com#include <list> 3711527Sdavid.guillen@arm.com#include <string> 3811527Sdavid.guillen@arm.com#include <vector> 3911527Sdavid.guillen@arm.com 4011527Sdavid.guillen@arm.com#include "base/hashmap.hh" 4111527Sdavid.guillen@arm.com 4211527Sdavid.guillen@arm.com/** 4311527Sdavid.guillen@arm.com * @file 4411527Sdavid.guillen@arm.com * Declaration of IniFile object. 4511527Sdavid.guillen@arm.com * @todo Change comments to match documentation style. 4611527Sdavid.guillen@arm.com */ 4711527Sdavid.guillen@arm.com 4811527Sdavid.guillen@arm.com/// 4911527Sdavid.guillen@arm.com/// This class represents the contents of a ".ini" file. 5011527Sdavid.guillen@arm.com/// 5111527Sdavid.guillen@arm.com/// It's basically a two level lookup table: a set of named sections, 5211527Sdavid.guillen@arm.com/// where each section is a set of key/value pairs. Section names, 5311527Sdavid.guillen@arm.com/// keys, and values are all uninterpreted strings. 5411527Sdavid.guillen@arm.com/// 5511527Sdavid.guillen@arm.comclass IniFile 5611527Sdavid.guillen@arm.com{ 5711527Sdavid.guillen@arm.com protected: 5811527Sdavid.guillen@arm.com 5911527Sdavid.guillen@arm.com /// 6011527Sdavid.guillen@arm.com /// A single key/value pair. 6111527Sdavid.guillen@arm.com /// 6211527Sdavid.guillen@arm.com class Entry 6311527Sdavid.guillen@arm.com { 6411527Sdavid.guillen@arm.com std::string value; ///< The entry value. 6511527Sdavid.guillen@arm.com mutable bool referenced; ///< Has this entry been used? 6611527Sdavid.guillen@arm.com 6711527Sdavid.guillen@arm.com public: 6811527Sdavid.guillen@arm.com /// Constructor. 6911527Sdavid.guillen@arm.com Entry(const std::string &v) 7011527Sdavid.guillen@arm.com : value(v), referenced(false) 7111527Sdavid.guillen@arm.com { 7211527Sdavid.guillen@arm.com } 7311527Sdavid.guillen@arm.com 7411527Sdavid.guillen@arm.com /// Has this entry been used? 7511527Sdavid.guillen@arm.com bool isReferenced() { return referenced; } 7611527Sdavid.guillen@arm.com 7711527Sdavid.guillen@arm.com /// Fetch the value. 7811527Sdavid.guillen@arm.com const std::string &getValue() const; 7911527Sdavid.guillen@arm.com 8011527Sdavid.guillen@arm.com /// Set the value. 8111527Sdavid.guillen@arm.com void setValue(const std::string &v) { value = v; } 8211527Sdavid.guillen@arm.com 8311527Sdavid.guillen@arm.com /// Append the given string to the value. A space is inserted 8411527Sdavid.guillen@arm.com /// between the existing value and the new value. Since this 8511527Sdavid.guillen@arm.com /// operation is typically used with values that are 8611527Sdavid.guillen@arm.com /// space-separated lists of tokens, this keeps the tokens 8711527Sdavid.guillen@arm.com /// separate. 8811527Sdavid.guillen@arm.com void appendValue(const std::string &v) { value += " "; value += v; } 8911527Sdavid.guillen@arm.com }; 9011527Sdavid.guillen@arm.com 9111527Sdavid.guillen@arm.com /// 9211527Sdavid.guillen@arm.com /// A section. 9311527Sdavid.guillen@arm.com /// 9411527Sdavid.guillen@arm.com class Section 9511527Sdavid.guillen@arm.com { 9611527Sdavid.guillen@arm.com /// EntryTable type. Map of strings to Entry object pointers. 9711527Sdavid.guillen@arm.com typedef m5::hash_map<std::string, Entry *> EntryTable; 9811527Sdavid.guillen@arm.com 9911527Sdavid.guillen@arm.com EntryTable table; ///< Table of entries. 10011527Sdavid.guillen@arm.com mutable bool referenced; ///< Has this section been used? 10111527Sdavid.guillen@arm.com 10211527Sdavid.guillen@arm.com public: 10311527Sdavid.guillen@arm.com /// Constructor. 10411527Sdavid.guillen@arm.com Section() 10511527Sdavid.guillen@arm.com : table(), referenced(false) 10611527Sdavid.guillen@arm.com { 10711527Sdavid.guillen@arm.com } 10811527Sdavid.guillen@arm.com 10911527Sdavid.guillen@arm.com /// Has this section been used? 11011527Sdavid.guillen@arm.com bool isReferenced() { return referenced; } 11111527Sdavid.guillen@arm.com 11211527Sdavid.guillen@arm.com /// Add an entry to the table. If an entry with the same name 11311527Sdavid.guillen@arm.com /// already exists, the 'append' parameter is checked If true, 11411527Sdavid.guillen@arm.com /// the new value will be appended to the existing entry. If 11511527Sdavid.guillen@arm.com /// false, the new value will replace the existing entry. 11611527Sdavid.guillen@arm.com void addEntry(const std::string &entryName, const std::string &value, 11711527Sdavid.guillen@arm.com bool append); 11811527Sdavid.guillen@arm.com 11911527Sdavid.guillen@arm.com /// Add an entry to the table given a string assigment. 12011527Sdavid.guillen@arm.com /// Assignment should be of the form "param=value" or 12111527Sdavid.guillen@arm.com /// "param+=value" (for append). This funciton parses the 12211527Sdavid.guillen@arm.com /// assignment statment and calls addEntry(). 12311527Sdavid.guillen@arm.com /// @retval True for success, false if parse error. 12411527Sdavid.guillen@arm.com bool add(const std::string &assignment); 12511527Sdavid.guillen@arm.com 12611527Sdavid.guillen@arm.com /// Find the entry with the given name. 12711527Sdavid.guillen@arm.com /// @retval Pointer to the entry object, or NULL if none. 12811527Sdavid.guillen@arm.com Entry *findEntry(const std::string &entryName) const; 12911527Sdavid.guillen@arm.com 13011527Sdavid.guillen@arm.com /// Print the unreferenced entries in this section to cerr. 13111527Sdavid.guillen@arm.com /// Messages can be suppressed using "unref_section_ok" and 13211527Sdavid.guillen@arm.com /// "unref_entries_ok". 13311527Sdavid.guillen@arm.com /// @param sectionName Name of this section, for use in output message. 13411527Sdavid.guillen@arm.com /// @retval True if any entries were printed. 13511527Sdavid.guillen@arm.com bool printUnreferenced(const std::string §ionName); 13611527Sdavid.guillen@arm.com 13711527Sdavid.guillen@arm.com /// Print the contents of this section to cout (for debugging). 13811527Sdavid.guillen@arm.com void dump(const std::string §ionName); 13911527Sdavid.guillen@arm.com }; 14011527Sdavid.guillen@arm.com 14111527Sdavid.guillen@arm.com /// SectionTable type. Map of strings to Section object pointers. 14211527Sdavid.guillen@arm.com typedef m5::hash_map<std::string, Section *> SectionTable; 14311527Sdavid.guillen@arm.com 14411527Sdavid.guillen@arm.com protected: 14511527Sdavid.guillen@arm.com /// Hash of section names to Section object pointers. 14611527Sdavid.guillen@arm.com SectionTable table; 14711527Sdavid.guillen@arm.com 14811527Sdavid.guillen@arm.com /// Look up section with the given name, creating a new section if 14911527Sdavid.guillen@arm.com /// not found. 15011527Sdavid.guillen@arm.com /// @retval Pointer to section object. 15111527Sdavid.guillen@arm.com Section *addSection(const std::string §ionName); 15211527Sdavid.guillen@arm.com 15311527Sdavid.guillen@arm.com /// Look up section with the given name. 15411527Sdavid.guillen@arm.com /// @retval Pointer to section object, or NULL if not found. 15511527Sdavid.guillen@arm.com Section *findSection(const std::string §ionName) const; 15611527Sdavid.guillen@arm.com 15711527Sdavid.guillen@arm.com public: 15811527Sdavid.guillen@arm.com /// Constructor. 15911527Sdavid.guillen@arm.com IniFile(); 16011527Sdavid.guillen@arm.com 16111527Sdavid.guillen@arm.com /// Destructor. 16211527Sdavid.guillen@arm.com ~IniFile(); 16311527Sdavid.guillen@arm.com 16411527Sdavid.guillen@arm.com /// Load parameter settings from given istream. This is a helper 16511527Sdavid.guillen@arm.com /// function for load(string) and loadCPP(), which open a file 16611527Sdavid.guillen@arm.com /// and then pass it here. 16711527Sdavid.guillen@arm.com /// @retval True if successful, false if errors were encountered. 16811527Sdavid.guillen@arm.com bool load(std::istream &f); 16911527Sdavid.guillen@arm.com 17011527Sdavid.guillen@arm.com /// Load the specified file, passing it through the C preprocessor. 17111527Sdavid.guillen@arm.com /// Parameter settings found in the file will be merged with any 17211527Sdavid.guillen@arm.com /// already defined in this object. 17311527Sdavid.guillen@arm.com /// @param file The path of the file to load. 17411527Sdavid.guillen@arm.com /// @param cppFlags Vector of extra flags to pass to cpp. 17511527Sdavid.guillen@arm.com /// @retval True if successful, false if errors were encountered. 17611527Sdavid.guillen@arm.com bool loadCPP(const std::string &file, std::vector<char *> &cppFlags); 17711527Sdavid.guillen@arm.com 178 /// Load the specified file. 179 /// Parameter settings found in the file will be merged with any 180 /// already defined in this object. 181 /// @param file The path of the file to load. 182 /// @retval True if successful, false if errors were encountered. 183 bool load(const std::string &file); 184 185 /// Take string of the form "<section>:<parameter>=<value>" or 186 /// "<section>:<parameter>+=<value>" and add to database. 187 /// @retval True if successful, false if parse error. 188 bool add(const std::string &s); 189 190 /// Find value corresponding to given section and entry names. 191 /// Value is returned by reference in 'value' param. 192 /// @retval True if found, false if not. 193 bool find(const std::string §ion, const std::string &entry, 194 std::string &value) const; 195 196 /// Determine whether the named section exists in the .ini file. 197 /// Note that the 'Section' class is (intentionally) not public, 198 /// so all clients can do is get a bool that says whether there 199 /// are any values in that section or not. 200 /// @return True if the section exists. 201 bool sectionExists(const std::string §ion) const; 202 203 /// Print unreferenced entries in object. Iteratively calls 204 /// printUnreferend() on all the constituent sections. 205 bool printUnreferenced(); 206 207 /// Dump contents to cout. For debugging. 208 void dump(); 209}; 210 211#endif // __INIFILE_HH__ 212