summaryrefslogtreecommitdiff
path: root/PC
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@microsoft.com>2016-10-03 09:12:42 -0700
committerSteve Dower <steve.dower@microsoft.com>2016-10-03 09:12:42 -0700
commitc94275f85328e340280396e0dc66288b76021fc4 (patch)
tree906c71314c0f71371da9e08cd293e4cab27d61bd /PC
parent9df4ea06252a16fb29b152c85af5f12a79ff2daf (diff)
parent3d0d1e31a864f8eac69b4fd63ccd947fb0d7c58b (diff)
downloadcpython-c94275f85328e340280396e0dc66288b76021fc4.tar.gz
Issue #28217: Adds _testconsole module to test console input.
Diffstat (limited to 'PC')
-rw-r--r--PC/_testconsole.c131
-rw-r--r--PC/clinic/_testconsole.c.h82
2 files changed, 213 insertions, 0 deletions
diff --git a/PC/_testconsole.c b/PC/_testconsole.c
new file mode 100644
index 0000000000..1c93679e43
--- /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 0000000000..93860cf5b2
--- /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]*/