inifile.cc revision 160
17119Sgblack@eecs.umich.edu/*
27119Sgblack@eecs.umich.edu * Copyright (c) 2003 The Regents of The University of Michigan
37120Sgblack@eecs.umich.edu * All rights reserved.
47120Sgblack@eecs.umich.edu *
57120Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67120Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77120Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87120Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97120Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107120Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117120Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127120Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137120Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147120Sgblack@eecs.umich.edu * this software without specific prior written permission.
157119Sgblack@eecs.umich.edu *
167119Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177119Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187119Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197119Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207119Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217119Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227119Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237119Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247119Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257119Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267119Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277119Sgblack@eecs.umich.edu */
287119Sgblack@eecs.umich.edu
297119Sgblack@eecs.umich.edu#define USE_CPP
307119Sgblack@eecs.umich.edu// #define CPP_PIPE
317119Sgblack@eecs.umich.edu
327119Sgblack@eecs.umich.edu
337119Sgblack@eecs.umich.edu#ifdef USE_CPP
347119Sgblack@eecs.umich.edu#include <sys/signal.h>
357119Sgblack@eecs.umich.edu#include <sys/types.h>
367119Sgblack@eecs.umich.edu#include <sys/wait.h>
377119Sgblack@eecs.umich.edu
387119Sgblack@eecs.umich.edu#include <stdio.h>
397119Sgblack@eecs.umich.edu#include <stdlib.h>
407119Sgblack@eecs.umich.edu#include <unistd.h>
417119Sgblack@eecs.umich.edu#endif
427119Sgblack@eecs.umich.edu
437119Sgblack@eecs.umich.edu#include <fstream>
447205Sgblack@eecs.umich.edu#include <iostream>
457205Sgblack@eecs.umich.edu#if __GNUC__ >= 3
467205Sgblack@eecs.umich.edu#include <ext/stdio_filebuf.h>
477205Sgblack@eecs.umich.edu#endif
487205Sgblack@eecs.umich.edu
497205Sgblack@eecs.umich.edu#include <vector>
507205Sgblack@eecs.umich.edu#include <string>
517205Sgblack@eecs.umich.edu
527205Sgblack@eecs.umich.edu#include "base/inifile.hh"
537205Sgblack@eecs.umich.edu#include "base/str.hh"
547205Sgblack@eecs.umich.edu
557205Sgblack@eecs.umich.eduusing namespace std;
567205Sgblack@eecs.umich.edu
577205Sgblack@eecs.umich.eduIniFile::IniFile()
587205Sgblack@eecs.umich.edu{}
597205Sgblack@eecs.umich.edu
607205Sgblack@eecs.umich.eduIniFile::~IniFile()
617205Sgblack@eecs.umich.edu{
627205Sgblack@eecs.umich.edu    SectionTable::iterator i = table.begin();
637205Sgblack@eecs.umich.edu    SectionTable::iterator end = table.end();
647205Sgblack@eecs.umich.edu
657205Sgblack@eecs.umich.edu    while (i != end) {
667205Sgblack@eecs.umich.edu        delete (*i).second;
677205Sgblack@eecs.umich.edu        ++i;
687205Sgblack@eecs.umich.edu    }
697205Sgblack@eecs.umich.edu}
707205Sgblack@eecs.umich.edu
717205Sgblack@eecs.umich.edu
727205Sgblack@eecs.umich.edu#ifdef USE_CPP
737205Sgblack@eecs.umich.edubool
747205Sgblack@eecs.umich.eduIniFile::loadCPP(const string &file, vector<char *> &cppArgs)
757205Sgblack@eecs.umich.edu{
767205Sgblack@eecs.umich.edu    int fd[2];
777205Sgblack@eecs.umich.edu
787205Sgblack@eecs.umich.edu    // Open the file just to verify that we can.  Otherwise if the
797205Sgblack@eecs.umich.edu    // file doesn't exist or has bad permissions the user will get
807205Sgblack@eecs.umich.edu    // confusing errors from cpp/g++.
817205Sgblack@eecs.umich.edu    ifstream tmpf(file.c_str());
827205Sgblack@eecs.umich.edu
837205Sgblack@eecs.umich.edu    if (!tmpf.is_open())
847205Sgblack@eecs.umich.edu        return false;
857205Sgblack@eecs.umich.edu
867205Sgblack@eecs.umich.edu    tmpf.close();
877205Sgblack@eecs.umich.edu
887205Sgblack@eecs.umich.edu#ifdef CPP_PIPE
897205Sgblack@eecs.umich.edu    if (pipe(fd) == -1)
907205Sgblack@eecs.umich.edu        return false;
917205Sgblack@eecs.umich.edu#else
927205Sgblack@eecs.umich.edu    char tempfile[] = "/tmp/configXXXXXX";
937205Sgblack@eecs.umich.edu    fd[0] = fd[1] = mkstemp(tempfile);
947205Sgblack@eecs.umich.edu#endif
957205Sgblack@eecs.umich.edu
967205Sgblack@eecs.umich.edu    int pid = fork();
977205Sgblack@eecs.umich.edu
987205Sgblack@eecs.umich.edu    if (pid == -1)
997205Sgblack@eecs.umich.edu        return 1;
1007205Sgblack@eecs.umich.edu
1017205Sgblack@eecs.umich.edu    if (pid == 0) {
1027205Sgblack@eecs.umich.edu        char filename[FILENAME_MAX];
1037205Sgblack@eecs.umich.edu        string::size_type i = file.copy(filename, sizeof(filename) - 1);
1047205Sgblack@eecs.umich.edu        filename[i] = '\0';
1057205Sgblack@eecs.umich.edu
1067205Sgblack@eecs.umich.edu        int arg_count = cppArgs.size();
1077205Sgblack@eecs.umich.edu
1087205Sgblack@eecs.umich.edu        char **args = new char *[arg_count + 20];
1097205Sgblack@eecs.umich.edu
1107205Sgblack@eecs.umich.edu        int nextArg = 0;
1117205Sgblack@eecs.umich.edu        args[nextArg++] = "g++";
1127205Sgblack@eecs.umich.edu        args[nextArg++] = "-E";
1137205Sgblack@eecs.umich.edu        args[nextArg++] = "-P";
1147205Sgblack@eecs.umich.edu        args[nextArg++] = "-nostdinc";
1157205Sgblack@eecs.umich.edu        args[nextArg++] = "-nostdinc++";
1167205Sgblack@eecs.umich.edu        args[nextArg++] = "-x";
1177205Sgblack@eecs.umich.edu        args[nextArg++] = "c++";
1187205Sgblack@eecs.umich.edu        args[nextArg++] = "-undef";
1197205Sgblack@eecs.umich.edu
1207205Sgblack@eecs.umich.edu        for (int i = 0; i < arg_count; i++)
1217205Sgblack@eecs.umich.edu            args[nextArg++] = cppArgs[i];
1227205Sgblack@eecs.umich.edu
1237205Sgblack@eecs.umich.edu        args[nextArg++] = filename;
1247205Sgblack@eecs.umich.edu        args[nextArg++] = NULL;
1257205Sgblack@eecs.umich.edu
1267205Sgblack@eecs.umich.edu        close(STDOUT_FILENO);
1277205Sgblack@eecs.umich.edu        if (dup2(fd[1], STDOUT_FILENO) == -1)
1287205Sgblack@eecs.umich.edu            return 1;
1297205Sgblack@eecs.umich.edu
1307205Sgblack@eecs.umich.edu        execvp("g++", args);
1317205Sgblack@eecs.umich.edu
1327205Sgblack@eecs.umich.edu        exit(1);
1337205Sgblack@eecs.umich.edu    }
1347119Sgblack@eecs.umich.edu
1357119Sgblack@eecs.umich.edu    int retval;
1367119Sgblack@eecs.umich.edu    waitpid(pid, &retval, 0);
1377119Sgblack@eecs.umich.edu
1387119Sgblack@eecs.umich.edu    // check for normal completion of CPP
1397119Sgblack@eecs.umich.edu    if (!WIFEXITED(retval) || WEXITSTATUS(retval) != 0)
1407119Sgblack@eecs.umich.edu        return false;
1417119Sgblack@eecs.umich.edu
1427119Sgblack@eecs.umich.edu#ifdef CPP_PIPE
1437119Sgblack@eecs.umich.edu    close(fd[1]);
1447119Sgblack@eecs.umich.edu#else
1457119Sgblack@eecs.umich.edu    lseek(fd[0], 0, SEEK_SET);
1467119Sgblack@eecs.umich.edu#endif
1477119Sgblack@eecs.umich.edu
1487119Sgblack@eecs.umich.edu    bool status = false;
1497119Sgblack@eecs.umich.edu
1507119Sgblack@eecs.umich.edu#if __GNUC__ >= 3
1517119Sgblack@eecs.umich.edu    using namespace __gnu_cxx;
1527119Sgblack@eecs.umich.edu    stdio_filebuf<char> fbuf(fd[0], ios_base::in, true,
1537119Sgblack@eecs.umich.edu        static_cast<stdio_filebuf<char>::int_type>(BUFSIZ));
1547119Sgblack@eecs.umich.edu
1557119Sgblack@eecs.umich.edu    if (fbuf.is_open()) {
1567119Sgblack@eecs.umich.edu        istream f(&fbuf);
1577119Sgblack@eecs.umich.edu        status = load(f);
1587119Sgblack@eecs.umich.edu    }
1597119Sgblack@eecs.umich.edu
1607119Sgblack@eecs.umich.edu#else
1617120Sgblack@eecs.umich.edu    ifstream f(fd[0]);
1627120Sgblack@eecs.umich.edu    if (f.is_open())
1637120Sgblack@eecs.umich.edu        status = load(f);
1647120Sgblack@eecs.umich.edu#endif
1657120Sgblack@eecs.umich.edu
1667120Sgblack@eecs.umich.edu#ifndef CPP_PIPE
1677120Sgblack@eecs.umich.edu    unlink(tempfile);
1687120Sgblack@eecs.umich.edu#endif
1697120Sgblack@eecs.umich.edu
1707120Sgblack@eecs.umich.edu    return status;
1717120Sgblack@eecs.umich.edu}
1727120Sgblack@eecs.umich.edu#endif
1737120Sgblack@eecs.umich.edu
1747120Sgblack@eecs.umich.edubool
1757120Sgblack@eecs.umich.eduIniFile::load(const string &file)
1767120Sgblack@eecs.umich.edu{
1777120Sgblack@eecs.umich.edu    ifstream f(file.c_str());
1787120Sgblack@eecs.umich.edu
1797120Sgblack@eecs.umich.edu    if (!f.is_open())
1807120Sgblack@eecs.umich.edu        return false;
1817120Sgblack@eecs.umich.edu
1827120Sgblack@eecs.umich.edu    return load(f);
1837120Sgblack@eecs.umich.edu}
1847120Sgblack@eecs.umich.edu
1857120Sgblack@eecs.umich.edu
1867120Sgblack@eecs.umich.educonst string &
1877120Sgblack@eecs.umich.eduIniFile::Entry::getValue() const
1887120Sgblack@eecs.umich.edu{
1897120Sgblack@eecs.umich.edu    referenced = true;
1907120Sgblack@eecs.umich.edu    return value;
1917120Sgblack@eecs.umich.edu}
1927120Sgblack@eecs.umich.edu
1937303Sgblack@eecs.umich.edu
1947303Sgblack@eecs.umich.eduvoid
1957303Sgblack@eecs.umich.eduIniFile::Section::addEntry(const std::string &entryName,
1967303Sgblack@eecs.umich.edu                           const std::string &value,
1977303Sgblack@eecs.umich.edu                           bool append)
1987303Sgblack@eecs.umich.edu{
1997303Sgblack@eecs.umich.edu    EntryTable::iterator ei = table.find(entryName);
2007303Sgblack@eecs.umich.edu
2017303Sgblack@eecs.umich.edu    if (ei == table.end()) {
2027303Sgblack@eecs.umich.edu        // new entry
2037303Sgblack@eecs.umich.edu        table[entryName] = new Entry(value);
2047303Sgblack@eecs.umich.edu    }
2057303Sgblack@eecs.umich.edu    else if (append) {
2067303Sgblack@eecs.umich.edu        // append new reult to old entry
2077303Sgblack@eecs.umich.edu        ei->second->appendValue(value);
2087303Sgblack@eecs.umich.edu    }
2097303Sgblack@eecs.umich.edu    else {
2107303Sgblack@eecs.umich.edu        // override old entry
2117303Sgblack@eecs.umich.edu        ei->second->setValue(value);
2127303Sgblack@eecs.umich.edu    }
2137303Sgblack@eecs.umich.edu}
2147303Sgblack@eecs.umich.edu
2157303Sgblack@eecs.umich.edu
2167303Sgblack@eecs.umich.edubool
2177303Sgblack@eecs.umich.eduIniFile::Section::add(const std::string &assignment)
2187303Sgblack@eecs.umich.edu{
2197303Sgblack@eecs.umich.edu    string::size_type offset = assignment.find('=');
2207303Sgblack@eecs.umich.edu    if (offset == string::npos)  // no '=' found
2217303Sgblack@eecs.umich.edu        return false;
2227303Sgblack@eecs.umich.edu
2237303Sgblack@eecs.umich.edu    // if "+=" rather than just "=" then append value
2247303Sgblack@eecs.umich.edu    bool append = (assignment[offset-1] == '+');
2257303Sgblack@eecs.umich.edu
2267303Sgblack@eecs.umich.edu    string entryName = assignment.substr(0, append ? offset-1 : offset);
2277303Sgblack@eecs.umich.edu    string value = assignment.substr(offset + 1);
2287303Sgblack@eecs.umich.edu
2297303Sgblack@eecs.umich.edu    eat_white(entryName);
2307303Sgblack@eecs.umich.edu    eat_white(value);
2317303Sgblack@eecs.umich.edu
2327303Sgblack@eecs.umich.edu    addEntry(entryName, value, append);
2337303Sgblack@eecs.umich.edu    return true;
2347303Sgblack@eecs.umich.edu}
2357303Sgblack@eecs.umich.edu
2367303Sgblack@eecs.umich.edu
2377303Sgblack@eecs.umich.eduIniFile::Entry *
2387303Sgblack@eecs.umich.eduIniFile::Section::findEntry(const std::string &entryName) const
2397303Sgblack@eecs.umich.edu{
2407303Sgblack@eecs.umich.edu    referenced = true;
2417303Sgblack@eecs.umich.edu
2427303Sgblack@eecs.umich.edu    EntryTable::const_iterator ei = table.find(entryName);
2437303Sgblack@eecs.umich.edu
2447303Sgblack@eecs.umich.edu    return (ei == table.end()) ? NULL : ei->second;
2457303Sgblack@eecs.umich.edu}
2467303Sgblack@eecs.umich.edu
2477303Sgblack@eecs.umich.edu
2487303Sgblack@eecs.umich.eduIniFile::Section *
2497303Sgblack@eecs.umich.eduIniFile::addSection(const string &sectionName)
2507303Sgblack@eecs.umich.edu{
2517303Sgblack@eecs.umich.edu    SectionTable::iterator i = table.find(sectionName);
2527303Sgblack@eecs.umich.edu
2537303Sgblack@eecs.umich.edu    if (i != table.end()) {
2547303Sgblack@eecs.umich.edu        return i->second;
2557303Sgblack@eecs.umich.edu    }
2567303Sgblack@eecs.umich.edu    else {
2577303Sgblack@eecs.umich.edu        // new entry
2587303Sgblack@eecs.umich.edu        Section *sec = new Section();
2597303Sgblack@eecs.umich.edu        table[sectionName] = sec;
2607303Sgblack@eecs.umich.edu        return sec;
2617303Sgblack@eecs.umich.edu    }
2627303Sgblack@eecs.umich.edu}
2637303Sgblack@eecs.umich.edu
2647120Sgblack@eecs.umich.edu
2657120Sgblack@eecs.umich.eduIniFile::Section *
2667120Sgblack@eecs.umich.eduIniFile::findSection(const string &sectionName) const
2677120Sgblack@eecs.umich.edu{
2687120Sgblack@eecs.umich.edu    SectionTable::const_iterator i = table.find(sectionName);
2697120Sgblack@eecs.umich.edu
2707120Sgblack@eecs.umich.edu    return (i == table.end()) ? NULL : i->second;
2717120Sgblack@eecs.umich.edu}
2727120Sgblack@eecs.umich.edu
2737120Sgblack@eecs.umich.edu
2747120Sgblack@eecs.umich.edu// Take string of the form "<section>:<parameter>=<value>" and add to
2757120Sgblack@eecs.umich.edu// database.  Return true if successful, false if parse error.
2767120Sgblack@eecs.umich.edubool
2777120Sgblack@eecs.umich.eduIniFile::add(const string &str)
2787120Sgblack@eecs.umich.edu{
2797120Sgblack@eecs.umich.edu    // find ':'
2807120Sgblack@eecs.umich.edu    string::size_type offset = str.find(':');
2817120Sgblack@eecs.umich.edu    if (offset == string::npos)  // no ':' found
2827120Sgblack@eecs.umich.edu        return false;
2837120Sgblack@eecs.umich.edu
2847120Sgblack@eecs.umich.edu    string sectionName = str.substr(0, offset);
2857120Sgblack@eecs.umich.edu    string rest = str.substr(offset + 1);
2867120Sgblack@eecs.umich.edu
2877120Sgblack@eecs.umich.edu    eat_white(sectionName);
2887120Sgblack@eecs.umich.edu    Section *s = addSection(sectionName);
2897120Sgblack@eecs.umich.edu
2907120Sgblack@eecs.umich.edu    return s->add(rest);
2917120Sgblack@eecs.umich.edu}
2927120Sgblack@eecs.umich.edu
2937120Sgblack@eecs.umich.edubool
2947120Sgblack@eecs.umich.eduIniFile::load(istream &f)
2957120Sgblack@eecs.umich.edu{
2967120Sgblack@eecs.umich.edu    Section *section = NULL;
2977119Sgblack@eecs.umich.edu
2987119Sgblack@eecs.umich.edu    while (!f.eof()) {
2997119Sgblack@eecs.umich.edu        f >> ws; // Eat whitespace
3007119Sgblack@eecs.umich.edu        if (f.eof()) {
3017119Sgblack@eecs.umich.edu            break;
3027119Sgblack@eecs.umich.edu        }
3037119Sgblack@eecs.umich.edu
3047119Sgblack@eecs.umich.edu        string line;
3057119Sgblack@eecs.umich.edu        getline(f, line);
3067119Sgblack@eecs.umich.edu        if (line.size() == 0)
3077119Sgblack@eecs.umich.edu            continue;
3087119Sgblack@eecs.umich.edu
3097119Sgblack@eecs.umich.edu        eat_end_white(line);
3107119Sgblack@eecs.umich.edu        int last = line.size() - 1;
3117119Sgblack@eecs.umich.edu
3127119Sgblack@eecs.umich.edu        if (line[0] == '[' && line[last] == ']') {
3137119Sgblack@eecs.umich.edu            string sectionName = line.substr(1, last - 1);
3147119Sgblack@eecs.umich.edu            eat_white(sectionName);
3157119Sgblack@eecs.umich.edu            section = addSection(sectionName);
3167119Sgblack@eecs.umich.edu            continue;
3177119Sgblack@eecs.umich.edu        }
3187119Sgblack@eecs.umich.edu
3197119Sgblack@eecs.umich.edu        if (section == NULL)
3207119Sgblack@eecs.umich.edu            continue;
3217119Sgblack@eecs.umich.edu
3227119Sgblack@eecs.umich.edu        if (!section->add(line))
3237119Sgblack@eecs.umich.edu            return false;
3247119Sgblack@eecs.umich.edu    }
3257119Sgblack@eecs.umich.edu
3267119Sgblack@eecs.umich.edu    return true;
3277119Sgblack@eecs.umich.edu}
3287119Sgblack@eecs.umich.edu
3297119Sgblack@eecs.umich.edubool
3307119Sgblack@eecs.umich.eduIniFile::find(const string &sectionName, const string &entryName,
3317119Sgblack@eecs.umich.edu              string &value) const
3327119Sgblack@eecs.umich.edu{
3337119Sgblack@eecs.umich.edu    Section *section = findSection(sectionName);
3347119Sgblack@eecs.umich.edu    if (section == NULL)
3357119Sgblack@eecs.umich.edu        return false;
3367119Sgblack@eecs.umich.edu
3377119Sgblack@eecs.umich.edu    Entry *entry = section->findEntry(entryName);
3387119Sgblack@eecs.umich.edu    if (entry == NULL)
3397119Sgblack@eecs.umich.edu        return false;
3407119Sgblack@eecs.umich.edu
3417119Sgblack@eecs.umich.edu    value = entry->getValue();
3427119Sgblack@eecs.umich.edu
3437119Sgblack@eecs.umich.edu    return true;
3447119Sgblack@eecs.umich.edu}
3457119Sgblack@eecs.umich.edu
3467119Sgblack@eecs.umich.edubool
3477120Sgblack@eecs.umich.eduIniFile::findDefault(const string &_section, const string &entry,
3487120Sgblack@eecs.umich.edu                     string &value) const
3497120Sgblack@eecs.umich.edu{
3507120Sgblack@eecs.umich.edu    string section = _section;
3517120Sgblack@eecs.umich.edu    while (!find(section, entry, value)) {
3527120Sgblack@eecs.umich.edu        if (!find(section, "default", section))
3537120Sgblack@eecs.umich.edu            return false;
3547120Sgblack@eecs.umich.edu    }
3557120Sgblack@eecs.umich.edu
3567120Sgblack@eecs.umich.edu    return true;
3577120Sgblack@eecs.umich.edu}
3587120Sgblack@eecs.umich.edu
3597120Sgblack@eecs.umich.edu
3607120Sgblack@eecs.umich.edubool
3617120Sgblack@eecs.umich.eduIniFile::Section::printUnreferenced(const string &sectionName)
3627120Sgblack@eecs.umich.edu{
3637120Sgblack@eecs.umich.edu    bool unref = false;
3647120Sgblack@eecs.umich.edu    bool search_unref_entries = false;
3657120Sgblack@eecs.umich.edu    vector<string> unref_ok_entries;
3667120Sgblack@eecs.umich.edu
3677120Sgblack@eecs.umich.edu    Entry *entry = findEntry("unref_entries_ok");
3687303Sgblack@eecs.umich.edu    if (entry != NULL) {
3697303Sgblack@eecs.umich.edu        tokenize(unref_ok_entries, entry->getValue(), ' ');
3707303Sgblack@eecs.umich.edu        if (unref_ok_entries.size()) {
3717303Sgblack@eecs.umich.edu            search_unref_entries = true;
3727303Sgblack@eecs.umich.edu        }
3737303Sgblack@eecs.umich.edu    }
3747303Sgblack@eecs.umich.edu
3757303Sgblack@eecs.umich.edu    for (EntryTable::iterator ei = table.begin();
3767303Sgblack@eecs.umich.edu         ei != table.end(); ++ei) {
3777303Sgblack@eecs.umich.edu        const string &entryName = ei->first;
3787303Sgblack@eecs.umich.edu        Entry *entry = ei->second;
3797303Sgblack@eecs.umich.edu
3807303Sgblack@eecs.umich.edu        if (entryName == "unref_section_ok" ||
3817303Sgblack@eecs.umich.edu            entryName == "unref_entries_ok")
3827303Sgblack@eecs.umich.edu        {
3837303Sgblack@eecs.umich.edu            continue;
3847303Sgblack@eecs.umich.edu        }
3857303Sgblack@eecs.umich.edu
3867303Sgblack@eecs.umich.edu        if (!entry->isReferenced()) {
3877303Sgblack@eecs.umich.edu            if (search_unref_entries &&
3887303Sgblack@eecs.umich.edu                (std::find(unref_ok_entries.begin(), unref_ok_entries.end(),
3897303Sgblack@eecs.umich.edu                           entryName) != unref_ok_entries.end()))
3907303Sgblack@eecs.umich.edu            {
3917303Sgblack@eecs.umich.edu                continue;
3927291Sgblack@eecs.umich.edu            }
3937291Sgblack@eecs.umich.edu
3947291Sgblack@eecs.umich.edu            cerr << "Parameter " << sectionName << ":" << entryName
3957291Sgblack@eecs.umich.edu                 << " not referenced." << endl;
3967291Sgblack@eecs.umich.edu            unref = true;
3977291Sgblack@eecs.umich.edu        }
3987291Sgblack@eecs.umich.edu    }
3997291Sgblack@eecs.umich.edu
4007291Sgblack@eecs.umich.edu    return unref;
4017291Sgblack@eecs.umich.edu}
4027291Sgblack@eecs.umich.edu
4037291Sgblack@eecs.umich.edu
4047291Sgblack@eecs.umich.edubool
4057291Sgblack@eecs.umich.eduIniFile::printUnreferenced()
4067291Sgblack@eecs.umich.edu{
4077291Sgblack@eecs.umich.edu    bool unref = false;
4087291Sgblack@eecs.umich.edu
4097291Sgblack@eecs.umich.edu    for (SectionTable::iterator i = table.begin();
4107291Sgblack@eecs.umich.edu         i != table.end(); ++i) {
4117291Sgblack@eecs.umich.edu        const string &sectionName = i->first;
4127312Sgblack@eecs.umich.edu        Section *section = i->second;
4137312Sgblack@eecs.umich.edu
4147312Sgblack@eecs.umich.edu        if (!section->isReferenced()) {
4157312Sgblack@eecs.umich.edu            if (section->findEntry("unref_section_ok") == NULL) {
4167312Sgblack@eecs.umich.edu                cerr << "Section " << sectionName << " not referenced."
4177312Sgblack@eecs.umich.edu                     << endl;
4187312Sgblack@eecs.umich.edu                unref = true;
4197312Sgblack@eecs.umich.edu            }
4207312Sgblack@eecs.umich.edu        }
4217312Sgblack@eecs.umich.edu        else {
4227312Sgblack@eecs.umich.edu            if (section->printUnreferenced(sectionName)) {
4237312Sgblack@eecs.umich.edu                unref = true;
4247312Sgblack@eecs.umich.edu            }
4257312Sgblack@eecs.umich.edu        }
4267312Sgblack@eecs.umich.edu    }
4277312Sgblack@eecs.umich.edu
4287312Sgblack@eecs.umich.edu    return unref;
4297312Sgblack@eecs.umich.edu}
4307312Sgblack@eecs.umich.edu
4317312Sgblack@eecs.umich.edu
4327205Sgblack@eecs.umich.eduvoid
4337205Sgblack@eecs.umich.eduIniFile::Section::dump(const string &sectionName)
4347205Sgblack@eecs.umich.edu{
4357205Sgblack@eecs.umich.edu    for (EntryTable::iterator ei = table.begin();
4367205Sgblack@eecs.umich.edu         ei != table.end(); ++ei) {
4377205Sgblack@eecs.umich.edu        cout << sectionName << ": " << (*ei).first << " => "
4387205Sgblack@eecs.umich.edu             << (*ei).second->getValue() << "\n";
4397205Sgblack@eecs.umich.edu    }
4407205Sgblack@eecs.umich.edu}
4417205Sgblack@eecs.umich.edu
4427205Sgblack@eecs.umich.eduvoid
4437205Sgblack@eecs.umich.eduIniFile::dump()
4447205Sgblack@eecs.umich.edu{
4457205Sgblack@eecs.umich.edu    for (SectionTable::iterator i = table.begin();
4467205Sgblack@eecs.umich.edu         i != table.end(); ++i) {
4477205Sgblack@eecs.umich.edu        i->second->dump(i->first);
4487205Sgblack@eecs.umich.edu    }
4497205Sgblack@eecs.umich.edu}
4507205Sgblack@eecs.umich.edu