1/* Copyright (c) 2012 Massachusetts Institute of Technology
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 */
21
22#include <fstream>
23
24#include "Assert.h"
25#include "Config.h"
26
27using namespace std;
28
29namespace LibUtil
30{
31    void readFile(const char *filename_, map<String, String> &config)
32    {
33        std::ifstream ist_(filename_);
34
35        // Set a Config from ist_
36        // Read in keys and values, keeping internal whitespace
37        typedef String::size_type pos;
38        const String& delimiter = "=";
39        const String& comment = "#";
40        const String& sentry = "End";
41        const pos skip = delimiter.length();        // length of separator
42
43        String nextline = "";  // might need to read ahead to see where value ends
44
45        while(ist_ || nextline.length() > 0)
46        {
47            // Read an entire line at a time
48            String line;
49            if(nextline.length() > 0)
50            {
51                line = nextline;  // we read ahead; use it now
52                nextline = "";
53            }
54            else
55            {
56                //std::getline(ist_, line);
57                safeGetline(ist_, line);
58            }
59
60            // Ignore comments and the spaces on both ends
61            line = line.substr(0, line.find(comment));
62            line.trim();
63
64            // Check for end of file sentry
65            if((sentry != "") && (line.find(sentry) != String::npos)) return;
66
67            if(line.length() == 0)
68                continue;
69
70            // Parse the line if it contains a delimiter
71            pos delimPos = line.find(delimiter);
72            ASSERT((delimPos < String::npos), "Invalid config line: '" + line + "'");
73
74            // Extract the key
75            String key = line.substr(0, delimPos);
76            line.replace(0, delimPos+skip, "");
77
78            // See if value continues on the next line
79            // Stop at blank line, next line with a key, end of stream,
80            // or end of file sentry
81            bool terminate = false;
82            while(!terminate && ist_)
83            {
84                if(line.at(line.size() - 1) == '\\')
85                    line.erase(line.size() - 1);
86                else
87                    break;
88
89                //std::getline(ist_, nextline);
90                safeGetline(ist_, nextline);
91                terminate = true;
92
93                String nlcopy = nextline;
94                nlcopy.trim();
95                if(nlcopy == "") continue;
96
97                nextline = nextline.substr(0, nextline.find(comment));
98                //if(nextline.find(delim) != String::npos)
99                //    continue;
100                if((sentry != "") && (nextline.find(sentry) != String::npos))
101                    continue;
102
103                //nlcopy = nextline;
104                //nlcopy.trim();
105                //if(nlcopy != "") line += "\n";
106                line += nextline;
107                nextline = "";
108                terminate = false;
109            }
110
111            // Store key and value
112            key.trim();
113            line.trim();
114            config[key] = line;  // overwrites if key is repeated
115        }
116    }
117}
118
119