Windows console is broken
Sergey Gromov
snake.scaly at gmail.com
Thu Jan 31 16:05:42 PST 2008
Sean Kelly Wrote:
> Perhaps this would be a good third-party project for someone so inclined?
Here's what I came to.
// Codepage-enabled console output functions for D and Phobos
// Copyright 2008 Sergey Gromov
module snake.cout;
import std.conv;
import std.stdio;
import std.format;
import std.c.windows.windows;
version (Windows)
{
void cwrite(T, R...)(T t, R r)
{
foreach (ch; to!(dchar[])(to!(string)(t)))
cout(ch);
static if (r.length)
cwrite(r);
}
void cwritef(...)
{
doFormat((dchar c){cout(c);}, _arguments, _argptr);
}
void cwriteln(T...)(T args)
{
cwrite(args, '\n');
}
void cwritefln(T...)(T args)
{
cwritef(args, '\n');
}
void cout(dchar c)
{
wchar src = c;
char[4] buf; // buffer for a converted char
auto used = WideCharToMultiByte(GetOEMCP(), 0, &src, 1, buf.ptr, buf.length, "?", null);
fwrite(buf.ptr, 1, used, stdout);
}
}
else
{
alias write cwrite;
alias writef cwritef;
alias writeln cwriteln;
alias writefln cwritefln;
}
import std.file;
import std.contracts;
unittest
{
auto testFileName = "cout-test-file.tmp";
{
FILE* save_stdout = stdout;
scope(exit) stdout = save_stdout;
stdout = enforce(fopen(testFileName, "wb"));
scope(failure) remove(testFileName);
scope(exit) fclose(stdout);
cwriteln("This is %dth day", 14);
cwritef("This is %dth day", 14);
}
scope(exit) remove(testFileName);
string result = cast(string) read(testFileName);
assert(result == "This is %dth day14\nThis is 14th day");
}
unittest
{
auto testFileName = "cout-test-file.tmp";
{
FILE* save_stdout = stdout;
scope(exit) stdout = save_stdout;
stdout = enforce(fopen(testFileName, "wb"));
scope(failure) remove(testFileName);
scope(exit) fclose(stdout);
cwrite("Ãòî ðóññêèÿ áóêâû");
}
scope(exit) remove(testFileName);
invariant wchar[] mustBe = "Ãòî ðóññêèÿ áóêâû"w;
auto required = WideCharToMultiByte(GetOEMCP(), 0, mustBe.ptr, mustBe.length, null, 0, "?", null);
assert(required);
auto mustBeConv = new char[required];
WideCharToMultiByte(GetOEMCP(), 0, mustBe.ptr, mustBe.length, mustBeConv.ptr, mustBeConv.length, "?", null);
string result = cast(string) read(testFileName);
assert(result == mustBeConv);
}
More information about the Digitalmars-d
mailing list