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