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 }