1 /******************************************************************************* 2 3 Static console tracer 4 5 Static console tracer - moves the cursor back to its original position after 6 printing the required text. 7 8 Copyright: 9 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 10 All rights reserved. 11 12 License: 13 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 14 Alternatively, this file may be distributed under the terms of the Tango 15 3-Clause BSD License (see LICENSE_BSD.txt for details). 16 17 *******************************************************************************/ 18 19 module ocean.util.log.StaticTrace; 20 21 import ocean.core.TypeConvert; 22 import ocean.io.Console; 23 import ocean.io.model.IConduit; 24 import ocean.io.Terminal; 25 import ocean.text.convert.Formatter; 26 import ocean.text.Search; 27 import ocean.meta.types.Qualifiers; 28 29 30 /******************************************************************************* 31 32 Construct StaticTrace when this module is loaded 33 34 *******************************************************************************/ 35 36 /// global static trace instance 37 public static StaticSyncPrint StaticTrace; 38 39 static this() 40 { 41 StaticTrace = new StaticSyncPrint(Cerr.stream); 42 } 43 44 45 46 /******************************************************************************* 47 48 Static trace class - internal only 49 50 *******************************************************************************/ 51 52 public class StaticSyncPrint 53 { 54 /*************************************************************************** 55 56 Buffer used for string formatting. 57 58 ***************************************************************************/ 59 60 private mstring formatted; 61 62 /*************************************************************************** 63 64 Find Fruct to find the \n's 65 66 ***************************************************************************/ 67 68 private typeof(find(cstring.init)) finder; 69 70 /*************************************************************************** 71 72 Outputstream to use. 73 74 ***************************************************************************/ 75 76 private OutputStream output; 77 78 /*************************************************************************** 79 80 C'tor 81 82 Params: 83 output = Outputstream to use. 84 85 ***************************************************************************/ 86 87 public this ( OutputStream output ) 88 { 89 this.finder = find(cast(cstring) "\n"); 90 this.output = output; 91 } 92 93 /*************************************************************************** 94 95 Outputs a string to the console. 96 97 Params: 98 Args = Tuple of arguments to format 99 fmt = format string (same format as tanog.util.log.Trace) 100 args = variadic list of values referenced in format string 101 102 Returns: 103 this instance for method chaining 104 105 ***************************************************************************/ 106 107 public typeof(this) format (Args...) ( cstring fmt, Args args ) 108 { 109 formatted.length = 0; 110 assumeSafeAppend(this.formatted); 111 112 sformat(formatted, fmt, args); 113 114 size_t lines = 0; 115 istring nl = ""; 116 117 foreach ( token; this.finder.tokens(this.formatted) ) 118 { 119 with ( this.output ) 120 { 121 write(nl); 122 write(token); 123 write(Terminal.CSI); 124 write(Terminal.ERASE_REST_OF_LINE); 125 flush(); 126 } 127 128 nl = "\n"; 129 130 lines++; 131 } 132 133 with (Terminal) if ( lines == 1 ) 134 { 135 with ( this.output ) 136 { 137 write(CSI); 138 write("0"); 139 write(HORIZONTAL_MOVE_CURSOR); 140 flush(); 141 } 142 } 143 else with ( this.output ) 144 { 145 formatted.length = 0; 146 assumeSafeAppend(this.formatted); 147 sformat(formatted, "{}", lines - 1); 148 149 write(CSI); 150 write(formatted); 151 write(LINE_UP); 152 flush(); 153 } 154 155 return this; 156 } 157 158 159 /*************************************************************************** 160 161 Flushes the output to the console. 162 163 Returns: 164 this instance for method chaining 165 166 ***************************************************************************/ 167 168 public typeof(this) flush ( ) 169 { 170 this.output.flush(); 171 return this; 172 } 173 } 174 175 unittest 176 { 177 class FakeStream : OutputStream 178 { 179 override size_t write (const(void)[] src) { return src.length; } 180 override OutputStream copy (InputStream src, size_t max = -1) { return this; } 181 override OutputStream output () { return this; } 182 override long seek (long offset, Anchor anchor = Anchor.Begin) { return offset; } 183 override IConduit conduit () { return null; } 184 override IOStream flush () { return this; } 185 override void close () {} 186 } 187 188 auto trace = new StaticSyncPrint(new FakeStream); 189 trace.format("static trace says hello {}", 1); 190 }