/* * Copyright (c) 2001-2005 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Nathan Binkert * Steve Reinhardt */ #ifndef __INIFILE_HH__ #define __INIFILE_HH__ #include #include #include #include #include /** * @file * Declaration of IniFile object. * @todo Change comments to match documentation style. */ /// /// This class represents the contents of a ".ini" file. /// /// It's basically a two level lookup table: a set of named sections, /// where each section is a set of key/value pairs. Section names, /// keys, and values are all uninterpreted strings. /// class IniFile { protected: /// /// A single key/value pair. /// class Entry { std::string value; ///< The entry value. mutable bool referenced; ///< Has this entry been used? public: /// Constructor. Entry(const std::string &v) : value(v), referenced(false) { } /// Has this entry been used? bool isReferenced() { return referenced; } /// Fetch the value. const std::string &getValue() const; /// Set the value. void setValue(const std::string &v) { value = v; } /// Append the given string to the value. A space is inserted /// between the existing value and the new value. Since this /// operation is typically used with values that are /// space-separated lists of tokens, this keeps the tokens /// separate. void appendValue(const std::string &v) { value += " "; value += v; } }; /// /// A section. /// class Section { /// EntryTable type. Map of strings to Entry object pointers. typedef std::unordered_map EntryTable; EntryTable table; ///< Table of entries. mutable bool referenced; ///< Has this section been used? public: /// Constructor. Section() : table(), referenced(false) { } /// Has this section been used? bool isReferenced() { return referenced; } /// Add an entry to the table. If an entry with the same name /// already exists, the 'append' parameter is checked If true, /// the new value will be appended to the existing entry. If /// false, the new value will replace the existing entry. void addEntry(const std::string &entryName, const std::string &value, bool append); /// Add an entry to the table given a string assigment. /// Assignment should be of the form "param=value" or /// "param+=value" (for append). This funciton parses the /// assignment statment and calls addEntry(). /// @retval True for success, false if parse error. bool add(const std::string &assignment); /// Find the entry with the given name. /// @retval Pointer to the entry object, or NULL if none. Entry *findEntry(const std::string &entryName) const; /// Print the unreferenced entries in this section to cerr. /// Messages can be suppressed using "unref_section_ok" and /// "unref_entries_ok". /// @param sectionName Name of this section, for use in output message. /// @retval True if any entries were printed. bool printUnreferenced(const std::string §ionName); /// Print the contents of this section to cout (for debugging). void dump(const std::string §ionName); }; /// SectionTable type. Map of strings to Section object pointers. typedef std::unordered_map SectionTable; protected: /// Hash of section names to Section object pointers. SectionTable table; /// Look up section with the given name, creating a new section if /// not found. /// @retval Pointer to section object. Section *addSection(const std::string §ionName); /// Look up section with the given name. /// @retval Pointer to section object, or NULL if not found. Section *findSection(const std::string §ionName) const; public: /// Constructor. IniFile(); /// Destructor. ~IniFile(); /// Load parameter settings from given istream. This is a helper /// function for load(string) and loadCPP(), which open a file /// and then pass it here. /// @retval True if successful, false if errors were encountered. bool load(std::istream &f); /// Load the specified file. /// Parameter settings found in the file will be merged with any /// already defined in this object. /// @param file The path of the file to load. /// @retval True if successful, false if errors were encountered. bool load(const std::string &file); /// Take string of the form "
:=" or /// "
:+=" and add to database. /// @retval True if successful, false if parse error. bool add(const std::string &s); /// Find value corresponding to given section and entry names. /// Value is returned by reference in 'value' param. /// @retval True if found, false if not. bool find(const std::string §ion, const std::string &entry, std::string &value) const; /// Determine whether the entry exists within named section exists /// in the .ini file. /// @return True if the section exists. bool entryExists(const std::string §ion, const std::string &entry) const; /// Determine whether the named section exists in the .ini file. /// Note that the 'Section' class is (intentionally) not public, /// so all clients can do is get a bool that says whether there /// are any values in that section or not. /// @return True if the section exists. bool sectionExists(const std::string §ion) const; /// Push all section names into the given vector void getSectionNames(std::vector &list) const; /// Print unreferenced entries in object. Iteratively calls /// printUnreferend() on all the constituent sections. bool printUnreferenced(); /// Dump contents to cout. For debugging. void dump(); }; #endif // __INIFILE_HH__