-
Notifications
You must be signed in to change notification settings - Fork 0
/
wmain.cpp
113 lines (100 loc) · 3.46 KB
/
wmain.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#define NOMINMAX
#include <Windows.h>
#include <string>
#include <ostream>
#include <vector>
#include "ArgParser.h"
#include <iostream>
class wostream : std::wostream
{
public:
typedef wchar_t char_type;
typedef std::char_traits<wchar_t> traits_type;
wostream(std::wostream& os)
: std::wostream(os.rdbuf()), stdOut(GetStdHandle( (&os == &std::wcout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE)),
is_console(GetConsoleMode(stdOut, &numWritten) != 0)
{}
~wostream(){}
wostream& operator<<(const wchar_t& c)
{
flush();
if (is_console)
{
WriteConsoleW(stdOut, &c, 1, &numWritten, NULL);
}
else
{
std::vector<char> buffer(WideCharToMultiByte(CP_UTF8, 0, &c, 1, NULL, 0, NULL, NULL));
WideCharToMultiByte(CP_UTF8, 0, &c, 1, buffer.data(), (int)buffer.size(), NULL, NULL);
buffer.emplace_back('\0');
WriteFile(stdOut, buffer.data(), (DWORD)buffer.size() - 1, &numWritten, NULL);
}
return *this;
}
wostream& operator<<(const std::wstring& s)
{
flush();
if (is_console)
{
WriteConsoleW(stdOut, s.c_str(), (DWORD)s.size(), &numWritten, NULL);
}
else
{
std::vector<char> buffer(WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, NULL,0, NULL, NULL));
WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, buffer.data(), (int)buffer.size(), NULL, NULL);
WriteFile(stdOut, buffer.data(), (DWORD)buffer.size()-1, &numWritten, NULL);
}
return *this;
}
// considers 's' as utf-8 encoded string!
wostream& operator<<(const std::string& s)
{
flush();
if (is_console)
{
std::vector<wchar_t> buffer(MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL,0 ));
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer.data(), (int)buffer.size());
WriteConsoleW(stdOut, buffer.data(), (DWORD)buffer.size()-1, &numWritten, NULL);
}
else
{
WriteFile(stdOut, s.data(), (DWORD)s.size()-1, &numWritten, NULL);
}
return *this;
}
template<typename Ty>
wostream& operator<<(Ty t)
{
static_cast<std::wostream&>(*this) << t;
return *this;
}
wostream& operator<<(std::wostream& (*f)(std::wostream&))
{
static_cast<std::wostream&>(*this) << f;
return *this;
}
private:
const HANDLE stdOut;
DWORD numWritten;
const bool is_console;
};
static wostream wcout(std::wcout);
static wostream wcerr(std::wcerr);
int wmain(int argc, const wchar_t** argv)
{
std::string filename;
std::wstring wfilename;
arg::Parser<std::wstring, true, wostream> parser(
TEXT("A configurable application\n")
TEXT("Author: Gabor Borbely, Contact: [email protected]\n")
TEXT("Very long text will be sliced into 'width' long chunks. But a manual '\\n' will produce a new-line, too."),
{ TEXT("-h"), TEXT("--help") },
wcout, wcerr,
TEXT("ASCII\tabcde xyz\nGerman\täöü ÄÖÜ ß\n")
TEXT("Hungarian\tőűíŐŰÍ\nPolish\tąęźżńłŁ\n")
TEXT("Russian\tабвгдеж эюя\nCJK\t你好\nemoji\t😂"), 75);
parser.AddArg(filename, { TEXT("-f"), TEXT("--file") }, TEXT("an ASCII filename"));
parser.AddArg(wfilename, { TEXT("-w"), TEXT("--wide") }, TEXT("a Unicode filename"));
parser.Do(argc, argv);
return 0;
}