1 module gccbuild.console; 2 3 import consoled, scriptlike, gccbuild; 4 5 private SysTime startTime; 6 7 void startSection(string text, bool log = true) 8 { 9 startTime = Clock.currTime; 10 static bool first = true; 11 12 if (first) 13 first = false; 14 else 15 writeln(); 16 17 writec(FontStyle.bold, Fg.green, "==> ", Fg.initial, text); 18 resetFontStyle(); 19 writecln(); 20 21 if (log) 22 startSectionLog(text); 23 } 24 25 void endSection(bool log = true) 26 { 27 auto dur = Clock.currTime - startTime; 28 writefln("%*s", consoled.width, "(" ~ dur.durationToString() ~ ")"); 29 if (log) 30 endSectionLog(dur); 31 } 32 33 private void writeError(string text) 34 { 35 enum prefix = "==> ERROR: "; 36 writec(FontStyle.bold, Fg.red, prefix, Fg.initial, text); 37 resetFontStyle(); 38 writecln(); 39 writelnLog(prefix, text); 40 } 41 42 static SysTime bulletStartTime; 43 44 void writeBulletPoint(string text) 45 { 46 bulletStartTime = Clock.currTime; 47 enum prefix = " -> "; 48 writec(FontStyle.bold, Fg.blue, prefix, Fg.initial, text); 49 resetFontStyle(); 50 writecln(); 51 writeBulletPointLog(text); 52 } 53 54 void endBulletPoint() 55 { 56 endBulletPointLog(Clock.currTime - bulletStartTime); 57 } 58 59 void failc(T...)(T args) 60 { 61 writeError(text(args)); 62 SilentFail(); 63 } 64 65 void failEnforcec(T...)(bool cond, T args) 66 { 67 if (!cond) 68 failc(args); 69 } 70 71 class SilentFail : Exception 72 { 73 private this() 74 { 75 super(null); 76 } 77 78 private static Fail opCall(string file = __FILE__, int line = __LINE__) 79 { 80 throw cast(SilentFail) cast(void*) SilentFail.classinfo.init; 81 } 82 83 override void toString(scope void delegate(in char[]) sink) const 84 { 85 } 86 } 87 88 // Duration formatting 89 90 string durationToString(Duration dur) nothrow 91 { 92 auto _hnsecs = dur.total!"hnsecs"; 93 static void appUnitVal(string units)(ref string res, long val) nothrow 94 { 95 immutable plural = val != 1; 96 string unit; 97 static if (units == "seconds") 98 unit = plural ? "secs" : "sec"; 99 else static if (units == "msecs") 100 unit = "ms"; 101 else static if (units == "usecs") 102 unit = "us"; 103 else 104 unit = plural ? units : units[0 .. $ - 1]; 105 res ~= to!string(val); 106 res ~= " "; 107 res ~= unit; 108 } 109 110 if (_hnsecs == 0) 111 return "0 hnsecs"; 112 113 template TT(T...) 114 { 115 alias TT = T; 116 } 117 118 alias units = TT!("weeks", "days", "hours", "minutes", "seconds", "msecs", "usecs"); 119 120 long hnsecs = _hnsecs; 121 string res; 122 uint pos; 123 size_t written = 0; 124 foreach (unit; units) 125 { 126 if (auto val = splitUnitsFromHNSecs!unit(hnsecs)) 127 { 128 if (written != 0) 129 res ~= ", "; 130 appUnitVal!unit(res, val); 131 if (++written == 2) 132 break; 133 } 134 if (hnsecs == 0) 135 break; 136 } 137 if (hnsecs != 0 && written < 2) 138 { 139 res ~= ", "; 140 appUnitVal!"hnsecs"(res, hnsecs); 141 } 142 return res; 143 } 144 145 long splitUnitsFromHNSecs(string units)(ref long hnsecs) @safe pure nothrow @nogc if ( 146 units == "weeks" || units == "days" || units == "hours" 147 || units == "minutes" || units == "seconds" || units == "msecs" 148 || units == "usecs" || units == "hnsecs") 149 { 150 immutable value = convert!("hnsecs", units)(hnsecs); 151 hnsecs -= convert!(units, "hnsecs")(value); 152 153 return value; 154 }