1 module econf.econf; 2 3 import std.stdio; 4 import std.conv : to; 5 import std.string; 6 import std.array; 7 import std.file : readText; 8 import std.uni : isNumber; 9 import std.conv : parse; 10 import econf.tokens; 11 import econf.extra; 12 13 class EConf { 14 private string f; 15 private EToken[int] toks_asnum; 16 private string[string] toks; 17 private EToken[string] toks_at_string; 18 private int currtok=0; 19 20 private void addTok(string str) { 21 this.toks_asnum[currtok]=new EToken(str); 22 this.currtok+=1; 23 } 24 25 private void toksToObject() { 26 int j=0; 27 while(j<toks_asnum.length) { 28 if(this.toks_asnum[j].getString() !in this.toks) { 29 this.toks[this.toks_asnum[j].getString()]= 30 this.toks_asnum[j+1].getString(); 31 this.toks_at_string[this.toks_asnum[j].getString()]= 32 this.toks_asnum[j+1]; 33 } 34 j+=2; 35 } 36 } 37 38 this(string f) { 39 this.f=f; 40 int i=0; 41 while(i<this.f.length) { 42 if(this.f[i]==' '||this.f[i]=='\t'||this.f[i]=='\n') {i+=1; continue;} 43 else if(this.f[i]=='#') { 44 if(this.f.indexOf("\n")==-1) { 45 break; 46 } 47 else { 48 i=to!int(this.f.indexOf("\n")+1); 49 continue; 50 } 51 } 52 else { 53 if(this.f[i]=='\"') { 54 // STRING 55 string temp_str="\""; 56 for(int j=i+1; j<this.f.length; j++) { 57 if(this.f[j]=='\"') { 58 temp_str~="\""; 59 i=j+1; 60 j=to!int(this.f.length+1); 61 } 62 else { 63 temp_str~=this.f[j]; 64 } 65 } 66 addTok(temp_str.strip()); 67 temp_str=""; 68 } 69 else { 70 // FLOAT, INTEGER OR IDENTIFIER 71 if(isNumber(this.f[i])) { 72 // FLOAT OR INTEGER 73 string temp_num=""~this.f[i]; 74 for(int j=i+1; j<this.f.length; j++) { 75 if(this.f[j]==' ' 76 ||this.f[j]=='\"' 77 ||this.f[j]=='[' 78 ||this.f[j]==']' 79 ||this.f[j]=='{' 80 ||this.f[j]=='}' 81 ||this.f[j]=='\t' 82 ||this.f[j]=='\n') { 83 i=j; 84 j=to!int(this.f.length+1); 85 } 86 else { 87 temp_num~=this.f[j]; 88 if(j+1==this.f.length) { 89 i=j+1; 90 } 91 } 92 } 93 addTok(temp_num.strip()); 94 temp_num=""; 95 } 96 else if(this.f[i]!='['&&this.f[i]!=']' 97 &&this.f[i]!='{'&&this.f[i]!='}'){ 98 // IDENTIFIER 99 string temp_i=""; 100 for(int j=i; j<this.f.length; j++) { 101 if(this.f[j]==' ' 102 ||this.f[j]=='\"' 103 ||this.f[j]=='[' 104 ||this.f[j]==']' 105 ||this.f[j]=='{' 106 ||this.f[j]=='}' 107 ||isNumber(this.f[j]) 108 ||this.f[j]=='\t' 109 ||this.f[j]=='\n') { 110 i=j; 111 j=to!int(this.f.length+1); 112 } 113 else { 114 temp_i~=this.f[j]; 115 if(j+1==this.f.length) { 116 i=j+1; 117 } 118 } 119 } 120 if(temp_i.strip()!="") addTok(temp_i.strip()); 121 temp_i=""; 122 } 123 else { 124 // START_ARRAY or END_ARRAY or START_OBJECT or END_OBJECT 125 addTok(""~this.f[i]); 126 i+=1; 127 } 128 } 129 } 130 } 131 this.toks_asnum=EConfInitArrays(this.toks_asnum); 132 this.toks_asnum=EConfInitObjects(this.toks_asnum); 133 toksToObject(); 134 } 135 136 EToken[int] getList() {return this.toks_asnum;} 137 138 template get(string name) { 139 string Str() { 140 if(name in this.toks) { 141 return this.toks[name][1..$-1]; 142 } 143 else { 144 throw new StringException("Error: undefined token \""~ 145 name~"\"!"); 146 } 147 } 148 string[int] StrArr() { 149 if(name in this.toks) { 150 EToken[int] chs=this.toks_at_string[name].childs; 151 string[int] arr; 152 for(int i=0; i<chs.length; i++) { 153 arr[i]=chs[i].getString()[1..$-1]; 154 } 155 return arr; 156 } 157 else { 158 throw new StringException("Error: undefined token \""~ 159 name~"\"!"); 160 } 161 } 162 int Int() { 163 if(name in this.toks) { 164 return to!int(this.toks[name]); 165 } 166 else { 167 throw new StringException("Error: undefined token \""~ 168 name~"\"!"); 169 } 170 } 171 float Float() { 172 if(name in this.toks) { 173 return to!float(this.toks[name]); 174 } 175 else { 176 throw new StringException("Error: undefined token \""~ 177 name~"\"!"); 178 } 179 } 180 int[int] IntArr() { 181 if(name in this.toks) { 182 EToken[int] chs=this.toks_at_string[name].childs; 183 int[int] arr; 184 for(int i=0; i<chs.length; i++) { 185 arr[i]=to!int(chs[i].getString()); 186 } 187 return arr; 188 } 189 else { 190 throw new StringException("Error: undefined token \""~ 191 name~"\"!"); 192 } 193 } 194 float[int] FloatArr() { 195 if(name in this.toks) { 196 EToken[int] chs=this.toks_at_string[name].childs; 197 float[int] arr; 198 for(int i=0; i<chs.length; i++) { 199 arr[i]=to!float(chs[i].getString()); 200 } 201 return arr; 202 } 203 else { 204 throw new StringException("Error: undefined token \""~ 205 name~"\"!"); 206 } 207 } 208 int Hex() { 209 if(name in this.toks) { 210 return to!int(this.toks[name][2..$],16); 211 } 212 else { 213 throw new StringException("Error: undefined token \""~ 214 name~"\"!"); 215 } 216 } 217 int[int] HexArr() { 218 if(name in this.toks) { 219 EToken[int] chs=this.toks_at_string[name].childs; 220 int[int] arr; 221 for(int i=0; i<chs.length; i++) { 222 arr[i]=to!int(chs[i].getString(),16); 223 } 224 return arr; 225 } 226 else { 227 throw new StringException("Error: undefined token \""~ 228 name~"\"!"); 229 } 230 } 231 EToken[string] Obj() { 232 if(name in this.toks) { 233 EToken[int] chs=this.toks_at_string[name].childs; 234 EToken[string] arr; 235 int i=0; 236 while(i<chs.length) { 237 arr[chs[i].getString()]=chs[i+1]; 238 i+=2; 239 } 240 return arr; 241 } 242 else { 243 throw new StringException("Error: undefined token \""~ 244 name~"\"!"); 245 } 246 } 247 } 248 template put(T) { 249 T put(string name, T value) { 250 T a; 251 string b; 252 if(typeid(a)==typeid(b)) { 253 this.toks[name]="\""~value~"\""; 254 } 255 else { 256 this.toks[name]=to!string(value); 257 } 258 } 259 } 260 string toksToString() { 261 string all_toks=""; 262 int j=0; 263 while(j<this.toks_asnum.length) { 264 all_toks~=this.toks_asnum[j].getString() 265 ~" "~this.toks_asnum[j+1].getString()~"\n"; 266 j+=2; 267 } 268 return all_toks.strip(); 269 } 270 }