diff options
author | Steve Dower <steve.dower@microsoft.com> | 2016-10-03 16:12:42 (GMT) |
---|---|---|
committer | Steve Dower <steve.dower@microsoft.com> | 2016-10-03 16:12:42 (GMT) |
commit | 4a8ff9ef6074632a682a230feababf1bec59d8f4 (patch) | |
tree | 19187bc4c7301dd5252106f7d59253f9f88a98d0 /PC | |
parent | 441e878e5b01596adfc203981eda035b08a61843 (diff) | |
parent | 312cef7452dcc8bb97ca6b20999d5db567406692 (diff) | |
download | cpython-4a8ff9ef6074632a682a230feababf1bec59d8f4.zip cpython-4a8ff9ef6074632a682a230feababf1bec59d8f4.tar.gz cpython-4a8ff9ef6074632a682a230feababf1bec59d8f4.tar.bz2 |
Issue #28217: Adds _testconsole module to test console input.
Diffstat (limited to 'PC')
-rw-r--r-- | PC/_testconsole.c | 131 | ||||
-rw-r--r-- | PC/clinic/_testconsole.c.h | 82 |
2 files changed, 213 insertions, 0 deletions
diff --git a/PC/_testconsole.c b/PC/_testconsole.c new file mode 100644 index 0000000..1c93679 --- /dev/null +++ b/PC/_testconsole.c @@ -0,0 +1,131 @@ + +/* Testing module for multi-phase initialization of extension modules (PEP 489) + */ + +#include "Python.h" + +#ifdef MS_WINDOWS + +#include "..\modules\_io\_iomodule.h" + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <fcntl.h> + + /* The full definition is in iomodule. We reproduce + enough here to get the handle, which is all we want. */ +typedef struct { + PyObject_HEAD + HANDLE handle; +} winconsoleio; + + +static int execfunc(PyObject *m) +{ + return 0; +} + +PyModuleDef_Slot testconsole_slots[] = { + {Py_mod_exec, execfunc}, + {0, NULL}, +}; + +/*[clinic input] +module _testconsole + +_testconsole.write_input + file: object + s: PyBytesObject + +Writes UTF-16-LE encoded bytes to the console as if typed by a user. +[clinic start generated code]*/ + +static PyObject * +_testconsole_write_input_impl(PyObject *module, PyObject *file, + PyBytesObject *s) +/*[clinic end generated code: output=48f9563db34aedb3 input=4c774f2d05770bc6]*/ +{ + INPUT_RECORD *rec = NULL; + + if (!PyWindowsConsoleIO_Check(file)) { + PyErr_SetString(PyExc_TypeError, "expected raw console object"); + return NULL; + } + + const wchar_t *p = (const wchar_t *)PyBytes_AS_STRING(s); + DWORD size = (DWORD)PyBytes_GET_SIZE(s) / sizeof(wchar_t); + + rec = (INPUT_RECORD*)PyMem_Malloc(sizeof(INPUT_RECORD) * size); + if (!rec) + goto error; + memset(rec, 0, sizeof(INPUT_RECORD) * size); + + INPUT_RECORD *prec = rec; + for (DWORD i = 0; i < size; ++i, ++p, ++prec) { + prec->EventType = KEY_EVENT; + prec->Event.KeyEvent.bKeyDown = TRUE; + prec->Event.KeyEvent.wRepeatCount = 10; + prec->Event.KeyEvent.uChar.UnicodeChar = *p; + } + + HANDLE hInput = ((winconsoleio*)file)->handle; + DWORD total = 0; + while (total < size) { + DWORD wrote; + if (!WriteConsoleInputW(hInput, &rec[total], (size - total), &wrote)) { + PyErr_SetFromWindowsErr(0); + goto error; + } + total += wrote; + } + + PyMem_Free((void*)rec); + + Py_RETURN_NONE; +error: + if (rec) + PyMem_Free((void*)rec); + return NULL; +} + +/*[clinic input] +_testconsole.read_output + file: object + +Reads a str from the console as written to stdout. +[clinic start generated code]*/ + +static PyObject * +_testconsole_read_output_impl(PyObject *module, PyObject *file) +/*[clinic end generated code: output=876310d81a73e6d2 input=b3521f64b1b558e3]*/ +{ + Py_RETURN_NONE; +} + +#include "clinic\_testconsole.c.h" + +PyMethodDef testconsole_methods[] = { + _TESTCONSOLE_WRITE_INPUT_METHODDEF + _TESTCONSOLE_READ_OUTPUT_METHODDEF + {NULL, NULL} +}; + +static PyModuleDef testconsole_def = { + PyModuleDef_HEAD_INIT, /* m_base */ + "_testconsole", /* m_name */ + PyDoc_STR("Test module for the Windows console"), /* m_doc */ + 0, /* m_size */ + testconsole_methods, /* m_methods */ + testconsole_slots, /* m_slots */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + +PyMODINIT_FUNC +PyInit__testconsole(PyObject *spec) +{ + return PyModuleDef_Init(&testconsole_def); +} + +#endif /* MS_WINDOWS */ diff --git a/PC/clinic/_testconsole.c.h b/PC/clinic/_testconsole.c.h new file mode 100644 index 0000000..93860cf --- /dev/null +++ b/PC/clinic/_testconsole.c.h @@ -0,0 +1,82 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_testconsole_write_input__doc__, +"write_input($module, /, file, s)\n" +"--\n" +"\n" +"Writes UTF-16-LE encoded bytes to the console as if typed by a user."); + +#define _TESTCONSOLE_WRITE_INPUT_METHODDEF \ + {"write_input", (PyCFunction)_testconsole_write_input, METH_FASTCALL, _testconsole_write_input__doc__}, + +static PyObject * +_testconsole_write_input_impl(PyObject *module, PyObject *file, + PyBytesObject *s); + +static PyObject * +_testconsole_write_input(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"file", "s", NULL}; + static _PyArg_Parser _parser = {"OS:write_input", _keywords, 0}; + PyObject *file; + PyBytesObject *s; + + if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser, + &file, &s)) { + goto exit; + } + return_value = _testconsole_write_input_impl(module, file, s); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_testconsole_read_output__doc__, +"read_output($module, /, file)\n" +"--\n" +"\n" +"Reads a str from the console as written to stdout."); + +#define _TESTCONSOLE_READ_OUTPUT_METHODDEF \ + {"read_output", (PyCFunction)_testconsole_read_output, METH_FASTCALL, _testconsole_read_output__doc__}, + +static PyObject * +_testconsole_read_output_impl(PyObject *module, PyObject *file); + +static PyObject * +_testconsole_read_output(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"file", NULL}; + static _PyArg_Parser _parser = {"O:read_output", _keywords, 0}; + PyObject *file; + + if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser, + &file)) { + goto exit; + } + return_value = _testconsole_read_output_impl(module, file); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#ifndef _TESTCONSOLE_WRITE_INPUT_METHODDEF + #define _TESTCONSOLE_WRITE_INPUT_METHODDEF +#endif /* !defined(_TESTCONSOLE_WRITE_INPUT_METHODDEF) */ + +#ifndef _TESTCONSOLE_READ_OUTPUT_METHODDEF + #define _TESTCONSOLE_READ_OUTPUT_METHODDEF +#endif /* !defined(_TESTCONSOLE_READ_OUTPUT_METHODDEF) */ +/*[clinic end generated code: output=3a8dc0c421807c41 input=a9049054013a1b77]*/ |