1 /******************************************************************************* 2 3 copyright: Copyright (c) 2005 Kris Bell. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Nov 2005: Initial release 8 9 author: Kris 10 11 Standard, global formatters for console output. If you don't need 12 formatted output or unicode translation, consider using the module 13 tango.io.Console directly. If you need to format, but not output 14 to console, consider tango.text.convert.Format instead. 15 16 Stdout & Stderr expose this style of usage: 17 --- 18 Stdout ("hello"); // => hello 19 Stdout (1); // => 1 20 Stdout (3.14); // => 3.14 21 Stdout ('b'); // => b 22 Stdout (1, 2, 3); // => 1, 2, 3 23 Stdout ("abc", 1, 2, 3); // => abc, 1, 2, 3 24 Stdout ("abc", 1, 2) ("foo"); // => abc, 1, 2foo 25 Stdout ("abc") ("def") (3.14); // => abcdef3.14 26 27 Stdout.format ("abc {}", 1); // => abc 1 28 Stdout.format ("abc {}:{}", 1, 2); // => abc 1:2 29 Stdout.format ("abc {1}:{0}", 1, 2); // => abc 2:1 30 Stdout.format ("abc ", 1); // => abc 31 --- 32 33 Note that the last example does not throw an exception. There 34 are several use-cases where dropping an argument is legitimate, 35 so we're currently not enforcing any particular trap mechanism. 36 37 Flushing the output is achieved through the flush() method, or 38 via an empty pair of parens: 39 --- 40 Stdout ("hello world") (); 41 Stdout ("hello world").flush; 42 43 Stdout.format ("hello {}", "world") (); 44 Stdout.format ("hello {}", "world").flush; 45 --- 46 47 Special character sequences, such as "\n", are written directly to 48 the output without any translation (though an output-filter could 49 be inserted to perform translation as required). Platform-specific 50 newlines are generated instead via the newline() method, which also 51 flushes the output when configured to do so: 52 --- 53 Stdout ("hello ") ("world").newline; 54 Stdout.format ("hello {}", "world").newline; 55 Stdout.formatln ("hello {}", "world"); 56 --- 57 58 The format() method of both Stderr and Stdout support the range 59 of formatting options provided by tango.text.convert.Layout and 60 extensions thereof; including the full I18N extensions where it 61 has been configured in that manner. To enable a French Stdout, 62 do the following: 63 --- 64 import tango.text.locale.Locale; 65 66 Stdout.layout = new Locale (Culture.getCulture ("fr-FR")); 67 --- 68 69 Note that Stdout is a shared entity, so every usage of it will 70 be affected by the above example. For applications supporting 71 multiple regions, create multiple Locale instances instead and 72 cache them in an appropriate manner. 73 74 Stdout.layout can also be used for formatting without outputting 75 to the console such as in the following example: 76 --- 77 char[] str = Stdout.layout.convert("{} and {}", 42, "abc"); 78 //str is "42 and abc" 79 --- 80 This can be useful if you already have Stdout imported. 81 82 Note also that the output-stream in use is exposed by these 83 global instances ~ this can be leveraged, for instance, to copy a 84 file to the standard output: 85 --- 86 Stdout.copy (new File ("myfile")); 87 --- 88 89 Note that Stdout is *not* intended to be thread-safe. Use either 90 tango.util.log.Trace or the standard logging facilities in order 91 to enable atomic console I/O. 92 93 *******************************************************************************/ 94 95 module tango.io.Stdout; 96 97 private import tango.io.Console; 98 99 private import tango.io.stream.Format; 100 101 private import tango.text.convert.Layout; 102 103 /******************************************************************************* 104 105 Construct Stdout & Stderr when this module is loaded 106 107 *******************************************************************************/ 108 109 private alias FormatOutput!(char) Output; 110 111 public static __gshared Output Stdout; /// global standard output 112 public static __gshared Output Stderr; /// global error output 113 public alias Stdout stdout; /// alternative 114 public alias Stderr stderr; /// alternative 115 116 shared static this () 117 { 118 // note that a static-ctor inside Layout fails 119 // to be invoked before this is executed (bug) 120 auto layout = Layout!(char).instance; 121 122 Stdout = new Output (layout, Cout.stream); 123 Stderr = new Output (layout, Cerr.stream); 124 125 Stdout.flush(!Cout.redirected); 126 Stderr.flush(!Cerr.redirected); 127 } 128 129 130 /****************************************************************************** 131 132 ******************************************************************************/ 133 134 debug (Stdout) 135 { 136 void main() 137 { 138 Stdout ("hello").newline; 139 Stdout (1).newline; 140 Stdout (3.14).newline; 141 Stdout ('b').newline; 142 Stdout ("abc") ("def") (3.14).newline; 143 Stdout ("abc", 1, 2, 3).newline; 144 Stdout (1, 2, 3).newline; 145 Stdout (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).newline; 146 147 Stdout ("abc {}{}{}", 1, 2, 3).newline; 148 Stdout.format ("abc {}{}{}", 1, 2, 3).newline; 149 } 150 }