1 | n/a | |
---|
2 | n/a | /* Testing module for multi-phase initialization of extension modules (PEP 489) |
---|
3 | n/a | */ |
---|
4 | n/a | |
---|
5 | n/a | #include "Python.h" |
---|
6 | n/a | |
---|
7 | n/a | #ifdef MS_WINDOWS |
---|
8 | n/a | |
---|
9 | n/a | #include "..\modules\_io\_iomodule.h" |
---|
10 | n/a | |
---|
11 | n/a | #define WIN32_LEAN_AND_MEAN |
---|
12 | n/a | #include <windows.h> |
---|
13 | n/a | #include <fcntl.h> |
---|
14 | n/a | |
---|
15 | n/a | /* The full definition is in iomodule. We reproduce |
---|
16 | n/a | enough here to get the handle, which is all we want. */ |
---|
17 | n/a | typedef struct { |
---|
18 | n/a | PyObject_HEAD |
---|
19 | n/a | HANDLE handle; |
---|
20 | n/a | } winconsoleio; |
---|
21 | n/a | |
---|
22 | n/a | |
---|
23 | n/a | static int execfunc(PyObject *m) |
---|
24 | n/a | { |
---|
25 | n/a | return 0; |
---|
26 | n/a | } |
---|
27 | n/a | |
---|
28 | n/a | PyModuleDef_Slot testconsole_slots[] = { |
---|
29 | n/a | {Py_mod_exec, execfunc}, |
---|
30 | n/a | {0, NULL}, |
---|
31 | n/a | }; |
---|
32 | n/a | |
---|
33 | n/a | /*[clinic input] |
---|
34 | n/a | module _testconsole |
---|
35 | n/a | |
---|
36 | n/a | _testconsole.write_input |
---|
37 | n/a | file: object |
---|
38 | n/a | s: PyBytesObject |
---|
39 | n/a | |
---|
40 | n/a | Writes UTF-16-LE encoded bytes to the console as if typed by a user. |
---|
41 | n/a | [clinic start generated code]*/ |
---|
42 | n/a | |
---|
43 | n/a | static PyObject * |
---|
44 | n/a | _testconsole_write_input_impl(PyObject *module, PyObject *file, |
---|
45 | n/a | PyBytesObject *s) |
---|
46 | n/a | /*[clinic end generated code: output=48f9563db34aedb3 input=4c774f2d05770bc6]*/ |
---|
47 | n/a | { |
---|
48 | n/a | INPUT_RECORD *rec = NULL; |
---|
49 | n/a | |
---|
50 | n/a | if (!PyWindowsConsoleIO_Check(file)) { |
---|
51 | n/a | PyErr_SetString(PyExc_TypeError, "expected raw console object"); |
---|
52 | n/a | return NULL; |
---|
53 | n/a | } |
---|
54 | n/a | |
---|
55 | n/a | const wchar_t *p = (const wchar_t *)PyBytes_AS_STRING(s); |
---|
56 | n/a | DWORD size = (DWORD)PyBytes_GET_SIZE(s) / sizeof(wchar_t); |
---|
57 | n/a | |
---|
58 | n/a | rec = (INPUT_RECORD*)PyMem_Malloc(sizeof(INPUT_RECORD) * size); |
---|
59 | n/a | if (!rec) |
---|
60 | n/a | goto error; |
---|
61 | n/a | memset(rec, 0, sizeof(INPUT_RECORD) * size); |
---|
62 | n/a | |
---|
63 | n/a | INPUT_RECORD *prec = rec; |
---|
64 | n/a | for (DWORD i = 0; i < size; ++i, ++p, ++prec) { |
---|
65 | n/a | prec->EventType = KEY_EVENT; |
---|
66 | n/a | prec->Event.KeyEvent.bKeyDown = TRUE; |
---|
67 | n/a | prec->Event.KeyEvent.wRepeatCount = 10; |
---|
68 | n/a | prec->Event.KeyEvent.uChar.UnicodeChar = *p; |
---|
69 | n/a | } |
---|
70 | n/a | |
---|
71 | n/a | HANDLE hInput = ((winconsoleio*)file)->handle; |
---|
72 | n/a | DWORD total = 0; |
---|
73 | n/a | while (total < size) { |
---|
74 | n/a | DWORD wrote; |
---|
75 | n/a | if (!WriteConsoleInputW(hInput, &rec[total], (size - total), &wrote)) { |
---|
76 | n/a | PyErr_SetFromWindowsErr(0); |
---|
77 | n/a | goto error; |
---|
78 | n/a | } |
---|
79 | n/a | total += wrote; |
---|
80 | n/a | } |
---|
81 | n/a | |
---|
82 | n/a | PyMem_Free((void*)rec); |
---|
83 | n/a | |
---|
84 | n/a | Py_RETURN_NONE; |
---|
85 | n/a | error: |
---|
86 | n/a | if (rec) |
---|
87 | n/a | PyMem_Free((void*)rec); |
---|
88 | n/a | return NULL; |
---|
89 | n/a | } |
---|
90 | n/a | |
---|
91 | n/a | /*[clinic input] |
---|
92 | n/a | _testconsole.read_output |
---|
93 | n/a | file: object |
---|
94 | n/a | |
---|
95 | n/a | Reads a str from the console as written to stdout. |
---|
96 | n/a | [clinic start generated code]*/ |
---|
97 | n/a | |
---|
98 | n/a | static PyObject * |
---|
99 | n/a | _testconsole_read_output_impl(PyObject *module, PyObject *file) |
---|
100 | n/a | /*[clinic end generated code: output=876310d81a73e6d2 input=b3521f64b1b558e3]*/ |
---|
101 | n/a | { |
---|
102 | n/a | Py_RETURN_NONE; |
---|
103 | n/a | } |
---|
104 | n/a | |
---|
105 | n/a | #include "clinic\_testconsole.c.h" |
---|
106 | n/a | |
---|
107 | n/a | PyMethodDef testconsole_methods[] = { |
---|
108 | n/a | _TESTCONSOLE_WRITE_INPUT_METHODDEF |
---|
109 | n/a | _TESTCONSOLE_READ_OUTPUT_METHODDEF |
---|
110 | n/a | {NULL, NULL} |
---|
111 | n/a | }; |
---|
112 | n/a | |
---|
113 | n/a | static PyModuleDef testconsole_def = { |
---|
114 | n/a | PyModuleDef_HEAD_INIT, /* m_base */ |
---|
115 | n/a | "_testconsole", /* m_name */ |
---|
116 | n/a | PyDoc_STR("Test module for the Windows console"), /* m_doc */ |
---|
117 | n/a | 0, /* m_size */ |
---|
118 | n/a | testconsole_methods, /* m_methods */ |
---|
119 | n/a | testconsole_slots, /* m_slots */ |
---|
120 | n/a | NULL, /* m_traverse */ |
---|
121 | n/a | NULL, /* m_clear */ |
---|
122 | n/a | NULL, /* m_free */ |
---|
123 | n/a | }; |
---|
124 | n/a | |
---|
125 | n/a | PyMODINIT_FUNC |
---|
126 | n/a | PyInit__testconsole(PyObject *spec) |
---|
127 | n/a | { |
---|
128 | n/a | return PyModuleDef_Init(&testconsole_def); |
---|
129 | n/a | } |
---|
130 | n/a | |
---|
131 | n/a | #endif /* MS_WINDOWS */ |
---|