1 #!/usr/bin/env rdmd-dev-module
2 
3 /** Various debug printing tools for debug printing in `@safe pure nothrow @nogc` code.
4     Copyright: Per Nordlöw 2016-.
5     License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
6     Authors: $(WEB Per Nordlöw)
7 */
8 module dbgio;
9 
10 // version = show;
11 
12 /** See_Also: http://forum.dlang.org/post/nq4eol$2h34$1@digitalmars.com */
13 void assumeNogc(alias Func, T...)(T xs) @nogc
14 {
15     import std.traits : isFunctionPointer, isDelegate, functionAttributes, FunctionAttribute, SetFunctionAttributes, functionLinkage;
16     static auto assumeNogcPtr(T)(T f) if (isFunctionPointer!T ||
17                                           isDelegate!T)
18     {
19         enum attrs = functionAttributes!T | FunctionAttribute.nogc;
20         return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) f;
21     } {}
22     assumeNogcPtr(&Func!T)(xs);
23 }
24 
25 mixin template dump(Names ... )
26 {
27     auto _unused_dump =
28     {
29         import std.stdio : writeln, write;
30         foreach(i,name; Names)
31         {
32             write(name, " = ", mixin(name), (i<Names.length-1)?", ": "\n");
33         }
34         return false;
35     }();
36 }
37 
38 @trusted:
39 
40 /* http://stackoverflow.com/questions/19413340/escaping-safety-with-debug-statements */
41 debug auto trustedPureDebugCall(alias fn, Args...) (Args args) pure
42 {
43     debug return fn(args);
44 }
45 
46 nothrow pure:
47 
48 /** Debug print `args` followed by a newline. */
49 void dln(string file = __FILE__,
50          uint line = __LINE__,
51          string fun = __FUNCTION__,
52          Args...)(Args args)
53 {
54     try
55     {
56         import std.stdio : writeln;
57         debug assumeNogc!writeln(file, ":", line, ":", " debug: ", args);
58     }
59     catch (Exception) { }
60 }
61 
62 version(show) @safe pure nothrow @nogc unittest
63 {
64     dln("x:", " ", 12);
65 }
66 
67 /** Show the symbol name and variable of $(D Args).
68     See also: http://forum.dlang.org/thread/yczwqrbkxdiqijtiynrh@forum.dlang.org?page=1
69  */
70 template show(Args...)
71     if (Args.length >= 1)
72 {
73     void show(string file = __FILE__,
74               uint line = __LINE__,
75               string fun = __FUNCTION__)
76     {
77         import std.stdio: write, writeln;
78         try
79         {
80             debug write(file, ":",line, ":" /* , ": in ",fun */, " debug: ");
81             foreach (const i, Arg; Args)
82             {
83                 if (i) debug write(", "); // separator
84                 debug write(Args[i].stringof, ":", Arg);
85             }
86             debug writeln();
87         }
88         catch (Exception) { }
89     }
90 }
91 
92 version(show) unittest
93 {
94     const x = 11;
95     const y = 12;
96     const z = 13;
97     show!x;
98     show!y;
99     show!z;
100 }
101 
102 version(show) unittest
103 {
104     const x = 11, y = 12, z = 13;
105     show!(x, y, z);
106 }