installed pty
[VSoRC/.git] / node_modules / node-pty / deps / winpty / misc / WriteConsole.cc
1 #include <windows.h>
2
3 #include <assert.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6
7 #include <string>
8 #include <vector>
9
10 static std::wstring mbsToWcs(const std::string &s) {
11     const size_t len = mbstowcs(nullptr, s.c_str(), 0);
12     if (len == static_cast<size_t>(-1)) {
13         assert(false && "mbsToWcs: invalid string");
14     }
15     std::wstring ret;
16     ret.resize(len);
17     const size_t len2 = mbstowcs(&ret[0], s.c_str(), len);
18     assert(len == len2);
19     return ret;
20 }
21
22 uint32_t parseHex(wchar_t ch, bool &invalid) {
23     if (ch >= L'0' && ch <= L'9') {
24         return ch - L'0';
25     } else if (ch >= L'a' && ch <= L'f') {
26         return ch - L'a' + 10;
27     } else if (ch >= L'A' && ch <= L'F') {
28         return ch - L'A' + 10;
29     } else {
30         invalid = true;
31         return 0;
32     }
33 }
34
35 int main(int argc, char *argv[]) {
36     std::vector<std::wstring> args;
37     for (int i = 1; i < argc; ++i) {
38         args.push_back(mbsToWcs(argv[i]));
39     }
40
41     std::wstring out;
42     for (const auto &arg : args) {
43         if (!out.empty()) {
44             out.push_back(L' ');
45         }
46         for (size_t i = 0; i < arg.size(); ++i) {
47             wchar_t ch = arg[i];
48             wchar_t nch = i + 1 < arg.size() ? arg[i + 1] : L'\0';
49             if (ch == L'\\') {
50                 switch (nch) {
51                     case L'a':  ch = L'\a'; ++i; break;
52                     case L'b':  ch = L'\b'; ++i; break;
53                     case L'e':  ch = L'\x1b'; ++i; break;
54                     case L'f':  ch = L'\f'; ++i; break;
55                     case L'n':  ch = L'\n'; ++i; break;
56                     case L'r':  ch = L'\r'; ++i; break;
57                     case L't':  ch = L'\t'; ++i; break;
58                     case L'v':  ch = L'\v'; ++i; break;
59                     case L'\\': ch = L'\\'; ++i; break;
60                     case L'\'': ch = L'\''; ++i; break;
61                     case L'\"': ch = L'\"'; ++i; break;
62                     case L'\?': ch = L'\?'; ++i; break;
63                     case L'x':
64                         if (i + 3 < arg.size()) {
65                             bool invalid = false;
66                             uint32_t d1 = parseHex(arg[i + 2], invalid);
67                             uint32_t d2 = parseHex(arg[i + 3], invalid);
68                             if (!invalid) {
69                                 i += 3;
70                                 ch = (d1 << 4) | d2;
71                             }
72                         }
73                         break;
74                     case L'u':
75                         if (i + 5 < arg.size()) {
76                             bool invalid = false;
77                             uint32_t d1 = parseHex(arg[i + 2], invalid);
78                             uint32_t d2 = parseHex(arg[i + 3], invalid);
79                             uint32_t d3 = parseHex(arg[i + 4], invalid);
80                             uint32_t d4 = parseHex(arg[i + 5], invalid);
81                             if (!invalid) {
82                                 i += 5;
83                                 ch = (d1 << 24) | (d2 << 16) | (d3 << 8) | d4;
84                             }
85                         }
86                         break;
87                     default: break;
88                 }
89             }
90             out.push_back(ch);
91         }
92     }
93
94     DWORD actual = 0;
95     if (!WriteConsoleW(
96             GetStdHandle(STD_OUTPUT_HANDLE),
97             out.c_str(),
98             out.size(),
99             &actual,
100             nullptr)) {
101         fprintf(stderr, "WriteConsole failed (is stdout a console?)\n");
102         exit(1);
103     }
104
105     return 0;
106 }