Config.cc revision 10448
110448Snilay@cs.wisc.edu/* Copyright (c) 2012 Massachusetts Institute of Technology
210448Snilay@cs.wisc.edu *
310448Snilay@cs.wisc.edu * Permission is hereby granted, free of charge, to any person obtaining a copy
410448Snilay@cs.wisc.edu * of this software and associated documentation files (the "Software"), to deal
510448Snilay@cs.wisc.edu * in the Software without restriction, including without limitation the rights
610448Snilay@cs.wisc.edu * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
710448Snilay@cs.wisc.edu * copies of the Software, and to permit persons to whom the Software is
810448Snilay@cs.wisc.edu * furnished to do so, subject to the following conditions:
910448Snilay@cs.wisc.edu *
1010448Snilay@cs.wisc.edu * The above copyright notice and this permission notice shall be included in
1110448Snilay@cs.wisc.edu * all copies or substantial portions of the Software.
1210448Snilay@cs.wisc.edu *
1310448Snilay@cs.wisc.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1410448Snilay@cs.wisc.edu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1510448Snilay@cs.wisc.edu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1610448Snilay@cs.wisc.edu * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1710448Snilay@cs.wisc.edu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1810448Snilay@cs.wisc.edu * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1910448Snilay@cs.wisc.edu * THE SOFTWARE.
2010448Snilay@cs.wisc.edu */
2110447Snilay@cs.wisc.edu
2210447Snilay@cs.wisc.edu#include <fstream>
2310447Snilay@cs.wisc.edu
2410447Snilay@cs.wisc.edu#include "Assert.h"
2510448Snilay@cs.wisc.edu#include "Config.h"
2610448Snilay@cs.wisc.edu
2710448Snilay@cs.wisc.eduusing namespace std;
2810447Snilay@cs.wisc.edu
2910447Snilay@cs.wisc.edunamespace LibUtil
3010447Snilay@cs.wisc.edu{
3110448Snilay@cs.wisc.edu    void readFile(const char *filename_, map<String, String> &config)
3210448Snilay@cs.wisc.edu    {
3310448Snilay@cs.wisc.edu        std::ifstream ist_(filename_);
3410447Snilay@cs.wisc.edu
3510447Snilay@cs.wisc.edu        // Set a Config from ist_
3610447Snilay@cs.wisc.edu        // Read in keys and values, keeping internal whitespace
3710447Snilay@cs.wisc.edu        typedef String::size_type pos;
3810448Snilay@cs.wisc.edu        const String& delimiter = "=";
3910448Snilay@cs.wisc.edu        const String& comment = "#";
4010448Snilay@cs.wisc.edu        const String& sentry = "End";
4110448Snilay@cs.wisc.edu        const pos skip = delimiter.length();        // length of separator
4210447Snilay@cs.wisc.edu
4310447Snilay@cs.wisc.edu        String nextline = "";  // might need to read ahead to see where value ends
4410447Snilay@cs.wisc.edu
4510447Snilay@cs.wisc.edu        while(ist_ || nextline.length() > 0)
4610447Snilay@cs.wisc.edu        {
4710447Snilay@cs.wisc.edu            // Read an entire line at a time
4810447Snilay@cs.wisc.edu            String line;
4910447Snilay@cs.wisc.edu            if(nextline.length() > 0)
5010447Snilay@cs.wisc.edu            {
5110447Snilay@cs.wisc.edu                line = nextline;  // we read ahead; use it now
5210447Snilay@cs.wisc.edu                nextline = "";
5310447Snilay@cs.wisc.edu            }
5410447Snilay@cs.wisc.edu            else
5510447Snilay@cs.wisc.edu            {
5610447Snilay@cs.wisc.edu                //std::getline(ist_, line);
5710447Snilay@cs.wisc.edu                safeGetline(ist_, line);
5810447Snilay@cs.wisc.edu            }
5910447Snilay@cs.wisc.edu
6010447Snilay@cs.wisc.edu            // Ignore comments and the spaces on both ends
6110448Snilay@cs.wisc.edu            line = line.substr(0, line.find(comment));
6210447Snilay@cs.wisc.edu            line.trim();
6310447Snilay@cs.wisc.edu
6410447Snilay@cs.wisc.edu            // Check for end of file sentry
6510448Snilay@cs.wisc.edu            if((sentry != "") && (line.find(sentry) != String::npos)) return;
6610447Snilay@cs.wisc.edu
6710447Snilay@cs.wisc.edu            if(line.length() == 0)
6810447Snilay@cs.wisc.edu                continue;
6910447Snilay@cs.wisc.edu
7010447Snilay@cs.wisc.edu            // Parse the line if it contains a delimiter
7110448Snilay@cs.wisc.edu            pos delimPos = line.find(delimiter);
7210447Snilay@cs.wisc.edu            ASSERT((delimPos < String::npos), "Invalid config line: '" + line + "'");
7310447Snilay@cs.wisc.edu
7410447Snilay@cs.wisc.edu            // Extract the key
7510447Snilay@cs.wisc.edu            String key = line.substr(0, delimPos);
7610447Snilay@cs.wisc.edu            line.replace(0, delimPos+skip, "");
7710447Snilay@cs.wisc.edu
7810447Snilay@cs.wisc.edu            // See if value continues on the next line
7910447Snilay@cs.wisc.edu            // Stop at blank line, next line with a key, end of stream,
8010447Snilay@cs.wisc.edu            // or end of file sentry
8110447Snilay@cs.wisc.edu            bool terminate = false;
8210447Snilay@cs.wisc.edu            while(!terminate && ist_)
8310447Snilay@cs.wisc.edu            {
8410447Snilay@cs.wisc.edu                if(line.at(line.size() - 1) == '\\')
8510447Snilay@cs.wisc.edu                    line.erase(line.size() - 1);
8610447Snilay@cs.wisc.edu                else
8710447Snilay@cs.wisc.edu                    break;
8810447Snilay@cs.wisc.edu
8910447Snilay@cs.wisc.edu                //std::getline(ist_, nextline);
9010447Snilay@cs.wisc.edu                safeGetline(ist_, nextline);
9110447Snilay@cs.wisc.edu                terminate = true;
9210447Snilay@cs.wisc.edu
9310447Snilay@cs.wisc.edu                String nlcopy = nextline;
9410447Snilay@cs.wisc.edu                nlcopy.trim();
9510447Snilay@cs.wisc.edu                if(nlcopy == "") continue;
9610447Snilay@cs.wisc.edu
9710448Snilay@cs.wisc.edu                nextline = nextline.substr(0, nextline.find(comment));
9810447Snilay@cs.wisc.edu                //if(nextline.find(delim) != String::npos)
9910447Snilay@cs.wisc.edu                //    continue;
10010447Snilay@cs.wisc.edu                if((sentry != "") && (nextline.find(sentry) != String::npos))
10110447Snilay@cs.wisc.edu                    continue;
10210447Snilay@cs.wisc.edu
10310447Snilay@cs.wisc.edu                //nlcopy = nextline;
10410447Snilay@cs.wisc.edu                //nlcopy.trim();
10510447Snilay@cs.wisc.edu                //if(nlcopy != "") line += "\n";
10610447Snilay@cs.wisc.edu                line += nextline;
10710447Snilay@cs.wisc.edu                nextline = "";
10810447Snilay@cs.wisc.edu                terminate = false;
10910447Snilay@cs.wisc.edu            }
11010447Snilay@cs.wisc.edu
11110447Snilay@cs.wisc.edu            // Store key and value
11210447Snilay@cs.wisc.edu            key.trim();
11310447Snilay@cs.wisc.edu            line.trim();
11410448Snilay@cs.wisc.edu            config[key] = line;  // overwrites if key is repeated
11510447Snilay@cs.wisc.edu        }
11610447Snilay@cs.wisc.edu    }
11710447Snilay@cs.wisc.edu}
11810447Snilay@cs.wisc.edu
119