installed pty
[VSoRC/.git] / node_modules / node-pty / deps / winpty / misc / TestUtil.cc
1 // This file is included into test programs using #include
2
3 #include <windows.h>
4 #include <assert.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <wchar.h>
8 #include <vector>
9 #include <string>
10
11 #include "../src/shared/DebugClient.h"
12 #include "../src/shared/TimeMeasurement.h"
13
14 #include "../src/shared/DebugClient.cc"
15 #include "../src/shared/WinptyAssert.cc"
16 #include "../src/shared/WinptyException.cc"
17
18 // Launch this test program again, in a new console that we will destroy.
19 static void startChildProcess(const wchar_t *args) {
20     wchar_t program[1024];
21     wchar_t cmdline[1024];
22     GetModuleFileNameW(NULL, program, 1024);
23     swprintf(cmdline, L"\"%ls\" %ls", program, args);
24
25     STARTUPINFOW sui;
26     PROCESS_INFORMATION pi;
27     memset(&sui, 0, sizeof(sui));
28     memset(&pi, 0, sizeof(pi));
29     sui.cb = sizeof(sui);
30
31     CreateProcessW(program, cmdline,
32                    NULL, NULL,
33                    /*bInheritHandles=*/FALSE,
34                    /*dwCreationFlags=*/CREATE_NEW_CONSOLE,
35                    NULL, NULL,
36                    &sui, &pi);
37 }
38
39 static void setBufferSize(HANDLE conout, int x, int y) {
40     COORD size = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
41     BOOL success = SetConsoleScreenBufferSize(conout, size);
42     trace("setBufferSize: (%d,%d), result=%d", x, y, success);
43 }
44
45 static void setWindowPos(HANDLE conout, int x, int y, int w, int h) {
46     SMALL_RECT r = {
47         static_cast<SHORT>(x), static_cast<SHORT>(y),
48         static_cast<SHORT>(x + w - 1),
49         static_cast<SHORT>(y + h - 1)
50     };
51     BOOL success = SetConsoleWindowInfo(conout, /*bAbsolute=*/TRUE, &r);
52     trace("setWindowPos: (%d,%d,%d,%d), result=%d", x, y, w, h, success);
53 }
54
55 static void setCursorPos(HANDLE conout, int x, int y) {
56     COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
57     SetConsoleCursorPosition(conout, coord);
58 }
59
60 static void setBufferSize(int x, int y) {
61     setBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), x, y);
62 }
63
64 static void setWindowPos(int x, int y, int w, int h) {
65     setWindowPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y, w, h);
66 }
67
68 static void setCursorPos(int x, int y) {
69     setCursorPos(GetStdHandle(STD_OUTPUT_HANDLE), x, y);
70 }
71
72 static void countDown(int sec) {
73     for (int i = sec; i > 0; --i) {
74         printf("%d.. ", i);
75         fflush(stdout);
76         Sleep(1000);
77     }
78     printf("\n");
79 }
80
81 static void writeBox(int x, int y, int w, int h, char ch, int attributes=7) {
82     CHAR_INFO info = { 0 };
83     info.Char.AsciiChar = ch;
84     info.Attributes = attributes;
85     std::vector<CHAR_INFO> buf(w * h, info);
86     HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
87     COORD bufSize = { static_cast<SHORT>(w), static_cast<SHORT>(h) };
88     COORD bufCoord = { 0, 0 };
89     SMALL_RECT writeRegion = {
90         static_cast<SHORT>(x),
91         static_cast<SHORT>(y),
92         static_cast<SHORT>(x + w - 1),
93         static_cast<SHORT>(y + h - 1)
94     };
95     WriteConsoleOutputA(conout, buf.data(), bufSize, bufCoord, &writeRegion);
96 }
97
98 static void setChar(int x, int y, char ch, int attributes=7) {
99     writeBox(x, y, 1, 1, ch, attributes);
100 }
101
102 static void fillChar(int x, int y, int repeat, char ch) {
103     COORD coord = { static_cast<SHORT>(x), static_cast<SHORT>(y) };
104     DWORD actual = 0;
105     FillConsoleOutputCharacterA(
106         GetStdHandle(STD_OUTPUT_HANDLE),
107         ch, repeat, coord, &actual);
108 }
109
110 static void repeatChar(int count, char ch) {
111     for (int i = 0; i < count; ++i) {
112         putchar(ch);
113     }
114     fflush(stdout);
115 }
116
117 // I don't know why, but wprintf fails to print this face name,
118 // "MS ゴシック" (aka MS Gothic).  It helps to use wprintf instead of printf, and
119 // it helps to call `setlocale(LC_ALL, "")`, but the Japanese symbols are
120 // ultimately converted to `?` symbols, even though MS Gothic is able to
121 // display its own name, and the current code page is 932 (Shift-JIS).
122 static void cvfprintf(HANDLE conout, const wchar_t *fmt, va_list ap) {
123     wchar_t buffer[256];
124     vswprintf(buffer, 256 - 1, fmt, ap);
125     buffer[255] = L'\0';
126     DWORD actual = 0;
127     if (!WriteConsoleW(conout, buffer, wcslen(buffer), &actual, NULL)) {
128         wprintf(L"WriteConsoleW call failed!\n");
129     }
130 }
131
132 static void cfprintf(HANDLE conout, const wchar_t *fmt, ...) {
133     va_list ap;
134     va_start(ap, fmt);
135     cvfprintf(conout, fmt, ap);
136     va_end(ap);
137 }
138
139 static void cprintf(const wchar_t *fmt, ...) {
140     va_list ap;
141     va_start(ap, fmt);
142     cvfprintf(GetStdHandle(STD_OUTPUT_HANDLE), fmt, ap);
143     va_end(ap);
144 }
145
146 static std::string narrowString(const std::wstring &input)
147 {
148     int mblen = WideCharToMultiByte(
149         CP_UTF8, 0,
150         input.data(), input.size(),
151         NULL, 0, NULL, NULL);
152     if (mblen <= 0) {
153         return std::string();
154     }
155     std::vector<char> tmp(mblen);
156     int mblen2 = WideCharToMultiByte(
157         CP_UTF8, 0,
158         input.data(), input.size(),
159         tmp.data(), tmp.size(),
160         NULL, NULL);
161     assert(mblen2 == mblen);
162     return std::string(tmp.data(), tmp.size());
163 }
164
165 HANDLE openConout() {
166     const HANDLE conout = CreateFileW(L"CONOUT$",
167                                       GENERIC_READ | GENERIC_WRITE,
168                                       FILE_SHARE_READ | FILE_SHARE_WRITE,
169                                       NULL, OPEN_EXISTING, 0, NULL);
170     ASSERT(conout != INVALID_HANDLE_VALUE);
171     return conout;
172 }