1 /* 2 Copyright (c) 2011-2014 Timur Gafarov 3 4 Boost Software License - Version 1.0 - August 17th, 2003 5 6 Permission is hereby granted, free of charge, to any person or organization 7 obtaining a copy of the software and accompanying documentation covered by 8 this license (the "Software") to use, reproduce, display, distribute, 9 execute, and transmit the Software, and to prepare derivative works of the 10 Software, and to permit third-parties to whom the Software is furnished to 11 do so, all subject to the following: 12 13 The copyright notices in the Software and this entire statement, including 14 the above license grant, this restriction and the following disclaimer, 15 must be included in all copies of the Software, in whole or in part, and 16 all derivative works of the Software, unless such copies or derivative 17 works are solely in the form of machine-executable object code generated by 18 a source language processor. 19 20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 DEALINGS IN THE SOFTWARE. 27 */ 28 29 module conf; 30 31 import std.stdio; 32 import std.file; 33 import lexer; 34 35 version(Windows) string OS = "windows"; 36 version(linux) string OS = "linux"; 37 38 final class Config 39 { 40 string[string] data; 41 42 bool has(string key, bool platformSpecific = true) 43 { 44 if (platformSpecific) 45 { 46 string oskey = OS ~ "." ~ key; 47 if (oskey in data) return true; 48 } 49 if (key in data) return true; 50 else return false; 51 } 52 53 string get(string key, bool platformSpecific = true) 54 { 55 if (platformSpecific) 56 { 57 string oskey = OS ~ "." ~ key; 58 if (oskey in data) return data[oskey]; 59 } 60 if (key in data) return data[key]; 61 else return ""; 62 } 63 64 /* 65 * TODO: The following should be rewrote in more clever way... 66 */ 67 void set(string key, string value, bool platformSpecific = true) 68 { 69 if (platformSpecific) 70 { 71 if (key.length > 7 && (key[0..7] == "windows" || key[0..5] == "linux")) 72 { 73 } 74 else 75 { 76 string oskey = OS ~ "." ~ key; 77 data[oskey] = value; 78 } 79 } 80 data[key] = value; 81 } 82 83 void append(string key, string value, bool platformSpecific = true) 84 { 85 if (platformSpecific) 86 { 87 if (key.length > 7 && (key[0..7] == "windows" || key[0..5] == "linux")) 88 { 89 } 90 else 91 { 92 string oskey = OS ~ "." ~ key; 93 data[oskey] ~= value; 94 } 95 } 96 data[key] ~= value; 97 } 98 } 99 100 /* 101 * Parse configuration file 102 */ 103 104 enum 105 { 106 tIdentifier, 107 tColon, 108 tValue, 109 tSemicolon 110 } 111 112 void readConfiguration(Config options, string filename) 113 { 114 auto text = readText(filename); 115 auto lex = new Lexer(text); 116 lex.addDelimiters(); 117 auto nextToken = tIdentifier; 118 string tempId = "_default_"; 119 120 string lexeme = ""; 121 do 122 { 123 lexeme = lex.getLexeme(); 124 if (lexeme.length > 0) 125 { 126 if (lexeme == ";") 127 { 128 if (nextToken == tSemicolon) 129 nextToken = tIdentifier; 130 else throw new Exception("unexpected \"" ~ lexeme ~ "\""); 131 } 132 else if (lexeme == ":") 133 { 134 if (nextToken == tColon) 135 nextToken = tValue; 136 else throw new Exception("unexpected \"" ~ lexeme ~ "\""); 137 } 138 else 139 { 140 if (nextToken == tIdentifier) 141 { 142 tempId = lexeme; 143 nextToken = tColon; 144 } 145 else if (nextToken == tValue) 146 { 147 if (lexeme[0] == '\"' && lexeme[$-1] == '\"') 148 { 149 if (lexeme.length > 2) 150 options.set(tempId, lexeme[1..$-1]); 151 else options.set(tempId, ""); 152 } 153 else options.set(tempId, lexeme); 154 tempId = "_default_"; 155 nextToken = tSemicolon; 156 } 157 else throw new Exception("unexpected \"" ~ lexeme ~ "\""); 158 } 159 } 160 } 161 while (lexeme.length > 0); 162 } 163 164 string formatPattern(string pat, Config data, dchar formattingSymbol) 165 { 166 string result; 167 string temp; 168 bool appending = true; 169 foreach(c; pat) 170 { 171 if (c == formattingSymbol) 172 { 173 if (appending) 174 { 175 appending = false; 176 } 177 else 178 { 179 appending = true; 180 if (data.has(temp)) 181 result ~= formatPattern(data.get(temp), data, formattingSymbol); //data[temp] 182 temp = ""; 183 } 184 } 185 else 186 { 187 if (appending) result ~= c; 188 else temp ~= c; 189 } 190 } 191 return result; 192 } 193