1 module dast.config; 2 3 import tame.data.yaml, 4 std.traits : isNumeric; 5 6 version (Have_ctfepp) 7 private enum PP = true; 8 else 9 private enum PP = false; 10 11 public import tame.data.yaml : Node; 12 13 Node readyml(string content, bool preprocess = PP) { 14 if (preprocess) { 15 static if (PP) { 16 import ctfepp; 17 18 auto file = PPFile(content); 19 executePPParser(file); 20 auto edata = EvaluateData(file); 21 static foreach (s; [ 22 "Windows", "Win32", "Win64", "linux", "OSX", "iOS", "TVOS", 23 "VisionOS", 24 "Posix", "Android", "Emscripten", "PlayStation", 25 "PlayStation4", 26 "Cygwin", "MinGW", "X86", "X86_64", "ARM", "AArch64", 27 "LittleEndian", "BigEndian", "D_SIMD", "D_AVX", "D_AVX2" 28 ]) { 29 mixin("version(", s, `) edata.defineValues[s] = "1";`); 30 } 31 executeEvaulator(edata); 32 content = edata.output; 33 } else 34 throw new Exception("Preprocess is not supported"); 35 } 36 return loadyml(content); 37 } 38 39 Exception readcfgEnv(alias s)(string path = null, bool preprocess = PP) { 40 import std.array; 41 import std.conv : to; 42 import dast.util; 43 import tame.io.file; 44 45 Node root; 46 try { 47 root = Node(string[string].init); 48 if (path.length) { 49 auto buf = uninitializedArray!(ubyte[])(getSize(path)); 50 auto file = File(path); 51 if (!file.isOpen) 52 return new Exception("Open file failed: " ~ path); 53 scope (exit) 54 file.close(); 55 file.read(buf); 56 if (file.error) 57 return new Exception("Read file failed: " ~ path); 58 root = readyml(cast(string)buf, preprocess); 59 } 60 61 foreach (i, ref f; s.tupleof) { 62 enum key = KeyName!(s.tupleof[i]); 63 auto var = getEnv!key; 64 if (var) { 65 alias T = typeof(f); 66 static if (is(T : string)) 67 f = var; 68 else static if (is(T : bool)) 69 f = var == "1"; 70 else static if (isNumeric!T) 71 f = var.to!T; 72 else 73 static assert(0, "Unsupported type: " ~ T.stringof); 74 } else if (key in root) 75 f = root[key].as!(T); 76 } 77 } catch (Exception e) 78 return e; 79 return null; 80 } 81 82 void readcfg(alias s, S)(S path = null, bool preprocess = PP) { 83 import std.file : read; 84 import dast.util; 85 86 Node root = Node(string[string].init); 87 if (path.length) 88 root = readyml(cast(string)read(path), preprocess); 89 90 foreach (i, ref f; s.tupleof) { 91 enum key = KeyName!(s.tupleof[i]); 92 if (key in root) 93 f = root[key].as!(typeof(f)); 94 } 95 }