diff options
Diffstat (limited to 'Modules')
198 files changed, 20549 insertions, 9050 deletions
diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index 02b55d1..22ddbf2 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -12,7 +12,8 @@ static Py_ssize_t internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) { PyObject *litem; - Py_ssize_t mid, res; + Py_ssize_t mid; + int res; if (lo < 0) { PyErr_SetString(PyExc_ValueError, "lo must be non-negative"); @@ -115,7 +116,8 @@ static Py_ssize_t internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) { PyObject *litem; - Py_ssize_t mid, res; + Py_ssize_t mid; + int res; if (lo < 0) { PyErr_SetString(PyExc_ValueError, "lo must be non-negative"); diff --git a/Modules/_blake2/blake2b2s.py b/Modules/_blake2/blake2b2s.py new file mode 100755 index 0000000..01cf265 --- /dev/null +++ b/Modules/_blake2/blake2b2s.py @@ -0,0 +1,49 @@ +#!/usr/bin/python3 + +import os +import re + +HERE = os.path.dirname(os.path.abspath(__file__)) +BLAKE2 = os.path.join(HERE, 'impl') + +PUBLIC_SEARCH = re.compile(r'\ int (blake2[bs]p?[a-z_]*)\(') + + +def getfiles(): + for name in os.listdir(BLAKE2): + name = os.path.join(BLAKE2, name) + if os.path.isfile(name): + yield name + + +def find_public(): + public_funcs = set() + for name in getfiles(): + with open(name) as f: + for line in f: + # find public functions + mo = PUBLIC_SEARCH.search(line) + if mo: + public_funcs.add(mo.group(1)) + + for f in sorted(public_funcs): + print('#define {0:<18} PyBlake2_{0}'.format(f)) + + return public_funcs + + +def main(): + lines = [] + with open(os.path.join(HERE, 'blake2b_impl.c')) as f: + for line in f: + line = line.replace('blake2b', 'blake2s') + line = line.replace('BLAKE2b', 'BLAKE2s') + line = line.replace('BLAKE2B', 'BLAKE2S') + lines.append(line) + with open(os.path.join(HERE, 'blake2s_impl.c'), 'w') as f: + f.write(''.join(lines)) + # find_public() + + +if __name__ == '__main__': + main() diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c new file mode 100644 index 0000000..58b502b --- /dev/null +++ b/Modules/_blake2/blake2b_impl.c @@ -0,0 +1,460 @@ +/* + * Written in 2013 by Dmitry Chestnykh <dmitry@codingrobots.com> + * Modified for CPython by Christian Heimes <christian@python.org> + * + * To the extent possible under law, the author have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* WARNING: autogenerated file! + * + * The blake2s_impl.c is autogenerated from blake2b_impl.c. + */ + +#include "Python.h" +#include "pystrhex.h" +#ifdef WITH_THREAD +#include "pythread.h" +#endif + +#include "../hashlib.h" +#include "blake2ns.h" + +#define HAVE_BLAKE2B 1 +#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) + +#include "impl/blake2.h" +#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ + +#ifdef BLAKE2_USE_SSE +#include "impl/blake2b.c" +#else +#include "impl/blake2b-ref.c" +#endif + + +extern PyTypeObject PyBlake2_BLAKE2bType; + +typedef struct { + PyObject_HEAD + blake2b_param param; + blake2b_state state; +#ifdef WITH_THREAD + PyThread_type_lock lock; +#endif +} BLAKE2bObject; + +#include "clinic/blake2b_impl.c.h" + +/*[clinic input] +module _blake2b +class _blake2b.blake2b "BLAKE2bObject *" "&PyBlake2_BLAKE2bType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6893358c6622aecf]*/ + + +static BLAKE2bObject * +new_BLAKE2bObject(PyTypeObject *type) +{ + BLAKE2bObject *self; + self = (BLAKE2bObject *)type->tp_alloc(type, 0); +#ifdef WITH_THREAD + if (self != NULL) { + self->lock = NULL; + } +#endif + return self; +} + +/*[clinic input] +@classmethod +_blake2b.blake2b.__new__ as py_blake2b_new + string as data: object = NULL + * + digest_size: int(c_default="BLAKE2B_OUTBYTES") = _blake2b.blake2b.MAX_DIGEST_SIZE + key: Py_buffer = None + salt: Py_buffer = None + person: Py_buffer = None + fanout: int = 1 + depth: int = 1 + leaf_size as leaf_size_obj: object = NULL + node_offset as node_offset_obj: object = NULL + node_depth: int = 0 + inner_size: int = 0 + last_node: bool = False + +Return a new BLAKE2b hash object. +[clinic start generated code]*/ + +static PyObject * +py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, + int fanout, int depth, PyObject *leaf_size_obj, + PyObject *node_offset_obj, int node_depth, + int inner_size, int last_node) +/*[clinic end generated code: output=7506d8d890e5f13b input=e41548dfa0866031]*/ +{ + BLAKE2bObject *self = NULL; + Py_buffer buf; + + unsigned long leaf_size = 0; + unsigned long long node_offset = 0; + + self = new_BLAKE2bObject(type); + if (self == NULL) { + goto error; + } + + /* Zero parameter block. */ + memset(&self->param, 0, sizeof(self->param)); + + /* Set digest size. */ + if (digest_size <= 0 || digest_size > BLAKE2B_OUTBYTES) { + PyErr_Format(PyExc_ValueError, + "digest_size must be between 1 and %d bytes", + BLAKE2B_OUTBYTES); + goto error; + } + self->param.digest_length = digest_size; + + /* Set salt parameter. */ + if ((salt->obj != NULL) && salt->len) { + if (salt->len > BLAKE2B_SALTBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum salt length is %d bytes", + BLAKE2B_SALTBYTES); + goto error; + } + memcpy(self->param.salt, salt->buf, salt->len); + } + + /* Set personalization parameter. */ + if ((person->obj != NULL) && person->len) { + if (person->len > BLAKE2B_PERSONALBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum person length is %d bytes", + BLAKE2B_PERSONALBYTES); + goto error; + } + memcpy(self->param.personal, person->buf, person->len); + } + + /* Set tree parameters. */ + if (fanout < 0 || fanout > 255) { + PyErr_SetString(PyExc_ValueError, + "fanout must be between 0 and 255"); + goto error; + } + self->param.fanout = (uint8_t)fanout; + + if (depth <= 0 || depth > 255) { + PyErr_SetString(PyExc_ValueError, + "depth must be between 1 and 255"); + goto error; + } + self->param.depth = (uint8_t)depth; + + if (leaf_size_obj != NULL) { + leaf_size = PyLong_AsUnsignedLong(leaf_size_obj); + if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) { + goto error; + } + if (leaf_size > 0xFFFFFFFFU) { + PyErr_SetString(PyExc_OverflowError, "leaf_size is too large"); + goto error; + } + } + self->param.leaf_length = (unsigned int)leaf_size; + + if (node_offset_obj != NULL) { + node_offset = PyLong_AsUnsignedLongLong(node_offset_obj); + if (node_offset == (unsigned long long) -1 && PyErr_Occurred()) { + goto error; + } + } +#ifdef HAVE_BLAKE2S + if (node_offset > 0xFFFFFFFFFFFFULL) { + /* maximum 2**48 - 1 */ + PyErr_SetString(PyExc_OverflowError, "node_offset is too large"); + goto error; + } + store48(&(self->param.node_offset), node_offset); +#else + self->param.node_offset = node_offset; +#endif + + if (node_depth < 0 || node_depth > 255) { + PyErr_SetString(PyExc_ValueError, + "node_depth must be between 0 and 255"); + goto error; + } + self->param.node_depth = node_depth; + + if (inner_size < 0 || inner_size > BLAKE2B_OUTBYTES) { + PyErr_Format(PyExc_ValueError, + "inner_size must be between 0 and is %d", + BLAKE2B_OUTBYTES); + goto error; + } + self->param.inner_length = inner_size; + + /* Set key length. */ + if ((key->obj != NULL) && key->len) { + if (key->len > BLAKE2B_KEYBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum key length is %d bytes", + BLAKE2B_KEYBYTES); + goto error; + } + self->param.key_length = (uint8_t)key->len; + } + + /* Initialize hash state. */ + if (blake2b_init_param(&self->state, &self->param) < 0) { + PyErr_SetString(PyExc_RuntimeError, + "error initializing hash state"); + goto error; + } + + /* Set last node flag (must come after initialization). */ + self->state.last_node = last_node; + + /* Process key block if any. */ + if (self->param.key_length) { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset(block, 0, sizeof(block)); + memcpy(block, key->buf, key->len); + blake2b_update(&self->state, block, sizeof(block)); + secure_zero_memory(block, sizeof(block)); + } + + /* Process initial data if any. */ + if (data != NULL) { + GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); + + if (buf.len >= HASHLIB_GIL_MINSIZE) { + Py_BEGIN_ALLOW_THREADS + blake2b_update(&self->state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + blake2b_update(&self->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)self; + + error: + if (self != NULL) { + Py_DECREF(self); + } + return NULL; +} + +/*[clinic input] +_blake2b.blake2b.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +_blake2b_blake2b_copy_impl(BLAKE2bObject *self) +/*[clinic end generated code: output=c89cd33550ab1543 input=4c9c319f18f10747]*/ +{ + BLAKE2bObject *cpy; + + if ((cpy = new_BLAKE2bObject(Py_TYPE(self))) == NULL) + return NULL; + + ENTER_HASHLIB(self); + cpy->param = self->param; + cpy->state = self->state; + LEAVE_HASHLIB(self); + return (PyObject *)cpy; +} + +/*[clinic input] +_blake2b.blake2b.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +_blake2b_blake2b_update(BLAKE2bObject *self, PyObject *obj) +/*[clinic end generated code: output=a888f07c4cddbe94 input=3ecb8c13ee4260f2]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + +#ifdef WITH_THREAD + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) + self->lock = PyThread_allocate_lock(); + + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + blake2b_update(&self->state, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + blake2b_update(&self->state, buf.buf, buf.len); + } +#else + blake2b_update(&self->state, buf.buf, buf.len); +#endif /* !WITH_THREAD */ + PyBuffer_Release(&buf); + + Py_INCREF(Py_None); + return Py_None; +} + +/*[clinic input] +_blake2b.blake2b.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ + +static PyObject * +_blake2b_blake2b_digest_impl(BLAKE2bObject *self) +/*[clinic end generated code: output=b13a79360d984740 input=ac2fa462ebb1b9c7]*/ +{ + uint8_t digest[BLAKE2B_OUTBYTES]; + blake2b_state state_cpy; + + ENTER_HASHLIB(self); + state_cpy = self->state; + blake2b_final(&state_cpy, digest, self->param.digest_length); + LEAVE_HASHLIB(self); + return PyBytes_FromStringAndSize((const char *)digest, + self->param.digest_length); +} + +/*[clinic input] +_blake2b.blake2b.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +_blake2b_blake2b_hexdigest_impl(BLAKE2bObject *self) +/*[clinic end generated code: output=6a503611715b24bd input=d58f0b2f37812e33]*/ +{ + uint8_t digest[BLAKE2B_OUTBYTES]; + blake2b_state state_cpy; + + ENTER_HASHLIB(self); + state_cpy = self->state; + blake2b_final(&state_cpy, digest, self->param.digest_length); + LEAVE_HASHLIB(self); + return _Py_strhex((const char *)digest, self->param.digest_length); +} + + +static PyMethodDef py_blake2b_methods[] = { + _BLAKE2B_BLAKE2B_COPY_METHODDEF + _BLAKE2B_BLAKE2B_DIGEST_METHODDEF + _BLAKE2B_BLAKE2B_HEXDIGEST_METHODDEF + _BLAKE2B_BLAKE2B_UPDATE_METHODDEF + {NULL, NULL} +}; + + + +static PyObject * +py_blake2b_get_name(BLAKE2bObject *self, void *closure) +{ + return PyUnicode_FromString("blake2b"); +} + + + +static PyObject * +py_blake2b_get_block_size(BLAKE2bObject *self, void *closure) +{ + return PyLong_FromLong(BLAKE2B_BLOCKBYTES); +} + + + +static PyObject * +py_blake2b_get_digest_size(BLAKE2bObject *self, void *closure) +{ + return PyLong_FromLong(self->param.digest_length); +} + + +static PyGetSetDef py_blake2b_getsetters[] = { + {"name", (getter)py_blake2b_get_name, + NULL, NULL, NULL}, + {"block_size", (getter)py_blake2b_get_block_size, + NULL, NULL, NULL}, + {"digest_size", (getter)py_blake2b_get_digest_size, + NULL, NULL, NULL}, + {NULL} +}; + + +static void +py_blake2b_dealloc(PyObject *self) +{ + BLAKE2bObject *obj = (BLAKE2bObject *)self; + + /* Try not to leave state in memory. */ + secure_zero_memory(&obj->param, sizeof(obj->param)); + secure_zero_memory(&obj->state, sizeof(obj->state)); +#ifdef WITH_THREAD + if (obj->lock) { + PyThread_free_lock(obj->lock); + obj->lock = NULL; + } +#endif + PyObject_Del(self); +} + + +PyTypeObject PyBlake2_BLAKE2bType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_blake2.blake2b", /* tp_name */ + sizeof(BLAKE2bObject), /* tp_size */ + 0, /* tp_itemsize */ + py_blake2b_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + py_blake2b_new__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + py_blake2b_methods, /* tp_methods */ + 0, /* tp_members */ + py_blake2b_getsetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + py_blake2b_new, /* tp_new */ +}; diff --git a/Modules/_blake2/blake2module.c b/Modules/_blake2/blake2module.c new file mode 100644 index 0000000..e2a3d42 --- /dev/null +++ b/Modules/_blake2/blake2module.c @@ -0,0 +1,105 @@ +/* + * Written in 2013 by Dmitry Chestnykh <dmitry@codingrobots.com> + * Modified for CPython by Christian Heimes <christian@python.org> + * + * To the extent possible under law, the author have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. http://creativecommons.org/publicdomain/zero/1.0/ + */ + +#include "Python.h" + +#include "impl/blake2.h" + +extern PyTypeObject PyBlake2_BLAKE2bType; +extern PyTypeObject PyBlake2_BLAKE2sType; + + +PyDoc_STRVAR(blake2mod__doc__, +"_blake2b provides BLAKE2b for hashlib\n" +); + + +static struct PyMethodDef blake2mod_functions[] = { + {NULL, NULL} +}; + +static struct PyModuleDef blake2_module = { + PyModuleDef_HEAD_INIT, + "_blake2", + blake2mod__doc__, + -1, + blake2mod_functions, + NULL, + NULL, + NULL, + NULL +}; + +#define ADD_INT(d, name, value) do { \ + PyObject *x = PyLong_FromLong(value); \ + if (!x) { \ + Py_DECREF(m); \ + return NULL; \ + } \ + if (PyDict_SetItemString(d, name, x) < 0) { \ + Py_DECREF(m); \ + return NULL; \ + } \ + Py_DECREF(x); \ +} while(0) + + +PyMODINIT_FUNC +PyInit__blake2(void) +{ + PyObject *m; + PyObject *d; + + m = PyModule_Create(&blake2_module); + if (m == NULL) + return NULL; + + /* BLAKE2b */ + Py_TYPE(&PyBlake2_BLAKE2bType) = &PyType_Type; + if (PyType_Ready(&PyBlake2_BLAKE2bType) < 0) { + return NULL; + } + + Py_INCREF(&PyBlake2_BLAKE2bType); + PyModule_AddObject(m, "blake2b", (PyObject *)&PyBlake2_BLAKE2bType); + + d = PyBlake2_BLAKE2bType.tp_dict; + ADD_INT(d, "SALT_SIZE", BLAKE2B_SALTBYTES); + ADD_INT(d, "PERSON_SIZE", BLAKE2B_PERSONALBYTES); + ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES); + ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); + + PyModule_AddIntConstant(m, "BLAKE2B_SALT_SIZE", BLAKE2B_SALTBYTES); + PyModule_AddIntConstant(m, "BLAKE2B_PERSON_SIZE", BLAKE2B_PERSONALBYTES); + PyModule_AddIntConstant(m, "BLAKE2B_MAX_KEY_SIZE", BLAKE2B_KEYBYTES); + PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); + + /* BLAKE2s */ + Py_TYPE(&PyBlake2_BLAKE2sType) = &PyType_Type; + if (PyType_Ready(&PyBlake2_BLAKE2sType) < 0) { + return NULL; + } + + Py_INCREF(&PyBlake2_BLAKE2sType); + PyModule_AddObject(m, "blake2s", (PyObject *)&PyBlake2_BLAKE2sType); + + d = PyBlake2_BLAKE2sType.tp_dict; + ADD_INT(d, "SALT_SIZE", BLAKE2S_SALTBYTES); + ADD_INT(d, "PERSON_SIZE", BLAKE2S_PERSONALBYTES); + ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES); + ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); + + PyModule_AddIntConstant(m, "BLAKE2S_SALT_SIZE", BLAKE2S_SALTBYTES); + PyModule_AddIntConstant(m, "BLAKE2S_PERSON_SIZE", BLAKE2S_PERSONALBYTES); + PyModule_AddIntConstant(m, "BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES); + PyModule_AddIntConstant(m, "BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); + + return m; +} diff --git a/Modules/_blake2/blake2ns.h b/Modules/_blake2/blake2ns.h new file mode 100644 index 0000000..53bce8e --- /dev/null +++ b/Modules/_blake2/blake2ns.h @@ -0,0 +1,32 @@ +/* Prefix all public blake2 symbols with PyBlake2_ + */ + +#ifndef Py_BLAKE2_NS +#define Py_BLAKE2_NS + +#define blake2b PyBlake2_blake2b +#define blake2b_compress PyBlake2_blake2b_compress +#define blake2b_final PyBlake2_blake2b_final +#define blake2b_init PyBlake2_blake2b_init +#define blake2b_init_key PyBlake2_blake2b_init_key +#define blake2b_init_param PyBlake2_blake2b_init_param +#define blake2b_update PyBlake2_blake2b_update +#define blake2bp PyBlake2_blake2bp +#define blake2bp_final PyBlake2_blake2bp_final +#define blake2bp_init PyBlake2_blake2bp_init +#define blake2bp_init_key PyBlake2_blake2bp_init_key +#define blake2bp_update PyBlake2_blake2bp_update +#define blake2s PyBlake2_blake2s +#define blake2s_compress PyBlake2_blake2s_compress +#define blake2s_final PyBlake2_blake2s_final +#define blake2s_init PyBlake2_blake2s_init +#define blake2s_init_key PyBlake2_blake2s_init_key +#define blake2s_init_param PyBlake2_blake2s_init_param +#define blake2s_update PyBlake2_blake2s_update +#define blake2sp PyBlake2_blake2sp +#define blake2sp_final PyBlake2_blake2sp_final +#define blake2sp_init PyBlake2_blake2sp_init +#define blake2sp_init_key PyBlake2_blake2sp_init_key +#define blake2sp_update PyBlake2_blake2sp_update + +#endif /* Py_BLAKE2_NS */ diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c new file mode 100644 index 0000000..11d2e02 --- /dev/null +++ b/Modules/_blake2/blake2s_impl.c @@ -0,0 +1,460 @@ +/* + * Written in 2013 by Dmitry Chestnykh <dmitry@codingrobots.com> + * Modified for CPython by Christian Heimes <christian@python.org> + * + * To the extent possible under law, the author have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* WARNING: autogenerated file! + * + * The blake2s_impl.c is autogenerated from blake2s_impl.c. + */ + +#include "Python.h" +#include "pystrhex.h" +#ifdef WITH_THREAD +#include "pythread.h" +#endif + +#include "../hashlib.h" +#include "blake2ns.h" + +#define HAVE_BLAKE2S 1 +#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) + +#include "impl/blake2.h" +#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ + +#ifdef BLAKE2_USE_SSE +#include "impl/blake2s.c" +#else +#include "impl/blake2s-ref.c" +#endif + + +extern PyTypeObject PyBlake2_BLAKE2sType; + +typedef struct { + PyObject_HEAD + blake2s_param param; + blake2s_state state; +#ifdef WITH_THREAD + PyThread_type_lock lock; +#endif +} BLAKE2sObject; + +#include "clinic/blake2s_impl.c.h" + +/*[clinic input] +module _blake2s +class _blake2s.blake2s "BLAKE2sObject *" "&PyBlake2_BLAKE2sType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=edbfcf7557a685a7]*/ + + +static BLAKE2sObject * +new_BLAKE2sObject(PyTypeObject *type) +{ + BLAKE2sObject *self; + self = (BLAKE2sObject *)type->tp_alloc(type, 0); +#ifdef WITH_THREAD + if (self != NULL) { + self->lock = NULL; + } +#endif + return self; +} + +/*[clinic input] +@classmethod +_blake2s.blake2s.__new__ as py_blake2s_new + string as data: object = NULL + * + digest_size: int(c_default="BLAKE2S_OUTBYTES") = _blake2s.blake2s.MAX_DIGEST_SIZE + key: Py_buffer = None + salt: Py_buffer = None + person: Py_buffer = None + fanout: int = 1 + depth: int = 1 + leaf_size as leaf_size_obj: object = NULL + node_offset as node_offset_obj: object = NULL + node_depth: int = 0 + inner_size: int = 0 + last_node: bool = False + +Return a new BLAKE2s hash object. +[clinic start generated code]*/ + +static PyObject * +py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, + int fanout, int depth, PyObject *leaf_size_obj, + PyObject *node_offset_obj, int node_depth, + int inner_size, int last_node) +/*[clinic end generated code: output=fe060b258a8cbfc6 input=458cfdcb3d0d47ff]*/ +{ + BLAKE2sObject *self = NULL; + Py_buffer buf; + + unsigned long leaf_size = 0; + unsigned long long node_offset = 0; + + self = new_BLAKE2sObject(type); + if (self == NULL) { + goto error; + } + + /* Zero parameter block. */ + memset(&self->param, 0, sizeof(self->param)); + + /* Set digest size. */ + if (digest_size <= 0 || digest_size > BLAKE2S_OUTBYTES) { + PyErr_Format(PyExc_ValueError, + "digest_size must be between 1 and %d bytes", + BLAKE2S_OUTBYTES); + goto error; + } + self->param.digest_length = digest_size; + + /* Set salt parameter. */ + if ((salt->obj != NULL) && salt->len) { + if (salt->len > BLAKE2S_SALTBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum salt length is %d bytes", + BLAKE2S_SALTBYTES); + goto error; + } + memcpy(self->param.salt, salt->buf, salt->len); + } + + /* Set personalization parameter. */ + if ((person->obj != NULL) && person->len) { + if (person->len > BLAKE2S_PERSONALBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum person length is %d bytes", + BLAKE2S_PERSONALBYTES); + goto error; + } + memcpy(self->param.personal, person->buf, person->len); + } + + /* Set tree parameters. */ + if (fanout < 0 || fanout > 255) { + PyErr_SetString(PyExc_ValueError, + "fanout must be between 0 and 255"); + goto error; + } + self->param.fanout = (uint8_t)fanout; + + if (depth <= 0 || depth > 255) { + PyErr_SetString(PyExc_ValueError, + "depth must be between 1 and 255"); + goto error; + } + self->param.depth = (uint8_t)depth; + + if (leaf_size_obj != NULL) { + leaf_size = PyLong_AsUnsignedLong(leaf_size_obj); + if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) { + goto error; + } + if (leaf_size > 0xFFFFFFFFU) { + PyErr_SetString(PyExc_OverflowError, "leaf_size is too large"); + goto error; + } + } + self->param.leaf_length = (unsigned int)leaf_size; + + if (node_offset_obj != NULL) { + node_offset = PyLong_AsUnsignedLongLong(node_offset_obj); + if (node_offset == (unsigned long long) -1 && PyErr_Occurred()) { + goto error; + } + } +#ifdef HAVE_BLAKE2S + if (node_offset > 0xFFFFFFFFFFFFULL) { + /* maximum 2**48 - 1 */ + PyErr_SetString(PyExc_OverflowError, "node_offset is too large"); + goto error; + } + store48(&(self->param.node_offset), node_offset); +#else + self->param.node_offset = node_offset; +#endif + + if (node_depth < 0 || node_depth > 255) { + PyErr_SetString(PyExc_ValueError, + "node_depth must be between 0 and 255"); + goto error; + } + self->param.node_depth = node_depth; + + if (inner_size < 0 || inner_size > BLAKE2S_OUTBYTES) { + PyErr_Format(PyExc_ValueError, + "inner_size must be between 0 and is %d", + BLAKE2S_OUTBYTES); + goto error; + } + self->param.inner_length = inner_size; + + /* Set key length. */ + if ((key->obj != NULL) && key->len) { + if (key->len > BLAKE2S_KEYBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum key length is %d bytes", + BLAKE2S_KEYBYTES); + goto error; + } + self->param.key_length = (uint8_t)key->len; + } + + /* Initialize hash state. */ + if (blake2s_init_param(&self->state, &self->param) < 0) { + PyErr_SetString(PyExc_RuntimeError, + "error initializing hash state"); + goto error; + } + + /* Set last node flag (must come after initialization). */ + self->state.last_node = last_node; + + /* Process key block if any. */ + if (self->param.key_length) { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset(block, 0, sizeof(block)); + memcpy(block, key->buf, key->len); + blake2s_update(&self->state, block, sizeof(block)); + secure_zero_memory(block, sizeof(block)); + } + + /* Process initial data if any. */ + if (data != NULL) { + GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); + + if (buf.len >= HASHLIB_GIL_MINSIZE) { + Py_BEGIN_ALLOW_THREADS + blake2s_update(&self->state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + blake2s_update(&self->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)self; + + error: + if (self != NULL) { + Py_DECREF(self); + } + return NULL; +} + +/*[clinic input] +_blake2s.blake2s.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +_blake2s_blake2s_copy_impl(BLAKE2sObject *self) +/*[clinic end generated code: output=6c5bada404b7aed7 input=c8858e887ae4a07a]*/ +{ + BLAKE2sObject *cpy; + + if ((cpy = new_BLAKE2sObject(Py_TYPE(self))) == NULL) + return NULL; + + ENTER_HASHLIB(self); + cpy->param = self->param; + cpy->state = self->state; + LEAVE_HASHLIB(self); + return (PyObject *)cpy; +} + +/*[clinic input] +_blake2s.blake2s.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +_blake2s_blake2s_update(BLAKE2sObject *self, PyObject *obj) +/*[clinic end generated code: output=fe8438a1d3cede87 input=47a408b9a3cc05c5]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + +#ifdef WITH_THREAD + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) + self->lock = PyThread_allocate_lock(); + + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + blake2s_update(&self->state, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + blake2s_update(&self->state, buf.buf, buf.len); + } +#else + blake2s_update(&self->state, buf.buf, buf.len); +#endif /* !WITH_THREAD */ + PyBuffer_Release(&buf); + + Py_INCREF(Py_None); + return Py_None; +} + +/*[clinic input] +_blake2s.blake2s.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ + +static PyObject * +_blake2s_blake2s_digest_impl(BLAKE2sObject *self) +/*[clinic end generated code: output=80e81a48c6f79cf9 input=feb9a220135bdeba]*/ +{ + uint8_t digest[BLAKE2S_OUTBYTES]; + blake2s_state state_cpy; + + ENTER_HASHLIB(self); + state_cpy = self->state; + blake2s_final(&state_cpy, digest, self->param.digest_length); + LEAVE_HASHLIB(self); + return PyBytes_FromStringAndSize((const char *)digest, + self->param.digest_length); +} + +/*[clinic input] +_blake2s.blake2s.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +_blake2s_blake2s_hexdigest_impl(BLAKE2sObject *self) +/*[clinic end generated code: output=db6c5028c0a3c2e5 input=4e4877b8bd7aea91]*/ +{ + uint8_t digest[BLAKE2S_OUTBYTES]; + blake2s_state state_cpy; + + ENTER_HASHLIB(self); + state_cpy = self->state; + blake2s_final(&state_cpy, digest, self->param.digest_length); + LEAVE_HASHLIB(self); + return _Py_strhex((const char *)digest, self->param.digest_length); +} + + +static PyMethodDef py_blake2s_methods[] = { + _BLAKE2S_BLAKE2S_COPY_METHODDEF + _BLAKE2S_BLAKE2S_DIGEST_METHODDEF + _BLAKE2S_BLAKE2S_HEXDIGEST_METHODDEF + _BLAKE2S_BLAKE2S_UPDATE_METHODDEF + {NULL, NULL} +}; + + + +static PyObject * +py_blake2s_get_name(BLAKE2sObject *self, void *closure) +{ + return PyUnicode_FromString("blake2s"); +} + + + +static PyObject * +py_blake2s_get_block_size(BLAKE2sObject *self, void *closure) +{ + return PyLong_FromLong(BLAKE2S_BLOCKBYTES); +} + + + +static PyObject * +py_blake2s_get_digest_size(BLAKE2sObject *self, void *closure) +{ + return PyLong_FromLong(self->param.digest_length); +} + + +static PyGetSetDef py_blake2s_getsetters[] = { + {"name", (getter)py_blake2s_get_name, + NULL, NULL, NULL}, + {"block_size", (getter)py_blake2s_get_block_size, + NULL, NULL, NULL}, + {"digest_size", (getter)py_blake2s_get_digest_size, + NULL, NULL, NULL}, + {NULL} +}; + + +static void +py_blake2s_dealloc(PyObject *self) +{ + BLAKE2sObject *obj = (BLAKE2sObject *)self; + + /* Try not to leave state in memory. */ + secure_zero_memory(&obj->param, sizeof(obj->param)); + secure_zero_memory(&obj->state, sizeof(obj->state)); +#ifdef WITH_THREAD + if (obj->lock) { + PyThread_free_lock(obj->lock); + obj->lock = NULL; + } +#endif + PyObject_Del(self); +} + + +PyTypeObject PyBlake2_BLAKE2sType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_blake2.blake2s", /* tp_name */ + sizeof(BLAKE2sObject), /* tp_size */ + 0, /* tp_itemsize */ + py_blake2s_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + py_blake2s_new__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + py_blake2s_methods, /* tp_methods */ + 0, /* tp_members */ + py_blake2s_getsetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + py_blake2s_new, /* tp_new */ +}; diff --git a/Modules/_blake2/clinic/blake2b_impl.c.h b/Modules/_blake2/clinic/blake2b_impl.c.h new file mode 100644 index 0000000..71c073a --- /dev/null +++ b/Modules/_blake2/clinic/blake2b_impl.c.h @@ -0,0 +1,125 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(py_blake2b_new__doc__, +"blake2b(string=None, *, digest_size=_blake2b.blake2b.MAX_DIGEST_SIZE,\n" +" key=None, salt=None, person=None, fanout=1, depth=1,\n" +" leaf_size=None, node_offset=None, node_depth=0, inner_size=0,\n" +" last_node=False)\n" +"--\n" +"\n" +"Return a new BLAKE2b hash object."); + +static PyObject * +py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, + int fanout, int depth, PyObject *leaf_size_obj, + PyObject *node_offset_obj, int node_depth, + int inner_size, int last_node); + +static PyObject * +py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", NULL}; + static _PyArg_Parser _parser = {"|O$iy*y*y*iiOOiip:blake2b", _keywords, 0}; + PyObject *data = NULL; + int digest_size = BLAKE2B_OUTBYTES; + Py_buffer key = {NULL, NULL}; + Py_buffer salt = {NULL, NULL}; + Py_buffer person = {NULL, NULL}; + int fanout = 1; + int depth = 1; + PyObject *leaf_size_obj = NULL; + PyObject *node_offset_obj = NULL; + int node_depth = 0; + int inner_size = 0; + int last_node = 0; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, &digest_size, &key, &salt, &person, &fanout, &depth, &leaf_size_obj, &node_offset_obj, &node_depth, &inner_size, &last_node)) { + goto exit; + } + return_value = py_blake2b_new_impl(type, data, digest_size, &key, &salt, &person, fanout, depth, leaf_size_obj, node_offset_obj, node_depth, inner_size, last_node); + +exit: + /* Cleanup for key */ + if (key.obj) { + PyBuffer_Release(&key); + } + /* Cleanup for salt */ + if (salt.obj) { + PyBuffer_Release(&salt); + } + /* Cleanup for person */ + if (person.obj) { + PyBuffer_Release(&person); + } + + return return_value; +} + +PyDoc_STRVAR(_blake2b_blake2b_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define _BLAKE2B_BLAKE2B_COPY_METHODDEF \ + {"copy", (PyCFunction)_blake2b_blake2b_copy, METH_NOARGS, _blake2b_blake2b_copy__doc__}, + +static PyObject * +_blake2b_blake2b_copy_impl(BLAKE2bObject *self); + +static PyObject * +_blake2b_blake2b_copy(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2b_blake2b_copy_impl(self); +} + +PyDoc_STRVAR(_blake2b_blake2b_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define _BLAKE2B_BLAKE2B_UPDATE_METHODDEF \ + {"update", (PyCFunction)_blake2b_blake2b_update, METH_O, _blake2b_blake2b_update__doc__}, + +PyDoc_STRVAR(_blake2b_blake2b_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of binary data."); + +#define _BLAKE2B_BLAKE2B_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_blake2b_blake2b_digest, METH_NOARGS, _blake2b_blake2b_digest__doc__}, + +static PyObject * +_blake2b_blake2b_digest_impl(BLAKE2bObject *self); + +static PyObject * +_blake2b_blake2b_digest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2b_blake2b_digest_impl(self); +} + +PyDoc_STRVAR(_blake2b_blake2b_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define _BLAKE2B_BLAKE2B_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_blake2b_blake2b_hexdigest, METH_NOARGS, _blake2b_blake2b_hexdigest__doc__}, + +static PyObject * +_blake2b_blake2b_hexdigest_impl(BLAKE2bObject *self); + +static PyObject * +_blake2b_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2b_blake2b_hexdigest_impl(self); +} +/*[clinic end generated code: output=535a54852c98e51c input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/clinic/blake2s_impl.c.h b/Modules/_blake2/clinic/blake2s_impl.c.h new file mode 100644 index 0000000..ca908d3 --- /dev/null +++ b/Modules/_blake2/clinic/blake2s_impl.c.h @@ -0,0 +1,125 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(py_blake2s_new__doc__, +"blake2s(string=None, *, digest_size=_blake2s.blake2s.MAX_DIGEST_SIZE,\n" +" key=None, salt=None, person=None, fanout=1, depth=1,\n" +" leaf_size=None, node_offset=None, node_depth=0, inner_size=0,\n" +" last_node=False)\n" +"--\n" +"\n" +"Return a new BLAKE2s hash object."); + +static PyObject * +py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, + int fanout, int depth, PyObject *leaf_size_obj, + PyObject *node_offset_obj, int node_depth, + int inner_size, int last_node); + +static PyObject * +py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", NULL}; + static _PyArg_Parser _parser = {"|O$iy*y*y*iiOOiip:blake2s", _keywords, 0}; + PyObject *data = NULL; + int digest_size = BLAKE2S_OUTBYTES; + Py_buffer key = {NULL, NULL}; + Py_buffer salt = {NULL, NULL}; + Py_buffer person = {NULL, NULL}; + int fanout = 1; + int depth = 1; + PyObject *leaf_size_obj = NULL; + PyObject *node_offset_obj = NULL; + int node_depth = 0; + int inner_size = 0; + int last_node = 0; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, &digest_size, &key, &salt, &person, &fanout, &depth, &leaf_size_obj, &node_offset_obj, &node_depth, &inner_size, &last_node)) { + goto exit; + } + return_value = py_blake2s_new_impl(type, data, digest_size, &key, &salt, &person, fanout, depth, leaf_size_obj, node_offset_obj, node_depth, inner_size, last_node); + +exit: + /* Cleanup for key */ + if (key.obj) { + PyBuffer_Release(&key); + } + /* Cleanup for salt */ + if (salt.obj) { + PyBuffer_Release(&salt); + } + /* Cleanup for person */ + if (person.obj) { + PyBuffer_Release(&person); + } + + return return_value; +} + +PyDoc_STRVAR(_blake2s_blake2s_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define _BLAKE2S_BLAKE2S_COPY_METHODDEF \ + {"copy", (PyCFunction)_blake2s_blake2s_copy, METH_NOARGS, _blake2s_blake2s_copy__doc__}, + +static PyObject * +_blake2s_blake2s_copy_impl(BLAKE2sObject *self); + +static PyObject * +_blake2s_blake2s_copy(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2s_blake2s_copy_impl(self); +} + +PyDoc_STRVAR(_blake2s_blake2s_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define _BLAKE2S_BLAKE2S_UPDATE_METHODDEF \ + {"update", (PyCFunction)_blake2s_blake2s_update, METH_O, _blake2s_blake2s_update__doc__}, + +PyDoc_STRVAR(_blake2s_blake2s_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of binary data."); + +#define _BLAKE2S_BLAKE2S_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_blake2s_blake2s_digest, METH_NOARGS, _blake2s_blake2s_digest__doc__}, + +static PyObject * +_blake2s_blake2s_digest_impl(BLAKE2sObject *self); + +static PyObject * +_blake2s_blake2s_digest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2s_blake2s_digest_impl(self); +} + +PyDoc_STRVAR(_blake2s_blake2s_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define _BLAKE2S_BLAKE2S_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_blake2s_blake2s_hexdigest, METH_NOARGS, _blake2s_blake2s_hexdigest__doc__}, + +static PyObject * +_blake2s_blake2s_hexdigest_impl(BLAKE2sObject *self); + +static PyObject * +_blake2s_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2s_blake2s_hexdigest_impl(self); +} +/*[clinic end generated code: output=535ea7903f9ccf76 input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/impl/blake2-config.h b/Modules/_blake2/impl/blake2-config.h new file mode 100644 index 0000000..40455b1 --- /dev/null +++ b/Modules/_blake2/impl/blake2-config.h @@ -0,0 +1,74 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2_CONFIG_H__ +#define __BLAKE2_CONFIG_H__ + +/* These don't work everywhere */ +#if defined(__SSE2__) || defined(__x86_64__) || defined(__amd64__) +#define HAVE_SSE2 +#endif + +#if defined(__SSSE3__) +#define HAVE_SSSE3 +#endif + +#if defined(__SSE4_1__) +#define HAVE_SSE41 +#endif + +#if defined(__AVX__) +#define HAVE_AVX +#endif + +#if defined(__XOP__) +#define HAVE_XOP +#endif + + +#ifdef HAVE_AVX2 +#ifndef HAVE_AVX +#define HAVE_AVX +#endif +#endif + +#ifdef HAVE_XOP +#ifndef HAVE_AVX +#define HAVE_AVX +#endif +#endif + +#ifdef HAVE_AVX +#ifndef HAVE_SSE41 +#define HAVE_SSE41 +#endif +#endif + +#ifdef HAVE_SSE41 +#ifndef HAVE_SSSE3 +#define HAVE_SSSE3 +#endif +#endif + +#ifdef HAVE_SSSE3 +#define HAVE_SSE2 +#endif + +#if !defined(HAVE_SSE2) +#error "This code requires at least SSE2." +#endif + +#endif + diff --git a/Modules/_blake2/impl/blake2-impl.h b/Modules/_blake2/impl/blake2-impl.h new file mode 100644 index 0000000..bbe3c0f --- /dev/null +++ b/Modules/_blake2/impl/blake2-impl.h @@ -0,0 +1,139 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2_IMPL_H__ +#define __BLAKE2_IMPL_H__ + +#include <stdint.h> +#include <string.h> + +BLAKE2_LOCAL_INLINE(uint32_t) load32( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + uint32_t w = *p++; + w |= ( uint32_t )( *p++ ) << 8; + w |= ( uint32_t )( *p++ ) << 16; + w |= ( uint32_t )( *p++ ) << 24; + return w; +#endif +} + +BLAKE2_LOCAL_INLINE(uint64_t) load64( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + uint64_t w = *p++; + w |= ( uint64_t )( *p++ ) << 8; + w |= ( uint64_t )( *p++ ) << 16; + w |= ( uint64_t )( *p++ ) << 24; + w |= ( uint64_t )( *p++ ) << 32; + w |= ( uint64_t )( *p++ ) << 40; + w |= ( uint64_t )( *p++ ) << 48; + w |= ( uint64_t )( *p++ ) << 56; + return w; +#endif +} + +BLAKE2_LOCAL_INLINE(void) store32( void *dst, uint32_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + +BLAKE2_LOCAL_INLINE(void) store64( void *dst, uint64_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + +BLAKE2_LOCAL_INLINE(uint64_t) load48( const void *src ) +{ + const uint8_t *p = ( const uint8_t * )src; + uint64_t w = *p++; + w |= ( uint64_t )( *p++ ) << 8; + w |= ( uint64_t )( *p++ ) << 16; + w |= ( uint64_t )( *p++ ) << 24; + w |= ( uint64_t )( *p++ ) << 32; + w |= ( uint64_t )( *p++ ) << 40; + return w; +} + +BLAKE2_LOCAL_INLINE(void) store48( void *dst, uint64_t w ) +{ + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +} + +BLAKE2_LOCAL_INLINE(uint32_t) rotl32( const uint32_t w, const unsigned c ) +{ + return ( w << c ) | ( w >> ( 32 - c ) ); +} + +BLAKE2_LOCAL_INLINE(uint64_t) rotl64( const uint64_t w, const unsigned c ) +{ + return ( w << c ) | ( w >> ( 64 - c ) ); +} + +BLAKE2_LOCAL_INLINE(uint32_t) rotr32( const uint32_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 32 - c ) ); +} + +BLAKE2_LOCAL_INLINE(uint64_t) rotr64( const uint64_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 64 - c ) ); +} + +/* prevents compiler optimizing out memset() */ +BLAKE2_LOCAL_INLINE(void) secure_zero_memory(void *v, size_t n) +{ + static void *(*const volatile memset_v)(void *, int, size_t) = &memset; + memset_v(v, 0, n); +} + +#endif + diff --git a/Modules/_blake2/impl/blake2.h b/Modules/_blake2/impl/blake2.h new file mode 100644 index 0000000..1a9fdf4 --- /dev/null +++ b/Modules/_blake2/impl/blake2.h @@ -0,0 +1,161 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2_H__ +#define __BLAKE2_H__ + +#include <stddef.h> +#include <stdint.h> + +#ifdef BLAKE2_NO_INLINE +#define BLAKE2_LOCAL_INLINE(type) static type +#endif + +#ifndef BLAKE2_LOCAL_INLINE +#define BLAKE2_LOCAL_INLINE(type) static inline type +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + enum blake2s_constant + { + BLAKE2S_BLOCKBYTES = 64, + BLAKE2S_OUTBYTES = 32, + BLAKE2S_KEYBYTES = 32, + BLAKE2S_SALTBYTES = 8, + BLAKE2S_PERSONALBYTES = 8 + }; + + enum blake2b_constant + { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 + }; + + typedef struct __blake2s_state + { + uint32_t h[8]; + uint32_t t[2]; + uint32_t f[2]; + uint8_t buf[2 * BLAKE2S_BLOCKBYTES]; + size_t buflen; + uint8_t last_node; + } blake2s_state; + + typedef struct __blake2b_state + { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[2 * BLAKE2B_BLOCKBYTES]; + size_t buflen; + uint8_t last_node; + } blake2b_state; + + typedef struct __blake2sp_state + { + blake2s_state S[8][1]; + blake2s_state R[1]; + uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; + size_t buflen; + } blake2sp_state; + + typedef struct __blake2bp_state + { + blake2b_state S[4][1]; + blake2b_state R[1]; + uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; + size_t buflen; + } blake2bp_state; + + +#pragma pack(push, 1) + typedef struct __blake2s_param + { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint8_t node_offset[6];// 14 + uint8_t node_depth; /* 15 */ + uint8_t inner_length; /* 16 */ + /* uint8_t reserved[0]; */ + uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ + uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ + } blake2s_param; + + typedef struct __blake2b_param + { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint64_t node_offset; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ + } blake2b_param; +#pragma pack(pop) + + /* Streaming API */ + int blake2s_init( blake2s_state *S, const uint8_t outlen ); + int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); + int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ); + int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ); + + int blake2b_init( blake2b_state *S, const uint8_t outlen ); + int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); + int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ); + int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ); + + int blake2sp_init( blake2sp_state *S, const uint8_t outlen ); + int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); + int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen ); + int blake2sp_final( blake2sp_state *S, uint8_t *out, uint8_t outlen ); + + int blake2bp_init( blake2bp_state *S, const uint8_t outlen ); + int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); + int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen ); + int blake2bp_final( blake2bp_state *S, uint8_t *out, uint8_t outlen ); + + /* Simple API */ + int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); + int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); + + int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); + int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); + + static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) + { + return blake2b( out, in, key, outlen, inlen, keylen ); + } + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/Modules/_blake2/impl/blake2b-load-sse2.h b/Modules/_blake2/impl/blake2b-load-sse2.h new file mode 100644 index 0000000..0004a98 --- /dev/null +++ b/Modules/_blake2/impl/blake2b-load-sse2.h @@ -0,0 +1,70 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2B_LOAD_SSE2_H__ +#define __BLAKE2B_LOAD_SSE2_H__ + +#define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) +#define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) +#define LOAD_MSG_0_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_0_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) +#define LOAD_MSG_1_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) +#define LOAD_MSG_1_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) +#define LOAD_MSG_1_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) +#define LOAD_MSG_1_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) +#define LOAD_MSG_2_1(b0, b1) b0 = _mm_set_epi64x(m12, m11); b1 = _mm_set_epi64x(m15, m5) +#define LOAD_MSG_2_2(b0, b1) b0 = _mm_set_epi64x(m0, m8); b1 = _mm_set_epi64x(m13, m2) +#define LOAD_MSG_2_3(b0, b1) b0 = _mm_set_epi64x(m3, m10); b1 = _mm_set_epi64x(m9, m7) +#define LOAD_MSG_2_4(b0, b1) b0 = _mm_set_epi64x(m6, m14); b1 = _mm_set_epi64x(m4, m1) +#define LOAD_MSG_3_1(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m13) +#define LOAD_MSG_3_2(b0, b1) b0 = _mm_set_epi64x(m1, m9); b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_3_3(b0, b1) b0 = _mm_set_epi64x(m5, m2); b1 = _mm_set_epi64x(m15, m4) +#define LOAD_MSG_3_4(b0, b1) b0 = _mm_set_epi64x(m10, m6); b1 = _mm_set_epi64x(m8, m0) +#define LOAD_MSG_4_1(b0, b1) b0 = _mm_set_epi64x(m5, m9); b1 = _mm_set_epi64x(m10, m2) +#define LOAD_MSG_4_2(b0, b1) b0 = _mm_set_epi64x(m7, m0); b1 = _mm_set_epi64x(m15, m4) +#define LOAD_MSG_4_3(b0, b1) b0 = _mm_set_epi64x(m11, m14); b1 = _mm_set_epi64x(m3, m6) +#define LOAD_MSG_4_4(b0, b1) b0 = _mm_set_epi64x(m12, m1); b1 = _mm_set_epi64x(m13, m8) +#define LOAD_MSG_5_1(b0, b1) b0 = _mm_set_epi64x(m6, m2); b1 = _mm_set_epi64x(m8, m0) +#define LOAD_MSG_5_2(b0, b1) b0 = _mm_set_epi64x(m10, m12); b1 = _mm_set_epi64x(m3, m11) +#define LOAD_MSG_5_3(b0, b1) b0 = _mm_set_epi64x(m7, m4); b1 = _mm_set_epi64x(m1, m15) +#define LOAD_MSG_5_4(b0, b1) b0 = _mm_set_epi64x(m5, m13); b1 = _mm_set_epi64x(m9, m14) +#define LOAD_MSG_6_1(b0, b1) b0 = _mm_set_epi64x(m1, m12); b1 = _mm_set_epi64x(m4, m14) +#define LOAD_MSG_6_2(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m10, m13) +#define LOAD_MSG_6_3(b0, b1) b0 = _mm_set_epi64x(m6, m0); b1 = _mm_set_epi64x(m8, m9) +#define LOAD_MSG_6_4(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m2) +#define LOAD_MSG_7_1(b0, b1) b0 = _mm_set_epi64x(m7, m13); b1 = _mm_set_epi64x(m3, m12) +#define LOAD_MSG_7_2(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m9, m1) +#define LOAD_MSG_7_3(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m2, m8) +#define LOAD_MSG_7_4(b0, b1) b0 = _mm_set_epi64x(m4, m0); b1 = _mm_set_epi64x(m10, m6) +#define LOAD_MSG_8_1(b0, b1) b0 = _mm_set_epi64x(m14, m6); b1 = _mm_set_epi64x(m0, m11) +#define LOAD_MSG_8_2(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m8, m3) +#define LOAD_MSG_8_3(b0, b1) b0 = _mm_set_epi64x(m13, m12); b1 = _mm_set_epi64x(m10, m1) +#define LOAD_MSG_8_4(b0, b1) b0 = _mm_set_epi64x(m7, m2); b1 = _mm_set_epi64x(m5, m4) +#define LOAD_MSG_9_1(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m1, m7) +#define LOAD_MSG_9_2(b0, b1) b0 = _mm_set_epi64x(m4, m2); b1 = _mm_set_epi64x(m5, m6) +#define LOAD_MSG_9_3(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m13, m3) +#define LOAD_MSG_9_4(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m0, m12) +#define LOAD_MSG_10_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) +#define LOAD_MSG_10_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) +#define LOAD_MSG_10_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_10_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) +#define LOAD_MSG_11_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) +#define LOAD_MSG_11_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) +#define LOAD_MSG_11_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) +#define LOAD_MSG_11_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) + + +#endif + diff --git a/Modules/_blake2/impl/blake2b-load-sse41.h b/Modules/_blake2/impl/blake2b-load-sse41.h new file mode 100644 index 0000000..42a1349 --- /dev/null +++ b/Modules/_blake2/impl/blake2b-load-sse41.h @@ -0,0 +1,404 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2B_LOAD_SSE41_H__ +#define __BLAKE2B_LOAD_SSE41_H__ + +#define LOAD_MSG_0_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m0, m1); \ +b1 = _mm_unpacklo_epi64(m2, m3); \ +} while(0) + + +#define LOAD_MSG_0_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m0, m1); \ +b1 = _mm_unpackhi_epi64(m2, m3); \ +} while(0) + + +#define LOAD_MSG_0_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m4, m5); \ +b1 = _mm_unpacklo_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_0_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m4, m5); \ +b1 = _mm_unpackhi_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_1_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m7, m2); \ +b1 = _mm_unpackhi_epi64(m4, m6); \ +} while(0) + + +#define LOAD_MSG_1_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m5, m4); \ +b1 = _mm_alignr_epi8(m3, m7, 8); \ +} while(0) + + +#define LOAD_MSG_1_3(b0, b1) \ +do \ +{ \ +b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ +b1 = _mm_unpackhi_epi64(m5, m2); \ +} while(0) + + +#define LOAD_MSG_1_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m6, m1); \ +b1 = _mm_unpackhi_epi64(m3, m1); \ +} while(0) + + +#define LOAD_MSG_2_1(b0, b1) \ +do \ +{ \ +b0 = _mm_alignr_epi8(m6, m5, 8); \ +b1 = _mm_unpackhi_epi64(m2, m7); \ +} while(0) + + +#define LOAD_MSG_2_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m4, m0); \ +b1 = _mm_blend_epi16(m1, m6, 0xF0); \ +} while(0) + + +#define LOAD_MSG_2_3(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m5, m1, 0xF0); \ +b1 = _mm_unpackhi_epi64(m3, m4); \ +} while(0) + + +#define LOAD_MSG_2_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m7, m3); \ +b1 = _mm_alignr_epi8(m2, m0, 8); \ +} while(0) + + +#define LOAD_MSG_3_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m3, m1); \ +b1 = _mm_unpackhi_epi64(m6, m5); \ +} while(0) + + +#define LOAD_MSG_3_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m4, m0); \ +b1 = _mm_unpacklo_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_3_3(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m1, m2, 0xF0); \ +b1 = _mm_blend_epi16(m2, m7, 0xF0); \ +} while(0) + + +#define LOAD_MSG_3_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m3, m5); \ +b1 = _mm_unpacklo_epi64(m0, m4); \ +} while(0) + + +#define LOAD_MSG_4_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m4, m2); \ +b1 = _mm_unpacklo_epi64(m1, m5); \ +} while(0) + + +#define LOAD_MSG_4_2(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m0, m3, 0xF0); \ +b1 = _mm_blend_epi16(m2, m7, 0xF0); \ +} while(0) + + +#define LOAD_MSG_4_3(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m7, m5, 0xF0); \ +b1 = _mm_blend_epi16(m3, m1, 0xF0); \ +} while(0) + + +#define LOAD_MSG_4_4(b0, b1) \ +do \ +{ \ +b0 = _mm_alignr_epi8(m6, m0, 8); \ +b1 = _mm_blend_epi16(m4, m6, 0xF0); \ +} while(0) + + +#define LOAD_MSG_5_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m1, m3); \ +b1 = _mm_unpacklo_epi64(m0, m4); \ +} while(0) + + +#define LOAD_MSG_5_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m6, m5); \ +b1 = _mm_unpackhi_epi64(m5, m1); \ +} while(0) + + +#define LOAD_MSG_5_3(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m2, m3, 0xF0); \ +b1 = _mm_unpackhi_epi64(m7, m0); \ +} while(0) + + +#define LOAD_MSG_5_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m6, m2); \ +b1 = _mm_blend_epi16(m7, m4, 0xF0); \ +} while(0) + + +#define LOAD_MSG_6_1(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m6, m0, 0xF0); \ +b1 = _mm_unpacklo_epi64(m7, m2); \ +} while(0) + + +#define LOAD_MSG_6_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m2, m7); \ +b1 = _mm_alignr_epi8(m5, m6, 8); \ +} while(0) + + +#define LOAD_MSG_6_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m0, m3); \ +b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \ +} while(0) + + +#define LOAD_MSG_6_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m3, m1); \ +b1 = _mm_blend_epi16(m1, m5, 0xF0); \ +} while(0) + + +#define LOAD_MSG_7_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m6, m3); \ +b1 = _mm_blend_epi16(m6, m1, 0xF0); \ +} while(0) + + +#define LOAD_MSG_7_2(b0, b1) \ +do \ +{ \ +b0 = _mm_alignr_epi8(m7, m5, 8); \ +b1 = _mm_unpackhi_epi64(m0, m4); \ +} while(0) + + +#define LOAD_MSG_7_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m2, m7); \ +b1 = _mm_unpacklo_epi64(m4, m1); \ +} while(0) + + +#define LOAD_MSG_7_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m0, m2); \ +b1 = _mm_unpacklo_epi64(m3, m5); \ +} while(0) + + +#define LOAD_MSG_8_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m3, m7); \ +b1 = _mm_alignr_epi8(m0, m5, 8); \ +} while(0) + + +#define LOAD_MSG_8_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m7, m4); \ +b1 = _mm_alignr_epi8(m4, m1, 8); \ +} while(0) + + +#define LOAD_MSG_8_3(b0, b1) \ +do \ +{ \ +b0 = m6; \ +b1 = _mm_alignr_epi8(m5, m0, 8); \ +} while(0) + + +#define LOAD_MSG_8_4(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m1, m3, 0xF0); \ +b1 = m2; \ +} while(0) + + +#define LOAD_MSG_9_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m5, m4); \ +b1 = _mm_unpackhi_epi64(m3, m0); \ +} while(0) + + +#define LOAD_MSG_9_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m1, m2); \ +b1 = _mm_blend_epi16(m3, m2, 0xF0); \ +} while(0) + + +#define LOAD_MSG_9_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m7, m4); \ +b1 = _mm_unpackhi_epi64(m1, m6); \ +} while(0) + + +#define LOAD_MSG_9_4(b0, b1) \ +do \ +{ \ +b0 = _mm_alignr_epi8(m7, m5, 8); \ +b1 = _mm_unpacklo_epi64(m6, m0); \ +} while(0) + + +#define LOAD_MSG_10_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m0, m1); \ +b1 = _mm_unpacklo_epi64(m2, m3); \ +} while(0) + + +#define LOAD_MSG_10_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m0, m1); \ +b1 = _mm_unpackhi_epi64(m2, m3); \ +} while(0) + + +#define LOAD_MSG_10_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m4, m5); \ +b1 = _mm_unpacklo_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_10_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m4, m5); \ +b1 = _mm_unpackhi_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_11_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m7, m2); \ +b1 = _mm_unpackhi_epi64(m4, m6); \ +} while(0) + + +#define LOAD_MSG_11_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m5, m4); \ +b1 = _mm_alignr_epi8(m3, m7, 8); \ +} while(0) + + +#define LOAD_MSG_11_3(b0, b1) \ +do \ +{ \ +b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ +b1 = _mm_unpackhi_epi64(m5, m2); \ +} while(0) + + +#define LOAD_MSG_11_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m6, m1); \ +b1 = _mm_unpackhi_epi64(m3, m1); \ +} while(0) + + +#endif + diff --git a/Modules/_blake2/impl/blake2b-ref.c b/Modules/_blake2/impl/blake2b-ref.c new file mode 100644 index 0000000..ab375a4 --- /dev/null +++ b/Modules/_blake2/impl/blake2b-ref.c @@ -0,0 +1,420 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + + +BLAKE2_LOCAL_INLINE(int) blake2b_set_lastnode( blake2b_state *S ) +{ + S->f[1] = -1; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastnode( blake2b_state *S ) +{ + S->f[1] = 0; + return 0; +} + +/* Some helper functions, not necessarily useful */ +BLAKE2_LOCAL_INLINE(int) blake2b_is_lastblock( const blake2b_state *S ) +{ + return S->f[0] != 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_set_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_set_lastnode( S ); + + S->f[0] = -1; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_clear_lastnode( S ); + + S->f[0] = 0; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); + return 0; +} + + + +/* Parameter-related functions */ +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length ) +{ + P->digest_length = digest_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) +{ + P->fanout = fanout; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth ) +{ + P->depth = depth; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) +{ + store32( &P->leaf_length, leaf_length ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset ) +{ + store64( &P->node_offset, node_offset ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) +{ + P->node_depth = node_depth; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length ) +{ + P->inner_length = inner_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) +{ + memcpy( P->salt, salt, BLAKE2B_SALTBYTES ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] ) +{ + memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_init0( blake2b_state *S ) +{ + int i; + memset( S, 0, sizeof( blake2b_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; + + return 0; +} + +/* init xors IV with input parameter block */ +int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ + const uint8_t *p = ( const uint8_t * )( P ); + size_t i; + + blake2b_init0( S ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); + + return 0; +} + + + +int blake2b_init( blake2b_state *S, const uint8_t outlen ) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + P->digest_length = outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store64( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2b_init_param( S, P ); +} + + +int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; + + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store64( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2b_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) +{ + uint64_t m[16]; + uint64_t v[16]; + int i; + + for( i = 0; i < 16; ++i ) + m[i] = load64( block + i * sizeof( m[i] ) ); + + for( i = 0; i < 8; ++i ) + v[i] = S->h[i]; + + v[ 8] = blake2b_IV[0]; + v[ 9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = S->t[0] ^ blake2b_IV[4]; + v[13] = S->t[1] ^ blake2b_IV[5]; + v[14] = S->f[0] ^ blake2b_IV[6]; + v[15] = S->f[1] ^ blake2b_IV[7]; +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2*i+0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2*i+1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + ROUND( 10 ); + ROUND( 11 ); + + for( i = 0; i < 8; ++i ) + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + +#undef G +#undef ROUND + return 0; +} + +/* inlen now in bytes */ +int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ) +{ + while( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = 2 * BLAKE2B_BLOCKBYTES - left; + + if( inlen > fill ) + { + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + S->buflen += fill; + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); /* Compress */ + memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */ + S->buflen -= BLAKE2B_BLOCKBYTES; + in += fill; + inlen -= fill; + } + else /* inlen <= fill */ + { + memcpy( S->buf + left, in, (size_t)inlen ); + S->buflen += (size_t)inlen; /* Be lazy, do not compress */ + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + +/* Is this correct? */ +int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ) +{ + uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; + int i; + + if( out == NULL || outlen == 0 || outlen > BLAKE2B_OUTBYTES ) + return -1; + + if( blake2b_is_lastblock( S ) ) + return -1; + + if( S->buflen > BLAKE2B_BLOCKBYTES ) + { + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); + S->buflen -= BLAKE2B_BLOCKBYTES; + memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); + } + + blake2b_increment_counter( S, S->buflen ); + blake2b_set_lastblock( S ); + memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ + blake2b_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + return 0; +} + +/* inlen, at least, should be uint64_t. Others can be size_t. */ +int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +{ + blake2b_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if( NULL == key && keylen > 0 ) return -1; + + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + if( keylen > BLAKE2B_KEYBYTES ) return -1; + + if( keylen > 0 ) + { + if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2b_init( S, outlen ) < 0 ) return -1; + } + + blake2b_update( S, ( const uint8_t * )in, inlen ); + blake2b_final( S, out, outlen ); + return 0; +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 ); +} +#endif + +#if defined(BLAKE2B_SELFTEST) +#include <string.h> +#include "blake2-kat.h" +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2B_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + size_t i; + + for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2B_OUTBYTES]; + blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ); + + if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} +#endif + diff --git a/Modules/_blake2/impl/blake2b-round.h b/Modules/_blake2/impl/blake2b-round.h new file mode 100644 index 0000000..4ce2255 --- /dev/null +++ b/Modules/_blake2/impl/blake2b-round.h @@ -0,0 +1,159 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2B_ROUND_H__ +#define __BLAKE2B_ROUND_H__ + +#define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) +#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) + +#define TOF(reg) _mm_castsi128_ps((reg)) +#define TOI(reg) _mm_castps_si128((reg)) + +#define LIKELY(x) __builtin_expect((x),1) + + +/* Microarchitecture-specific macros */ +#ifndef HAVE_XOP +#ifdef HAVE_SSSE3 +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \ + : (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c)))) +#else +#define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-(c)) )) +#endif +#else +/* ... */ +#endif + + + +#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -32); \ + row4h = _mm_roti_epi64(row4h, -32); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -24); \ + row2h = _mm_roti_epi64(row2h, -24); \ + +#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -16); \ + row4h = _mm_roti_epi64(row4h, -16); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -63); \ + row2h = _mm_roti_epi64(row2h, -63); \ + +#if defined(HAVE_SSSE3) +#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = _mm_alignr_epi8(row2h, row2l, 8); \ + t1 = _mm_alignr_epi8(row2l, row2h, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4h, row4l, 8); \ + t1 = _mm_alignr_epi8(row4l, row4h, 8); \ + row4l = t1; \ + row4h = t0; + +#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = _mm_alignr_epi8(row2l, row2h, 8); \ + t1 = _mm_alignr_epi8(row2h, row2l, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4l, row4h, 8); \ + t1 = _mm_alignr_epi8(row4h, row4l, 8); \ + row4l = t1; \ + row4h = t0; +#else + +#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = row4l;\ + t1 = row2l;\ + row4l = row3l;\ + row3l = row3h;\ + row3h = row4l;\ + row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \ + row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \ + row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \ + row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1)) + +#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = row3l;\ + row3l = row3h;\ + row3h = t0;\ + t0 = row2l;\ + t1 = row4l;\ + row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \ + row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \ + row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \ + row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1)) + +#endif + +#if defined(HAVE_SSE41) +#include "blake2b-load-sse41.h" +#else +#include "blake2b-load-sse2.h" +#endif + +#define ROUND(r) \ + LOAD_MSG_ ##r ##_1(b0, b1); \ + G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + LOAD_MSG_ ##r ##_2(b0, b1); \ + G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ + LOAD_MSG_ ##r ##_3(b0, b1); \ + G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + LOAD_MSG_ ##r ##_4(b0, b1); \ + G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); + +#endif + diff --git a/Modules/_blake2/impl/blake2b.c b/Modules/_blake2/impl/blake2b.c new file mode 100644 index 0000000..ebb65bb --- /dev/null +++ b/Modules/_blake2/impl/blake2b.c @@ -0,0 +1,453 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include "blake2.h" +#include "blake2-impl.h" + +#include "blake2-config.h" + +#ifdef _MSC_VER +#include <intrin.h> /* for _mm_set_epi64x */ +#endif +#include <emmintrin.h> +#if defined(HAVE_SSSE3) +#include <tmmintrin.h> +#endif +#if defined(HAVE_SSE41) +#include <smmintrin.h> +#endif +#if defined(HAVE_AVX) +#include <immintrin.h> +#endif +#if defined(HAVE_XOP) +#include <x86intrin.h> +#endif + +#include "blake2b-round.h" + +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + + +/* Some helper functions, not necessarily useful */ +BLAKE2_LOCAL_INLINE(int) blake2b_set_lastnode( blake2b_state *S ) +{ + S->f[1] = -1; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastnode( blake2b_state *S ) +{ + S->f[1] = 0; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_is_lastblock( const blake2b_state *S ) +{ + return S->f[0] != 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_set_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_set_lastnode( S ); + + S->f[0] = -1; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_clear_lastnode( S ); + + S->f[0] = 0; + return 0; +} + + +BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) +{ +#if __x86_64__ + /* ADD/ADC chain */ + __uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0]; + t += inc; + S->t[0] = ( uint64_t )( t >> 0 ); + S->t[1] = ( uint64_t )( t >> 64 ); +#else + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); +#endif + return 0; +} + + +/* Parameter-related functions */ +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length ) +{ + P->digest_length = digest_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) +{ + P->fanout = fanout; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth ) +{ + P->depth = depth; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) +{ + P->leaf_length = leaf_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset ) +{ + P->node_offset = node_offset; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) +{ + P->node_depth = node_depth; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length ) +{ + P->inner_length = inner_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) +{ + memcpy( P->salt, salt, BLAKE2B_SALTBYTES ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] ) +{ + memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_init0( blake2b_state *S ) +{ + int i; + memset( S, 0, sizeof( blake2b_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; + + return 0; +} + +/* init xors IV with input parameter block */ +int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ + /*blake2b_init0( S ); */ + const uint8_t * v = ( const uint8_t * )( blake2b_IV ); + const uint8_t * p = ( const uint8_t * )( P ); + uint8_t * h = ( uint8_t * )( S->h ); + int i; + /* IV XOR ParamBlock */ + memset( S, 0, sizeof( blake2b_state ) ); + + for( i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; + + return 0; +} + + +/* Some sort of default parameter block initialization, for sequential blake2b */ +int blake2b_init( blake2b_state *S, const uint8_t outlen ) +{ + const blake2b_param P = + { + outlen, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + {0}, + {0}, + {0} + }; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + return blake2b_init_param( S, &P ); +} + +int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +{ + const blake2b_param P = + { + outlen, + keylen, + 1, + 1, + 0, + 0, + 0, + 0, + {0}, + {0}, + {0} + }; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1; + + if( blake2b_init_param( S, &P ) < 0 ) + return 0; + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) +{ + __m128i row1l, row1h; + __m128i row2l, row2h; + __m128i row3l, row3h; + __m128i row4l, row4h; + __m128i b0, b1; + __m128i t0, t1; +#if defined(HAVE_SSSE3) && !defined(HAVE_XOP) + const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 ); + const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 ); +#endif +#if defined(HAVE_SSE41) + const __m128i m0 = LOADU( block + 00 ); + const __m128i m1 = LOADU( block + 16 ); + const __m128i m2 = LOADU( block + 32 ); + const __m128i m3 = LOADU( block + 48 ); + const __m128i m4 = LOADU( block + 64 ); + const __m128i m5 = LOADU( block + 80 ); + const __m128i m6 = LOADU( block + 96 ); + const __m128i m7 = LOADU( block + 112 ); +#else + const uint64_t m0 = ( ( uint64_t * )block )[ 0]; + const uint64_t m1 = ( ( uint64_t * )block )[ 1]; + const uint64_t m2 = ( ( uint64_t * )block )[ 2]; + const uint64_t m3 = ( ( uint64_t * )block )[ 3]; + const uint64_t m4 = ( ( uint64_t * )block )[ 4]; + const uint64_t m5 = ( ( uint64_t * )block )[ 5]; + const uint64_t m6 = ( ( uint64_t * )block )[ 6]; + const uint64_t m7 = ( ( uint64_t * )block )[ 7]; + const uint64_t m8 = ( ( uint64_t * )block )[ 8]; + const uint64_t m9 = ( ( uint64_t * )block )[ 9]; + const uint64_t m10 = ( ( uint64_t * )block )[10]; + const uint64_t m11 = ( ( uint64_t * )block )[11]; + const uint64_t m12 = ( ( uint64_t * )block )[12]; + const uint64_t m13 = ( ( uint64_t * )block )[13]; + const uint64_t m14 = ( ( uint64_t * )block )[14]; + const uint64_t m15 = ( ( uint64_t * )block )[15]; +#endif + row1l = LOADU( &S->h[0] ); + row1h = LOADU( &S->h[2] ); + row2l = LOADU( &S->h[4] ); + row2h = LOADU( &S->h[6] ); + row3l = LOADU( &blake2b_IV[0] ); + row3h = LOADU( &blake2b_IV[2] ); + row4l = _mm_xor_si128( LOADU( &blake2b_IV[4] ), LOADU( &S->t[0] ) ); + row4h = _mm_xor_si128( LOADU( &blake2b_IV[6] ), LOADU( &S->f[0] ) ); + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + ROUND( 10 ); + ROUND( 11 ); + row1l = _mm_xor_si128( row3l, row1l ); + row1h = _mm_xor_si128( row3h, row1h ); + STOREU( &S->h[0], _mm_xor_si128( LOADU( &S->h[0] ), row1l ) ); + STOREU( &S->h[2], _mm_xor_si128( LOADU( &S->h[2] ), row1h ) ); + row2l = _mm_xor_si128( row4l, row2l ); + row2h = _mm_xor_si128( row4h, row2h ); + STOREU( &S->h[4], _mm_xor_si128( LOADU( &S->h[4] ), row2l ) ); + STOREU( &S->h[6], _mm_xor_si128( LOADU( &S->h[6] ), row2h ) ); + return 0; +} + + +int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ) +{ + while( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = 2 * BLAKE2B_BLOCKBYTES - left; + + if( inlen > fill ) + { + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + S->buflen += fill; + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); /* Compress */ + memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */ + S->buflen -= BLAKE2B_BLOCKBYTES; + in += fill; + inlen -= fill; + } + else /* inlen <= fill */ + { + memcpy( S->buf + left, in, inlen ); + S->buflen += inlen; /* Be lazy, do not compress */ + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + + +int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ) +{ + if( outlen > BLAKE2B_OUTBYTES ) + return -1; + + if( blake2b_is_lastblock( S ) ) + return -1; + + if( S->buflen > BLAKE2B_BLOCKBYTES ) + { + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); + S->buflen -= BLAKE2B_BLOCKBYTES; + memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); + } + + blake2b_increment_counter( S, S->buflen ); + blake2b_set_lastblock( S ); + memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ + blake2b_compress( S, S->buf ); + memcpy( out, &S->h[0], outlen ); + return 0; +} + + +int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +{ + blake2b_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if( NULL == key && keylen > 0 ) return -1; + + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + if( keylen > BLAKE2B_KEYBYTES ) return -1; + + if( keylen ) + { + if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2b_init( S, outlen ) < 0 ) return -1; + } + + blake2b_update( S, ( const uint8_t * )in, inlen ); + blake2b_final( S, out, outlen ); + return 0; +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 ); +} +#endif + +#if defined(BLAKE2B_SELFTEST) +#include <string.h> +#include "blake2-kat.h" +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2B_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + size_t i; + + for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2B_OUTBYTES]; + blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ); + + if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} +#endif + diff --git a/Modules/_blake2/impl/blake2s-load-sse2.h b/Modules/_blake2/impl/blake2s-load-sse2.h new file mode 100644 index 0000000..eadefa7 --- /dev/null +++ b/Modules/_blake2/impl/blake2s-load-sse2.h @@ -0,0 +1,61 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2S_LOAD_SSE2_H__ +#define __BLAKE2S_LOAD_SSE2_H__ + +#define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0) +#define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1) +#define LOAD_MSG_0_3(buf) buf = _mm_set_epi32(m14,m12,m10,m8) +#define LOAD_MSG_0_4(buf) buf = _mm_set_epi32(m15,m13,m11,m9) +#define LOAD_MSG_1_1(buf) buf = _mm_set_epi32(m13,m9,m4,m14) +#define LOAD_MSG_1_2(buf) buf = _mm_set_epi32(m6,m15,m8,m10) +#define LOAD_MSG_1_3(buf) buf = _mm_set_epi32(m5,m11,m0,m1) +#define LOAD_MSG_1_4(buf) buf = _mm_set_epi32(m3,m7,m2,m12) +#define LOAD_MSG_2_1(buf) buf = _mm_set_epi32(m15,m5,m12,m11) +#define LOAD_MSG_2_2(buf) buf = _mm_set_epi32(m13,m2,m0,m8) +#define LOAD_MSG_2_3(buf) buf = _mm_set_epi32(m9,m7,m3,m10) +#define LOAD_MSG_2_4(buf) buf = _mm_set_epi32(m4,m1,m6,m14) +#define LOAD_MSG_3_1(buf) buf = _mm_set_epi32(m11,m13,m3,m7) +#define LOAD_MSG_3_2(buf) buf = _mm_set_epi32(m14,m12,m1,m9) +#define LOAD_MSG_3_3(buf) buf = _mm_set_epi32(m15,m4,m5,m2) +#define LOAD_MSG_3_4(buf) buf = _mm_set_epi32(m8,m0,m10,m6) +#define LOAD_MSG_4_1(buf) buf = _mm_set_epi32(m10,m2,m5,m9) +#define LOAD_MSG_4_2(buf) buf = _mm_set_epi32(m15,m4,m7,m0) +#define LOAD_MSG_4_3(buf) buf = _mm_set_epi32(m3,m6,m11,m14) +#define LOAD_MSG_4_4(buf) buf = _mm_set_epi32(m13,m8,m12,m1) +#define LOAD_MSG_5_1(buf) buf = _mm_set_epi32(m8,m0,m6,m2) +#define LOAD_MSG_5_2(buf) buf = _mm_set_epi32(m3,m11,m10,m12) +#define LOAD_MSG_5_3(buf) buf = _mm_set_epi32(m1,m15,m7,m4) +#define LOAD_MSG_5_4(buf) buf = _mm_set_epi32(m9,m14,m5,m13) +#define LOAD_MSG_6_1(buf) buf = _mm_set_epi32(m4,m14,m1,m12) +#define LOAD_MSG_6_2(buf) buf = _mm_set_epi32(m10,m13,m15,m5) +#define LOAD_MSG_6_3(buf) buf = _mm_set_epi32(m8,m9,m6,m0) +#define LOAD_MSG_6_4(buf) buf = _mm_set_epi32(m11,m2,m3,m7) +#define LOAD_MSG_7_1(buf) buf = _mm_set_epi32(m3,m12,m7,m13) +#define LOAD_MSG_7_2(buf) buf = _mm_set_epi32(m9,m1,m14,m11) +#define LOAD_MSG_7_3(buf) buf = _mm_set_epi32(m2,m8,m15,m5) +#define LOAD_MSG_7_4(buf) buf = _mm_set_epi32(m10,m6,m4,m0) +#define LOAD_MSG_8_1(buf) buf = _mm_set_epi32(m0,m11,m14,m6) +#define LOAD_MSG_8_2(buf) buf = _mm_set_epi32(m8,m3,m9,m15) +#define LOAD_MSG_8_3(buf) buf = _mm_set_epi32(m10,m1,m13,m12) +#define LOAD_MSG_8_4(buf) buf = _mm_set_epi32(m5,m4,m7,m2) +#define LOAD_MSG_9_1(buf) buf = _mm_set_epi32(m1,m7,m8,m10) +#define LOAD_MSG_9_2(buf) buf = _mm_set_epi32(m5,m6,m4,m2) +#define LOAD_MSG_9_3(buf) buf = _mm_set_epi32(m13,m3,m9,m15) +#define LOAD_MSG_9_4(buf) buf = _mm_set_epi32(m0,m12,m14,m11) + + +#endif diff --git a/Modules/_blake2/impl/blake2s-load-sse41.h b/Modules/_blake2/impl/blake2s-load-sse41.h new file mode 100644 index 0000000..54bf0cd --- /dev/null +++ b/Modules/_blake2/impl/blake2s-load-sse41.h @@ -0,0 +1,231 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2S_LOAD_SSE41_H__ +#define __BLAKE2S_LOAD_SSE41_H__ + +#define LOAD_MSG_0_1(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0))); + +#define LOAD_MSG_0_2(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1))); + +#define LOAD_MSG_0_3(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(2,0,2,0))); + +#define LOAD_MSG_0_4(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(3,1,3,1))); + +#define LOAD_MSG_1_1(buf) \ +t0 = _mm_blend_epi16(m1, m2, 0x0C); \ +t1 = _mm_slli_si128(m3, 4); \ +t2 = _mm_blend_epi16(t0, t1, 0xF0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); + +#define LOAD_MSG_1_2(buf) \ +t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \ +t1 = _mm_blend_epi16(m1,m3,0xC0); \ +t2 = _mm_blend_epi16(t0, t1, 0xF0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + +#define LOAD_MSG_1_3(buf) \ +t0 = _mm_slli_si128(m1, 4); \ +t1 = _mm_blend_epi16(m2, t0, 0x30); \ +t2 = _mm_blend_epi16(m0, t1, 0xF0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + +#define LOAD_MSG_1_4(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_slli_si128(m3, 4); \ +t2 = _mm_blend_epi16(t0, t1, 0x0C); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + +#define LOAD_MSG_2_1(buf) \ +t0 = _mm_unpackhi_epi32(m2,m3); \ +t1 = _mm_blend_epi16(m3,m1,0x0C); \ +t2 = _mm_blend_epi16(t0, t1, 0x0F); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + +#define LOAD_MSG_2_2(buf) \ +t0 = _mm_unpacklo_epi32(m2,m0); \ +t1 = _mm_blend_epi16(t0, m0, 0xF0); \ +t2 = _mm_slli_si128(m3, 8); \ +buf = _mm_blend_epi16(t1, t2, 0xC0); + +#define LOAD_MSG_2_3(buf) \ +t0 = _mm_blend_epi16(m0, m2, 0x3C); \ +t1 = _mm_srli_si128(m1, 12); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,3,2)); + +#define LOAD_MSG_2_4(buf) \ +t0 = _mm_slli_si128(m3, 4); \ +t1 = _mm_blend_epi16(m0, m1, 0x33); \ +t2 = _mm_blend_epi16(t1, t0, 0xC0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,1,2,3)); + +#define LOAD_MSG_3_1(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_unpackhi_epi32(t0, m2); \ +t2 = _mm_blend_epi16(t1, m3, 0x0C); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + +#define LOAD_MSG_3_2(buf) \ +t0 = _mm_slli_si128(m2, 8); \ +t1 = _mm_blend_epi16(m3,m0,0x0C); \ +t2 = _mm_blend_epi16(t1, t0, 0xC0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); + +#define LOAD_MSG_3_3(buf) \ +t0 = _mm_blend_epi16(m0,m1,0x0F); \ +t1 = _mm_blend_epi16(t0, m3, 0xC0); \ +buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); + +#define LOAD_MSG_3_4(buf) \ +t0 = _mm_unpacklo_epi32(m0,m2); \ +t1 = _mm_unpackhi_epi32(m1,m2); \ +buf = _mm_unpacklo_epi64(t1,t0); + +#define LOAD_MSG_4_1(buf) \ +t0 = _mm_unpacklo_epi64(m1,m2); \ +t1 = _mm_unpackhi_epi64(m0,m2); \ +t2 = _mm_blend_epi16(t0,t1,0x33); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); + +#define LOAD_MSG_4_2(buf) \ +t0 = _mm_unpackhi_epi64(m1,m3); \ +t1 = _mm_unpacklo_epi64(m0,m1); \ +buf = _mm_blend_epi16(t0,t1,0x33); + +#define LOAD_MSG_4_3(buf) \ +t0 = _mm_unpackhi_epi64(m3,m1); \ +t1 = _mm_unpackhi_epi64(m2,m0); \ +buf = _mm_blend_epi16(t1,t0,0x33); + +#define LOAD_MSG_4_4(buf) \ +t0 = _mm_blend_epi16(m0,m2,0x03); \ +t1 = _mm_slli_si128(t0, 8); \ +t2 = _mm_blend_epi16(t1,m3,0x0F); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,0,3)); + +#define LOAD_MSG_5_1(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_unpacklo_epi32(m0,m2); \ +buf = _mm_unpacklo_epi64(t0,t1); + +#define LOAD_MSG_5_2(buf) \ +t0 = _mm_srli_si128(m2, 4); \ +t1 = _mm_blend_epi16(m0,m3,0x03); \ +buf = _mm_blend_epi16(t1,t0,0x3C); + +#define LOAD_MSG_5_3(buf) \ +t0 = _mm_blend_epi16(m1,m0,0x0C); \ +t1 = _mm_srli_si128(m3, 4); \ +t2 = _mm_blend_epi16(t0,t1,0x30); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0)); + +#define LOAD_MSG_5_4(buf) \ +t0 = _mm_unpacklo_epi64(m1,m2); \ +t1= _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,2,0,1)); \ +buf = _mm_blend_epi16(t0,t1,0x33); + +#define LOAD_MSG_6_1(buf) \ +t0 = _mm_slli_si128(m1, 12); \ +t1 = _mm_blend_epi16(m0,m3,0x33); \ +buf = _mm_blend_epi16(t1,t0,0xC0); + +#define LOAD_MSG_6_2(buf) \ +t0 = _mm_blend_epi16(m3,m2,0x30); \ +t1 = _mm_srli_si128(m1, 4); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0)); + +#define LOAD_MSG_6_3(buf) \ +t0 = _mm_unpacklo_epi64(m0,m2); \ +t1 = _mm_srli_si128(m1, 4); \ +buf = _mm_shuffle_epi32(_mm_blend_epi16(t0,t1,0x0C), _MM_SHUFFLE(2,3,1,0)); + +#define LOAD_MSG_6_4(buf) \ +t0 = _mm_unpackhi_epi32(m1,m2); \ +t1 = _mm_unpackhi_epi64(m0,t0); \ +buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); + +#define LOAD_MSG_7_1(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_blend_epi16(t0,m3,0x0F); \ +buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1)); + +#define LOAD_MSG_7_2(buf) \ +t0 = _mm_blend_epi16(m2,m3,0x30); \ +t1 = _mm_srli_si128(m0,4); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3)); + +#define LOAD_MSG_7_3(buf) \ +t0 = _mm_unpackhi_epi64(m0,m3); \ +t1 = _mm_unpacklo_epi64(m1,m2); \ +t2 = _mm_blend_epi16(t0,t1,0x3C); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,3,1)); + +#define LOAD_MSG_7_4(buf) \ +t0 = _mm_unpacklo_epi32(m0,m1); \ +t1 = _mm_unpackhi_epi32(m1,m2); \ +buf = _mm_unpacklo_epi64(t0,t1); + +#define LOAD_MSG_8_1(buf) \ +t0 = _mm_unpackhi_epi32(m1,m3); \ +t1 = _mm_unpacklo_epi64(t0,m0); \ +t2 = _mm_blend_epi16(t1,m2,0xC0); \ +buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2)); + +#define LOAD_MSG_8_2(buf) \ +t0 = _mm_unpackhi_epi32(m0,m3); \ +t1 = _mm_blend_epi16(m2,t0,0xF0); \ +buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3)); + +#define LOAD_MSG_8_3(buf) \ +t0 = _mm_blend_epi16(m2,m0,0x0C); \ +t1 = _mm_slli_si128(t0,4); \ +buf = _mm_blend_epi16(t1,m3,0x0F); + +#define LOAD_MSG_8_4(buf) \ +t0 = _mm_blend_epi16(m1,m0,0x30); \ +buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(1,0,3,2)); + +#define LOAD_MSG_9_1(buf) \ +t0 = _mm_blend_epi16(m0,m2,0x03); \ +t1 = _mm_blend_epi16(m1,m2,0x30); \ +t2 = _mm_blend_epi16(t1,t0,0x0F); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2)); + +#define LOAD_MSG_9_2(buf) \ +t0 = _mm_slli_si128(m0,4); \ +t1 = _mm_blend_epi16(m1,t0,0xC0); \ +buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3)); + +#define LOAD_MSG_9_3(buf) \ +t0 = _mm_unpackhi_epi32(m0,m3); \ +t1 = _mm_unpacklo_epi32(m2,m3); \ +t2 = _mm_unpackhi_epi64(t0,t1); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(3,0,2,1)); + +#define LOAD_MSG_9_4(buf) \ +t0 = _mm_blend_epi16(m3,m2,0xC0); \ +t1 = _mm_unpacklo_epi32(m0,m3); \ +t2 = _mm_blend_epi16(t0,t1,0x0F); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,1,2,3)); + +#endif + diff --git a/Modules/_blake2/impl/blake2s-load-xop.h b/Modules/_blake2/impl/blake2s-load-xop.h new file mode 100644 index 0000000..a3b5d65 --- /dev/null +++ b/Modules/_blake2/impl/blake2s-load-xop.h @@ -0,0 +1,191 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2S_LOAD_XOP_H__ +#define __BLAKE2S_LOAD_XOP_H__ + +#define TOB(x) ((x)*4*0x01010101 + 0x03020100) /* ..or not TOB */ + +/* Basic VPPERM emulation, for testing purposes */ +/*static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel) +{ + const __m128i sixteen = _mm_set1_epi8(16); + const __m128i t0 = _mm_shuffle_epi8(src1, sel); + const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen)); + const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen), + _mm_cmpgt_epi8(sel, sixteen)); /* (>=16) = 0xff : 00 */ + return _mm_blendv_epi8(t0, s1, mask); +}*/ + +#define LOAD_MSG_0_1(buf) \ +buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); + +#define LOAD_MSG_0_2(buf) \ +buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); + +#define LOAD_MSG_0_3(buf) \ +buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); + +#define LOAD_MSG_0_4(buf) \ +buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); + +#define LOAD_MSG_1_1(buf) \ +t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(5),TOB(0),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); + +#define LOAD_MSG_1_2(buf) \ +t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(2),TOB(0),TOB(4),TOB(6)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); + +#define LOAD_MSG_1_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(0),TOB(0),TOB(1)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); + +#define LOAD_MSG_1_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(7),TOB(2),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); + +#define LOAD_MSG_2_1(buf) \ +t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(1),TOB(0),TOB(7)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(4),TOB(0)) ); + +#define LOAD_MSG_2_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(2),TOB(0),TOB(4)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_2_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(7),TOB(3),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); + +#define LOAD_MSG_2_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(1),TOB(6),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); + +#define LOAD_MSG_3_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(3),TOB(7)) ); \ +t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(1),TOB(0)) ); + +#define LOAD_MSG_3_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(1),TOB(5)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(1),TOB(0)) ); + +#define LOAD_MSG_3_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(5),TOB(2)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_3_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ +buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(6),TOB(0)) ); + +#define LOAD_MSG_4_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(5),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(5)) ); + +#define LOAD_MSG_4_2(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(7),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_4_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(6),TOB(0),TOB(0)) ); \ +t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); + +#define LOAD_MSG_4_4(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(4),TOB(0),TOB(1)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(4),TOB(0)) ); + +#define LOAD_MSG_5_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(2)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_5_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(6),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); + +#define LOAD_MSG_5_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(0),TOB(7),TOB(4)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); + +#define LOAD_MSG_5_4(buf) \ +t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(5),TOB(0),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(5)) ); + +#define LOAD_MSG_6_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(0),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(4)) ); + +#define LOAD_MSG_6_2(buf) \ +t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(6),TOB(0),TOB(0),TOB(1)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(7),TOB(0)) ); + +#define LOAD_MSG_6_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(5),TOB(1),TOB(0)) ); + +#define LOAD_MSG_6_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(3),TOB(7)) ); \ +buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_7_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(0),TOB(7),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(5)) ); + +#define LOAD_MSG_7_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(5),TOB(1),TOB(0),TOB(7)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); + +#define LOAD_MSG_7_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(2),TOB(0),TOB(0),TOB(5)) ); \ +t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); + +#define LOAD_MSG_7_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(6),TOB(4),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_8_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ +t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); + +#define LOAD_MSG_8_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(4),TOB(3),TOB(5),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(7)) ); + +#define LOAD_MSG_8_3(buf) \ +t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \ + +#define LOAD_MSG_8_4(buf) \ +buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) ); + +#define LOAD_MSG_9_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(7),TOB(0),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(4),TOB(6)) ); + +#define LOAD_MSG_9_2(buf) \ +buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(6),TOB(4),TOB(2)) ); + +#define LOAD_MSG_9_3(buf) \ +t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(3),TOB(5),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(7)) ); + +#define LOAD_MSG_9_4(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(7)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(6),TOB(0)) ); + +#endif + diff --git a/Modules/_blake2/impl/blake2s-ref.c b/Modules/_blake2/impl/blake2s-ref.c new file mode 100644 index 0000000..6636753 --- /dev/null +++ b/Modules/_blake2/impl/blake2s-ref.c @@ -0,0 +1,411 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint32_t blake2s_IV[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const uint8_t blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + +BLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S ) +{ + S->f[1] = -1; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S ) +{ + S->f[1] = 0; + return 0; +} + +/* Some helper functions, not necessarily useful */ +BLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S ) +{ + return S->f[0] != 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_set_lastnode( S ); + + S->f[0] = -1; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_clear_lastnode( S ); + + S->f[0] = 0; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); + return 0; +} + +/* Parameter-related functions */ +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) +{ + P->digest_length = digest_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) +{ + P->fanout = fanout; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) +{ + P->depth = depth; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) +{ + store32( &P->leaf_length, leaf_length ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) +{ + store48( P->node_offset, node_offset ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) +{ + P->node_depth = node_depth; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) +{ + P->inner_length = inner_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) +{ + memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) +{ + memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S ) +{ + int i; + memset( S, 0, sizeof( blake2s_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; + + return 0; +} + +/* init2 xors IV with input parameter block */ +int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + const uint32_t *p = ( const uint32_t * )( P ); + size_t i; + + blake2s_init0( S ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + S->h[i] ^= load32( &p[i] ); + + return 0; +} + + +/* Sequential blake2s initialization */ +int blake2s_init( blake2s_state *S, const uint8_t outlen ) +{ + blake2s_param P[1]; + + /* Move interval verification here? */ + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + P->digest_length = outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store48( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2s_init_param( S, P ); +} + +int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +{ + blake2s_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; + + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store48( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2s_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) +{ + uint32_t m[16]; + uint32_t v[16]; + size_t i; + + for( i = 0; i < 16; ++i ) + m[i] = load32( block + i * sizeof( m[i] ) ); + + for( i = 0; i < 8; ++i ) + v[i] = S->h[i]; + + v[ 8] = blake2s_IV[0]; + v[ 9] = blake2s_IV[1]; + v[10] = blake2s_IV[2]; + v[11] = blake2s_IV[3]; + v[12] = S->t[0] ^ blake2s_IV[4]; + v[13] = S->t[1] ^ blake2s_IV[5]; + v[14] = S->f[0] ^ blake2s_IV[6]; + v[15] = S->f[1] ^ blake2s_IV[7]; +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2*i+0]]; \ + d = rotr32(d ^ a, 16); \ + c = c + d; \ + b = rotr32(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2*i+1]]; \ + d = rotr32(d ^ a, 8); \ + c = c + d; \ + b = rotr32(b ^ c, 7); \ + } while(0) +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + + for( i = 0; i < 8; ++i ) + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + +#undef G +#undef ROUND + return 0; +} + + +int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) +{ + while( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = 2 * BLAKE2S_BLOCKBYTES - left; + + if( inlen > fill ) + { + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + S->buflen += fill; + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); /* Compress */ + memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */ + S->buflen -= BLAKE2S_BLOCKBYTES; + in += fill; + inlen -= fill; + } + else /* inlen <= fill */ + { + memcpy( S->buf + left, in, (size_t)inlen ); + S->buflen += (size_t)inlen; /* Be lazy, do not compress */ + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + +int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ) +{ + uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; + int i; + + if( out == NULL || outlen == 0 || outlen > BLAKE2S_OUTBYTES ) + return -1; + + if( blake2s_is_lastblock( S ) ) + return -1; + + + if( S->buflen > BLAKE2S_BLOCKBYTES ) + { + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); + S->buflen -= BLAKE2S_BLOCKBYTES; + memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); + } + + blake2s_increment_counter( S, ( uint32_t )S->buflen ); + blake2s_set_lastblock( S ); + memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + blake2s_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + return 0; +} + +int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +{ + blake2s_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if ( NULL == key && keylen > 0) return -1; + + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + if( keylen > BLAKE2S_KEYBYTES ) return -1; + + if( keylen > 0 ) + { + if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2s_init( S, outlen ) < 0 ) return -1; + } + + blake2s_update( S, ( const uint8_t * )in, inlen ); + blake2s_final( S, out, outlen ); + return 0; +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 ); +} +#endif + +#if defined(BLAKE2S_SELFTEST) +#include <string.h> +#include "blake2-kat.h" +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2S_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + size_t i; + + for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2S_OUTBYTES]; + blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ); + + if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} +#endif + + diff --git a/Modules/_blake2/impl/blake2s-round.h b/Modules/_blake2/impl/blake2s-round.h new file mode 100644 index 0000000..7470d92 --- /dev/null +++ b/Modules/_blake2/impl/blake2s-round.h @@ -0,0 +1,90 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once +#ifndef __BLAKE2S_ROUND_H__ +#define __BLAKE2S_ROUND_H__ + +#define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) +#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) + +#define TOF(reg) _mm_castsi128_ps((reg)) +#define TOI(reg) _mm_castps_si128((reg)) + +#define LIKELY(x) __builtin_expect((x),1) + + +/* Microarchitecture-specific macros */ +#ifndef HAVE_XOP +#ifdef HAVE_SSSE3 +#define _mm_roti_epi32(r, c) ( \ + (8==-(c)) ? _mm_shuffle_epi8(r,r8) \ + : (16==-(c)) ? _mm_shuffle_epi8(r,r16) \ + : _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) ) +#else +#define _mm_roti_epi32(r, c) _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) +#endif +#else +/* ... */ +#endif + + +#define G1(row1,row2,row3,row4,buf) \ + row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ + row4 = _mm_xor_si128( row4, row1 ); \ + row4 = _mm_roti_epi32(row4, -16); \ + row3 = _mm_add_epi32( row3, row4 ); \ + row2 = _mm_xor_si128( row2, row3 ); \ + row2 = _mm_roti_epi32(row2, -12); + +#define G2(row1,row2,row3,row4,buf) \ + row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ + row4 = _mm_xor_si128( row4, row1 ); \ + row4 = _mm_roti_epi32(row4, -8); \ + row3 = _mm_add_epi32( row3, row4 ); \ + row2 = _mm_xor_si128( row2, row3 ); \ + row2 = _mm_roti_epi32(row2, -7); + +#define DIAGONALIZE(row1,row2,row3,row4) \ + row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(2,1,0,3) ); \ + row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ + row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(0,3,2,1) ); + +#define UNDIAGONALIZE(row1,row2,row3,row4) \ + row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(0,3,2,1) ); \ + row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ + row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) ); + +#if defined(HAVE_XOP) +#include "blake2s-load-xop.h" +#elif defined(HAVE_SSE41) +#include "blake2s-load-sse41.h" +#else +#include "blake2s-load-sse2.h" +#endif + +#define ROUND(r) \ + LOAD_MSG_ ##r ##_1(buf1); \ + G1(row1,row2,row3,row4,buf1); \ + LOAD_MSG_ ##r ##_2(buf2); \ + G2(row1,row2,row3,row4,buf2); \ + DIAGONALIZE(row1,row2,row3,row4); \ + LOAD_MSG_ ##r ##_3(buf3); \ + G1(row1,row2,row3,row4,buf3); \ + LOAD_MSG_ ##r ##_4(buf4); \ + G2(row1,row2,row3,row4,buf4); \ + UNDIAGONALIZE(row1,row2,row3,row4); \ + +#endif + diff --git a/Modules/_blake2/impl/blake2s.c b/Modules/_blake2/impl/blake2s.c new file mode 100644 index 0000000..69385dc --- /dev/null +++ b/Modules/_blake2/impl/blake2s.c @@ -0,0 +1,435 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include "blake2.h" +#include "blake2-impl.h" + +#include "blake2-config.h" + + +#include <emmintrin.h> +#if defined(HAVE_SSSE3) +#include <tmmintrin.h> +#endif +#if defined(HAVE_SSE41) +#include <smmintrin.h> +#endif +#if defined(HAVE_AVX) +#include <immintrin.h> +#endif +#if defined(HAVE_XOP) +#include <x86intrin.h> +#endif + +#include "blake2s-round.h" + +static const uint32_t blake2s_IV[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const uint8_t blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + + +/* Some helper functions, not necessarily useful */ +BLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S ) +{ + S->f[1] = -1; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S ) +{ + S->f[1] = 0; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S ) +{ + return S->f[0] != 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_set_lastnode( S ); + + S->f[0] = -1; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_clear_lastnode( S ); + + S->f[0] = 0; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) +{ + uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0]; + t += inc; + S->t[0] = ( uint32_t )( t >> 0 ); + S->t[1] = ( uint32_t )( t >> 32 ); + return 0; +} + + +/* Parameter-related functions */ +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) +{ + P->digest_length = digest_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) +{ + P->fanout = fanout; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) +{ + P->depth = depth; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) +{ + P->leaf_length = leaf_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) +{ + store48( P->node_offset, node_offset ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) +{ + P->node_depth = node_depth; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) +{ + P->inner_length = inner_length; + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) +{ + memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) +{ + memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); + return 0; +} + +BLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S ) +{ + int i; + memset( S, 0, sizeof( blake2s_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; + + return 0; +} + +/* init2 xors IV with input parameter block */ +int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + /*blake2s_init0( S ); */ + const uint8_t * v = ( const uint8_t * )( blake2s_IV ); + const uint8_t * p = ( const uint8_t * )( P ); + uint8_t * h = ( uint8_t * )( S->h ); + int i; + /* IV XOR ParamBlock */ + memset( S, 0, sizeof( blake2s_state ) ); + + for( i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; + + return 0; +} + + +/* Some sort of default parameter block initialization, for sequential blake2s */ +int blake2s_init( blake2s_state *S, const uint8_t outlen ) +{ + const blake2s_param P = + { + outlen, + 0, + 1, + 1, + 0, + {0}, + 0, + 0, + {0}, + {0} + }; + /* Move interval verification here? */ + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + return blake2s_init_param( S, &P ); +} + + +int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +{ + const blake2s_param P = + { + outlen, + keylen, + 1, + 1, + 0, + {0}, + 0, + 0, + {0}, + {0} + }; + + /* Move interval verification here? */ + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1; + + if( blake2s_init_param( S, &P ) < 0 ) + return -1; + + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + + +BLAKE2_LOCAL_INLINE(int) blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) +{ + __m128i row1, row2, row3, row4; + __m128i buf1, buf2, buf3, buf4; +#if defined(HAVE_SSE41) + __m128i t0, t1; +#if !defined(HAVE_XOP) + __m128i t2; +#endif +#endif + __m128i ff0, ff1; +#if defined(HAVE_SSSE3) && !defined(HAVE_XOP) + const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 ); + const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 ); +#endif +#if defined(HAVE_SSE41) + const __m128i m0 = LOADU( block + 00 ); + const __m128i m1 = LOADU( block + 16 ); + const __m128i m2 = LOADU( block + 32 ); + const __m128i m3 = LOADU( block + 48 ); +#else + const uint32_t m0 = ( ( uint32_t * )block )[ 0]; + const uint32_t m1 = ( ( uint32_t * )block )[ 1]; + const uint32_t m2 = ( ( uint32_t * )block )[ 2]; + const uint32_t m3 = ( ( uint32_t * )block )[ 3]; + const uint32_t m4 = ( ( uint32_t * )block )[ 4]; + const uint32_t m5 = ( ( uint32_t * )block )[ 5]; + const uint32_t m6 = ( ( uint32_t * )block )[ 6]; + const uint32_t m7 = ( ( uint32_t * )block )[ 7]; + const uint32_t m8 = ( ( uint32_t * )block )[ 8]; + const uint32_t m9 = ( ( uint32_t * )block )[ 9]; + const uint32_t m10 = ( ( uint32_t * )block )[10]; + const uint32_t m11 = ( ( uint32_t * )block )[11]; + const uint32_t m12 = ( ( uint32_t * )block )[12]; + const uint32_t m13 = ( ( uint32_t * )block )[13]; + const uint32_t m14 = ( ( uint32_t * )block )[14]; + const uint32_t m15 = ( ( uint32_t * )block )[15]; +#endif + row1 = ff0 = LOADU( &S->h[0] ); + row2 = ff1 = LOADU( &S->h[4] ); + row3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A ); + row4 = _mm_xor_si128( _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ), LOADU( &S->t[0] ) ); + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) ); + STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) ); + return 0; +} + +/* inlen now in bytes */ +int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) +{ + while( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = 2 * BLAKE2S_BLOCKBYTES - left; + + if( inlen > fill ) + { + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + S->buflen += fill; + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); /* Compress */ + memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */ + S->buflen -= BLAKE2S_BLOCKBYTES; + in += fill; + inlen -= fill; + } + else /* inlen <= fill */ + { + memcpy( S->buf + left, in, inlen ); + S->buflen += inlen; /* Be lazy, do not compress */ + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + +/* Is this correct? */ +int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ) +{ + uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; + int i; + + if( outlen > BLAKE2S_OUTBYTES ) + return -1; + + if( blake2s_is_lastblock( S ) ) + return -1; + + if( S->buflen > BLAKE2S_BLOCKBYTES ) + { + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); + S->buflen -= BLAKE2S_BLOCKBYTES; + memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); + } + + blake2s_increment_counter( S, ( uint32_t )S->buflen ); + blake2s_set_lastblock( S ); + memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + blake2s_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + return 0; +} + +/* inlen, at least, should be uint64_t. Others can be size_t. */ +int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +{ + blake2s_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if ( NULL == key && keylen > 0) return -1; + + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + if( keylen > BLAKE2S_KEYBYTES ) return -1; + + if( keylen > 0 ) + { + if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2s_init( S, outlen ) < 0 ) return -1; + } + + blake2s_update( S, ( const uint8_t * )in, inlen ); + blake2s_final( S, out, outlen ); + return 0; +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 ); +} +#endif + +#if defined(BLAKE2S_SELFTEST) +#include <string.h> +#include "blake2-kat.h" +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2S_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + size_t i; + + for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2S_OUTBYTES]; + + if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || + 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} +#endif + + diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index e3e0eb1..f4077fa 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -592,7 +592,6 @@ error: /*[clinic input] _bz2.BZ2Decompressor.decompress - self: self(type="BZ2Decompressor *") data: Py_buffer max_length: Py_ssize_t=-1 @@ -615,7 +614,7 @@ the unused_data attribute. static PyObject * _bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data, Py_ssize_t max_length) -/*[clinic end generated code: output=23e41045deb240a3 input=9558b424c8b00516]*/ +/*[clinic end generated code: output=23e41045deb240a3 input=52e1ffc66a8ea624]*/ { PyObject *result = NULL; diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 9b1194e..586b73a 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -20,10 +20,6 @@ <encoding>_decode(char_buffer_obj[,errors='strict']) -> (Unicode object, bytes consumed) - <encoding>_encode() interfaces also accept non-Unicode object as - input. The objects are then converted to Unicode using - PyUnicode_FromObject() prior to applying the conversion. - These <encoding>s are available: utf_8, unicode_escape, raw_unicode_escape, unicode_internal, latin_1, ascii (7-bit), mbcs (on win32). @@ -608,7 +604,7 @@ _codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, return codec_tuple(decoded, data->len); } -#ifdef HAVE_MBCS +#ifdef MS_WINDOWS /*[clinic input] _codecs.mbcs_decode @@ -630,6 +626,25 @@ _codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, } /*[clinic input] +_codecs.oem_decode + data: Py_buffer + errors: str(accept={str, NoneType}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_oem_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=da1617612f3fcad8 input=95b8a92c446b03cd]*/ +{ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeCodePageStateful(CP_OEMCP, + data->buf, data->len, errors, final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/*[clinic input] _codecs.code_page_decode codepage: int data: Py_buffer @@ -651,7 +666,7 @@ _codecs_code_page_decode_impl(PyObject *module, int codepage, return codec_tuple(decoded, consumed); } -#endif /* HAVE_MBCS */ +#endif /* MS_WINDOWS */ /* --- Encoder ------------------------------------------------------------ */ @@ -718,7 +733,7 @@ _codecs_unicode_internal_encode_impl(PyObject *module, PyObject *obj, /*[clinic input] _codecs.utf_7_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -726,24 +741,15 @@ _codecs.utf_7_encode static PyObject * _codecs_utf_7_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=0feda21ffc921bc8 input=fd91a78f103b0421]*/ +/*[clinic end generated code: output=0feda21ffc921bc8 input=d1a47579e79cbe15]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_EncodeUTF7(str, 0, 0, errors), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_EncodeUTF7(str, 0, 0, errors), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.utf_8_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -751,19 +757,10 @@ _codecs.utf_8_encode static PyObject * _codecs_utf_8_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=02bf47332b9c796c input=2c22d40532f071f3]*/ +/*[clinic end generated code: output=02bf47332b9c796c input=42e3ba73c4392eef]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(PyUnicode_AsEncodedString(str, "utf-8", errors), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_AsUTF8String(str, errors), + PyUnicode_GET_LENGTH(str)); } /* This version provides access to the byteorder parameter of the @@ -775,7 +772,7 @@ _codecs_utf_8_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.utf_16_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL byteorder: int = 0 / @@ -784,24 +781,15 @@ _codecs.utf_16_encode static PyObject * _codecs_utf_16_encode_impl(PyObject *module, PyObject *str, const char *errors, int byteorder) -/*[clinic end generated code: output=c654e13efa2e64e4 input=3935a489b2d5385e]*/ +/*[clinic end generated code: output=c654e13efa2e64e4 input=ff46416b04edb944]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_EncodeUTF16(str, errors, byteorder), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, byteorder), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.utf_16_le_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -809,24 +797,15 @@ _codecs.utf_16_le_encode static PyObject * _codecs_utf_16_le_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=431b01e55f2d4995 input=bc27df05d1d20dfe]*/ +/*[clinic end generated code: output=431b01e55f2d4995 input=cb385455ea8f2fe0]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_EncodeUTF16(str, errors, -1), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, -1), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.utf_16_be_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -834,19 +813,10 @@ _codecs.utf_16_be_encode static PyObject * _codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=96886a6fd54dcae3 input=5a69d4112763462b]*/ +/*[clinic end generated code: output=96886a6fd54dcae3 input=9119997066bdaefd]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_EncodeUTF16(str, errors, +1), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, +1), + PyUnicode_GET_LENGTH(str)); } /* This version provides access to the byteorder parameter of the @@ -858,7 +828,7 @@ _codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str, /*[clinic input] _codecs.utf_32_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL byteorder: int = 0 / @@ -867,24 +837,15 @@ _codecs.utf_32_encode static PyObject * _codecs_utf_32_encode_impl(PyObject *module, PyObject *str, const char *errors, int byteorder) -/*[clinic end generated code: output=5c760da0c09a8b83 input=434a1efa492b8d58]*/ +/*[clinic end generated code: output=5c760da0c09a8b83 input=c5e77da82fbe5c2a]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_EncodeUTF32(str, errors, byteorder), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, byteorder), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.utf_32_le_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -892,24 +853,15 @@ _codecs.utf_32_le_encode static PyObject * _codecs_utf_32_le_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=b65cd176de8e36d6 input=dfa2d7dc78b99422]*/ +/*[clinic end generated code: output=b65cd176de8e36d6 input=9993b25fe0877848]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_EncodeUTF32(str, errors, -1), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, -1), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.utf_32_be_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -917,24 +869,15 @@ _codecs.utf_32_be_encode static PyObject * _codecs_utf_32_be_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=1d9e71a9358709e9 input=4595617b18169002]*/ +/*[clinic end generated code: output=1d9e71a9358709e9 input=d3e0ccaa02920431]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_EncodeUTF32(str, errors, +1), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, +1), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.unicode_escape_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -942,24 +885,15 @@ _codecs.unicode_escape_encode static PyObject * _codecs_unicode_escape_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=66271b30bc4f7a3c input=8273506f14076912]*/ +/*[clinic end generated code: output=66271b30bc4f7a3c input=65d9eefca65b455a]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(PyUnicode_AsUnicodeEscapeString(str), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(PyUnicode_AsUnicodeEscapeString(str), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.raw_unicode_escape_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -967,24 +901,15 @@ _codecs.raw_unicode_escape_encode static PyObject * _codecs_raw_unicode_escape_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=a66a806ed01c830a input=181755d5dfacef3c]*/ +/*[clinic end generated code: output=a66a806ed01c830a input=5aa33e4a133391ab]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(PyUnicode_AsRawUnicodeEscapeString(str), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(PyUnicode_AsRawUnicodeEscapeString(str), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.latin_1_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -992,24 +917,15 @@ _codecs.latin_1_encode static PyObject * _codecs_latin_1_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=2c28c83a27884e08 input=f03f6dcf1d84bee4]*/ +/*[clinic end generated code: output=2c28c83a27884e08 input=30b11c9e49a65150]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_AsLatin1String(str, errors), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_AsLatin1String(str, errors), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.ascii_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -1017,24 +933,15 @@ _codecs.ascii_encode static PyObject * _codecs_ascii_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=b5e035182d33befc input=d87e25a10a593fee]*/ +/*[clinic end generated code: output=b5e035182d33befc input=843a1d268e6dfa8e]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_AsASCIIString(str, errors), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_AsASCIIString(str, errors), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.charmap_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL mapping: object = NULL / @@ -1043,22 +950,13 @@ _codecs.charmap_encode static PyObject * _codecs_charmap_encode_impl(PyObject *module, PyObject *str, const char *errors, PyObject *mapping) -/*[clinic end generated code: output=047476f48495a9e9 input=85f4172661e8dad9]*/ +/*[clinic end generated code: output=047476f48495a9e9 input=0752cde07a6d6d00]*/ { - PyObject *v; - if (mapping == Py_None) mapping = NULL; - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(_PyUnicode_EncodeCharmap(str, mapping, errors), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(_PyUnicode_EncodeCharmap(str, mapping, errors), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] @@ -1074,36 +972,42 @@ _codecs_charmap_build_impl(PyObject *module, PyObject *map) return PyUnicode_BuildEncodingMap(map); } -#ifdef HAVE_MBCS +#ifdef MS_WINDOWS /*[clinic input] _codecs.mbcs_encode - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ static PyObject * _codecs_mbcs_encode_impl(PyObject *module, PyObject *str, const char *errors) -/*[clinic end generated code: output=76e2e170c966c080 input=65c09ee1e4203263]*/ +/*[clinic end generated code: output=76e2e170c966c080 input=de471e0815947553]*/ { - PyObject *v; + return codec_tuple(PyUnicode_EncodeCodePage(CP_ACP, str, errors), + PyUnicode_GET_LENGTH(str)); +} - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(PyUnicode_EncodeCodePage(CP_ACP, str, errors), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; +/*[clinic input] +_codecs.oem_encode + str: unicode + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + +static PyObject * +_codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors) +/*[clinic end generated code: output=65d5982c737de649 input=3fc5f0028aad3cda]*/ +{ + return codec_tuple(PyUnicode_EncodeCodePage(CP_OEMCP, str, errors), + PyUnicode_GET_LENGTH(str)); } /*[clinic input] _codecs.code_page_encode code_page: int - str: object + str: unicode errors: str(accept={str, NoneType}) = NULL / [clinic start generated code]*/ @@ -1111,24 +1015,13 @@ _codecs.code_page_encode static PyObject * _codecs_code_page_encode_impl(PyObject *module, int code_page, PyObject *str, const char *errors) -/*[clinic end generated code: output=45673f6085657a9e input=c8562ec460c2e309]*/ +/*[clinic end generated code: output=45673f6085657a9e input=786421ae617d680b]*/ { - PyObject *v; - - str = PyUnicode_FromObject(str); - if (str == NULL || PyUnicode_READY(str) < 0) { - Py_XDECREF(str); - return NULL; - } - v = codec_tuple(PyUnicode_EncodeCodePage(code_page, - str, - errors), - PyUnicode_GET_LENGTH(str)); - Py_DECREF(str); - return v; + return codec_tuple(PyUnicode_EncodeCodePage(code_page, str, errors), + PyUnicode_GET_LENGTH(str)); } -#endif /* HAVE_MBCS */ +#endif /* MS_WINDOWS */ /* --- Error handler registry --------------------------------------------- */ @@ -1216,6 +1109,8 @@ static PyMethodDef _codecs_functions[] = { _CODECS_READBUFFER_ENCODE_METHODDEF _CODECS_MBCS_ENCODE_METHODDEF _CODECS_MBCS_DECODE_METHODDEF + _CODECS_OEM_ENCODE_METHODDEF + _CODECS_OEM_DECODE_METHODDEF _CODECS_CODE_PAGE_ENCODE_METHODDEF _CODECS_CODE_PAGE_DECODE_METHODDEF _CODECS_REGISTER_ERROR_METHODDEF diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 10fbcfe..1675102 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -81,7 +81,7 @@ typedef struct { Py_ssize_t leftindex; /* 0 <= leftindex < BLOCKLEN */ Py_ssize_t rightindex; /* 0 <= rightindex < BLOCKLEN */ size_t state; /* incremented whenever the indices move */ - Py_ssize_t maxlen; + Py_ssize_t maxlen; /* maxlen is -1 for unbounded deques */ PyObject *weakreflist; } dequeobject; @@ -108,29 +108,18 @@ static PyTypeObject deque_type; #define CHECK_NOT_END(link) #endif -/* To prevent len from overflowing PY_SSIZE_T_MAX, we refuse to - allocate new blocks if the current len is nearing overflow. -*/ - -#define MAX_DEQUE_LEN (PY_SSIZE_T_MAX - 3*BLOCKLEN) - /* A simple freelisting scheme is used to minimize calls to the memory allocator. It accommodates common use cases where new blocks are being added at about the same rate as old blocks are being freed. */ -#define MAXFREEBLOCKS 10 +#define MAXFREEBLOCKS 16 static Py_ssize_t numfreeblocks = 0; static block *freeblocks[MAXFREEBLOCKS]; static block * -newblock(Py_ssize_t len) { +newblock(void) { block *b; - if (len >= MAX_DEQUE_LEN) { - PyErr_SetString(PyExc_OverflowError, - "cannot add more blocks to the deque"); - return NULL; - } if (numfreeblocks) { numfreeblocks--; return freeblocks[numfreeblocks]; @@ -154,12 +143,6 @@ freeblock(block *b) } } -/* XXX Todo: - If aligned memory allocations become available, make the - deque object 64 byte aligned so that all of the fields - can be retrieved or updated in a single cache line. -*/ - static PyObject * deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -171,7 +154,7 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (deque == NULL) return NULL; - b = newblock(0); + b = newblock(); if (b == NULL) { Py_DECREF(deque); return NULL; @@ -207,7 +190,7 @@ deque_pop(dequeobject *deque, PyObject *unused) Py_SIZE(deque)--; deque->state++; - if (deque->rightindex == -1) { + if (deque->rightindex < 0) { if (Py_SIZE(deque)) { prevblock = deque->rightblock->leftlink; assert(deque->leftblock != deque->rightblock); @@ -270,42 +253,24 @@ PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element."); /* The deque's size limit is d.maxlen. The limit can be zero or positive. * If there is no limit, then d.maxlen == -1. * - * After an item is added to a deque, we check to see if the size has grown past - * the limit. If it has, we get the size back down to the limit by popping an - * item off of the opposite end. The methods that can trigger this are append(), - * appendleft(), extend(), and extendleft(). + * After an item is added to a deque, we check to see if the size has + * grown past the limit. If it has, we get the size back down to the limit + * by popping an item off of the opposite end. The methods that can + * trigger this are append(), appendleft(), extend(), and extendleft(). + * + * The macro to check whether a deque needs to be trimmed uses a single + * unsigned test that returns true whenever 0 <= maxlen < Py_SIZE(deque). */ -static void -deque_trim_right(dequeobject *deque) -{ - if (deque->maxlen != -1 && Py_SIZE(deque) > deque->maxlen) { - PyObject *rv = deque_pop(deque, NULL); - assert(rv != NULL); - assert(Py_SIZE(deque) <= deque->maxlen); - Py_DECREF(rv); - } -} +#define NEEDS_TRIM(deque, maxlen) ((size_t)(maxlen) < (size_t)(Py_SIZE(deque))) -static void -deque_trim_left(dequeobject *deque) -{ - if (deque->maxlen != -1 && Py_SIZE(deque) > deque->maxlen) { - PyObject *rv = deque_popleft(deque, NULL); - assert(rv != NULL); - assert(Py_SIZE(deque) <= deque->maxlen); - Py_DECREF(rv); - } -} - -static PyObject * -deque_append(dequeobject *deque, PyObject *item) +static int +deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) { - deque->state++; if (deque->rightindex == BLOCKLEN - 1) { - block *b = newblock(Py_SIZE(deque)); + block *b = newblock(); if (b == NULL) - return NULL; + return -1; b->leftlink = deque->rightblock; CHECK_END(deque->rightblock->rightlink); deque->rightblock->rightlink = b; @@ -313,24 +278,36 @@ deque_append(dequeobject *deque, PyObject *item) MARK_END(b->rightlink); deque->rightindex = -1; } - Py_INCREF(item); Py_SIZE(deque)++; deque->rightindex++; deque->rightblock->data[deque->rightindex] = item; - deque_trim_left(deque); + if (NEEDS_TRIM(deque, maxlen)) { + PyObject *olditem = deque_popleft(deque, NULL); + Py_DECREF(olditem); + } else { + deque->state++; + } + return 0; +} + +static PyObject * +deque_append(dequeobject *deque, PyObject *item) +{ + Py_INCREF(item); + if (deque_append_internal(deque, item, deque->maxlen) < 0) + return NULL; Py_RETURN_NONE; } PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque."); -static PyObject * -deque_appendleft(dequeobject *deque, PyObject *item) +static int +deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) { - deque->state++; if (deque->leftindex == 0) { - block *b = newblock(Py_SIZE(deque)); + block *b = newblock(); if (b == NULL) - return NULL; + return -1; b->rightlink = deque->leftblock; CHECK_END(deque->leftblock->leftlink); deque->leftblock->leftlink = b; @@ -338,37 +315,65 @@ deque_appendleft(dequeobject *deque, PyObject *item) MARK_END(b->leftlink); deque->leftindex = BLOCKLEN; } - Py_INCREF(item); Py_SIZE(deque)++; deque->leftindex--; deque->leftblock->data[deque->leftindex] = item; - deque_trim_right(deque); + if (NEEDS_TRIM(deque, deque->maxlen)) { + PyObject *olditem = deque_pop(deque, NULL); + Py_DECREF(olditem); + } else { + deque->state++; + } + return 0; +} + +static PyObject * +deque_appendleft(dequeobject *deque, PyObject *item) +{ + Py_INCREF(item); + if (deque_appendleft_internal(deque, item, deque->maxlen) < 0) + return NULL; Py_RETURN_NONE; } PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque."); +static PyObject* +finalize_iterator(PyObject *it) +{ + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else { + Py_DECREF(it); + return NULL; + } + } + Py_DECREF(it); + Py_RETURN_NONE; +} /* Run an iterator to exhaustion. Shortcut for the extend/extendleft methods when maxlen == 0. */ static PyObject* consume_iterator(PyObject *it) { + PyObject *(*iternext)(PyObject *); PyObject *item; - while ((item = PyIter_Next(it)) != NULL) { + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { Py_DECREF(item); } - Py_DECREF(it); - if (PyErr_Occurred()) - return NULL; - Py_RETURN_NONE; + return finalize_iterator(it); } static PyObject * deque_extend(dequeobject *deque, PyObject *iterable) { PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + Py_ssize_t maxlen = deque->maxlen; /* Handle case where id(deque) == id(iterable) */ if ((PyObject *)deque == iterable) { @@ -381,6 +386,13 @@ deque_extend(dequeobject *deque, PyObject *iterable) return result; } + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + + if (maxlen == 0) + return consume_iterator(it); + /* Space saving heuristic. Start filling from the left */ if (Py_SIZE(deque) == 0) { assert(deque->leftblock == deque->rightblock); @@ -389,40 +401,15 @@ deque_extend(dequeobject *deque, PyObject *iterable) deque->rightindex = 0; } - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - if (deque->maxlen == 0) - return consume_iterator(it); - - while ((item = PyIter_Next(it)) != NULL) { - deque->state++; - if (deque->rightindex == BLOCKLEN - 1) { - block *b = newblock(Py_SIZE(deque)); - if (b == NULL) { - Py_DECREF(item); - Py_DECREF(it); - return NULL; - } - b->leftlink = deque->rightblock; - CHECK_END(deque->rightblock->rightlink); - deque->rightblock->rightlink = b; - deque->rightblock = b; - MARK_END(b->rightlink); - deque->rightindex = -1; + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { + if (deque_append_internal(deque, item, maxlen) < 0) { + Py_DECREF(item); + Py_DECREF(it); + return NULL; } - Py_SIZE(deque)++; - deque->rightindex++; - deque->rightblock->data[deque->rightindex] = item; - deque_trim_left(deque); } - if (PyErr_Occurred()) { - Py_DECREF(it); - return NULL; - } - Py_DECREF(it); - Py_RETURN_NONE; + return finalize_iterator(it); } PyDoc_STRVAR(extend_doc, @@ -432,6 +419,8 @@ static PyObject * deque_extendleft(dequeobject *deque, PyObject *iterable) { PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + Py_ssize_t maxlen = deque->maxlen; /* Handle case where id(deque) == id(iterable) */ if ((PyObject *)deque == iterable) { @@ -444,6 +433,13 @@ deque_extendleft(dequeobject *deque, PyObject *iterable) return result; } + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + + if (maxlen == 0) + return consume_iterator(it); + /* Space saving heuristic. Start filling from the right */ if (Py_SIZE(deque) == 0) { assert(deque->leftblock == deque->rightblock); @@ -452,40 +448,15 @@ deque_extendleft(dequeobject *deque, PyObject *iterable) deque->rightindex = BLOCKLEN - 2; } - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - if (deque->maxlen == 0) - return consume_iterator(it); - - while ((item = PyIter_Next(it)) != NULL) { - deque->state++; - if (deque->leftindex == 0) { - block *b = newblock(Py_SIZE(deque)); - if (b == NULL) { - Py_DECREF(item); - Py_DECREF(it); - return NULL; - } - b->rightlink = deque->leftblock; - CHECK_END(deque->leftblock->leftlink); - deque->leftblock->leftlink = b; - deque->leftblock = b; - MARK_END(b->leftlink); - deque->leftindex = BLOCKLEN; + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { + if (deque_appendleft_internal(deque, item, maxlen) < 0) { + Py_DECREF(item); + Py_DECREF(it); + return NULL; } - Py_SIZE(deque)++; - deque->leftindex--; - deque->leftblock->data[deque->leftindex] = item; - deque_trim_right(deque); - } - if (PyErr_Occurred()) { - Py_DECREF(it); - return NULL; } - Py_DECREF(it); - Py_RETURN_NONE; + return finalize_iterator(it); } PyDoc_STRVAR(extendleft_doc, @@ -504,7 +475,40 @@ deque_inplace_concat(dequeobject *deque, PyObject *other) return (PyObject *)deque; } -static PyObject *deque_copy(PyObject *deque); +static PyObject * +deque_copy(PyObject *deque) +{ + dequeobject *old_deque = (dequeobject *)deque; + if (Py_TYPE(deque) == &deque_type) { + dequeobject *new_deque; + PyObject *rv; + + new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL); + if (new_deque == NULL) + return NULL; + new_deque->maxlen = old_deque->maxlen; + /* Fast path for the deque_repeat() common case where len(deque) == 1 */ + if (Py_SIZE(deque) == 1) { + PyObject *item = old_deque->leftblock->data[old_deque->leftindex]; + rv = deque_append(new_deque, item); + } else { + rv = deque_extend(new_deque, deque); + } + if (rv != NULL) { + Py_DECREF(rv); + return (PyObject *)new_deque; + } + Py_DECREF(new_deque); + return NULL; + } + if (old_deque->maxlen < 0) + return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL); + else + return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", + deque, old_deque->maxlen, NULL); +} + +PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); static PyObject * deque_concat(dequeobject *deque, PyObject *other) @@ -534,38 +538,102 @@ deque_concat(dequeobject *deque, PyObject *other) return new_deque; } -static void deque_clear(dequeobject *deque); - -static PyObject * -deque_repeat(dequeobject *deque, Py_ssize_t n) +static void +deque_clear(dequeobject *deque) { - dequeobject *new_deque; - PyObject *result; + block *b; + block *prevblock; + block *leftblock; + Py_ssize_t leftindex; + Py_ssize_t n, m; + PyObject *item; + PyObject **itemptr, **limit; - /* XXX add a special case for when maxlen is defined */ - if (n < 0) - n = 0; - else if (n > 0 && Py_SIZE(deque) > MAX_DEQUE_LEN / n) - return PyErr_NoMemory(); + if (Py_SIZE(deque) == 0) + return; - new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL); - new_deque->maxlen = deque->maxlen; + /* During the process of clearing a deque, decrefs can cause the + deque to mutate. To avoid fatal confusion, we have to make the + deque empty before clearing the blocks and never refer to + anything via deque->ref while clearing. (This is the same + technique used for clearing lists, sets, and dicts.) - for ( ; n ; n--) { - result = deque_extend(new_deque, (PyObject *)deque); - if (result == NULL) { - Py_DECREF(new_deque); - return NULL; + Making the deque empty requires allocating a new empty block. In + the unlikely event that memory is full, we fall back to an + alternate method that doesn't require a new block. Repeating + pops in a while-loop is slower, possibly re-entrant (and a clever + adversary could cause it to never terminate). + */ + + b = newblock(); + if (b == NULL) { + PyErr_Clear(); + goto alternate_method; + } + + /* Remember the old size, leftblock, and leftindex */ + n = Py_SIZE(deque); + leftblock = deque->leftblock; + leftindex = deque->leftindex; + + /* Set the deque to be empty using the newly allocated block */ + MARK_END(b->leftlink); + MARK_END(b->rightlink); + Py_SIZE(deque) = 0; + deque->leftblock = b; + deque->rightblock = b; + deque->leftindex = CENTER + 1; + deque->rightindex = CENTER; + deque->state++; + + /* Now the old size, leftblock, and leftindex are disconnected from + the empty deque and we can use them to decref the pointers. + */ + m = (BLOCKLEN - leftindex > n) ? n : BLOCKLEN - leftindex; + itemptr = &leftblock->data[leftindex]; + limit = itemptr + m; + n -= m; + while (1) { + if (itemptr == limit) { + if (n == 0) + break; + CHECK_NOT_END(leftblock->rightlink); + prevblock = leftblock; + leftblock = leftblock->rightlink; + m = (n > BLOCKLEN) ? BLOCKLEN : n; + itemptr = leftblock->data; + limit = itemptr + m; + n -= m; + freeblock(prevblock); } - Py_DECREF(result); + item = *(itemptr++); + Py_DECREF(item); } - return (PyObject *)new_deque; + CHECK_END(leftblock->rightlink); + freeblock(leftblock); + return; + + alternate_method: + while (Py_SIZE(deque)) { + item = deque_pop(deque, NULL); + assert (item != NULL); + Py_DECREF(item); + } +} + +static PyObject * +deque_clearmethod(dequeobject *deque) +{ + deque_clear(deque); + Py_RETURN_NONE; } +PyDoc_STRVAR(clear_doc, "Remove all elements from the deque."); + static PyObject * deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) { - Py_ssize_t i, size; + Py_ssize_t i, m, size; PyObject *seq; PyObject *rv; @@ -581,27 +649,47 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) return (PyObject *)deque; } - if (size > MAX_DEQUE_LEN / n) { - return PyErr_NoMemory(); - } - if (size == 1) { /* common case, repeating a single element */ PyObject *item = deque->leftblock->data[deque->leftindex]; - if (deque->maxlen != -1 && n > deque->maxlen) + if (deque->maxlen >= 0 && n > deque->maxlen) n = deque->maxlen; - for (i = 0 ; i < n-1 ; i++) { - rv = deque_append(deque, item); - if (rv == NULL) - return NULL; - Py_DECREF(rv); + deque->state++; + for (i = 0 ; i < n-1 ; ) { + if (deque->rightindex == BLOCKLEN - 1) { + block *b = newblock(); + if (b == NULL) { + Py_SIZE(deque) += i; + return NULL; + } + b->leftlink = deque->rightblock; + CHECK_END(deque->rightblock->rightlink); + deque->rightblock->rightlink = b; + deque->rightblock = b; + MARK_END(b->rightlink); + deque->rightindex = -1; + } + m = n - 1 - i; + if (m > BLOCKLEN - 1 - deque->rightindex) + m = BLOCKLEN - 1 - deque->rightindex; + i += m; + while (m--) { + deque->rightindex++; + Py_INCREF(item); + deque->rightblock->data[deque->rightindex] = item; + } } + Py_SIZE(deque) += i; Py_INCREF(deque); return (PyObject *)deque; } + if ((size_t)size > PY_SSIZE_T_MAX / (size_t)n) { + return PyErr_NoMemory(); + } + seq = PySequence_List((PyObject *)deque); if (seq == NULL) return seq; @@ -619,6 +707,20 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) return (PyObject *)deque; } +static PyObject * +deque_repeat(dequeobject *deque, Py_ssize_t n) +{ + dequeobject *new_deque; + PyObject *rv; + + new_deque = (dequeobject *)deque_copy((PyObject *) deque); + if (new_deque == NULL) + return NULL; + rv = deque_inplace_repeat(new_deque, n); + Py_DECREF(new_deque); + return rv; +} + /* The rotate() method is part of the public API and is used internally as a primitive for other methods. @@ -671,7 +773,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n) while (n > 0) { if (leftindex == 0) { if (b == NULL) { - b = newblock(len); + b = newblock(); if (b == NULL) goto done; } @@ -702,7 +804,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n) *(dest++) = *(src++); } while (--m); } - if (rightindex == -1) { + if (rightindex < 0) { assert(leftblock != rightblock); assert(b == NULL); b = rightblock; @@ -715,7 +817,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n) while (n < 0) { if (rightindex == BLOCKLEN - 1) { if (b == NULL) { - b = newblock(len); + b = newblock(); if (b == NULL) goto done; } @@ -790,11 +892,11 @@ deque_reverse(dequeobject *deque, PyObject *unused) block *rightblock = deque->rightblock; Py_ssize_t leftindex = deque->leftindex; Py_ssize_t rightindex = deque->rightindex; - Py_ssize_t n = Py_SIZE(deque) / 2; - Py_ssize_t i; + Py_ssize_t n = Py_SIZE(deque) >> 1; PyObject *tmp; - for (i=0 ; i<n ; i++) { + n++; + while (--n) { /* Validate that pointers haven't met in the middle */ assert(leftblock != rightblock || leftindex < rightindex); CHECK_NOT_END(leftblock); @@ -814,7 +916,7 @@ deque_reverse(dequeobject *deque, PyObject *unused) /* Step backwards with the right block/index pair */ rightindex--; - if (rightindex == -1) { + if (rightindex < 0) { rightblock = rightblock->leftlink; rightindex = BLOCKLEN - 1; } @@ -831,20 +933,19 @@ deque_count(dequeobject *deque, PyObject *v) block *b = deque->leftblock; Py_ssize_t index = deque->leftindex; Py_ssize_t n = Py_SIZE(deque); - Py_ssize_t i; Py_ssize_t count = 0; size_t start_state = deque->state; PyObject *item; int cmp; - for (i=0 ; i<n ; i++) { + n++; + while (--n) { CHECK_NOT_END(b); item = b->data[index]; cmp = PyObject_RichCompareBool(item, v, Py_EQ); - if (cmp > 0) - count++; - else if (cmp < 0) + if (cmp < 0) return NULL; + count += cmp; if (start_state != deque->state) { PyErr_SetString(PyExc_RuntimeError, @@ -871,12 +972,12 @@ deque_contains(dequeobject *deque, PyObject *v) block *b = deque->leftblock; Py_ssize_t index = deque->leftindex; Py_ssize_t n = Py_SIZE(deque); - Py_ssize_t i; size_t start_state = deque->state; PyObject *item; int cmp; - for (i=0 ; i<n ; i++) { + n++; + while (--n) { CHECK_NOT_END(b); item = b->data[index]; cmp = PyObject_RichCompareBool(item, v, Py_EQ); @@ -906,11 +1007,12 @@ deque_len(dequeobject *deque) static PyObject * deque_index(dequeobject *deque, PyObject *args) { - Py_ssize_t i, start=0, stop=Py_SIZE(deque); + Py_ssize_t i, n, start=0, stop=Py_SIZE(deque); PyObject *v, *item; block *b = deque->leftblock; Py_ssize_t index = deque->leftindex; size_t start_state = deque->state; + int cmp; if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, _PyEval_SliceIndex, &start, @@ -928,22 +1030,32 @@ deque_index(dequeobject *deque, PyObject *args) } if (stop > Py_SIZE(deque)) stop = Py_SIZE(deque); + if (start > stop) + start = stop; + assert(0 <= start && start <= stop && stop <= Py_SIZE(deque)); - for (i=0 ; i<stop ; i++) { - if (i >= start) { - int cmp; - CHECK_NOT_END(b); - item = b->data[index]; - cmp = PyObject_RichCompareBool(item, v, Py_EQ); - if (cmp > 0) - return PyLong_FromSsize_t(i); - else if (cmp < 0) - return NULL; - if (start_state != deque->state) { - PyErr_SetString(PyExc_RuntimeError, - "deque mutated during iteration"); - return NULL; - } + /* XXX Replace this loop with faster code from deque_item() */ + for (i=0 ; i<start ; i++) { + index++; + if (index == BLOCKLEN) { + b = b->rightlink; + index = 0; + } + } + + n = stop - i + 1; + while (--n) { + CHECK_NOT_END(b); + item = b->data[index]; + cmp = PyObject_RichCompareBool(item, v, Py_EQ); + if (cmp > 0) + return PyLong_FromSsize_t(stop - n); + if (cmp < 0) + return NULL; + if (start_state != deque->state) { + PyErr_SetString(PyExc_RuntimeError, + "deque mutated during iteration"); + return NULL; } index++; if (index == BLOCKLEN) { @@ -1037,84 +1149,10 @@ deque_remove(dequeobject *deque, PyObject *value) PyDoc_STRVAR(remove_doc, "D.remove(value) -- remove first occurrence of value."); -static void -deque_clear(dequeobject *deque) -{ - block *b; - block *prevblock; - block *leftblock; - Py_ssize_t leftindex; - Py_ssize_t n; - PyObject *item; - - if (Py_SIZE(deque) == 0) - return; - - /* During the process of clearing a deque, decrefs can cause the - deque to mutate. To avoid fatal confusion, we have to make the - deque empty before clearing the blocks and never refer to - anything via deque->ref while clearing. (This is the same - technique used for clearing lists, sets, and dicts.) - - Making the deque empty requires allocating a new empty block. In - the unlikely event that memory is full, we fall back to an - alternate method that doesn't require a new block. Repeating - pops in a while-loop is slower, possibly re-entrant (and a clever - adversary could cause it to never terminate). - */ - - b = newblock(0); - if (b == NULL) { - PyErr_Clear(); - goto alternate_method; - } - - /* Remember the old size, leftblock, and leftindex */ - leftblock = deque->leftblock; - leftindex = deque->leftindex; - n = Py_SIZE(deque); - - /* Set the deque to be empty using the newly allocated block */ - MARK_END(b->leftlink); - MARK_END(b->rightlink); - Py_SIZE(deque) = 0; - deque->leftblock = b; - deque->rightblock = b; - deque->leftindex = CENTER + 1; - deque->rightindex = CENTER; - deque->state++; - - /* Now the old size, leftblock, and leftindex are disconnected from - the empty deque and we can use them to decref the pointers. - */ - while (n--) { - item = leftblock->data[leftindex]; - Py_DECREF(item); - leftindex++; - if (leftindex == BLOCKLEN && n) { - CHECK_NOT_END(leftblock->rightlink); - prevblock = leftblock; - leftblock = leftblock->rightlink; - leftindex = 0; - freeblock(prevblock); - } - } - CHECK_END(leftblock->rightlink); - freeblock(leftblock); - return; - - alternate_method: - while (Py_SIZE(deque)) { - item = deque_pop(deque, NULL); - assert (item != NULL); - Py_DECREF(item); - } -} - static int valid_index(Py_ssize_t i, Py_ssize_t limit) { - /* The cast to size_t let us use just a single comparison + /* The cast to size_t lets us use just a single comparison to check whether i is in the range: 0 <= i < limit */ return (size_t) i < (size_t) limit; } @@ -1143,14 +1181,16 @@ deque_item(dequeobject *deque, Py_ssize_t i) i = (Py_ssize_t)((size_t) i % BLOCKLEN); if (index < (Py_SIZE(deque) >> 1)) { b = deque->leftblock; - while (n--) + n++; + while (--n) b = b->rightlink; } else { n = (Py_ssize_t)( ((size_t)(deque->leftindex + Py_SIZE(deque) - 1)) / BLOCKLEN - n); b = deque->rightblock; - while (n--) + n++; + while (--n) b = b->leftlink; } } @@ -1194,14 +1234,16 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) i = (Py_ssize_t)((size_t) i % BLOCKLEN); if (index <= halflen) { b = deque->leftblock; - while (n--) + n++; + while (--n) b = b->rightlink; } else { n = (Py_ssize_t)( ((size_t)(deque->leftindex + Py_SIZE(deque) - 1)) / BLOCKLEN - n); b = deque->rightblock; - while (n--) + n++; + while (--n) b = b->leftlink; } Py_INCREF(v); @@ -1211,15 +1253,6 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) return 0; } -static PyObject * -deque_clearmethod(dequeobject *deque) -{ - deque_clear(deque); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(clear_doc, "Remove all elements from the deque."); - static void deque_dealloc(dequeobject *deque) { @@ -1243,6 +1276,7 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg) PyObject *item; Py_ssize_t index; Py_ssize_t indexlo = deque->leftindex; + Py_ssize_t indexhigh; for (b = deque->leftblock; b != deque->rightblock; b = b->rightlink) { for (index = indexlo; index < BLOCKLEN ; index++) { @@ -1251,7 +1285,8 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg) } indexlo = 0; } - for (index = indexlo; index <= deque->rightindex; index++) { + indexhigh = deque->rightindex; + for (index = indexlo; index <= indexhigh; index++) { item = b->data[index]; Py_VISIT(item); } @@ -1259,45 +1294,33 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg) } static PyObject * -deque_copy(PyObject *deque) -{ - if (((dequeobject *)deque)->maxlen == -1) - return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL); - else - return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", - deque, ((dequeobject *)deque)->maxlen, NULL); -} - -PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); - -static PyObject * deque_reduce(dequeobject *deque) { - PyObject *dict, *result, *aslist; + PyObject *dict, *it; _Py_IDENTIFIER(__dict__); dict = _PyObject_GetAttrId((PyObject *)deque, &PyId___dict__); - if (dict == NULL) + if (dict == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + return NULL; + } PyErr_Clear(); - aslist = PySequence_List((PyObject *)deque); - if (aslist == NULL) { - Py_XDECREF(dict); + dict = Py_None; + Py_INCREF(dict); + } + + it = PyObject_GetIter((PyObject *)deque); + if (it == NULL) { + Py_DECREF(dict); return NULL; } - if (dict == NULL) { - if (deque->maxlen == -1) - result = Py_BuildValue("O(O)", Py_TYPE(deque), aslist); - else - result = Py_BuildValue("O(On)", Py_TYPE(deque), aslist, deque->maxlen); - } else { - if (deque->maxlen == -1) - result = Py_BuildValue("O(OO)O", Py_TYPE(deque), aslist, Py_None, dict); - else - result = Py_BuildValue("O(On)O", Py_TYPE(deque), aslist, deque->maxlen, dict); + + if (deque->maxlen < 0) { + return Py_BuildValue("O()NN", Py_TYPE(deque), dict, it); + } + else { + return Py_BuildValue("O(()n)NN", Py_TYPE(deque), deque->maxlen, dict, it); } - Py_XDECREF(dict); - Py_DECREF(aslist); - return result; } PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); @@ -1320,7 +1343,7 @@ deque_repr(PyObject *deque) Py_ReprLeave(deque); return NULL; } - if (((dequeobject *)deque)->maxlen != -1) + if (((dequeobject *)deque)->maxlen >= 0) result = PyUnicode_FromFormat("deque(%R, maxlen=%zd)", aslist, ((dequeobject *)deque)->maxlen); else @@ -1381,7 +1404,7 @@ deque_richcompare(PyObject *v, PyObject *w, int op) } Py_DECREF(x); Py_DECREF(y); - if (b == -1) + if (b < 0) goto done; } /* We reached the end of one deque or both */ @@ -1416,8 +1439,14 @@ deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs) Py_ssize_t maxlen = -1; char *kwlist[] = {"iterable", "maxlen", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist, &iterable, &maxlenobj)) - return -1; + if (kwdargs == NULL) { + if (!PyArg_UnpackTuple(args, "deque()", 0, 2, &iterable, &maxlenobj)) + return -1; + } else { + if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist, + &iterable, &maxlenobj)) + return -1; + } if (maxlenobj != NULL && maxlenobj != Py_None) { maxlen = PyLong_AsSsize_t(maxlenobj); if (maxlen == -1 && PyErr_Occurred()) @@ -1446,7 +1475,7 @@ deque_sizeof(dequeobject *deque, void *unused) Py_ssize_t blocks; res = _PyObject_SIZE(Py_TYPE(deque)); - blocks = (deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN; + blocks = (size_t)(deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN; assert(deque->leftindex + Py_SIZE(deque) - 1 == (blocks - 1) * BLOCKLEN + deque->rightindex); res += blocks * sizeof(block); @@ -1465,7 +1494,7 @@ deque_bool(dequeobject *deque) static PyObject * deque_get_maxlen(dequeobject *deque) { - if (deque->maxlen == -1) + if (deque->maxlen < 0) Py_RETURN_NONE; return PyLong_FromSsize_t(deque->maxlen); } @@ -1806,7 +1835,7 @@ dequereviter_next(dequeiterobject *it) item = it->b->data[it->index]; it->index--; it->counter--; - if (it->index == -1 && it->counter > 0) { + if (it->index < 0 && it->counter > 0) { CHECK_NOT_END(it->b->leftlink); it->b = it->b->leftlink; it->index = BLOCKLEN - 1; @@ -1980,7 +2009,7 @@ defdict_reduce(defdictobject *dd) args = PyTuple_Pack(1, dd->default_factory); if (args == NULL) return NULL; - items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, "()"); + items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, NULL); if (items == NULL) { Py_DECREF(args); return NULL; @@ -2235,13 +2264,13 @@ _count_elements(PyObject *self, PyObject *args) oldval = _PyDict_GetItem_KnownHash(mapping, key, hash); if (oldval == NULL) { - if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) == -1) + if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) < 0) goto done; } else { newval = PyNumber_Add(oldval, one); if (newval == NULL) goto done; - if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) == -1) + if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0) goto done; Py_CLEAR(newval); } @@ -2267,7 +2296,7 @@ _count_elements(PyObject *self, PyObject *args) Py_DECREF(oldval); if (newval == NULL) break; - if (PyObject_SetItem(mapping, key, newval) == -1) + if (PyObject_SetItem(mapping, key, newval) < 0) break; Py_CLEAR(newval); Py_DECREF(key); diff --git a/Modules/_csv.c b/Modules/_csv.c index b428279..7a78541 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -60,10 +60,10 @@ typedef enum { typedef struct { QuoteStyle style; - char *name; + const char *name; } StyleDesc; -static StyleDesc quote_styles[] = { +static const StyleDesc quote_styles[] = { { QUOTE_MINIMAL, "QUOTE_MINIMAL" }, { QUOTE_ALL, "QUOTE_ALL" }, { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" }, @@ -286,7 +286,7 @@ _set_str(const char *name, PyObject **target, PyObject *src, const char *dflt) static int dialect_check_quoting(int quoting) { - StyleDesc *qs; + const StyleDesc *qs; for (qs = quote_styles; qs->name; qs++) { if ((int)qs->style == quoting) @@ -518,15 +518,13 @@ static PyTypeObject Dialect_Type = { static PyObject * _call_dialect(PyObject *dialect_inst, PyObject *kwargs) { - PyObject *ctor_args; - PyObject *dialect; - - ctor_args = Py_BuildValue(dialect_inst ? "(O)" : "()", dialect_inst); - if (ctor_args == NULL) - return NULL; - dialect = PyObject_Call((PyObject *)&Dialect_Type, ctor_args, kwargs); - Py_DECREF(ctor_args); - return dialect; + PyObject *type = (PyObject *)&Dialect_Type; + if (dialect_inst) { + return _PyObject_FastCallDict(type, &dialect_inst, 1, kwargs); + } + else { + return _PyObject_FastCallDict(type, NULL, 0, kwargs); + } } /* @@ -1648,7 +1646,7 @@ PyMODINIT_FUNC PyInit__csv(void) { PyObject *module; - StyleDesc *style; + const StyleDesc *style; if (PyType_Ready(&Dialect_Type) < 0) return NULL; diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 7de9cee..b3a9581 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -111,12 +111,6 @@ bytes(cdata) #ifndef IS_INTRESOURCE #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0) #endif -# ifdef _WIN32_WCE -/* Unlike desktop Windows, WinCE has both W and A variants of - GetProcAddress, but the default W version is not what we want */ -# undef GetProcAddress -# define GetProcAddress GetProcAddressA -# endif #else #include "ctypes_dlfcn.h" #endif @@ -435,7 +429,7 @@ UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return StructUnionType_new(type, args, kwds, 0); } -static char from_address_doc[] = +static const char from_address_doc[] = "C.from_address(integer) -> C instance\naccess a C instance at the specified address"; static PyObject * @@ -453,7 +447,7 @@ CDataType_from_address(PyObject *type, PyObject *value) return PyCData_AtAddress(type, buf); } -static char from_buffer_doc[] = +static const char from_buffer_doc[] = "C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer"; static int @@ -524,7 +518,7 @@ CDataType_from_buffer(PyObject *type, PyObject *args) return result; } -static char from_buffer_copy_doc[] = +static const char from_buffer_copy_doc[] = "C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer"; static PyObject * @@ -566,7 +560,7 @@ CDataType_from_buffer_copy(PyObject *type, PyObject *args) return result; } -static char in_dll_doc[] = +static const char in_dll_doc[] = "C.in_dll(dll, name) -> C instance\naccess a C instance in a dll"; static PyObject * @@ -623,7 +617,7 @@ CDataType_in_dll(PyObject *type, PyObject *args) return PyCData_AtAddress(type, address); } -static char from_param_doc[] = +static const char from_param_doc[] = "Convert a Python object into a function call parameter."; static PyObject * @@ -1489,7 +1483,7 @@ _type_ attribute. */ -static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv?g"; +static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g"; static PyObject * c_wchar_p_from_param(PyObject *type, PyObject *value) @@ -2414,7 +2408,7 @@ unique_key(CDataObject *target, Py_ssize_t index) char *cp = string; size_t bytes_left; - assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2); + Py_BUILD_ASSERT(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2); cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int)); while (target->b_base) { bytes_left = sizeof(string) - (cp - string) - 1; @@ -3075,7 +3069,7 @@ static PyGetSetDef PyCFuncPtr_getsets[] = { }; #ifdef MS_WIN32 -static PPROC FindAddress(void *handle, char *name, PyObject *type) +static PPROC FindAddress(void *handle, const char *name, PyObject *type) { #ifdef MS_WIN64 /* win64 has no stdcall calling conv, so it should @@ -3209,7 +3203,7 @@ _validate_paramflags(PyTypeObject *type, PyObject *paramflags) } static int -_get_name(PyObject *obj, char **pname) +_get_name(PyObject *obj, const char **pname) { #ifdef MS_WIN32 if (PyLong_Check(obj)) { @@ -3237,7 +3231,7 @@ _get_name(PyObject *obj, char **pname) static PyObject * PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) { - char *name; + const char *name; int (* address)(void); PyObject *ftuple; PyObject *dll; @@ -5127,29 +5121,28 @@ static const char module_docs[] = #ifdef MS_WIN32 -static char comerror_doc[] = "Raised when a COM method call failed."; +static const char comerror_doc[] = "Raised when a COM method call failed."; int comerror_init(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *hresult, *text, *details; - PyBaseExceptionObject *bself; PyObject *a; int status; if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) - return -1; + return -1; if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details)) return -1; a = PySequence_GetSlice(args, 1, PySequence_Size(args)); if (!a) - return -1; + return -1; status = PyObject_SetAttrString(self, "args", a); Py_DECREF(a); if (status < 0) - return -1; + return -1; if (PyObject_SetAttrString(self, "hresult", hresult) < 0) return -1; @@ -5160,9 +5153,8 @@ comerror_init(PyObject *self, PyObject *args, PyObject *kwds) if (PyObject_SetAttrString(self, "details", details) < 0) return -1; - bself = (PyBaseExceptionObject *)self; Py_INCREF(args); - Py_SETREF(bself->args, args); + Py_SETREF(((PyBaseExceptionObject *)self)->args, args); return 0; } @@ -5492,14 +5484,14 @@ PyInit__ctypes(void) #endif /* If RTLD_LOCAL is not defined (Windows!), set it to zero. */ -#ifndef RTLD_LOCAL +#if !HAVE_DECL_RTLD_LOCAL #define RTLD_LOCAL 0 #endif /* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as RTLD_LOCAL. */ -#ifndef RTLD_GLOBAL +#if !HAVE_DECL_RTLD_GLOBAL #define RTLD_GLOBAL RTLD_LOCAL #endif diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 3c7f892..629ddf6 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -233,16 +233,15 @@ EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *)) return (*func)(table); } -#ifdef HAVE_LONG_LONG -EXPORT(PY_LONG_LONG) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f, - double d, PY_LONG_LONG q) +EXPORT(long long) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f, + double d, long long q) { - return (PY_LONG_LONG)(b + h + i + l + f + d + q); + return (long long)(b + h + i + l + f + d + q); } -EXPORT(PY_LONG_LONG) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d) +EXPORT(long long) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d) { - return (PY_LONG_LONG)(b + h + i + l + f + d); + return (long long)(b + h + i + l + f + d); } EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int)) @@ -255,10 +254,10 @@ EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int)) return sum; } -EXPORT(PY_LONG_LONG) _testfunc_callback_q_qf(PY_LONG_LONG value, - PY_LONG_LONG (*func)(PY_LONG_LONG)) +EXPORT(long long) _testfunc_callback_q_qf(long long value, + long long (*func)(long long)) { - PY_LONG_LONG sum = 0; + long long sum = 0; while (value != 0) { sum += func(value); @@ -267,8 +266,6 @@ EXPORT(PY_LONG_LONG) _testfunc_callback_q_qf(PY_LONG_LONG value, return sum; } -#endif - typedef struct { char *name; char *value; @@ -384,8 +381,8 @@ EXPORT(void) _py_func(void) { } -EXPORT(PY_LONG_LONG) last_tf_arg_s; -EXPORT(unsigned PY_LONG_LONG) last_tf_arg_u; +EXPORT(long long) last_tf_arg_s; +EXPORT(unsigned long long) last_tf_arg_u; struct BITS { int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9; @@ -448,8 +445,8 @@ static PyMethodDef module_methods[] = { { NULL, NULL, 0, NULL}, }; -#define S last_tf_arg_s = (PY_LONG_LONG)c -#define U last_tf_arg_u = (unsigned PY_LONG_LONG)c +#define S last_tf_arg_s = (long long)c +#define U last_tf_arg_u = (unsigned long long)c EXPORT(signed char) tf_b(signed char c) { S; return c/3; } EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; } @@ -459,8 +456,8 @@ EXPORT(int) tf_i(int c) { S; return c/3; } EXPORT(unsigned int) tf_I(unsigned int c) { U; return c/3; } EXPORT(long) tf_l(long c) { S; return c/3; } EXPORT(unsigned long) tf_L(unsigned long c) { U; return c/3; } -EXPORT(PY_LONG_LONG) tf_q(PY_LONG_LONG c) { S; return c/3; } -EXPORT(unsigned PY_LONG_LONG) tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; } +EXPORT(long long) tf_q(long long c) { S; return c/3; } +EXPORT(unsigned long long) tf_Q(unsigned long long c) { U; return c/3; } EXPORT(float) tf_f(float c) { S; return c/3; } EXPORT(double) tf_d(double c) { S; return c/3; } EXPORT(long double) tf_D(long double c) { S; return c/3; } @@ -474,8 +471,8 @@ EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; } EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; } EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; } EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; } -EXPORT(PY_LONG_LONG) __stdcall s_tf_q(PY_LONG_LONG c) { S; return c/3; } -EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; } +EXPORT(long long) __stdcall s_tf_q(long long c) { S; return c/3; } +EXPORT(unsigned long long) __stdcall s_tf_Q(unsigned long long c) { U; return c/3; } EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; } EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; } EXPORT(long double) __stdcall s_tf_D(long double c) { S; return c/3; } @@ -490,8 +487,8 @@ EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; } EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; } EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; } EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; } -EXPORT(PY_LONG_LONG) tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; } -EXPORT(unsigned PY_LONG_LONG) tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; } +EXPORT(long long) tf_bq(signed char x, long long c) { S; return c/3; } +EXPORT(unsigned long long) tf_bQ(signed char x, unsigned long long c) { U; return c/3; } EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; } EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; } EXPORT(long double) tf_bD(signed char x, long double c) { S; return c/3; } @@ -506,8 +503,8 @@ EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; } EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; } EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; } EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; } -EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; } -EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; } +EXPORT(long long) __stdcall s_tf_bq(signed char x, long long c) { S; return c/3; } +EXPORT(unsigned long long) __stdcall s_tf_bQ(signed char x, unsigned long long c) { U; return c/3; } EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; } EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; } EXPORT(long double) __stdcall s_tf_bD(signed char x, long double c) { S; return c/3; } diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 91413d7..b958f30 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -77,7 +77,7 @@ PyTypeObject PyCThunk_Type = { /**************************************************************/ static void -PrintError(char *msg, ...) +PrintError(const char *msg, ...) { char buf[512]; PyObject *f = PySys_GetObject("stderr"); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 30e3a96..d3044f3 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -382,7 +382,7 @@ static void SetException(DWORD code, EXCEPTION_RECORD *pr) whose operation is not allowed in the current machine mode. */ PyErr_SetString(PyExc_OSError, - "exception: priviledged instruction"); + "exception: privileged instruction"); break; case EXCEPTION_NONCONTINUABLE_EXCEPTION: @@ -474,7 +474,6 @@ PyCArg_repr(PyCArgObject *self) self->tag, self->value.l); break; -#ifdef HAVE_LONG_LONG case 'q': case 'Q': sprintf(buffer, @@ -485,7 +484,6 @@ PyCArg_repr(PyCArgObject *self) #endif self->tag, self->value.q); break; -#endif case 'd': sprintf(buffer, "<cparam '%c' (%f)>", self->tag, self->value.d); @@ -593,9 +591,7 @@ union result { short h; int i; long l; -#ifdef HAVE_LONG_LONG - PY_LONG_LONG q; -#endif + long long q; long double D; double d; float f; @@ -930,7 +926,7 @@ static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker) * Raise a new exception 'exc_class', adding additional text to the original * exception string. */ -void _ctypes_extend_error(PyObject *exc_class, char *fmt, ...) +void _ctypes_extend_error(PyObject *exc_class, const char *fmt, ...) { va_list vargs; PyObject *tp, *v, *tb, *s, *cls_str, *msg_str; @@ -1203,7 +1199,7 @@ _parse_voidp(PyObject *obj, void **address) #ifdef MS_WIN32 -static char format_error_doc[] = +static const char format_error_doc[] = "FormatError([integer]) -> string\n\ \n\ Convert a win32 error code into a string. If the error code is not\n\ @@ -1227,7 +1223,7 @@ static PyObject *format_error(PyObject *self, PyObject *args) return result; } -static char load_library_doc[] = +static const char load_library_doc[] = "LoadLibrary(name) -> handle\n\ \n\ Load an executable (usually a DLL), and return a handle to it.\n\ @@ -1256,7 +1252,7 @@ static PyObject *load_library(PyObject *self, PyObject *args) #endif } -static char free_library_doc[] = +static const char free_library_doc[] = "FreeLibrary(handle) -> void\n\ \n\ Free the handle of an executable previously loaded by LoadLibrary.\n"; @@ -1271,7 +1267,7 @@ static PyObject *free_library(PyObject *self, PyObject *args) return Py_None; } -static char copy_com_pointer_doc[] = +static const char copy_com_pointer_doc[] = "CopyComPointer(src, dst) -> HRESULT value\n"; static PyObject * @@ -1309,7 +1305,7 @@ static PyObject *py_dl_open(PyObject *self, PyObject *args) PyObject *name, *name2; char *name_str; void * handle; -#ifdef RTLD_LOCAL +#if HAVE_DECL_RTLD_LOCAL int mode = RTLD_NOW | RTLD_LOCAL; #else /* cygwin doesn't define RTLD_LOCAL */ @@ -1441,7 +1437,7 @@ call_cdeclfunction(PyObject *self, PyObject *args) /***************************************************************** * functions */ -static char sizeof_doc[] = +static const char sizeof_doc[] = "sizeof(C type) -> integer\n" "sizeof(C instance) -> integer\n" "Return the size in bytes of a C instance"; @@ -1462,7 +1458,7 @@ sizeof_func(PyObject *self, PyObject *obj) return NULL; } -static char alignment_doc[] = +static const char alignment_doc[] = "alignment(C type) -> integer\n" "alignment(C instance) -> integer\n" "Return the alignment requirements of a C instance"; @@ -1485,7 +1481,7 @@ align_func(PyObject *self, PyObject *obj) return NULL; } -static char byref_doc[] = +static const char byref_doc[] = "byref(C instance[, offset=0]) -> byref-object\n" "Return a pointer lookalike to a C instance, only usable\n" "as function argument"; @@ -1529,7 +1525,7 @@ byref(PyObject *self, PyObject *args) return (PyObject *)parg; } -static char addressof_doc[] = +static const char addressof_doc[] = "addressof(C instance) -> integer\n" "Return the address of the C instance internal buffer"; diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index d666be5..a43585f 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -379,14 +379,12 @@ get_ulong(PyObject *v, unsigned long *p) return 0; } -#ifdef HAVE_LONG_LONG - /* Same, but handling native long long. */ static int -get_longlong(PyObject *v, PY_LONG_LONG *p) +get_longlong(PyObject *v, long long *p) { - PY_LONG_LONG x; + long long x; if (PyFloat_Check(v)) { PyErr_SetString(PyExc_TypeError, "int expected instead of float"); @@ -402,23 +400,21 @@ get_longlong(PyObject *v, PY_LONG_LONG *p) /* Same, but handling native unsigned long long. */ static int -get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) +get_ulonglong(PyObject *v, unsigned long long *p) { - unsigned PY_LONG_LONG x; + unsigned long long x; if (PyFloat_Check(v)) { PyErr_SetString(PyExc_TypeError, "int expected instead of float"); return -1; } x = PyLong_AsUnsignedLongLongMask(v); - if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) + if (x == (unsigned long long)-1 && PyErr_Occurred()) return -1; *p = x; return 0; } -#endif - /***************************************************************** * Integer fields, with bitfield support */ @@ -715,14 +711,6 @@ vBOOL_get(void *ptr, Py_ssize_t size) } #endif -#ifdef HAVE_C99_BOOL -#define BOOL_TYPE _Bool -#else -#define BOOL_TYPE char -#undef SIZEOF__BOOL -#define SIZEOF__BOOL 1 -#endif - static PyObject * bool_set(void *ptr, PyObject *value, Py_ssize_t size) { @@ -730,10 +718,10 @@ bool_set(void *ptr, PyObject *value, Py_ssize_t size) case -1: return NULL; case 0: - *(BOOL_TYPE *)ptr = 0; + *(_Bool *)ptr = 0; _RET(value); default: - *(BOOL_TYPE *)ptr = 1; + *(_Bool *)ptr = 1; _RET(value); } } @@ -741,7 +729,7 @@ bool_set(void *ptr, PyObject *value, Py_ssize_t size) static PyObject * bool_get(void *ptr, Py_ssize_t size) { - return PyBool_FromLong((long)*(BOOL_TYPE *)ptr); + return PyBool_FromLong((long)*(_Bool *)ptr); } static PyObject * @@ -888,16 +876,15 @@ L_get_sw(void *ptr, Py_ssize_t size) return PyLong_FromUnsignedLong(val); } -#ifdef HAVE_LONG_LONG static PyObject * q_set(void *ptr, PyObject *value, Py_ssize_t size) { - PY_LONG_LONG val; - PY_LONG_LONG x; + long long val; + long long x; if (get_longlong(value, &val) < 0) return NULL; memcpy(&x, ptr, sizeof(x)); - x = SET(PY_LONG_LONG, x, val, size); + x = SET(long long, x, val, size); memcpy(ptr, &x, sizeof(x)); _RET(value); } @@ -905,13 +892,13 @@ q_set(void *ptr, PyObject *value, Py_ssize_t size) static PyObject * q_set_sw(void *ptr, PyObject *value, Py_ssize_t size) { - PY_LONG_LONG val; - PY_LONG_LONG field; + long long val; + long long field; if (get_longlong(value, &val) < 0) return NULL; memcpy(&field, ptr, sizeof(field)); field = SWAP_8(field); - field = SET(PY_LONG_LONG, field, val, size); + field = SET(long long, field, val, size); field = SWAP_8(field); memcpy(ptr, &field, sizeof(field)); _RET(value); @@ -920,7 +907,7 @@ q_set_sw(void *ptr, PyObject *value, Py_ssize_t size) static PyObject * q_get(void *ptr, Py_ssize_t size) { - PY_LONG_LONG val; + long long val; memcpy(&val, ptr, sizeof(val)); GET_BITFIELD(val, size); return PyLong_FromLongLong(val); @@ -929,7 +916,7 @@ q_get(void *ptr, Py_ssize_t size) static PyObject * q_get_sw(void *ptr, Py_ssize_t size) { - PY_LONG_LONG val; + long long val; memcpy(&val, ptr, sizeof(val)); val = SWAP_8(val); GET_BITFIELD(val, size); @@ -939,12 +926,12 @@ q_get_sw(void *ptr, Py_ssize_t size) static PyObject * Q_set(void *ptr, PyObject *value, Py_ssize_t size) { - unsigned PY_LONG_LONG val; - unsigned PY_LONG_LONG x; + unsigned long long val; + unsigned long long x; if (get_ulonglong(value, &val) < 0) return NULL; memcpy(&x, ptr, sizeof(x)); - x = SET(PY_LONG_LONG, x, val, size); + x = SET(long long, x, val, size); memcpy(ptr, &x, sizeof(x)); _RET(value); } @@ -952,13 +939,13 @@ Q_set(void *ptr, PyObject *value, Py_ssize_t size) static PyObject * Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size) { - unsigned PY_LONG_LONG val; - unsigned PY_LONG_LONG field; + unsigned long long val; + unsigned long long field; if (get_ulonglong(value, &val) < 0) return NULL; memcpy(&field, ptr, sizeof(field)); field = SWAP_8(field); - field = SET(unsigned PY_LONG_LONG, field, val, size); + field = SET(unsigned long long, field, val, size); field = SWAP_8(field); memcpy(ptr, &field, sizeof(field)); _RET(value); @@ -967,7 +954,7 @@ Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size) static PyObject * Q_get(void *ptr, Py_ssize_t size) { - unsigned PY_LONG_LONG val; + unsigned long long val; memcpy(&val, ptr, sizeof(val)); GET_BITFIELD(val, size); return PyLong_FromUnsignedLongLong(val); @@ -976,13 +963,12 @@ Q_get(void *ptr, Py_ssize_t size) static PyObject * Q_get_sw(void *ptr, Py_ssize_t size) { - unsigned PY_LONG_LONG val; + unsigned long long val; memcpy(&val, ptr, sizeof(val)); val = SWAP_8(val); GET_BITFIELD(val, size); return PyLong_FromUnsignedLongLong(val); } -#endif /***************************************************************** * non-integer accessor methods, not supporting bit fields @@ -1490,10 +1476,8 @@ P_set(void *ptr, PyObject *value, Py_ssize_t size) #if SIZEOF_VOID_P <= SIZEOF_LONG v = (void *)PyLong_AsUnsignedLongMask(value); #else -#ifndef HAVE_LONG_LONG -# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long" -#elif SIZEOF_LONG_LONG < SIZEOF_VOID_P -# error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)" +#if SIZEOF_LONG_LONG < SIZEOF_VOID_P +# error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)" #endif v = (void *)PyLong_AsUnsignedLongLongMask(value); #endif @@ -1538,14 +1522,12 @@ static struct fielddesc formattable[] = { #else # error #endif -#ifdef HAVE_LONG_LONG #if SIZEOF_LONG_LONG == 8 { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw}, { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw}, #else # error #endif -#endif { 'P', P_set, P_get, &ffi_type_pointer}, { 'z', z_set, z_get, &ffi_type_pointer}, #ifdef CTYPES_UNICODE @@ -1635,10 +1617,8 @@ typedef struct { char c; wchar_t *x; } s_wchar_p; #endif */ -#ifdef HAVE_LONG_LONG -typedef struct { char c; PY_LONG_LONG x; } s_long_long; -#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG)) -#endif +typedef struct { char c; long long x; } s_long_long; +#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) /* from ffi.h: typedef struct _ffi_type diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index f2df5c0..5d3b966 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -31,9 +31,7 @@ union value { long l; float f; double d; -#ifdef HAVE_LONG_LONG - PY_LONG_LONG ll; -#endif + long long ll; long double D; }; @@ -303,9 +301,7 @@ struct tagPyCArgObject { short h; int i; long l; -#ifdef HAVE_LONG_LONG - PY_LONG_LONG q; -#endif + long long q; long double D; double d; float f; @@ -327,7 +323,7 @@ extern int PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, Py_ssize_t index, Py_ssize_t size, char *ptr); -extern void _ctypes_extend_error(PyObject *exc_class, char *fmt, ...); +extern void _ctypes_extend_error(PyObject *exc_class, const char *fmt, ...); struct basespec { CDataObject *base; diff --git a/Modules/_ctypes/libffi/src/dlmalloc.c b/Modules/_ctypes/libffi/src/dlmalloc.c index 6e474b7..55c2d76 100644 --- a/Modules/_ctypes/libffi/src/dlmalloc.c +++ b/Modules/_ctypes/libffi/src/dlmalloc.c @@ -525,7 +525,7 @@ DEFAULT_MMAP_THRESHOLD default: 256K #define MMAP_CLEARS 1 #endif /* MMAP_CLEARS */ #ifndef HAVE_MREMAP -#ifdef linux +#ifdef __linux__ #define HAVE_MREMAP 1 #else /* linux */ #define HAVE_MREMAP 0 diff --git a/Modules/_ctypes/libffi_arm_wince/debug.c b/Modules/_ctypes/libffi_arm_wince/debug.c deleted file mode 100644 index 98f1f9f..0000000 --- a/Modules/_ctypes/libffi_arm_wince/debug.c +++ /dev/null @@ -1,59 +0,0 @@ -/* ----------------------------------------------------------------------- - debug.c - Copyright (c) 1996 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> -#include <stdlib.h> -#include <stdio.h> - -/* General debugging routines */ - -void ffi_stop_here(void) -{ - /* This function is only useful for debugging purposes. - Place a breakpoint on ffi_stop_here to be notified of - significant events. */ -} - -/* This function should only be called via the FFI_ASSERT() macro */ - -void ffi_assert(char *expr, char *file, int line) -{ - fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line); - ffi_stop_here(); - abort(); -} - -/* Perform a sanity check on an ffi_type structure */ - -void ffi_type_test(ffi_type *a, char *file, int line) -{ - FFI_ASSERT_AT(a != NULL, file, line); - - /*@-usedef@*/ - FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line); - FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line); - FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line); - FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line); - /*@=usedef@*/ -} diff --git a/Modules/_ctypes/libffi_arm_wince/ffi.c b/Modules/_ctypes/libffi_arm_wince/ffi.c deleted file mode 100644 index 1193aaa..0000000 --- a/Modules/_ctypes/libffi_arm_wince/ffi.c +++ /dev/null @@ -1,310 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Red Hat, Inc. - - ARM Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> - -#include <stdlib.h> - -#ifdef _WIN32_WCE -#pragma warning (disable : 4142) /* benign redefinition of type */ -#include <windows.h> -#endif - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -/*@-exportheader@*/ -void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ -{ - register unsigned int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - argp = stack; - - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) { - *(void **) argp = ecif->rvalue; - argp += 4; - } - - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - (i != 0); - i--, p_arg++) - { - size_t z; - size_t argalign = (*p_arg)->alignment; - -#ifdef _WIN32_WCE - if (argalign > 4) - argalign = 4; -#endif - /* Align if necessary */ - if ((argalign - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, argalign); - } - - z = (*p_arg)->size; - if (z < sizeof(int)) - { - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - /* *p_argv may not be aligned for a UINT32 */ - memcpy(argp, *p_argv, z); - break; - - default: - FFI_ASSERT(0); - } - } - else if (z == sizeof(int)) - { - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - } - else - { - memcpy(argp, *p_argv, z); - } - p_argv++; - argp += z; - } - - return; -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_SINT64: - cif->flags = (unsigned) cif->rtype->type; - break; - - case FFI_TYPE_UINT64: - cif->flags = FFI_TYPE_SINT64; - break; - - default: - cif->flags = FFI_TYPE_INT; - break; - } - - return FFI_OK; -} - -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ - -/* Return type changed from void for ctypes */ -int ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; - default: - FFI_ASSERT(0); - break; - } - /* I think calculating the real stack pointer delta is not useful - because stdcall is not supported */ - return 0; -} - -/** private members **/ - -static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, - void** args, ffi_cif* cif); - -/* This function is called by ffi_closure_SYSV in sysv.asm */ - -unsigned int -ffi_closure_SYSV_inner (ffi_closure *closure, char *in_args, void *rvalue) -{ - ffi_cif *cif = closure->cif; - void **out_args; - - out_args = (void **) alloca(cif->nargs * sizeof (void *)); - - /* this call will initialize out_args, such that each - * element in that array points to the corresponding - * value on the stack; and if the function returns - * a structure, it will re-set rvalue to point to the - * structure return address. */ - - ffi_prep_incoming_args_SYSV(in_args, &rvalue, out_args, cif); - - (closure->fun)(cif, rvalue, out_args, closure->user_data); - - /* Tell ffi_closure_SYSV what the returntype is */ - return cif->flags; -} - -/*@-exportheader@*/ -static void -ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, - void **avalue, ffi_cif *cif) -/*@=exportheader@*/ -{ - unsigned int i; - void **p_argv; - char *argp; - ffi_type **p_arg; - - argp = stack; - - if ( cif->rtype->type == FFI_TYPE_STRUCT ) { - *rvalue = *(void **) argp; - argp += 4; - } - - p_argv = avalue; - - for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) - { - size_t z; - size_t argalign = (*p_arg)->alignment; - -#ifdef _WIN32_WCE - if (argalign > 4) - argalign = 4; -#endif - /* Align if necessary */ - if ((argalign - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, argalign); - } - - z = (*p_arg)->size; - if (z < sizeof(int)) - z = sizeof(int); - - *p_argv = (void*) argp; - - p_argv++; - argp += z; - } -} - -/* - add ip, pc, #-8 ; ip = address of this trampoline == address of ffi_closure - ldr pc, [pc, #-4] ; jump to __fun - DCD __fun -*/ -#define FFI_INIT_TRAMPOLINE(TRAMP,FUN) \ -{ \ - unsigned int *__tramp = (unsigned int *)(TRAMP); \ - __tramp[0] = 0xe24fc008; /* add ip, pc, #-8 */ \ - __tramp[1] = 0xe51ff004; /* ldr pc, [pc, #-4] */ \ - __tramp[2] = (unsigned int)(FUN); \ - } - -/* the cif must already be prep'ed */ - -/* defined in sysv.asm */ -void ffi_closure_SYSV(void); - -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) -{ - FFI_ASSERT (cif->abi == FFI_SYSV); - - FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - -#ifdef _WIN32_WCE - /* This is important to allow calling the trampoline safely */ - FlushInstructionCache(GetCurrentProcess(), 0, 0); -#endif - - return FFI_OK; -} - diff --git a/Modules/_ctypes/libffi_arm_wince/ffi.h b/Modules/_ctypes/libffi_arm_wince/ffi.h deleted file mode 100644 index 67975b6..0000000 --- a/Modules/_ctypes/libffi_arm_wince/ffi.h +++ /dev/null @@ -1,317 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - libffi 2.00-beta-wince - Copyright (c) 1996-2003 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------- - The basic API is described in the README file. - - The raw API is designed to bypass some of the argument packing - and unpacking on architectures for which it can be avoided. - - The closure API allows interpreted functions to be packaged up - inside a C function pointer, so that they can be called as C functions, - with no understanding on the client side that they are interpreted. - It can also be used in other cases in which it is necessary to package - up a user specified parameter and a function pointer as a single - function pointer. - - The closure API must be implemented in order to get its functionality, - e.g. for use by gij. Routines are provided to emulate the raw API - if the underlying platform doesn't allow faster implementation. - - More details on the raw and cloure API can be found in: - - http://gcc.gnu.org/ml/java/1999-q3/msg00138.html - - and - - http://gcc.gnu.org/ml/java/1999-q3/msg00174.html - -------------------------------------------------------------------- */ - -#ifndef LIBFFI_H -#define LIBFFI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Specify which architecture libffi is configured for. */ -/*#define @TARGET@*/ - -/* ---- System configuration information --------------------------------- */ - -#include <ffitarget.h> - -#ifndef LIBFFI_ASM - -#include <stddef.h> -#include <limits.h> - -/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). - But we can find it either under the correct ANSI name, or under GNU - C's internal name. */ -#ifdef LONG_LONG_MAX -# define FFI_LONG_LONG_MAX LONG_LONG_MAX -#else -# ifdef LLONG_MAX -# define FFI_LONG_LONG_MAX LLONG_MAX -# else -# ifdef __GNUC__ -# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ -# endif -# ifdef _MSC_VER -# define FFI_LONG_LONG_MAX _I64_MAX -# endif -# endif -#endif - -#if SCHAR_MAX == 127 -# define ffi_type_uchar ffi_type_uint8 -# define ffi_type_schar ffi_type_sint8 -#else - #error "char size not supported" -#endif - -#if SHRT_MAX == 32767 -# define ffi_type_ushort ffi_type_uint16 -# define ffi_type_sshort ffi_type_sint16 -#elif SHRT_MAX == 2147483647 -# define ffi_type_ushort ffi_type_uint32 -# define ffi_type_sshort ffi_type_sint32 -#else - #error "short size not supported" -#endif - -#if INT_MAX == 32767 -# define ffi_type_uint ffi_type_uint16 -# define ffi_type_sint ffi_type_sint16 -#elif INT_MAX == 2147483647 -# define ffi_type_uint ffi_type_uint32 -# define ffi_type_sint ffi_type_sint32 -#elif INT_MAX == 9223372036854775807 -# define ffi_type_uint ffi_type_uint64 -# define ffi_type_sint ffi_type_sint64 -#else - #error "int size not supported" -#endif - -#define ffi_type_ulong ffi_type_uint64 -#define ffi_type_slong ffi_type_sint64 -#if LONG_MAX == 2147483647 -# if FFI_LONG_LONG_MAX != 9223372036854775807 - #error "no 64-bit data type supported" -# endif -#elif LONG_MAX != 9223372036854775807 - #error "long size not supported" -#endif - -/* The closure code assumes that this works on pointers, i.e. a size_t */ -/* can hold a pointer. */ - -typedef struct _ffi_type -{ - size_t size; - unsigned short alignment; - unsigned short type; - /*@null@*/ struct _ffi_type **elements; -} ffi_type; - -/* These are defined in types.c */ -extern ffi_type ffi_type_void; -extern ffi_type ffi_type_uint8; -extern ffi_type ffi_type_sint8; -extern ffi_type ffi_type_uint16; -extern ffi_type ffi_type_sint16; -extern ffi_type ffi_type_uint32; -extern ffi_type ffi_type_sint32; -extern ffi_type ffi_type_uint64; -extern ffi_type ffi_type_sint64; -extern ffi_type ffi_type_float; -extern ffi_type ffi_type_double; -extern ffi_type ffi_type_longdouble; -extern ffi_type ffi_type_pointer; - - -typedef enum { - FFI_OK = 0, - FFI_BAD_TYPEDEF, - FFI_BAD_ABI -} ffi_status; - -typedef unsigned FFI_TYPE; - -typedef struct { - ffi_abi abi; - unsigned nargs; - /*@dependent@*/ ffi_type **arg_types; - /*@dependent@*/ ffi_type *rtype; - unsigned bytes; - unsigned flags; -#ifdef FFI_EXTRA_CIF_FIELDS - FFI_EXTRA_CIF_FIELDS; -#endif -} ffi_cif; - -/* ---- Definitions for the raw API -------------------------------------- */ - -#ifndef FFI_SIZEOF_ARG -# if LONG_MAX == 2147483647 -# define FFI_SIZEOF_ARG 4 -# elif LONG_MAX == 9223372036854775807 -# define FFI_SIZEOF_ARG 8 -# endif -#endif - -typedef union { - ffi_sarg sint; - ffi_arg uint; - float flt; - char data[FFI_SIZEOF_ARG]; - void* ptr; -} ffi_raw; - -void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *avalue); - -void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); -void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); -size_t ffi_raw_size (ffi_cif *cif); - -/* This is analogous to the raw API, except it uses Java parameter */ -/* packing, even on 64-bit machines. I.e. on 64-bit machines */ -/* longs and doubles are followed by an empty 64-bit word. */ - -void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *avalue); - -void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); -void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); -size_t ffi_java_raw_size (ffi_cif *cif); - -/* ---- Definitions for closures ----------------------------------------- */ - -#if FFI_CLOSURES - -typedef struct { - char tramp[FFI_TRAMPOLINE_SIZE]; - ffi_cif *cif; - void (*fun)(ffi_cif*,void*,void**,void*); - void *user_data; -} ffi_closure; - -ffi_status -ffi_prep_closure (ffi_closure*, - ffi_cif *, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data); - -typedef struct { - char tramp[FFI_TRAMPOLINE_SIZE]; - - ffi_cif *cif; - -#if !FFI_NATIVE_RAW_API - - /* if this is enabled, then a raw closure has the same layout - as a regular closure. We use this to install an intermediate - handler to do the transaltion, void** -> ffi_raw*. */ - - void (*translate_args)(ffi_cif*,void*,void**,void*); - void *this_closure; - -#endif - - void (*fun)(ffi_cif*,void*,ffi_raw*,void*); - void *user_data; - -} ffi_raw_closure; - -ffi_status -ffi_prep_raw_closure (ffi_raw_closure*, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data); - -ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure*, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data); - -#endif /* FFI_CLOSURES */ - -/* ---- Public interface definition -------------------------------------- */ - -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, - ffi_abi abi, - unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes); - -/* Return type changed from void for ctypes */ -int ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue); - -/* Useful for eliminating compiler warnings */ -#define FFI_FN(f) ((void (*)())f) - -/* ---- Definitions shared with assembly code ---------------------------- */ - -#endif - -/* If these change, update src/mips/ffitarget.h. */ -#define FFI_TYPE_VOID 0 -#define FFI_TYPE_INT 1 -#define FFI_TYPE_FLOAT 2 -#define FFI_TYPE_DOUBLE 3 -#if 0 /*@HAVE_LONG_DOUBLE@*/ -#define FFI_TYPE_LONGDOUBLE 4 -#else -#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE -#endif -#define FFI_TYPE_UINT8 5 -#define FFI_TYPE_SINT8 6 -#define FFI_TYPE_UINT16 7 -#define FFI_TYPE_SINT16 8 -#define FFI_TYPE_UINT32 9 -#define FFI_TYPE_SINT32 10 -#define FFI_TYPE_UINT64 11 -#define FFI_TYPE_SINT64 12 -#define FFI_TYPE_STRUCT 13 -#define FFI_TYPE_POINTER 14 - -/* This should always refer to the last type code (for sanity checks) */ -#define FFI_TYPE_LAST FFI_TYPE_POINTER - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/Modules/_ctypes/libffi_arm_wince/ffi_common.h b/Modules/_ctypes/libffi_arm_wince/ffi_common.h deleted file mode 100644 index bf879d1..0000000 --- a/Modules/_ctypes/libffi_arm_wince/ffi_common.h +++ /dev/null @@ -1,111 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi_common.h - Copyright (c) 1996 Red Hat, Inc. - - Common internal definitions and macros. Only necessary for building - libffi. - ----------------------------------------------------------------------- */ - -#ifndef FFI_COMMON_H -#define FFI_COMMON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <fficonfig.h> - -/* Do not move this. Some versions of AIX are very picky about where - this is positioned. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# if HAVE_ALLOCA_H -# include <alloca.h> -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -# endif -# endif -# endif -#endif - -/* Check for the existence of memcpy. */ -#if STDC_HEADERS -# include <string.h> -#else -# ifndef HAVE_MEMCPY -# define memcpy(d, s, n) bcopy ((s), (d), (n)) -# endif -#endif - -#if defined(FFI_DEBUG) -#include <stdio.h> -#endif - -#ifdef FFI_DEBUG -/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line); -void ffi_stop_here(void); -void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line); - -#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) -#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) -#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) -#else -#define FFI_ASSERT(x) -#define FFI_ASSERT_AT(x, f, l) -#define FFI_ASSERT_VALID_TYPE(x) -#endif - -#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1) - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif); - -/* Extended cif, used in callback from assembly routine */ -typedef struct -{ - /*@dependent@*/ ffi_cif *cif; - /*@dependent@*/ void *rvalue; - /*@dependent@*/ void **avalue; -} extended_cif; - -/* Terse sized type definitions. */ -#if defined(__GNUC__) - -typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); -typedef signed int SINT8 __attribute__((__mode__(__QI__))); -typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); -typedef signed int SINT16 __attribute__((__mode__(__HI__))); -typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); -typedef signed int SINT32 __attribute__((__mode__(__SI__))); -typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); -typedef signed int SINT64 __attribute__((__mode__(__DI__))); - -#elif defined(_MSC_VER) - -typedef unsigned __int8 UINT8; -typedef signed __int8 SINT8; -typedef unsigned __int16 UINT16; -typedef signed __int16 SINT16; -typedef unsigned __int32 UINT32; -typedef signed __int32 SINT32; -typedef unsigned __int64 UINT64; -typedef signed __int64 SINT64; - -#else -#error "Need typedefs here" -#endif - -typedef float FLOAT32; - - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/Modules/_ctypes/libffi_arm_wince/fficonfig.h b/Modules/_ctypes/libffi_arm_wince/fficonfig.h deleted file mode 100644 index 3c7964c..0000000 --- a/Modules/_ctypes/libffi_arm_wince/fficonfig.h +++ /dev/null @@ -1,152 +0,0 @@ -/* fficonfig.h created manually for Windows CE on ARM */ -/* fficonfig.h.in. Generated from configure.ac by autoheader. */ - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#define BYTEORDER 1234 - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. - */ -/* #undef CRAY_STACKSEG_END */ - -/* Define to 1 if using `alloca.c'. */ -/* #undef C_ALLOCA */ - -/* Define to the flags needed for the .section .eh_frame directive. */ -/* #undef EH_FRAME_FLAGS */ - -/* Define this if you want extra debugging. */ -#ifdef DEBUG /* Defined by the project settings for Debug builds */ -#define FFI_DEBUG -#else -#undef FFI_DEBUG -#endif - -/* Define this is you do not want support for the raw API. */ -/* #undef FFI_NO_RAW_API */ - -/* Define this is you do not want support for aggregate types. */ -/* #undef FFI_NO_STRUCTS */ - -/* Define to 1 if you have `alloca', as a function or macro. */ -#define HAVE_ALLOCA 1 - -/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). - */ -/* #undef HAVE_ALLOCA_H */ - -/* Define if your assembler supports .register. */ -/* #undef HAVE_AS_REGISTER_PSEUDO_OP */ - -/* Define if your assembler and linker support unaligned PC relative relocs. - */ -/* #undef HAVE_AS_SPARC_UA_PCREL */ - -/* Define to 1 if you have the <inttypes.h> header file. */ -/* #undef HAVE_INTTYPES_H */ - -/* Define if you have the long double type and it is bigger than a double */ -/* This differs from the MSVC build, but even there it should not be defined */ -/* #undef HAVE_LONG_DOUBLE */ - -/* Define to 1 if you have the `memcpy' function. */ -#define HAVE_MEMCPY 1 - -/* Define to 1 if you have the <memory.h> header file. */ -/* WinCE has this but I don't think we need to use it */ -/* #undef HAVE_MEMORY_H */ - -/* Define to 1 if you have the `mmap' function. */ -/* #undef HAVE_MMAP */ - -/* Define if mmap with MAP_ANON(YMOUS) works. */ -/* #undef HAVE_MMAP_ANON */ - -/* Define if mmap of /dev/zero works. */ -/* #undef HAVE_MMAP_DEV_ZERO */ - -/* Define if read-only mmap of a plain file works. */ -/* #undef HAVE_MMAP_FILE */ - -/* Define if .eh_frame sections should be read-only. */ -/* #undef HAVE_RO_EH_FRAME */ - -/* Define to 1 if you have the <stdint.h> header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -/* #undef HAVE_STRINGS_H */ - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/mman.h> header file. */ -/* #undef HAVE_SYS_MMAN_H */ - -/* Define to 1 if you have the <sys/stat.h> header file. */ -/* #undef HAVE_SYS_STAT_H */ - -/* Define to 1 if you have the <sys/types.h> header file. */ -/* #undef HAVE_SYS_TYPES_H */ - -/* Define to 1 if you have the <unistd.h> header file. */ -/* #undef HAVE_UNISTD_H */ - -/* Define if the host machine stores words of multi-word integers in - big-endian order. */ -/* #undef HOST_WORDS_BIG_ENDIAN */ - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -/* #undef PACKAGE */ - -/* Define to the address where bug reports for this package should be sent. */ -/* #undef PACKAGE_BUGREPORT */ - -/* Define to the full name of this package. */ -/* #undef PACKAGE_NAME */ - -/* Define to the full name and version of this package. */ -/* #undef PACKAGE_STRING */ - -/* Define to the one symbol short name of this package. */ -/* #undef PACKAGE_TARNAME */ - -/* Define to the version of this package. */ -/* #undef PACKAGE_VERSION */ - -/* The number of bytes in type double */ -#define SIZEOF_DOUBLE 8 - -/* The number of bytes in type long double */ -#define SIZEOF_LONG_DOUBLE 8 - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -/* #undef STACK_DIRECTION */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define this if you are using Purify and want to suppress spurious messages. - */ -/* #undef USING_PURIFY */ - -/* Version number of package */ -/* #undef VERSION */ - -/* whether byteorder is bigendian */ -/* #undef WORDS_BIGENDIAN */ - -#define alloca _alloca - -#define abort() exit(999) diff --git a/Modules/_ctypes/libffi_arm_wince/ffitarget.h b/Modules/_ctypes/libffi_arm_wince/ffitarget.h deleted file mode 100644 index 2627b25..0000000 --- a/Modules/_ctypes/libffi_arm_wince/ffitarget.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. - Target configuration macros for ARM. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -#ifndef LIBFFI_ASM -typedef unsigned long ffi_arg; -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - FFI_SYSV, - FFI_DEFAULT_ABI = FFI_SYSV, - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 -} ffi_abi; -#endif - -/* ---- Definitions for closures ----------------------------------------- */ - -#define FFI_CLOSURES 1 -#define FFI_TRAMPOLINE_SIZE 12 - -#define FFI_NATIVE_RAW_API 0 - -#endif - diff --git a/Modules/_ctypes/libffi_arm_wince/prep_cif.c b/Modules/_ctypes/libffi_arm_wince/prep_cif.c deleted file mode 100644 index 9edce2f..0000000 --- a/Modules/_ctypes/libffi_arm_wince/prep_cif.c +++ /dev/null @@ -1,175 +0,0 @@ -/* ----------------------------------------------------------------------- - prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> -#include <stdlib.h> - - -/* Round up to FFI_SIZEOF_ARG. */ - -#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) - -/* Perform machine independent initialization of aggregate type - specifications. */ - -static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) -{ - ffi_type **ptr; - - FFI_ASSERT(arg != NULL); - - /*@-usedef@*/ - - FFI_ASSERT(arg->elements != NULL); - FFI_ASSERT(arg->size == 0); - FFI_ASSERT(arg->alignment == 0); - - ptr = &(arg->elements[0]); - - while ((*ptr) != NULL) - { - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type */ - FFI_ASSERT_VALID_TYPE(*ptr); - - arg->size = ALIGN(arg->size, (*ptr)->alignment); - arg->size += (*ptr)->size; - - arg->alignment = (arg->alignment > (*ptr)->alignment) ? - arg->alignment : (*ptr)->alignment; - - ptr++; - } - - /* Structure size includes tail padding. This is important for - structures that fit in one register on ABIs like the PowerPC64 - Linux ABI that right justify small structs in a register. - It's also needed for nested structure layout, for example - struct A { long a; char b; }; struct B { struct A x; char y; }; - should find y at an offset of 2*sizeof(long) and result in a - total size of 3*sizeof(long). */ - arg->size = ALIGN (arg->size, arg->alignment); - - if (arg->size == 0) - return FFI_BAD_TYPEDEF; - else - return FFI_OK; - - /*@=usedef@*/ -} - -/* Perform machine independent ffi_cif preparation, then call - machine dependent routine. */ - -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, - ffi_abi abi, unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes) -{ - unsigned bytes = 0; - unsigned int i; - ffi_type **ptr; - - FFI_ASSERT(cif != NULL); - FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)); - - cif->abi = abi; - cif->arg_types = atypes; - cif->nargs = nargs; - cif->rtype = rtype; - - cif->flags = 0; - - /* Initialize the return type if necessary */ - /*@-usedef@*/ - if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) - return FFI_BAD_TYPEDEF; - /*@=usedef@*/ - - /* Perform a sanity check on the return type */ - FFI_ASSERT_VALID_TYPE(cif->rtype); - - /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ -#if !defined M68K && !defined __x86_64__ && !defined S390 - /* Make space for the return structure pointer */ - if (cif->rtype->type == FFI_TYPE_STRUCT - /* MSVC returns small structures in registers. But we have a different - workaround: pretend int32 or int64 return type, and converting to - structure afterwards. */ -#ifdef SPARC - && (cif->abi != FFI_V9 || cif->rtype->size > 32) -#endif - ) - bytes = STACK_ARG_SIZE(sizeof(void*)); -#endif - - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - - /* Initialize any uninitialized aggregate type definitions */ - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type, do this - check after the initialization. */ - FFI_ASSERT_VALID_TYPE(*ptr); - -#if !defined __x86_64__ && !defined S390 -#ifdef SPARC - if (((*ptr)->type == FFI_TYPE_STRUCT - && ((*ptr)->size > 16 || cif->abi != FFI_V9)) - || ((*ptr)->type == FFI_TYPE_LONGDOUBLE - && cif->abi != FFI_V9)) - bytes += sizeof(void*); - else -#endif - { -#ifndef _MSC_VER - /* Don't know if this is a libffi bug or not. At least on - Windows with MSVC, function call parameters are *not* - aligned in the same way as structure fields are, they are - only aligned in integer boundaries. - - This doesn't do any harm for cdecl functions and closures, - since the caller cleans up the stack, but it is wrong for - stdcall functions where the callee cleans. - */ - - /* Add any padding if necessary */ - if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); - -#endif - bytes += STACK_ARG_SIZE((*ptr)->size); - } -#endif - } - - cif->bytes = bytes; - - /* Perform machine dependent cif processing */ - return ffi_prep_cif_machdep(cif); -} diff --git a/Modules/_ctypes/libffi_arm_wince/sysv.asm b/Modules/_ctypes/libffi_arm_wince/sysv.asm deleted file mode 100644 index db78b90..0000000 --- a/Modules/_ctypes/libffi_arm_wince/sysv.asm +++ /dev/null @@ -1,228 +0,0 @@ -; ----------------------------------------------------------------------- -; sysv.S - Copyright (c) 1998 Red Hat, Inc. -; -; ARM Foreign Function Interface -; -; Permission is hereby granted, free of charge, to any person obtaining -; a copy of this software and associated documentation files (the -; ``Software''), to deal in the Software without restriction, including -; without limitation the rights to use, copy, modify, merge, publish, -; distribute, sublicense, and/or sell copies of the Software, and to -; permit persons to whom the Software is furnished to do so, subject to -; the following conditions: -; -; The above copyright notice and this permission notice shall be included -; in all copies or substantial portions of the Software. -; -; THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS -; OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -; IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR -; OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -; OTHER DEALINGS IN THE SOFTWARE. -; ----------------------------------------------------------------------- */ - -;#define LIBFFI_ASM -;#include <fficonfig.h> -;#include <ffi.h> -;#ifdef HAVE_MACHINE_ASM_H -;#include <machine/asm.h> -;#else -;#ifdef __USER_LABEL_PREFIX__ -;#define CONCAT1(a, b) CONCAT2(a, b) -;#define CONCAT2(a, b) a ## b - -;/* Use the right prefix for global labels. */ -;#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x) -;#else -;#define CNAME(x) x -;#endif -;#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): -;#endif - - -FFI_TYPE_VOID EQU 0 -FFI_TYPE_INT EQU 1 -FFI_TYPE_FLOAT EQU 2 -FFI_TYPE_DOUBLE EQU 3 -;FFI_TYPE_LONGDOUBLE EQU 4 -FFI_TYPE_UINT8 EQU 5 -FFI_TYPE_SINT8 EQU 6 -FFI_TYPE_UINT16 EQU 7 -FFI_TYPE_SINT16 EQU 8 -FFI_TYPE_UINT32 EQU 9 -FFI_TYPE_SINT32 EQU 10 -FFI_TYPE_UINT64 EQU 11 -FFI_TYPE_SINT64 EQU 12 -FFI_TYPE_STRUCT EQU 13 -FFI_TYPE_POINTER EQU 14 - -; WinCE always uses software floating point (I think) -__SOFTFP__ EQU {TRUE} - - - AREA |.text|, CODE, ARM ; .text - - - ; a1: ffi_prep_args - ; a2: &ecif - ; a3: cif->bytes - ; a4: fig->flags - ; sp+0: ecif.rvalue - ; sp+4: fn - - ; This assumes we are using gas. -;ENTRY(ffi_call_SYSV) - - EXPORT |ffi_call_SYSV| - -|ffi_call_SYSV| PROC - - ; Save registers - stmfd sp!, {a1-a4, fp, lr} - mov fp, sp - - ; Make room for all of the new args. - sub sp, fp, a3 - - ; Place all of the ffi_prep_args in position - mov ip, a1 - mov a1, sp - ; a2 already set - - ; And call - mov lr, pc - mov pc, ip - - ; move first 4 parameters in registers - ldr a1, [sp, #0] - ldr a2, [sp, #4] - ldr a3, [sp, #8] - ldr a4, [sp, #12] - - ; and adjust stack - ldr ip, [fp, #8] - cmp ip, #16 - movge ip, #16 - add sp, sp, ip - - ; call function - mov lr, pc - ldr pc, [fp, #28] - - ; Remove the space we pushed for the args - mov sp, fp - - ; Load a3 with the pointer to storage for the return value - ldr a3, [sp, #24] - - ; Load a4 with the return type code - ldr a4, [sp, #12] - - ; If the return value pointer is NULL, assume no return value. - cmp a3, #0 - beq call_epilogue - -; return INT - cmp a4, #FFI_TYPE_INT - streq a1, [a3] - beq call_epilogue - -; return FLOAT - cmp a4, #FFI_TYPE_FLOAT - [ __SOFTFP__ ;ifdef __SOFTFP__ - streq a1, [a3] - | ;else - stfeqs f0, [a3] - ] ;endif - beq call_epilogue - -; return DOUBLE or LONGDOUBLE - cmp a4, #FFI_TYPE_DOUBLE - [ __SOFTFP__ ;ifdef __SOFTFP__ - stmeqia a3, {a1, a2} - | ;else - stfeqd f0, [a3] - ] ;endif - beq call_epilogue - -; return SINT64 or UINT64 - cmp a4, #FFI_TYPE_SINT64 - stmeqia a3, {a1, a2} - -call_epilogue - ldmfd sp!, {a1-a4, fp, pc} - -;.ffi_call_SYSV_end: - ;.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) - ENDP - - -RESERVE_RETURN EQU 16 - - ; This function is called by the trampoline - ; It is NOT callable from C - ; ip = pointer to struct ffi_closure - - IMPORT |ffi_closure_SYSV_inner| - - EXPORT |ffi_closure_SYSV| -|ffi_closure_SYSV| PROC - - ; Store the argument registers on the stack - stmfd sp!, {a1-a4} - ; Push the return address onto the stack - stmfd sp!, {lr} - - mov a1, ip ; first arg = address of ffi_closure - add a2, sp, #4 ; second arg = sp+4 (points to saved a1) - - ; Allocate space for a non-struct return value - sub sp, sp, #RESERVE_RETURN - mov a3, sp ; third arg = return value address - - ; static unsigned int - ; ffi_closure_SYSV_inner (ffi_closure *closure, char *in_args, void *rvalue) - bl ffi_closure_SYSV_inner - ; a1 now contains the return type code - - ; At this point the return value is on the stack - ; Transfer it to the correct registers if necessary - -; return INT - cmp a1, #FFI_TYPE_INT - ldreq a1, [sp] - beq closure_epilogue - -; return FLOAT - cmp a1, #FFI_TYPE_FLOAT - [ __SOFTFP__ ;ifdef __SOFTFP__ - ldreq a1, [sp] - | ;else - stfeqs f0, [sp] - ] ;endif - beq closure_epilogue - -; return DOUBLE or LONGDOUBLE - cmp a1, #FFI_TYPE_DOUBLE - [ __SOFTFP__ ;ifdef __SOFTFP__ - ldmeqia sp, {a1, a2} - | ;else - stfeqd f0, [sp] - ] ;endif - beq closure_epilogue - -; return SINT64 or UINT64 - cmp a1, #FFI_TYPE_SINT64 - ldmeqia sp, {a1, a2} - -closure_epilogue - add sp, sp, #RESERVE_RETURN ; remove return value buffer - ldmfd sp!, {ip} ; ip = pop return address - add sp, sp, #16 ; remove saved argument registers {a1-a4} from the stack - mov pc, ip ; return - - ENDP ; ffi_closure_SYSV - - END diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index 228f497..18ef335 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -6,7 +6,7 @@ /* Release Number */ -static char *PyCursesVersion = "2.1"; +static const char PyCursesVersion[] = "2.1"; /* Includes */ @@ -56,7 +56,7 @@ static struct PyModuleDef _curses_panelmodule; */ static PyObject * -PyCursesCheckERR(int code, char *fname) +PyCursesCheckERR(int code, const char *fname) { if (code != ERR) { Py_INCREF(Py_None); diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 960752c..a48735f 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -2306,7 +2306,7 @@ PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) goto error; } - data = _PyObject_CallMethodId(stream, &PyId_read, ""); + data = _PyObject_CallMethodId(stream, &PyId_read, NULL); if (data == NULL) goto error; if (!PyBytes_Check(data)) { diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index f419cb2..6597cb7 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -9,6 +9,12 @@ #ifdef MS_WINDOWS # include <winsock2.h> /* struct timeval */ +static struct tm *localtime_r(const time_t *timep, struct tm *result) +{ + if (localtime_s(result, timep) == 0) + return result; + return NULL; +} #endif /* Differentiate between building the core module and building extension @@ -56,6 +62,7 @@ class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" #define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE #define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND #define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND +#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD /* Date accessors for date and datetime. */ #define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \ @@ -71,12 +78,14 @@ class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" (((o)->data[7] = ((v) & 0xff0000) >> 16), \ ((o)->data[8] = ((v) & 0x00ff00) >> 8), \ ((o)->data[9] = ((v) & 0x0000ff))) +#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v)) /* Time accessors for time. */ #define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR #define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE #define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND #define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND +#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD #define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v)) #define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v)) #define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v)) @@ -84,6 +93,7 @@ class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" (((o)->data[3] = ((v) & 0xff0000) >> 16), \ ((o)->data[4] = ((v) & 0x00ff00) >> 8), \ ((o)->data[5] = ((v) & 0x0000ff))) +#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v)) /* Delta accessors for timedelta. */ #define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days) @@ -184,12 +194,12 @@ divide_nearest(PyObject *m, PyObject *n) * and the number of days before that month in the same year. These * are correct for non-leap years only. */ -static int _days_in_month[] = { +static const int _days_in_month[] = { 0, /* unused; this vector uses 1-based indexing */ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -static int _days_before_month[] = { +static const int _days_before_month[] = { 0, /* unused; this vector uses 1-based indexing */ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; @@ -417,7 +427,7 @@ check_date_args(int year, int month, int day) * aren't, raise ValueError and return -1. */ static int -check_time_args(int h, int m, int s, int us) +check_time_args(int h, int m, int s, int us, int fold) { if (h < 0 || h > 23) { PyErr_SetString(PyExc_ValueError, @@ -439,6 +449,11 @@ check_time_args(int h, int m, int s, int us) "microsecond must be in 0..999999"); return -1; } + if (fold != 0 && fold != 1) { + PyErr_SetString(PyExc_ValueError, + "fold must be either 0 or 1"); + return -1; + } return 0; } @@ -674,8 +689,8 @@ new_date_ex(int year, int month, int day, PyTypeObject *type) /* Create a datetime instance with no range checking. */ static PyObject * -new_datetime_ex(int year, int month, int day, int hour, int minute, - int second, int usecond, PyObject *tzinfo, PyTypeObject *type) +new_datetime_ex2(int year, int month, int day, int hour, int minute, + int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type) { PyDateTime_DateTime *self; char aware = tzinfo != Py_None; @@ -692,18 +707,27 @@ new_datetime_ex(int year, int month, int day, int hour, int minute, Py_INCREF(tzinfo); self->tzinfo = tzinfo; } + DATE_SET_FOLD(self, fold); } return (PyObject *)self; } -#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \ - new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \ +static PyObject * +new_datetime_ex(int year, int month, int day, int hour, int minute, + int second, int usecond, PyObject *tzinfo, PyTypeObject *type) +{ + return new_datetime_ex2(year, month, day, hour, minute, second, usecond, + tzinfo, 0, type); +} + +#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \ + new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \ &PyDateTime_DateTimeType) /* Create a time instance with no range checking. */ static PyObject * -new_time_ex(int hour, int minute, int second, int usecond, - PyObject *tzinfo, PyTypeObject *type) +new_time_ex2(int hour, int minute, int second, int usecond, + PyObject *tzinfo, int fold, PyTypeObject *type) { PyDateTime_Time *self; char aware = tzinfo != Py_None; @@ -720,12 +744,20 @@ new_time_ex(int hour, int minute, int second, int usecond, Py_INCREF(tzinfo); self->tzinfo = tzinfo; } + TIME_SET_FOLD(self, fold); } return (PyObject *)self; } -#define new_time(hh, mm, ss, us, tzinfo) \ - new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType) +static PyObject * +new_time_ex(int hour, int minute, int second, int usecond, + PyObject *tzinfo, PyTypeObject *type) +{ + return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type); +} + +#define new_time(hh, mm, ss, us, tzinfo, fold) \ + new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType) /* Create a timedelta instance. Normalize the members iff normalize is * true. Passing false is a speed optimization, if you know for sure @@ -873,7 +905,7 @@ get_tzinfo_member(PyObject *self) * this returns NULL. Else result is returned. */ static PyObject * -call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg) +call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg) { PyObject *offset; @@ -887,10 +919,10 @@ call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg) if (offset == Py_None || offset == NULL) return offset; if (PyDelta_Check(offset)) { - if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) { + if (GET_TD_MICROSECONDS(offset) != 0) { Py_DECREF(offset); PyErr_Format(PyExc_ValueError, "offset must be a timedelta" - " representing a whole number of minutes"); + " representing a whole number of seconds"); return NULL; } if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) || @@ -1002,6 +1034,30 @@ append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo) return repr; } +/* repr is like "someclass(arg1, arg2)". If fold isn't 0, + * stuff + * ", fold=" + repr(tzinfo) + * before the closing ")". + */ +static PyObject * +append_keyword_fold(PyObject *repr, int fold) +{ + PyObject *temp; + + assert(PyUnicode_Check(repr)); + if (fold == 0) + return repr; + /* Get rid of the trailing ')'. */ + assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')'); + temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1); + Py_DECREF(repr); + if (temp == NULL) + return NULL; + repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold); + Py_DECREF(temp); + return repr; +} + /* --------------------------------------------------------------------------- * String format helpers. */ @@ -1009,10 +1065,10 @@ append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo) static PyObject * format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds) { - static const char *DayNames[] = { + static const char * const DayNames[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; - static const char *MonthNames[] = { + static const char * const MonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; @@ -1057,10 +1113,8 @@ format_utcoffset(char *buf, size_t buflen, const char *sep, } /* Offset is normalized, so it is negative if days < 0 */ if (GET_TD_DAYS(offset) < 0) { - PyObject *temp = offset; sign = '-'; - offset = delta_negative((PyDateTime_Delta *)offset); - Py_DECREF(temp); + Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset)); if (offset == NULL) return -1; } @@ -1072,10 +1126,11 @@ format_utcoffset(char *buf, size_t buflen, const char *sep, Py_DECREF(offset); minutes = divmod(seconds, 60, &seconds); hours = divmod(minutes, 60, &minutes); - assert(seconds == 0); - /* XXX ignore sub-minute data, currently not allowed. */ - PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes); - + if (seconds == 0) + PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes); + else + PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours, + sep, minutes, sep, seconds); return 0; } @@ -1323,7 +1378,7 @@ time_time(void) if (time != NULL) { _Py_IDENTIFIER(time); - result = _PyObject_CallMethodId(time, &PyId_time, "()"); + result = _PyObject_CallMethodId(time, &PyId_time, NULL); Py_DECREF(time); } return result; @@ -2307,7 +2362,7 @@ static PyMethodDef delta_methods[] = { {NULL, NULL}, }; -static char delta_doc[] = +static const char delta_doc[] = PyDoc_STR("Difference between two datetime values."); static PyNumberMethods delta_as_number = { @@ -2648,7 +2703,7 @@ date_isoformat(PyDateTime_Date *self) static PyObject * date_str(PyDateTime_Date *self) { - return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()"); + return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL); } @@ -2674,7 +2729,7 @@ date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) &format)) return NULL; - tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()"); + tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL); if (tuple == NULL) return NULL; result = wrap_strftime((PyObject *)self, format, tuple, @@ -2886,7 +2941,7 @@ static PyMethodDef date_methods[] = { {NULL, NULL} }; -static char date_doc[] = +static const char date_doc[] = PyDoc_STR("date(year, month, day) --> date object"); static PyNumberMethods date_as_number = { @@ -3047,10 +3102,8 @@ tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt) if (dst == Py_None) goto Inconsistent; if (delta_bool((PyDateTime_Delta *)dst) != 0) { - PyObject *temp = result; - result = add_datetime_timedelta((PyDateTime_DateTime *)result, - (PyDateTime_Delta *)dst, 1); - Py_DECREF(temp); + Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result, + (PyDateTime_Delta *)dst, 1)); if (result == NULL) goto Fail; } @@ -3080,37 +3133,34 @@ Fail: static PyObject * tzinfo_reduce(PyObject *self) { - PyObject *args, *state, *tmp; + PyObject *args, *state; PyObject *getinitargs, *getstate; _Py_IDENTIFIER(__getinitargs__); _Py_IDENTIFIER(__getstate__); - tmp = PyTuple_New(0); - if (tmp == NULL) - return NULL; - getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__); if (getinitargs != NULL) { - args = PyObject_CallObject(getinitargs, tmp); + args = _PyObject_CallNoArg(getinitargs); Py_DECREF(getinitargs); if (args == NULL) { - Py_DECREF(tmp); return NULL; } } else { PyErr_Clear(); - args = tmp; - Py_INCREF(args); + + args = PyTuple_New(0); + if (args == NULL) { + return NULL; + } } getstate = _PyObject_GetAttrId(self, &PyId___getstate__); if (getstate != NULL) { - state = PyObject_CallObject(getstate, tmp); + state = _PyObject_CallNoArg(getstate); Py_DECREF(getstate); if (state == NULL) { Py_DECREF(args); - Py_DECREF(tmp); return NULL; } } @@ -3119,13 +3169,12 @@ tzinfo_reduce(PyObject *self) PyErr_Clear(); state = Py_None; dictptr = _PyObject_GetDictPtr(self); - if (dictptr && *dictptr && PyDict_Size(*dictptr)) + if (dictptr && *dictptr && PyDict_Size(*dictptr)) { state = *dictptr; + } Py_INCREF(state); } - Py_DECREF(tmp); - if (state == Py_None) { Py_DECREF(state); return Py_BuildValue("(ON)", Py_TYPE(self), args); @@ -3155,7 +3204,7 @@ static PyMethodDef tzinfo_methods[] = { {NULL, NULL} }; -static char tzinfo_doc[] = +static const char tzinfo_doc[] = PyDoc_STR("Abstract base class for time zone info objects."); static PyTypeObject PyDateTime_TZInfoType = { @@ -3287,6 +3336,11 @@ timezone_str(PyDateTime_TimeZone *self) Py_INCREF(self->name); return self->name; } + if ((PyObject *)self == PyDateTime_TimeZone_UTC || + (GET_TD_DAYS(self->offset) == 0 && + GET_TD_SECONDS(self->offset) == 0 && + GET_TD_MICROSECONDS(self->offset) == 0)) + return PyUnicode_FromString("UTC"); /* Offset is normalized, so it is negative if days < 0 */ if (GET_TD_DAYS(self->offset) < 0) { sign = '-'; @@ -3382,7 +3436,7 @@ static PyMethodDef timezone_methods[] = { {NULL, NULL} }; -static char timezone_doc[] = +static const char timezone_doc[] = PyDoc_STR("Fixed offset from UTC implementation of tzinfo."); static PyTypeObject PyDateTime_TimeZoneType = { @@ -3466,12 +3520,19 @@ time_tzinfo(PyDateTime_Time *self, void *unused) return result; } +static PyObject * +time_fold(PyDateTime_Time *self, void *unused) +{ + return PyLong_FromLong(TIME_GET_FOLD(self)); +} + static PyGetSetDef time_getset[] = { {"hour", (getter)time_hour}, {"minute", (getter)time_minute}, {"second", (getter)py_time_second}, {"microsecond", (getter)time_microsecond}, - {"tzinfo", (getter)time_tzinfo}, + {"tzinfo", (getter)time_tzinfo}, + {"fold", (getter)time_fold}, {NULL} }; @@ -3480,7 +3541,7 @@ static PyGetSetDef time_getset[] = { */ static char *time_kws[] = {"hour", "minute", "second", "microsecond", - "tzinfo", NULL}; + "tzinfo", "fold", NULL}; static PyObject * time_new(PyTypeObject *type, PyObject *args, PyObject *kw) @@ -3492,13 +3553,14 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw) int second = 0; int usecond = 0; PyObject *tzinfo = Py_None; + int fold = 0; /* Check for invocation from pickle with __getstate__ state */ if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2 && PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE && - ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24) + (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24) { PyDateTime_Time *me; char aware; @@ -3523,19 +3585,26 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw) Py_INCREF(tzinfo); me->tzinfo = tzinfo; } + if (pdata[0] & (1 << 7)) { + me->data[0] -= 128; + me->fold = 1; + } + else { + me->fold = 0; + } } return (PyObject *)me; } - if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws, + if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws, &hour, &minute, &second, &usecond, - &tzinfo)) { - if (check_time_args(hour, minute, second, usecond) < 0) + &tzinfo, &fold)) { + if (check_time_args(hour, minute, second, usecond, fold) < 0) return NULL; if (check_tzinfo_subclass(tzinfo) < 0) return NULL; - self = new_time_ex(hour, minute, second, usecond, tzinfo, - type); + self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold, + type); } return self; } @@ -3585,6 +3654,7 @@ time_repr(PyDateTime_Time *self) int m = TIME_GET_MINUTE(self); int s = TIME_GET_SECOND(self); int us = TIME_GET_MICROSECOND(self); + int fold = TIME_GET_FOLD(self); PyObject *result = NULL; if (us) @@ -3597,33 +3667,68 @@ time_repr(PyDateTime_Time *self) result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m); if (result != NULL && HASTZINFO(self)) result = append_keyword_tzinfo(result, self->tzinfo); + if (result != NULL && fold) + result = append_keyword_fold(result, fold); return result; } static PyObject * time_str(PyDateTime_Time *self) { - return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()"); + return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL); } static PyObject * -time_isoformat(PyDateTime_Time *self, PyObject *unused) +time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw) { char buf[100]; + char *timespec = NULL; + static char *keywords[] = {"timespec", NULL}; PyObject *result; int us = TIME_GET_MICROSECOND(self); + static char *specs[][2] = { + {"hours", "%02d"}, + {"minutes", "%02d:%02d"}, + {"seconds", "%02d:%02d:%02d"}, + {"milliseconds", "%02d:%02d:%02d.%03d"}, + {"microseconds", "%02d:%02d:%02d.%06d"}, + }; + size_t given_spec; - if (us) - result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d", - TIME_GET_HOUR(self), - TIME_GET_MINUTE(self), - TIME_GET_SECOND(self), - us); - else - result = PyUnicode_FromFormat("%02d:%02d:%02d", - TIME_GET_HOUR(self), - TIME_GET_MINUTE(self), - TIME_GET_SECOND(self)); + if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, ×pec)) + return NULL; + + if (timespec == NULL || strcmp(timespec, "auto") == 0) { + if (us == 0) { + /* seconds */ + given_spec = 2; + } + else { + /* microseconds */ + given_spec = 4; + } + } + else { + for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) { + if (strcmp(timespec, specs[given_spec][0]) == 0) { + if (given_spec == 3) { + /* milliseconds */ + us = us / 1000; + } + break; + } + } + } + + if (given_spec == Py_ARRAY_LENGTH(specs)) { + PyErr_Format(PyExc_ValueError, "Unknown timespec value"); + return NULL; + } + else { + result = PyUnicode_FromFormat(specs[given_spec][1], + TIME_GET_HOUR(self), TIME_GET_MINUTE(self), + TIME_GET_SECOND(self), us); + } if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None) return result; @@ -3750,9 +3855,23 @@ static Py_hash_t time_hash(PyDateTime_Time *self) { if (self->hashcode == -1) { - PyObject *offset; - - offset = time_utcoffset((PyObject *)self, NULL); + PyObject *offset, *self0; + if (DATE_GET_FOLD(self)) { + self0 = new_time_ex2(DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + DATE_GET_MICROSECOND(self), + HASTZINFO(self) ? self->tzinfo : Py_None, + 0, Py_TYPE(self)); + if (self0 == NULL) + return -1; + } + else { + self0 = (PyObject *)self; + Py_INCREF(self0); + } + offset = time_utcoffset(self0, NULL); + Py_DECREF(self0); if (offset == NULL) return -1; @@ -3798,15 +3917,24 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) int ss = TIME_GET_SECOND(self); int us = TIME_GET_MICROSECOND(self); PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None; + int fold = TIME_GET_FOLD(self); - if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace", + if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace", time_kws, - &hh, &mm, &ss, &us, &tzinfo)) + &hh, &mm, &ss, &us, &tzinfo, &fold)) return NULL; tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo); if (tuple == NULL) return NULL; clone = time_new(Py_TYPE(self), tuple, NULL); + if (clone != NULL) { + if (fold != 0 && fold != 1) { + PyErr_SetString(PyExc_ValueError, + "fold must be either 0 or 1"); + return NULL; + } + TIME_SET_FOLD(clone, fold); + } Py_DECREF(tuple); return clone; } @@ -3819,7 +3947,7 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) * __getstate__ isn't exposed. */ static PyObject * -time_getstate(PyDateTime_Time *self) +time_getstate(PyDateTime_Time *self, int proto) { PyObject *basestate; PyObject *result = NULL; @@ -3827,6 +3955,9 @@ time_getstate(PyDateTime_Time *self) basestate = PyBytes_FromStringAndSize((char *)self->data, _PyDateTime_TIME_DATASIZE); if (basestate != NULL) { + if (proto > 3 && TIME_GET_FOLD(self)) + /* Set the first bit of the first byte */ + PyBytes_AS_STRING(basestate)[0] |= (1 << 7); if (! HASTZINFO(self) || self->tzinfo == Py_None) result = PyTuple_Pack(1, basestate); else @@ -3837,16 +3968,21 @@ time_getstate(PyDateTime_Time *self) } static PyObject * -time_reduce(PyDateTime_Time *self, PyObject *arg) +time_reduce(PyDateTime_Time *self, PyObject *args) { - return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self)); + int proto = 0; + if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto)) + return NULL; + + return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto)); } static PyMethodDef time_methods[] = { - {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS, - PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]" - "[+HH:MM].")}, + {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]" + "[+HH:MM].\n\n" + "timespec specifies what components of the time to include.\n")}, {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("format -> strftime() style string.")}, @@ -3866,13 +4002,13 @@ static PyMethodDef time_methods[] = { {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Return time with new specified fields.")}, - {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS, - PyDoc_STR("__reduce__() -> (cls, state)")}, + {"__reduce_ex__", (PyCFunction)time_reduce, METH_VARARGS, + PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")}, {NULL, NULL} }; -static char time_doc[] = +static const char time_doc[] = PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\ \n\ All arguments are optional. tzinfo may be None, or an instance of\n\ @@ -3960,12 +4096,19 @@ datetime_tzinfo(PyDateTime_DateTime *self, void *unused) return result; } +static PyObject * +datetime_fold(PyDateTime_DateTime *self, void *unused) +{ + return PyLong_FromLong(DATE_GET_FOLD(self)); +} + static PyGetSetDef datetime_getset[] = { {"hour", (getter)datetime_hour}, {"minute", (getter)datetime_minute}, {"second", (getter)datetime_second}, {"microsecond", (getter)datetime_microsecond}, - {"tzinfo", (getter)datetime_tzinfo}, + {"tzinfo", (getter)datetime_tzinfo}, + {"fold", (getter)datetime_fold}, {NULL} }; @@ -3975,7 +4118,7 @@ static PyGetSetDef datetime_getset[] = { static char *datetime_kws[] = { "year", "month", "day", "hour", "minute", "second", - "microsecond", "tzinfo", NULL + "microsecond", "tzinfo", "fold", NULL }; static PyObject * @@ -3990,6 +4133,7 @@ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) int minute = 0; int second = 0; int usecond = 0; + int fold = 0; PyObject *tzinfo = Py_None; /* Check for invocation from pickle with __getstate__ state */ @@ -3997,7 +4141,7 @@ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) PyTuple_GET_SIZE(args) <= 2 && PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE && - MONTH_IS_SANE(PyBytes_AS_STRING(state)[2])) + MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F)) { PyDateTime_DateTime *me; char aware; @@ -4022,22 +4166,29 @@ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) Py_INCREF(tzinfo); me->tzinfo = tzinfo; } + if (pdata[2] & (1 << 7)) { + me->data[2] -= 128; + me->fold = 1; + } + else { + me->fold = 0; + } } return (PyObject *)me; } - if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws, + if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws, &year, &month, &day, &hour, &minute, - &second, &usecond, &tzinfo)) { + &second, &usecond, &tzinfo, &fold)) { if (check_date_args(year, month, day) < 0) return NULL; - if (check_time_args(hour, minute, second, usecond) < 0) + if (check_time_args(hour, minute, second, usecond, fold) < 0) return NULL; if (check_tzinfo_subclass(tzinfo) < 0) return NULL; - self = new_datetime_ex(year, month, day, + self = new_datetime_ex2(year, month, day, hour, minute, second, usecond, - tzinfo, type); + tzinfo, fold, type); } return self; } @@ -4045,6 +4196,45 @@ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) /* TM_FUNC is the shared type of localtime() and gmtime(). */ typedef struct tm *(*TM_FUNC)(const time_t *timer); +/* As of version 2015f max fold in IANA database is + * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */ +static long long max_fold_seconds = 24 * 3600; +/* NB: date(1970,1,1).toordinal() == 719163 */ +static long long epoch = Py_LL(719163) * 24 * 60 * 60; + +static long long +utc_to_seconds(int year, int month, int day, + int hour, int minute, int second) +{ + long long ordinal = ymd_to_ord(year, month, day); + return ((ordinal * 24 + hour) * 60 + minute) * 60 + second; +} + +static long long +local(long long u) +{ + struct tm local_time; + time_t t; + u -= epoch; + t = u; + if (t != u) { + PyErr_SetString(PyExc_OverflowError, + "timestamp out of range for platform time_t"); + return -1; + } + /* XXX: add bounds checking */ + if (localtime_r(&t, &local_time) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + return utc_to_seconds(local_time.tm_year + 1900, + local_time.tm_mon + 1, + local_time.tm_mday, + local_time.tm_hour, + local_time.tm_min, + local_time.tm_sec); +} + /* Internal helper. * Build datetime from a time_t and a distinct count of microseconds. * Pass localtime or gmtime for f, to control the interpretation of timet. @@ -4054,6 +4244,7 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, PyObject *tzinfo) { struct tm *tm; + int year, month, day, hour, minute, second, fold = 0; tm = f(&timet); if (tm == NULL) { @@ -4064,61 +4255,40 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, return PyErr_SetFromErrno(PyExc_OSError); } + year = tm->tm_year + 1900; + month = tm->tm_mon + 1; + day = tm->tm_mday; + hour = tm->tm_hour; + minute = tm->tm_min; /* The platform localtime/gmtime may insert leap seconds, * indicated by tm->tm_sec > 59. We don't care about them, * except to the extent that passing them on to the datetime * constructor would raise ValueError for a reason that * made no sense to the user. */ - if (tm->tm_sec > 59) - tm->tm_sec = 59; - return PyObject_CallFunction(cls, "iiiiiiiO", - tm->tm_year + 1900, - tm->tm_mon + 1, - tm->tm_mday, - tm->tm_hour, - tm->tm_min, - tm->tm_sec, - us, - tzinfo); -} - -static time_t -_PyTime_DoubleToTimet(double x) -{ - time_t result; - double diff; - - result = (time_t)x; - /* How much info did we lose? time_t may be an integral or - * floating type, and we don't know which. If it's integral, - * we don't know whether C truncates, rounds, returns the floor, - * etc. If we lost a second or more, the C rounding is - * unreasonable, or the input just doesn't fit in a time_t; - * call it an error regardless. Note that the original cast to - * time_t can cause a C error too, but nothing we can do to - * worm around that. - */ - diff = x - (double)result; - if (diff <= -1.0 || diff >= 1.0) { - PyErr_SetString(PyExc_OverflowError, - "timestamp out of range for platform time_t"); - result = (time_t)-1; - } - return result; -} + second = Py_MIN(59, tm->tm_sec); -/* Round a double to the nearest long. |x| must be small enough to fit - * in a C long; this is not checked. - */ -static double -_PyTime_RoundHalfEven(double x) -{ - double rounded = round(x); - if (fabs(x-rounded) == 0.5) - /* halfway case: round to even */ - rounded = 2.0*round(x/2.0); - return rounded; + if (tzinfo == Py_None && f == localtime) { + long long probe_seconds, result_seconds, transition; + + result_seconds = utc_to_seconds(year, month, day, + hour, minute, second); + /* Probe max_fold_seconds to detect a fold. */ + probe_seconds = local(epoch + timet - max_fold_seconds); + if (probe_seconds == -1) + return NULL; + transition = result_seconds - probe_seconds - max_fold_seconds; + if (transition < 0) { + probe_seconds = local(epoch + timet + transition); + if (probe_seconds == -1) + return NULL; + if (probe_seconds == result_seconds) + fold = 1; + } + } + return new_datetime_ex2(year, month, day, hour, + minute, second, us, tzinfo, fold, + (PyTypeObject *)cls); } /* Internal helper. @@ -4129,32 +4299,17 @@ _PyTime_RoundHalfEven(double x) * to get that much precision (e.g., C time() isn't good enough). */ static PyObject * -datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp, +datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, PyObject *tzinfo) { time_t timet; - double fraction; - int us; + long us; - timet = _PyTime_DoubleToTimet(timestamp); - if (timet == (time_t)-1 && PyErr_Occurred()) + if (_PyTime_ObjectToTimeval(timestamp, + &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1) return NULL; - fraction = timestamp - (double)timet; - us = (int)_PyTime_RoundHalfEven(fraction * 1e6); - if (us < 0) { - /* Truncation towards zero is not what we wanted - for negative numbers (Python's mod semantics) */ - timet -= 1; - us += 1000000; - } - /* If timestamp is less than one microsecond smaller than a - * full second, round up. Otherwise, ValueErrors are raised - * for some floats. */ - if (us == 1000000) { - timet += 1; - us = 0; - } - return datetime_from_timet_and_us(cls, f, timet, us, tzinfo); + + return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo); } /* Internal helper. @@ -4205,10 +4360,7 @@ datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz) tz); if (self != NULL && tz != Py_None) { /* Convert UTC to tzinfo's zone. */ - PyObject *temp = self; - - self = _PyObject_CallMethodId(tz, &PyId_fromutc, "O", self); - Py_DECREF(temp); + self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self); } return self; } @@ -4227,11 +4379,11 @@ static PyObject * datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) { PyObject *self; - double timestamp; + PyObject *timestamp; PyObject *tzinfo = Py_None; static char *keywords[] = {"timestamp", "tz", NULL}; - if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp", + if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp", keywords, ×tamp, &tzinfo)) return NULL; if (check_tzinfo_subclass(tzinfo) < 0) @@ -4243,10 +4395,7 @@ datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) tzinfo); if (self != NULL && tzinfo != Py_None) { /* Convert UTC to tzinfo's zone. */ - PyObject *temp = self; - - self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self); - Py_DECREF(temp); + self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self); } return self; } @@ -4255,10 +4404,10 @@ datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) static PyObject * datetime_utcfromtimestamp(PyObject *cls, PyObject *args) { - double timestamp; + PyObject *timestamp; PyObject *result = NULL; - if (PyArg_ParseTuple(args, "d:utcfromtimestamp", ×tamp)) + if (PyArg_ParseTuple(args, "O:utcfromtimestamp", ×tamp)) result = datetime_from_timestamp(cls, gmtime, timestamp, Py_None); return result; @@ -4288,27 +4437,32 @@ datetime_strptime(PyObject *cls, PyObject *args) static PyObject * datetime_combine(PyObject *cls, PyObject *args, PyObject *kw) { - static char *keywords[] = {"date", "time", NULL}; + static char *keywords[] = {"date", "time", "tzinfo", NULL}; PyObject *date; PyObject *time; + PyObject *tzinfo = NULL; PyObject *result = NULL; - if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords, + if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords, &PyDateTime_DateType, &date, - &PyDateTime_TimeType, &time)) { - PyObject *tzinfo = Py_None; - - if (HASTZINFO(time)) - tzinfo = ((PyDateTime_Time *)time)->tzinfo; + &PyDateTime_TimeType, &time, &tzinfo)) { + if (tzinfo == NULL) { + if (HASTZINFO(time)) + tzinfo = ((PyDateTime_Time *)time)->tzinfo; + else + tzinfo = Py_None; + } result = PyObject_CallFunction(cls, "iiiiiiiO", - GET_YEAR(date), - GET_MONTH(date), - GET_DAY(date), - TIME_GET_HOUR(time), - TIME_GET_MINUTE(time), - TIME_GET_SECOND(time), - TIME_GET_MICROSECOND(time), - tzinfo); + GET_YEAR(date), + GET_MONTH(date), + GET_DAY(date), + TIME_GET_HOUR(time), + TIME_GET_MINUTE(time), + TIME_GET_SECOND(time), + TIME_GET_MICROSECOND(time), + tzinfo); + if (result) + DATE_SET_FOLD(result, TIME_GET_FOLD(time)); } return result; } @@ -4376,7 +4530,7 @@ add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta, else return new_datetime(year, month, day, hour, minute, second, microsecond, - HASTZINFO(date) ? date->tzinfo : Py_None); + HASTZINFO(date) ? date->tzinfo : Py_None, 0); } static PyObject * @@ -4469,9 +4623,7 @@ datetime_subtract(PyObject *left, PyObject *right) return NULL; if (offdiff != NULL) { - PyObject *temp = result; - result = delta_subtract(result, offdiff); - Py_DECREF(temp); + Py_SETREF(result, delta_subtract(result, offdiff)); Py_DECREF(offdiff); } } @@ -4521,6 +4673,8 @@ datetime_repr(PyDateTime_DateTime *self) GET_YEAR(self), GET_MONTH(self), GET_DAY(self), DATE_GET_HOUR(self), DATE_GET_MINUTE(self)); } + if (baserepr != NULL && DATE_GET_FOLD(self) != 0) + baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self)); if (baserepr == NULL || ! HASTZINFO(self)) return baserepr; return append_keyword_tzinfo(baserepr, self->tzinfo); @@ -4536,25 +4690,55 @@ static PyObject * datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) { int sep = 'T'; - static char *keywords[] = {"sep", NULL}; + char *timespec = NULL; + static char *keywords[] = {"sep", "timespec", NULL}; char buffer[100]; - PyObject *result; + PyObject *result = NULL; int us = DATE_GET_MICROSECOND(self); + static char *specs[][2] = { + {"hours", "%04d-%02d-%02d%c%02d"}, + {"minutes", "%04d-%02d-%02d%c%02d:%02d"}, + {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"}, + {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"}, + {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"}, + }; + size_t given_spec; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, ×pec)) return NULL; - if (us) - result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d", + + if (timespec == NULL || strcmp(timespec, "auto") == 0) { + if (us == 0) { + /* seconds */ + given_spec = 2; + } + else { + /* microseconds */ + given_spec = 4; + } + } + else { + for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) { + if (strcmp(timespec, specs[given_spec][0]) == 0) { + if (given_spec == 3) { + us = us / 1000; + } + break; + } + } + } + + if (given_spec == Py_ARRAY_LENGTH(specs)) { + PyErr_Format(PyExc_ValueError, "Unknown timespec value"); + return NULL; + } + else { + result = PyUnicode_FromFormat(specs[given_spec][1], GET_YEAR(self), GET_MONTH(self), GET_DAY(self), (int)sep, DATE_GET_HOUR(self), DATE_GET_MINUTE(self), DATE_GET_SECOND(self), us); - else - result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d", - GET_YEAR(self), GET_MONTH(self), - GET_DAY(self), (int)sep, - DATE_GET_HOUR(self), DATE_GET_MINUTE(self), - DATE_GET_SECOND(self)); + } if (!result || !HASTZINFO(self)) return result; @@ -4581,6 +4765,70 @@ datetime_ctime(PyDateTime_DateTime *self) /* Miscellaneous methods. */ static PyObject * +flip_fold(PyObject *dt) +{ + return new_datetime_ex2(GET_YEAR(dt), + GET_MONTH(dt), + GET_DAY(dt), + DATE_GET_HOUR(dt), + DATE_GET_MINUTE(dt), + DATE_GET_SECOND(dt), + DATE_GET_MICROSECOND(dt), + HASTZINFO(dt) ? + ((PyDateTime_DateTime *)dt)->tzinfo : Py_None, + !DATE_GET_FOLD(dt), + Py_TYPE(dt)); +} + +static PyObject * +get_flip_fold_offset(PyObject *dt) +{ + PyObject *result, *flip_dt; + + flip_dt = flip_fold(dt); + if (flip_dt == NULL) + return NULL; + result = datetime_utcoffset(flip_dt, NULL); + Py_DECREF(flip_dt); + return result; +} + +/* PEP 495 exception: Whenever one or both of the operands in + * inter-zone comparison is such that its utcoffset() depends + * on the value of its fold fold attribute, the result is False. + * + * Return 1 if exception applies, 0 if not, and -1 on error. + */ +static int +pep495_eq_exception(PyObject *self, PyObject *other, + PyObject *offset_self, PyObject *offset_other) +{ + int result = 0; + PyObject *flip_offset; + + flip_offset = get_flip_fold_offset(self); + if (flip_offset == NULL) + return -1; + if (flip_offset != offset_self && + delta_cmp(flip_offset, offset_self)) + { + result = 1; + goto done; + } + Py_DECREF(flip_offset); + + flip_offset = get_flip_fold_offset(other); + if (flip_offset == NULL) + return -1; + if (flip_offset != offset_other && + delta_cmp(flip_offset, offset_other)) + result = 1; + done: + Py_DECREF(flip_offset); + return result; +} + +static PyObject * datetime_richcompare(PyObject *self, PyObject *other, int op) { PyObject *result = NULL; @@ -4627,6 +4875,13 @@ datetime_richcompare(PyObject *self, PyObject *other, int op) diff = memcmp(((PyDateTime_DateTime *)self)->data, ((PyDateTime_DateTime *)other)->data, _PyDateTime_DATETIME_DATASIZE); + if ((op == Py_EQ || op == Py_NE) && diff == 0) { + int ex = pep495_eq_exception(self, other, offset1, offset2); + if (ex == -1) + goto done; + if (ex) + diff = 1; + } result = diff_to_bool(diff, op); } else if (offset1 != Py_None && offset2 != Py_None) { @@ -4642,6 +4897,13 @@ datetime_richcompare(PyObject *self, PyObject *other, int op) diff = GET_TD_SECONDS(delta) | GET_TD_MICROSECONDS(delta); Py_DECREF(delta); + if ((op == Py_EQ || op == Py_NE) && diff == 0) { + int ex = pep495_eq_exception(self, other, offset1, offset2); + if (ex == -1) + goto done; + if (ex) + diff = 1; + } result = diff_to_bool(diff, op); } else if (op == Py_EQ) { @@ -4667,9 +4929,26 @@ static Py_hash_t datetime_hash(PyDateTime_DateTime *self) { if (self->hashcode == -1) { - PyObject *offset; - - offset = datetime_utcoffset((PyObject *)self, NULL); + PyObject *offset, *self0; + if (DATE_GET_FOLD(self)) { + self0 = new_datetime_ex2(GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self), + DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + DATE_GET_MICROSECOND(self), + HASTZINFO(self) ? self->tzinfo : Py_None, + 0, Py_TYPE(self)); + if (self0 == NULL) + return -1; + } + else { + self0 = (PyObject *)self; + Py_INCREF(self0); + } + offset = datetime_utcoffset(self0, NULL); + Py_DECREF(self0); if (offset == NULL) return -1; @@ -4723,76 +5002,78 @@ datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) int ss = DATE_GET_SECOND(self); int us = DATE_GET_MICROSECOND(self); PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None; + int fold = DATE_GET_FOLD(self); - if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace", + if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace", datetime_kws, &y, &m, &d, &hh, &mm, &ss, &us, - &tzinfo)) + &tzinfo, &fold)) return NULL; tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo); if (tuple == NULL) return NULL; clone = datetime_new(Py_TYPE(self), tuple, NULL); + + if (clone != NULL) { + if (fold != 0 && fold != 1) { + PyErr_SetString(PyExc_ValueError, + "fold must be either 0 or 1"); + return NULL; + } + DATE_SET_FOLD(clone, fold); + } Py_DECREF(tuple); return clone; } static PyObject * -local_timezone(PyDateTime_DateTime *utc_time) +local_timezone_from_timestamp(time_t timestamp) { PyObject *result = NULL; - struct tm *timep; - time_t timestamp; PyObject *delta; - PyObject *one_second; - PyObject *seconds; + struct tm *local_time_tm; PyObject *nameo = NULL; const char *zone = NULL; - delta = new_delta(ymd_to_ord(GET_YEAR(utc_time), GET_MONTH(utc_time), - GET_DAY(utc_time)) - 719163, - 60 * (60 * DATE_GET_HOUR(utc_time) + - DATE_GET_MINUTE(utc_time)) + - DATE_GET_SECOND(utc_time), - 0, 0); - if (delta == NULL) - return NULL; - one_second = new_delta(0, 1, 0, 0); - if (one_second == NULL) - goto error; - seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta, - (PyDateTime_Delta *)one_second); - Py_DECREF(one_second); - if (seconds == NULL) - goto error; - Py_DECREF(delta); - timestamp = PyLong_AsLong(seconds); - Py_DECREF(seconds); - if (timestamp == -1 && PyErr_Occurred()) - return NULL; - timep = localtime(×tamp); + local_time_tm = localtime(×tamp); #ifdef HAVE_STRUCT_TM_TM_ZONE - zone = timep->tm_zone; - delta = new_delta(0, timep->tm_gmtoff, 0, 1); + zone = local_time_tm->tm_zone; + delta = new_delta(0, local_time_tm->tm_gmtoff, 0, 1); #else /* HAVE_STRUCT_TM_TM_ZONE */ { - PyObject *local_time; - local_time = new_datetime(timep->tm_year + 1900, timep->tm_mon + 1, - timep->tm_mday, timep->tm_hour, timep->tm_min, - timep->tm_sec, DATE_GET_MICROSECOND(utc_time), - utc_time->tzinfo); - if (local_time == NULL) - goto error; - delta = datetime_subtract(local_time, (PyObject*)utc_time); - /* XXX: before relying on tzname, we should compare delta - to the offset implied by timezone/altzone */ - if (daylight && timep->tm_isdst >= 0) - zone = tzname[timep->tm_isdst % 2]; - else - zone = tzname[0]; + PyObject *local_time, *utc_time; + struct tm *utc_time_tm; + char buf[100]; + strftime(buf, sizeof(buf), "%Z", local_time_tm); + zone = buf; + local_time = new_datetime(local_time_tm->tm_year + 1900, + local_time_tm->tm_mon + 1, + local_time_tm->tm_mday, + local_time_tm->tm_hour, + local_time_tm->tm_min, + local_time_tm->tm_sec, 0, Py_None, 0); + if (local_time == NULL) { + return NULL; + } + utc_time_tm = gmtime(×tamp); + utc_time = new_datetime(utc_time_tm->tm_year + 1900, + utc_time_tm->tm_mon + 1, + utc_time_tm->tm_mday, + utc_time_tm->tm_hour, + utc_time_tm->tm_min, + utc_time_tm->tm_sec, 0, Py_None, 0); + if (utc_time == NULL) { + Py_DECREF(local_time); + return NULL; + } + delta = datetime_subtract(local_time, utc_time); Py_DECREF(local_time); + Py_DECREF(utc_time); } #endif /* HAVE_STRUCT_TM_TM_ZONE */ + if (delta == NULL) { + return NULL; + } if (zone != NULL) { nameo = PyUnicode_DecodeLocale(zone, "surrogateescape"); if (nameo == NULL) @@ -4805,12 +5086,65 @@ local_timezone(PyDateTime_DateTime *utc_time) return result; } +static PyObject * +local_timezone(PyDateTime_DateTime *utc_time) +{ + time_t timestamp; + PyObject *delta; + PyObject *one_second; + PyObject *seconds; + + delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch); + if (delta == NULL) + return NULL; + one_second = new_delta(0, 1, 0, 0); + if (one_second == NULL) { + Py_DECREF(delta); + return NULL; + } + seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta, + (PyDateTime_Delta *)one_second); + Py_DECREF(one_second); + Py_DECREF(delta); + if (seconds == NULL) + return NULL; + timestamp = _PyLong_AsTime_t(seconds); + Py_DECREF(seconds); + if (timestamp == -1 && PyErr_Occurred()) + return NULL; + return local_timezone_from_timestamp(timestamp); +} + +static long long +local_to_seconds(int year, int month, int day, + int hour, int minute, int second, int fold); + +static PyObject * +local_timezone_from_local(PyDateTime_DateTime *local_dt) +{ + long long seconds; + time_t timestamp; + seconds = local_to_seconds(GET_YEAR(local_dt), + GET_MONTH(local_dt), + GET_DAY(local_dt), + DATE_GET_HOUR(local_dt), + DATE_GET_MINUTE(local_dt), + DATE_GET_SECOND(local_dt), + DATE_GET_FOLD(local_dt)); + if (seconds == -1) + return NULL; + /* XXX: add bounds check */ + timestamp = seconds - epoch; + return local_timezone_from_timestamp(timestamp); +} + static PyDateTime_DateTime * datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) { PyDateTime_DateTime *result; PyObject *offset; PyObject *temp; + PyObject *self_tzinfo; PyObject *tzinfo = Py_None; static char *keywords[] = {"tz", NULL}; @@ -4821,27 +5155,27 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) if (check_tzinfo_subclass(tzinfo) == -1) return NULL; - if (!HASTZINFO(self) || self->tzinfo == Py_None) - goto NeedAware; + if (!HASTZINFO(self) || self->tzinfo == Py_None) { + self_tzinfo = local_timezone_from_local(self); + if (self_tzinfo == NULL) + return NULL; + } else { + self_tzinfo = self->tzinfo; + Py_INCREF(self_tzinfo); + } /* Conversion to self's own time zone is a NOP. */ - if (self->tzinfo == tzinfo) { + if (self_tzinfo == tzinfo) { + Py_DECREF(self_tzinfo); Py_INCREF(self); return self; } /* Convert self to UTC. */ - offset = datetime_utcoffset((PyObject *)self, NULL); + offset = call_utcoffset(self_tzinfo, (PyObject *)self); + Py_DECREF(self_tzinfo); if (offset == NULL) return NULL; - if (offset == Py_None) { - Py_DECREF(offset); - NeedAware: - PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to " - "a naive datetime"); - return NULL; - } - /* result = self - offset */ result = (PyDateTime_DateTime *)add_datetime_timedelta(self, (PyDateTime_Delta *)offset, -1); @@ -4849,6 +5183,32 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) if (result == NULL) return NULL; + /* Make sure result is aware and UTC. */ + if (!HASTZINFO(result)) { + temp = (PyObject *)result; + result = (PyDateTime_DateTime *) + new_datetime_ex2(GET_YEAR(result), + GET_MONTH(result), + GET_DAY(result), + DATE_GET_HOUR(result), + DATE_GET_MINUTE(result), + DATE_GET_SECOND(result), + DATE_GET_MICROSECOND(result), + PyDateTime_TimeZone_UTC, + DATE_GET_FOLD(result), + Py_TYPE(result)); + Py_DECREF(temp); + if (result == NULL) + return NULL; + } + else { + /* Result is already aware - just replace tzinfo. */ + temp = result->tzinfo; + result->tzinfo = PyDateTime_TimeZone_UTC; + Py_INCREF(result->tzinfo); + Py_DECREF(temp); + } + /* Attach new tzinfo and let fromutc() do the rest. */ temp = result->tzinfo; if (tzinfo == Py_None) { @@ -4896,6 +5256,56 @@ datetime_timetuple(PyDateTime_DateTime *self) dstflag); } +static long long +local_to_seconds(int year, int month, int day, + int hour, int minute, int second, int fold) +{ + long long t, a, b, u1, u2, t1, t2, lt; + t = utc_to_seconds(year, month, day, hour, minute, second); + /* Our goal is to solve t = local(u) for u. */ + lt = local(t); + if (lt == -1) + return -1; + a = lt - t; + u1 = t - a; + t1 = local(u1); + if (t1 == -1) + return -1; + if (t1 == t) { + /* We found one solution, but it may not be the one we need. + * Look for an earlier solution (if `fold` is 0), or a + * later one (if `fold` is 1). */ + if (fold) + u2 = u1 + max_fold_seconds; + else + u2 = u1 - max_fold_seconds; + lt = local(u2); + if (lt == -1) + return -1; + b = lt - u2; + if (a == b) + return u1; + } + else { + b = t1 - u1; + assert(a != b); + } + u2 = t - b; + t2 = local(u2); + if (t2 == -1) + return -1; + if (t2 == t) + return u2; + if (t1 == t) + return u1; + /* We have found both offsets a and b, but neither t - a nor t - b is + * a solution. This means t is in the gap. */ + return fold?Py_MIN(u1, u2):Py_MAX(u1, u2); +} + +/* date(1970,1,1).toordinal() == 719163 */ +#define EPOCH_SECONDS (719163LL * 24 * 60 * 60) + static PyObject * datetime_timestamp(PyDateTime_DateTime *self) { @@ -4910,33 +5320,18 @@ datetime_timestamp(PyDateTime_DateTime *self) Py_DECREF(delta); } else { - struct tm time; - time_t timestamp; - memset((void *) &time, '\0', sizeof(struct tm)); - time.tm_year = GET_YEAR(self) - 1900; - time.tm_mon = GET_MONTH(self) - 1; - time.tm_mday = GET_DAY(self); - time.tm_hour = DATE_GET_HOUR(self); - time.tm_min = DATE_GET_MINUTE(self); - time.tm_sec = DATE_GET_SECOND(self); - time.tm_wday = -1; - time.tm_isdst = -1; - timestamp = mktime(&time); - if (timestamp == (time_t)(-1) -#ifndef _AIX - /* Return value of -1 does not necessarily mean an error, - * but tm_wday cannot remain set to -1 if mktime succeeded. */ - && time.tm_wday == -1 -#else - /* on AIX, tm_wday is always sets, even on error */ -#endif - ) - { - PyErr_SetString(PyExc_OverflowError, - "timestamp out of range"); + long long seconds; + seconds = local_to_seconds(GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self), + DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + DATE_GET_FOLD(self)); + if (seconds == -1) return NULL; - } - result = PyFloat_FromDouble(timestamp + DATE_GET_MICROSECOND(self) / 1e6); + result = PyFloat_FromDouble(seconds - EPOCH_SECONDS + + DATE_GET_MICROSECOND(self) / 1e6); } return result; } @@ -4956,7 +5351,8 @@ datetime_gettime(PyDateTime_DateTime *self) DATE_GET_MINUTE(self), DATE_GET_SECOND(self), DATE_GET_MICROSECOND(self), - Py_None); + Py_None, + DATE_GET_FOLD(self)); } static PyObject * @@ -4966,7 +5362,8 @@ datetime_gettimetz(PyDateTime_DateTime *self) DATE_GET_MINUTE(self), DATE_GET_SECOND(self), DATE_GET_MICROSECOND(self), - GET_DT_TZINFO(self)); + GET_DT_TZINFO(self), + DATE_GET_FOLD(self)); } static PyObject * @@ -5018,7 +5415,7 @@ datetime_utctimetuple(PyDateTime_DateTime *self) * __getstate__ isn't exposed. */ static PyObject * -datetime_getstate(PyDateTime_DateTime *self) +datetime_getstate(PyDateTime_DateTime *self, int proto) { PyObject *basestate; PyObject *result = NULL; @@ -5026,6 +5423,9 @@ datetime_getstate(PyDateTime_DateTime *self) basestate = PyBytes_FromStringAndSize((char *)self->data, _PyDateTime_DATETIME_DATASIZE); if (basestate != NULL) { + if (proto > 3 && DATE_GET_FOLD(self)) + /* Set the first bit of the third byte */ + PyBytes_AS_STRING(basestate)[2] |= (1 << 7); if (! HASTZINFO(self) || self->tzinfo == Py_None) result = PyTuple_Pack(1, basestate); else @@ -5036,9 +5436,13 @@ datetime_getstate(PyDateTime_DateTime *self) } static PyObject * -datetime_reduce(PyDateTime_DateTime *self, PyObject *arg) +datetime_reduce(PyDateTime_DateTime *self, PyObject *args) { - return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self)); + int proto = 0; + if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto)) + return NULL; + + return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto)); } static PyMethodDef datetime_methods[] = { @@ -5093,9 +5497,12 @@ static PyMethodDef datetime_methods[] = { {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("[sep] -> string in ISO 8601 format, " - "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n" + "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n" "sep is used to separate the year from the time, and " - "defaults to 'T'.")}, + "defaults to 'T'.\n" + "timespec specifies what components of the time to include" + " (allowed values are 'auto', 'hours', 'minutes', 'seconds'," + " 'milliseconds', and 'microseconds').\n")}, {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS, PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, @@ -5112,13 +5519,13 @@ static PyMethodDef datetime_methods[] = { {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS, PyDoc_STR("tz -> convert to local time in new timezone tz\n")}, - {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS, - PyDoc_STR("__reduce__() -> (cls, state)")}, + {"__reduce_ex__", (PyCFunction)datetime_reduce, METH_VARARGS, + PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")}, {NULL, NULL} }; -static char datetime_doc[] = +static const char datetime_doc[] = PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\ \n\ The year, month and day arguments are required. tzinfo may be None, or an\n\ @@ -5201,7 +5608,9 @@ static PyDateTime_CAPI CAPI = { new_time_ex, new_delta_ex, datetime_fromtimestamp, - date_fromtimestamp + date_fromtimestamp, + new_datetime_ex2, + new_time_ex2 }; @@ -5282,12 +5691,12 @@ PyInit__datetime(void) /* time values */ d = PyDateTime_TimeType.tp_dict; - x = new_time(0, 0, 0, 0, Py_None); + x = new_time(0, 0, 0, 0, Py_None, 0); if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) return NULL; Py_DECREF(x); - x = new_time(23, 59, 59, 999999, Py_None); + x = new_time(23, 59, 59, 999999, Py_None, 0); if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) return NULL; Py_DECREF(x); @@ -5300,12 +5709,12 @@ PyInit__datetime(void) /* datetime values */ d = PyDateTime_DateTimeType.tp_dict; - x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None); + x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0); if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) return NULL; Py_DECREF(x); - x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None); + x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0); if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) return NULL; Py_DECREF(x); @@ -5347,7 +5756,7 @@ PyInit__datetime(void) /* Epoch */ PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0, - PyDateTime_TimeZone_UTC); + PyDateTime_TimeZone_UTC, 0); if (PyDateTime_Epoch == NULL) return NULL; @@ -5382,19 +5791,19 @@ PyInit__datetime(void) /* A 4-year cycle has an extra leap day over what we'd get from * pasting together 4 single years. */ - assert(DI4Y == 4 * 365 + 1); + Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1); assert(DI4Y == days_before_year(4+1)); /* Similarly, a 400-year cycle has an extra leap day over what we'd * get from pasting together 4 100-year cycles. */ - assert(DI400Y == 4 * DI100Y + 1); + Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1); assert(DI400Y == days_before_year(400+1)); /* OTOH, a 100-year cycle has one fewer leap day than we'd get from * pasting together 25 4-year cycles. */ - assert(DI100Y == 25 * DI4Y - 1); + Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1); assert(DI100Y == days_before_year(100+1)); one = PyLong_FromLong(1); diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index ea8790b..804978a 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -14,16 +14,16 @@ */ #if defined(HAVE_NDBM_H) #include <ndbm.h> -static char *which_dbm = "GNU gdbm"; /* EMX port of GDBM */ +static const char which_dbm[] = "GNU gdbm"; /* EMX port of GDBM */ #elif defined(HAVE_GDBM_NDBM_H) #include <gdbm/ndbm.h> -static char *which_dbm = "GNU gdbm"; +static const char which_dbm[] = "GNU gdbm"; #elif defined(HAVE_GDBM_DASH_NDBM_H) #include <gdbm-ndbm.h> -static char *which_dbm = "GNU gdbm"; +static const char which_dbm[] = "GNU gdbm"; #elif defined(HAVE_BERKDB_H) #include <db.h> -static char *which_dbm = "Berkeley DB"; +static const char which_dbm[] = "Berkeley DB"; #else #error "No ndbm.h available!" #endif diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index e15941a..3ba8e35 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -36,7 +36,6 @@ #include <stdlib.h> #include "docstrings.h" -#include "memory.h" #if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02040100 @@ -3394,6 +3393,105 @@ dec_as_long(PyObject *dec, PyObject *context, int round) return (PyObject *) pylong; } +/* Convert a Decimal to its exact integer ratio representation. */ +static PyObject * +dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED) +{ + PyObject *numerator = NULL; + PyObject *denominator = NULL; + PyObject *exponent = NULL; + PyObject *result = NULL; + PyObject *tmp; + mpd_ssize_t exp; + PyObject *context; + uint32_t status = 0; + + if (mpd_isspecial(MPD(self))) { + if (mpd_isnan(MPD(self))) { + PyErr_SetString(PyExc_ValueError, + "cannot convert NaN to integer ratio"); + } + else { + PyErr_SetString(PyExc_OverflowError, + "cannot convert Infinity to integer ratio"); + } + return NULL; + } + + CURRENT_CONTEXT(context); + + tmp = dec_alloc(); + if (tmp == NULL) { + return NULL; + } + + if (!mpd_qcopy(MPD(tmp), MPD(self), &status)) { + Py_DECREF(tmp); + PyErr_NoMemory(); + return NULL; + } + + exp = mpd_iszero(MPD(tmp)) ? 0 : MPD(tmp)->exp; + MPD(tmp)->exp = 0; + + /* context and rounding are unused here: the conversion is exact */ + numerator = dec_as_long(tmp, context, MPD_ROUND_FLOOR); + Py_DECREF(tmp); + if (numerator == NULL) { + goto error; + } + + exponent = PyLong_FromSsize_t(exp < 0 ? -exp : exp); + if (exponent == NULL) { + goto error; + } + + tmp = PyLong_FromLong(10); + if (tmp == NULL) { + goto error; + } + + Py_SETREF(exponent, _py_long_power(tmp, exponent, Py_None)); + Py_DECREF(tmp); + if (exponent == NULL) { + goto error; + } + + if (exp >= 0) { + Py_SETREF(numerator, _py_long_multiply(numerator, exponent)); + if (numerator == NULL) { + goto error; + } + denominator = PyLong_FromLong(1); + if (denominator == NULL) { + goto error; + } + } + else { + denominator = exponent; + exponent = NULL; + tmp = _PyLong_GCD(numerator, denominator); + if (tmp == NULL) { + goto error; + } + Py_SETREF(numerator, _py_long_floor_divide(numerator, tmp)); + Py_SETREF(denominator, _py_long_floor_divide(denominator, tmp)); + Py_DECREF(tmp); + if (numerator == NULL || denominator == NULL) { + goto error; + } + } + + result = PyTuple_Pack(2, numerator, denominator); + + +error: + Py_XDECREF(exponent); + Py_XDECREF(denominator); + Py_XDECREF(numerator); + return result; +} + static PyObject * PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds) { @@ -4702,6 +4800,7 @@ static PyMethodDef dec_methods [] = /* Miscellaneous */ { "from_float", dec_from_float, METH_O|METH_CLASS, doc_from_float }, { "as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple }, + { "as_integer_ratio", dec_as_integer_ratio, METH_NOARGS, doc_as_integer_ratio }, /* Special methods */ { "__copy__", dec_copy, METH_NOARGS, NULL }, diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index 71029a9..f7fd6e7 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -70,6 +70,15 @@ PyDoc_STRVAR(doc_as_tuple, Return a tuple representation of the number.\n\ \n"); +PyDoc_STRVAR(doc_as_integer_ratio, +"as_integer_ratio($self, /)\n--\n\n\ +Decimal.as_integer_ratio() -> (int, int)\n\ +\n\ +Return a pair of integers, whose ratio is exactly equal to the original\n\ +Decimal and with a positive denominator. The ratio is in lowest terms.\n\ +Raise OverflowError on infinities and a ValueError on NaNs.\n\ +\n"); + PyDoc_STRVAR(doc_canonical, "canonical($self, /)\n--\n\n\ Return the canonical encoding of the argument. Currently, the encoding\n\ diff --git a/Modules/_decimal/libmpdec/basearith.c b/Modules/_decimal/libmpdec/basearith.c index 35de6b8..dfe1523 100644 --- a/Modules/_decimal/libmpdec/basearith.c +++ b/Modules/_decimal/libmpdec/basearith.c @@ -32,7 +32,6 @@ #include <string.h> #include <assert.h> #include "constants.h" -#include "memory.h" #include "typearith.h" #include "basearith.h" diff --git a/Modules/_decimal/libmpdec/io.c b/Modules/_decimal/libmpdec/io.c index a45a429..3aadfb0 100644 --- a/Modules/_decimal/libmpdec/io.c +++ b/Modules/_decimal/libmpdec/io.c @@ -37,7 +37,6 @@ #include <locale.h> #include "bits.h" #include "constants.h" -#include "memory.h" #include "typearith.h" #include "io.h" diff --git a/Modules/_decimal/libmpdec/memory.c b/Modules/_decimal/libmpdec/memory.c index 0f41fe5..a854e09 100644 --- a/Modules/_decimal/libmpdec/memory.c +++ b/Modules/_decimal/libmpdec/memory.c @@ -30,7 +30,12 @@ #include <stdio.h> #include <stdlib.h> #include "typearith.h" -#include "memory.h" +#include "mpalloc.h" + + +#if defined(_MSC_VER) + #pragma warning(disable : 4232) +#endif /* Guaranteed minimum allocation for a coefficient. May be changed once diff --git a/Modules/_decimal/libmpdec/memory.h b/Modules/_decimal/libmpdec/mpalloc.h index 9c98d1a..efd7119 100644 --- a/Modules/_decimal/libmpdec/memory.h +++ b/Modules/_decimal/libmpdec/mpalloc.h @@ -26,8 +26,8 @@ */ -#ifndef MEMORY_H -#define MEMORY_H +#ifndef MPALLOC_H +#define MPALLOC_H #include "mpdecimal.h" diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index 593f9f5..328ab92 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -36,7 +36,7 @@ #include "bits.h" #include "convolute.h" #include "crt.h" -#include "memory.h" +#include "mpalloc.h" #include "typearith.h" #include "umodarith.h" diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h index 5ca7413..daf2b9d 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.h +++ b/Modules/_decimal/libmpdec/mpdecimal.h @@ -48,6 +48,8 @@ extern "C" { #include <string.h> #include <limits.h> #include <assert.h> +#include <stdint.h> +#include <inttypes.h> #ifdef _MSC_VER #include "vccompat.h" @@ -59,12 +61,6 @@ extern "C" { #define MPD_HIDE_SYMBOLS_END #define EXTINLINE extern inline #else - #ifdef HAVE_STDINT_H - #include <stdint.h> - #endif - #ifdef HAVE_INTTYPES_H - #include <inttypes.h> - #endif #ifndef __GNUC_STDC_INLINE__ #define __GNUC_STDC_INLINE__ 1 #endif @@ -108,9 +104,9 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) #define MPD_MAJOR_VERSION 2 #define MPD_MINOR_VERSION 4 -#define MPD_MICRO_VERSION 1 +#define MPD_MICRO_VERSION 2 -#define MPD_VERSION "2.4.1" +#define MPD_VERSION "2.4.2" #define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \ (MPD_MINOR_VERSION << 16) | \ diff --git a/Modules/_decimal/libmpdec/vccompat.h b/Modules/_decimal/libmpdec/vccompat.h index f58e023..dd131d8 100644 --- a/Modules/_decimal/libmpdec/vccompat.h +++ b/Modules/_decimal/libmpdec/vccompat.h @@ -32,7 +32,6 @@ /* Visual C fixes: no stdint.h, no snprintf ... */ #ifdef _MSC_VER - #include "vcstdint.h" #undef inline #define inline __inline #undef random @@ -49,10 +48,6 @@ #undef strtoll #define strtoll _strtoi64 #define strdup _strdup - #define PRIi64 "I64i" - #define PRIu64 "I64u" - #define PRIi32 "I32i" - #define PRIu32 "I32u" #endif diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index ab7d5bd..f907531 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -50,8 +50,8 @@ Functions = { '__abs__', '__bool__', '__ceil__', '__complex__', '__copy__', '__floor__', '__float__', '__hash__', '__int__', '__neg__', '__pos__', '__reduce__', '__repr__', '__str__', '__trunc__', - 'adjusted', 'as_tuple', 'canonical', 'conjugate', 'copy_abs', - 'copy_negate', 'is_canonical', 'is_finite', 'is_infinite', + 'adjusted', 'as_integer_ratio', 'as_tuple', 'canonical', 'conjugate', + 'copy_abs', 'copy_negate', 'is_canonical', 'is_finite', 'is_infinite', 'is_nan', 'is_qnan', 'is_signed', 'is_snan', 'is_zero', 'radix' ), # Unary with optional context: @@ -128,7 +128,7 @@ ContextFunctions = { # Functions that require a restricted exponent range for reasonable runtimes. UnaryRestricted = [ '__ceil__', '__floor__', '__int__', '__trunc__', - 'to_integral', 'to_integral_value' + 'as_integer_ratio', 'to_integral', 'to_integral_value' ] BinaryRestricted = ['__round__'] diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 85ffca2..dd8417a 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -57,9 +57,9 @@ do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0) that all use of text and tail as object pointers must be wrapped in JOIN_OBJ. see comments in the ElementObject definition for more info. */ -#define JOIN_GET(p) ((Py_uintptr_t) (p) & 1) -#define JOIN_SET(p, flag) ((void*) ((Py_uintptr_t) (JOIN_OBJ(p)) | (flag))) -#define JOIN_OBJ(p) ((PyObject*) ((Py_uintptr_t) (p) & ~(Py_uintptr_t)1)) +#define JOIN_GET(p) ((uintptr_t) (p) & 1) +#define JOIN_SET(p, flag) ((void*) ((uintptr_t) (JOIN_OBJ(p)) | (flag))) +#define JOIN_OBJ(p) ((PyObject*) ((uintptr_t) (p) & ~(uintptr_t)1)) /* Py_CLEAR for a PyObject* that uses a join flag. Pass the pointer by * reference since this function sets it to NULL. @@ -129,30 +129,6 @@ elementtree_free(void *m) /* helpers */ LOCAL(PyObject*) -deepcopy(PyObject* object, PyObject* memo) -{ - /* do a deep copy of the given object */ - PyObject* args; - PyObject* result; - elementtreestate *st = ET_STATE_GLOBAL; - - if (!st->deepcopy_obj) { - PyErr_SetString( - PyExc_RuntimeError, - "deepcopy helper not found" - ); - return NULL; - } - - args = PyTuple_Pack(2, object, memo); - if (!args) - return NULL; - result = PyObject_CallObject(st->deepcopy_obj, args); - Py_DECREF(args); - return result; -} - -LOCAL(PyObject*) list_join(PyObject* list) { /* join list elements (destroying the list in the process) */ @@ -420,10 +396,8 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds) Py_XDECREF(attrib); /* Replace the objects already pointed to by tag, text and tail. */ - tmp = self_elem->tag; Py_INCREF(tag); - self_elem->tag = tag; - Py_DECREF(tmp); + Py_XSETREF(self_elem->tag, tag); tmp = self_elem->text; Py_INCREF(Py_None); @@ -748,6 +722,9 @@ _elementtree_Element___copy___impl(ElementObject *self) return (PyObject*) element; } +/* Helper for a deep copy. */ +LOCAL(PyObject *) deepcopy(PyObject *, PyObject *); + /*[clinic input] _elementtree.Element.__deepcopy__ @@ -820,7 +797,7 @@ _elementtree_Element___deepcopy__(ElementObject *self, PyObject *memo) } /* add object to memo dictionary (so deepcopy won't visit it again) */ - id = PyLong_FromSsize_t((Py_uintptr_t) self); + id = PyLong_FromSsize_t((uintptr_t) self); if (!id) goto error; @@ -838,6 +815,53 @@ _elementtree_Element___deepcopy__(ElementObject *self, PyObject *memo) return NULL; } +LOCAL(PyObject *) +deepcopy(PyObject *object, PyObject *memo) +{ + /* do a deep copy of the given object */ + elementtreestate *st; + PyObject *stack[2]; + + /* Fast paths */ + if (object == Py_None || PyUnicode_CheckExact(object)) { + Py_INCREF(object); + return object; + } + + if (Py_REFCNT(object) == 1) { + if (PyDict_CheckExact(object)) { + PyObject *key, *value; + Py_ssize_t pos = 0; + int simple = 1; + while (PyDict_Next(object, &pos, &key, &value)) { + if (!PyUnicode_CheckExact(key) || !PyUnicode_CheckExact(value)) { + simple = 0; + break; + } + } + if (simple) + return PyDict_Copy(object); + /* Fall through to general case */ + } + else if (Element_CheckExact(object)) { + return _elementtree_Element___deepcopy__((ElementObject *)object, memo); + } + } + + /* General case */ + st = ET_STATE_GLOBAL; + if (!st->deepcopy_obj) { + PyErr_SetString(PyExc_RuntimeError, + "deepcopy helper not found"); + return NULL; + } + + stack[0] = object; + stack[1] = memo; + return _PyObject_FastCall(st->deepcopy_obj, stack, 2); +} + + /*[clinic input] _elementtree.Element.__sizeof__ -> Py_ssize_t @@ -1763,7 +1787,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) step = -step; } - assert((size_t)slicelen <= PY_SIZE_MAX / sizeof(PyObject *)); + assert((size_t)slicelen <= SIZE_MAX / sizeof(PyObject *)); /* recycle is a list that will contain all the children * scheduled for removal. @@ -1892,92 +1916,90 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) } static PyObject* -element_getattro(ElementObject* self, PyObject* nameobj) +element_tag_getter(ElementObject *self, void *closure) { - PyObject* res; - char *name = ""; + PyObject *res = self->tag; + Py_INCREF(res); + return res; +} - if (PyUnicode_Check(nameobj)) - name = _PyUnicode_AsString(nameobj); +static PyObject* +element_text_getter(ElementObject *self, void *closure) +{ + PyObject *res = element_get_text(self); + Py_XINCREF(res); + return res; +} - if (name == NULL) - return NULL; +static PyObject* +element_tail_getter(ElementObject *self, void *closure) +{ + PyObject *res = element_get_tail(self); + Py_XINCREF(res); + return res; +} - /* handle common attributes first */ - if (strcmp(name, "tag") == 0) { - res = self->tag; - Py_INCREF(res); - return res; - } else if (strcmp(name, "text") == 0) { - res = element_get_text(self); - Py_XINCREF(res); - return res; +static PyObject* +element_attrib_getter(ElementObject *self, void *closure) +{ + PyObject *res; + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return NULL; } + res = element_get_attrib(self); + Py_XINCREF(res); + return res; +} - /* methods */ - res = PyObject_GenericGetAttr((PyObject*) self, nameobj); - if (res) - return res; - - /* less common attributes */ - if (strcmp(name, "tail") == 0) { - PyErr_Clear(); - res = element_get_tail(self); - } else if (strcmp(name, "attrib") == 0) { - PyErr_Clear(); - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return NULL; - } - res = element_get_attrib(self); +/* macro for setter validation */ +#define _VALIDATE_ATTR_VALUE(V) \ + if ((V) == NULL) { \ + PyErr_SetString( \ + PyExc_AttributeError, \ + "can't delete element attribute"); \ + return -1; \ } - if (!res) - return NULL; - - Py_INCREF(res); - return res; +static int +element_tag_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); + Py_INCREF(value); + Py_SETREF(self->tag, value); + return 0; } static int -element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value) +element_text_setter(ElementObject *self, PyObject *value, void *closure) { - char *name = ""; + _VALIDATE_ATTR_VALUE(value); + Py_INCREF(value); + Py_DECREF(JOIN_OBJ(self->text)); + self->text = value; + return 0; +} - if (value == NULL) { - PyErr_SetString(PyExc_AttributeError, - "can't delete attribute"); - return -1; - } - if (PyUnicode_Check(nameobj)) - name = _PyUnicode_AsString(nameobj); - if (name == NULL) - return -1; +static int +element_tail_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); + Py_INCREF(value); + Py_DECREF(JOIN_OBJ(self->tail)); + self->tail = value; + return 0; +} - if (strcmp(name, "tag") == 0) { - Py_INCREF(value); - Py_SETREF(self->tag, value); - } else if (strcmp(name, "text") == 0) { - Py_DECREF(JOIN_OBJ(self->text)); - self->text = value; - Py_INCREF(self->text); - } else if (strcmp(name, "tail") == 0) { - Py_DECREF(JOIN_OBJ(self->tail)); - self->tail = value; - Py_INCREF(self->tail); - } else if (strcmp(name, "attrib") == 0) { - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return -1; - } - Py_INCREF(value); - Py_SETREF(self->extra->attrib, value); - } else { - PyErr_SetString(PyExc_AttributeError, - "Can't set arbitrary attributes on Element"); - return -1; +static int +element_attrib_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return -1; } - + Py_INCREF(value); + Py_SETREF(self->extra->attrib, value); return 0; } @@ -1997,22 +2019,22 @@ static PySequenceMethods element_as_sequence = { * pre-order traversal. To keep track of which sub-element should be returned * next, a stack of parents is maintained. This is a standard stack-based * iterative pre-order traversal of a tree. - * The stack is managed using a single-linked list starting at parent_stack. - * Each stack node contains the saved parent to which we should return after + * The stack is managed using a continuous array. + * Each stack item contains the saved parent to which we should return after * the current one is exhausted, and the next child to examine in that parent. */ typedef struct ParentLocator_t { ElementObject *parent; Py_ssize_t child_index; - struct ParentLocator_t *next; } ParentLocator; typedef struct { PyObject_HEAD ParentLocator *parent_stack; + Py_ssize_t parent_stack_used; + Py_ssize_t parent_stack_size; ElementObject *root_element; PyObject *sought_tag; - int root_done; int gettext; } ElementIterObject; @@ -2020,13 +2042,11 @@ typedef struct { static void elementiter_dealloc(ElementIterObject *it) { - ParentLocator *p = it->parent_stack; - while (p) { - ParentLocator *temp = p; - Py_XDECREF(p->parent); - p = p->next; - PyObject_Free(temp); - } + Py_ssize_t i = it->parent_stack_used; + it->parent_stack_used = 0; + while (i--) + Py_XDECREF(it->parent_stack[i].parent); + PyMem_Free(it->parent_stack); Py_XDECREF(it->sought_tag); Py_XDECREF(it->root_element); @@ -2038,11 +2058,9 @@ elementiter_dealloc(ElementIterObject *it) static int elementiter_traverse(ElementIterObject *it, visitproc visit, void *arg) { - ParentLocator *p = it->parent_stack; - while (p) { - Py_VISIT(p->parent); - p = p->next; - } + Py_ssize_t i = it->parent_stack_used; + while (i--) + Py_VISIT(it->parent_stack[i].parent); Py_VISIT(it->root_element); Py_VISIT(it->sought_tag); @@ -2051,17 +2069,25 @@ elementiter_traverse(ElementIterObject *it, visitproc visit, void *arg) /* Helper function for elementiter_next. Add a new parent to the parent stack. */ -static ParentLocator * -parent_stack_push_new(ParentLocator *stack, ElementObject *parent) +static int +parent_stack_push_new(ElementIterObject *it, ElementObject *parent) { - ParentLocator *new_node = PyObject_Malloc(sizeof(ParentLocator)); - if (new_node) { - new_node->parent = parent; - Py_INCREF(parent); - new_node->child_index = 0; - new_node->next = stack; + ParentLocator *item; + + if (it->parent_stack_used >= it->parent_stack_size) { + Py_ssize_t new_size = it->parent_stack_size * 2; /* never overflow */ + ParentLocator *parent_stack = it->parent_stack; + PyMem_Resize(parent_stack, ParentLocator, new_size); + if (parent_stack == NULL) + return -1; + it->parent_stack = parent_stack; + it->parent_stack_size = new_size; } - return new_node; + item = it->parent_stack + it->parent_stack_used++; + Py_INCREF(parent); + item->parent = parent; + item->child_index = 0; + return 0; } static PyObject * @@ -2078,151 +2104,91 @@ elementiter_next(ElementIterObject *it) * - itertext() also has to handle tail, after finishing with all the * children of a node. */ - ElementObject *cur_parent; - Py_ssize_t child_index; int rc; ElementObject *elem; + PyObject *text; while (1) { /* Handle the case reached in the beginning and end of iteration, where - * the parent stack is empty. The root_done flag gives us indication - * whether we've just started iterating (so root_done is 0), in which - * case the root is returned. If root_done is 1 and we're here, the + * the parent stack is empty. If root_element is NULL and we're here, the * iterator is exhausted. */ - if (!it->parent_stack->parent) { - if (it->root_done) { + if (!it->parent_stack_used) { + if (!it->root_element) { PyErr_SetNone(PyExc_StopIteration); return NULL; - } else { - elem = it->root_element; - it->parent_stack = parent_stack_push_new(it->parent_stack, - elem); - if (!it->parent_stack) { - PyErr_NoMemory(); - return NULL; - } + } - Py_INCREF(elem); - it->root_done = 1; - rc = (it->sought_tag == Py_None); - if (!rc) { - rc = PyObject_RichCompareBool(elem->tag, - it->sought_tag, Py_EQ); - if (rc < 0) { - Py_DECREF(elem); - return NULL; - } - } - if (rc) { - if (it->gettext) { - PyObject *text = element_get_text(elem); - if (!text) { - Py_DECREF(elem); - return NULL; - } - Py_INCREF(text); - Py_DECREF(elem); - rc = PyObject_IsTrue(text); - if (rc > 0) - return text; - Py_DECREF(text); - if (rc < 0) - return NULL; - } else { - return (PyObject *)elem; - } - } - else { - Py_DECREF(elem); + elem = it->root_element; /* steals a reference */ + it->root_element = NULL; + } + else { + /* See if there are children left to traverse in the current parent. If + * yes, visit the next child. If not, pop the stack and try again. + */ + ParentLocator *item = &it->parent_stack[it->parent_stack_used - 1]; + Py_ssize_t child_index = item->child_index; + ElementObjectExtra *extra; + elem = item->parent; + extra = elem->extra; + if (!extra || child_index >= extra->length) { + it->parent_stack_used--; + /* Note that extra condition on it->parent_stack_used here; + * this is because itertext() is supposed to only return *inner* + * text, not text following the element it began iteration with. + */ + if (it->gettext && it->parent_stack_used) { + text = element_get_tail(elem); + goto gettext; } + Py_DECREF(elem); + continue; } + + elem = (ElementObject *)extra->children[child_index]; + item->child_index++; + Py_INCREF(elem); } - /* See if there are children left to traverse in the current parent. If - * yes, visit the next child. If not, pop the stack and try again. - */ - cur_parent = it->parent_stack->parent; - child_index = it->parent_stack->child_index; - if (cur_parent->extra && child_index < cur_parent->extra->length) { - elem = (ElementObject *)cur_parent->extra->children[child_index]; - it->parent_stack->child_index++; - it->parent_stack = parent_stack_push_new(it->parent_stack, - elem); - if (!it->parent_stack) { - PyErr_NoMemory(); - return NULL; - } + if (parent_stack_push_new(it, elem) < 0) { + Py_DECREF(elem); + PyErr_NoMemory(); + return NULL; + } + if (it->gettext) { + text = element_get_text(elem); + goto gettext; + } - Py_INCREF(elem); - if (it->gettext) { - PyObject *text = element_get_text(elem); - if (!text) { - Py_DECREF(elem); - return NULL; - } - Py_INCREF(text); - Py_DECREF(elem); - rc = PyObject_IsTrue(text); - if (rc > 0) - return text; - Py_DECREF(text); - if (rc < 0) - return NULL; - } else { - rc = (it->sought_tag == Py_None); - if (!rc) { - rc = PyObject_RichCompareBool(elem->tag, - it->sought_tag, Py_EQ); - if (rc < 0) { - Py_DECREF(elem); - return NULL; - } - } - if (rc) { - return (PyObject *)elem; - } - Py_DECREF(elem); - } + if (it->sought_tag == Py_None) + return (PyObject *)elem; + + rc = PyObject_RichCompareBool(elem->tag, it->sought_tag, Py_EQ); + if (rc > 0) + return (PyObject *)elem; + + Py_DECREF(elem); + if (rc < 0) + return NULL; + continue; + +gettext: + if (!text) { + Py_DECREF(elem); + return NULL; + } + if (text == Py_None) { + Py_DECREF(elem); } else { - PyObject *tail; - ParentLocator *next; - if (it->gettext) { - Py_INCREF(cur_parent); - tail = element_get_tail(cur_parent); - if (!tail) { - Py_DECREF(cur_parent); - return NULL; - } - Py_INCREF(tail); - Py_DECREF(cur_parent); - } - else { - tail = Py_None; - Py_INCREF(tail); - } - next = it->parent_stack->next; - cur_parent = it->parent_stack->parent; - PyObject_Free(it->parent_stack); - it->parent_stack = next; - Py_XDECREF(cur_parent); - - /* Note that extra condition on it->parent_stack->parent here; - * this is because itertext() is supposed to only return *inner* - * text, not text following the element it began iteration with. - */ - if (it->parent_stack->parent) { - rc = PyObject_IsTrue(tail); - if (rc > 0) - return tail; - Py_DECREF(tail); - if (rc < 0) - return NULL; - } - else { - Py_DECREF(tail); - } + Py_INCREF(text); + Py_DECREF(elem); + rc = PyObject_IsTrue(text); + if (rc > 0) + return text; + Py_DECREF(text); + if (rc < 0) + return NULL; } } @@ -2274,6 +2240,7 @@ static PyTypeObject ElementIter_Type = { 0, /* tp_new */ }; +#define INIT_PARENT_STACK_SIZE 8 static PyObject * create_elementiter(ElementObject *self, PyObject *tag, int gettext) @@ -2286,22 +2253,20 @@ create_elementiter(ElementObject *self, PyObject *tag, int gettext) Py_INCREF(tag); it->sought_tag = tag; - it->root_done = 0; it->gettext = gettext; Py_INCREF(self); it->root_element = self; PyObject_GC_Track(it); - it->parent_stack = PyObject_Malloc(sizeof(ParentLocator)); + it->parent_stack = PyMem_New(ParentLocator, INIT_PARENT_STACK_SIZE); if (it->parent_stack == NULL) { Py_DECREF(it); PyErr_NoMemory(); return NULL; } - it->parent_stack->parent = NULL; - it->parent_stack->child_index = 0; - it->parent_stack->next = NULL; + it->parent_stack_used = 0; + it->parent_stack_size = INIT_PARENT_STACK_SIZE; return (PyObject *)it; } @@ -2326,7 +2291,7 @@ typedef struct { PyObject *element_factory; /* element tracing */ - PyObject *events; /* list of events, or NULL if not collecting */ + PyObject *events_append; /* the append method of the list of events, or NULL */ PyObject *start_event_obj; /* event objects (NULL to ignore) */ PyObject *end_event_obj; PyObject *start_ns_event_obj; @@ -2361,7 +2326,7 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } t->index = 0; - t->events = NULL; + t->events_append = NULL; t->start_event_obj = t->end_event_obj = NULL; t->start_ns_event_obj = t->end_ns_event_obj = NULL; } @@ -2380,13 +2345,9 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, PyObject *element_factory) /*[clinic end generated code: output=91cfa7558970ee96 input=1b424eeefc35249c]*/ { - PyObject *tmp; - if (element_factory) { Py_INCREF(element_factory); - tmp = self->element_factory; - self->element_factory = element_factory; - Py_XDECREF(tmp); + Py_XSETREF(self->element_factory, element_factory); } return 0; @@ -2411,7 +2372,7 @@ treebuilder_gc_clear(TreeBuilderObject *self) Py_CLEAR(self->start_ns_event_obj); Py_CLEAR(self->end_event_obj); Py_CLEAR(self->start_event_obj); - Py_CLEAR(self->events); + Py_CLEAR(self->events_append); Py_CLEAR(self->stack); Py_CLEAR(self->data); Py_CLEAR(self->last); @@ -2492,13 +2453,14 @@ treebuilder_append_event(TreeBuilderObject *self, PyObject *action, PyObject *node) { if (action != NULL) { - PyObject *res = PyTuple_Pack(2, action, node); - if (res == NULL) + PyObject *res; + PyObject *event = PyTuple_Pack(2, action, node); + if (event == NULL) return -1; - if (PyList_Append(self->events, res) < 0) { - Py_DECREF(res); + res = PyObject_CallFunctionObjArgs(self->events_append, event, NULL); + Py_DECREF(event); + if (res == NULL) return -1; - } Py_DECREF(res); } return 0; @@ -2527,10 +2489,17 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, self->data = NULL; } - if (self->element_factory && self->element_factory != Py_None) { - node = PyObject_CallFunction(self->element_factory, "OO", tag, attrib); - } else { + if (!self->element_factory || self->element_factory == Py_None) { node = create_new_element(tag, attrib); + } else if (attrib == Py_None) { + attrib = PyDict_New(); + if (!attrib) + return NULL; + node = PyObject_CallFunction(self->element_factory, "OO", tag, attrib); + Py_DECREF(attrib); + } + else { + node = PyObject_CallFunction(self->element_factory, "OO", tag, attrib); } if (!node) { return NULL; @@ -2989,12 +2958,8 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, attrib_in += 2; } } else { - /* Pass an empty dictionary on */ - attrib = PyDict_New(); - if (!attrib) { - Py_DECREF(tag); - return; - } + Py_INCREF(Py_None); + attrib = Py_None; } if (TreeBuilder_CheckExact(self->target)) { @@ -3003,6 +2968,14 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, tag, attrib); } else if (self->handle_start) { + if (attrib == Py_None) { + Py_DECREF(attrib); + attrib = PyDict_New(); + if (!attrib) { + Py_DECREF(tag); + return; + } + } res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib); } else res = NULL; @@ -3076,7 +3049,7 @@ expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix, if (PyErr_Occurred()) return; - if (!target->events || !target->start_ns_event_obj) + if (!target->events_append || !target->start_ns_event_obj) return; if (!uri) @@ -3099,7 +3072,7 @@ expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) if (PyErr_Occurred()) return; - if (!target->events) + if (!target->events_append) return; treebuilder_append_event(target, target->end_ns_event_obj, Py_None); @@ -3426,7 +3399,7 @@ _elementtree_XMLParser_close_impl(XMLParserObject *self) } else if (self->handle_close) { Py_DECREF(res); - return PyObject_CallFunction(self->handle_close, ""); + return _PyObject_CallNoArg(self->handle_close); } else { return res; @@ -3588,7 +3561,7 @@ _elementtree_XMLParser_doctype_impl(XMLParserObject *self, PyObject *name, /*[clinic input] _elementtree.XMLParser._setevents - events_queue: object(subclass_of='&PyList_Type') + events_queue: object events_to_report: object = None / @@ -3598,12 +3571,12 @@ static PyObject * _elementtree_XMLParser__setevents_impl(XMLParserObject *self, PyObject *events_queue, PyObject *events_to_report) -/*[clinic end generated code: output=1440092922b13ed1 input=59db9742910c6174]*/ +/*[clinic end generated code: output=1440092922b13ed1 input=abf90830a1c3b0fc]*/ { /* activate element event reporting */ Py_ssize_t i; TreeBuilderObject *target; - PyObject *events_seq; + PyObject *events_append, *events_seq; if (!TreeBuilder_CheckExact(self->target)) { PyErr_SetString( @@ -3616,8 +3589,10 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, target = (TreeBuilderObject*) self->target; - Py_INCREF(events_queue); - Py_XSETREF(target->events, events_queue); + events_append = PyObject_GetAttrString(events_queue, "append"); + if (events_append == NULL) + return NULL; + Py_XSETREF(target->events_append, events_append); /* clear out existing events */ Py_CLEAR(target->start_event_obj); @@ -3750,6 +3725,26 @@ static PyMappingMethods element_as_mapping = { (objobjargproc) element_ass_subscr, }; +static PyGetSetDef element_getsetlist[] = { + {"tag", + (getter)element_tag_getter, + (setter)element_tag_setter, + "A string identifying what kind of data this element represents"}, + {"text", + (getter)element_text_getter, + (setter)element_text_setter, + "A string of text directly after the start tag, or None"}, + {"tail", + (getter)element_tail_getter, + (setter)element_tail_setter, + "A string of text directly after the end tag, or None"}, + {"attrib", + (getter)element_attrib_getter, + (setter)element_attrib_setter, + "A dictionary containing the element's attributes"}, + {NULL}, +}; + static PyTypeObject Element_Type = { PyVarObject_HEAD_INIT(NULL, 0) "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, @@ -3766,8 +3761,8 @@ static PyTypeObject Element_Type = { 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - (getattrofunc)element_getattro, /* tp_getattro */ - (setattrofunc)element_setattro, /* tp_setattro */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ @@ -3780,7 +3775,7 @@ static PyTypeObject Element_Type = { 0, /* tp_iternext */ element_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ + element_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index d785c49..848a03c 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -128,44 +128,60 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kw) { PyObject *ret; PyObject *argappl, *kwappl; + PyObject **stack; + Py_ssize_t nargs; assert (PyCallable_Check(pto->fn)); assert (PyTuple_Check(pto->args)); assert (PyDict_Check(pto->kw)); if (PyTuple_GET_SIZE(pto->args) == 0) { - argappl = args; - Py_INCREF(args); - } else if (PyTuple_GET_SIZE(args) == 0) { - argappl = pto->args; - Py_INCREF(pto->args); - } else { + stack = &PyTuple_GET_ITEM(args, 0); + nargs = PyTuple_GET_SIZE(args); + argappl = NULL; + } + else if (PyTuple_GET_SIZE(args) == 0) { + stack = &PyTuple_GET_ITEM(pto->args, 0); + nargs = PyTuple_GET_SIZE(pto->args); + argappl = NULL; + } + else { + stack = NULL; argappl = PySequence_Concat(pto->args, args); - if (argappl == NULL) + if (argappl == NULL) { return NULL; + } + assert(PyTuple_Check(argappl)); } if (PyDict_Size(pto->kw) == 0) { kwappl = kw; Py_XINCREF(kwappl); - } else { + } + else { kwappl = PyDict_Copy(pto->kw); if (kwappl == NULL) { - Py_DECREF(argappl); + Py_XDECREF(argappl); return NULL; } + if (kw != NULL) { if (PyDict_Merge(kwappl, kw, 1) != 0) { - Py_DECREF(argappl); + Py_XDECREF(argappl); Py_DECREF(kwappl); return NULL; } } } - ret = PyObject_Call(pto->fn, argappl, kwappl); - Py_DECREF(argappl); + if (stack) { + ret = _PyObject_FastCallDict(pto->fn, stack, nargs, kwappl); + } + else { + ret = PyObject_Call(pto->fn, argappl, kwappl); + Py_DECREF(argappl); + } Py_XDECREF(kwappl); return ret; } @@ -461,12 +477,12 @@ static PyObject * keyobject_richcompare(PyObject *ko, PyObject *other, int op) { PyObject *res; - PyObject *args; PyObject *x; PyObject *y; PyObject *compare; PyObject *answer; static PyObject *zero; + PyObject* stack[2]; if (zero == NULL) { zero = PyLong_FromLong(0); @@ -490,17 +506,13 @@ keyobject_richcompare(PyObject *ko, PyObject *other, int op) /* Call the user's comparison function and translate the 3-way * result into true or false (or error). */ - args = PyTuple_New(2); - if (args == NULL) - return NULL; - Py_INCREF(x); - Py_INCREF(y); - PyTuple_SET_ITEM(args, 0, x); - PyTuple_SET_ITEM(args, 1, y); - res = PyObject_Call(compare, args, NULL); - Py_DECREF(args); - if (res == NULL) + stack[0] = x; + stack[1] = y; + res = _PyObject_FastCall(compare, stack, 2); + if (res == NULL) { return NULL; + } + answer = PyObject_RichCompare(res, zero, op); Py_DECREF(res); return answer; diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index b840bf5..daae71d 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -614,7 +614,7 @@ dbmopen_impl(PyObject *module, const char *name, const char *flags, int mode) return newdbmobject(name, iflags, mode); } -static char dbmmodule_open_flags[] = "rwcn" +static const char dbmmodule_open_flags[] = "rwcn" #ifdef GDBM_FAST "f" #endif diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index ff57614..daa4f3d 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -25,6 +25,12 @@ #include <openssl/objects.h> #include "openssl/err.h" +#include "clinic/_hashopenssl.c.h" +/*[clinic input] +module _hashlib +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c2b4ff081bac4be1]*/ + #define MUNCH_SIZE INT_MAX #ifndef HASH_OBJ_CONSTRUCTOR @@ -713,6 +719,128 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict) #endif +#if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER) +#define PY_SCRYPT 1 + +/*[clinic input] +_hashlib.scrypt + + password: Py_buffer + * + salt: Py_buffer = None + n as n_obj: object(subclass_of='&PyLong_Type') = None + r as r_obj: object(subclass_of='&PyLong_Type') = None + p as p_obj: object(subclass_of='&PyLong_Type') = None + maxmem: long = 0 + dklen: long = 64 + + +scrypt password-based key derivation function. +[clinic start generated code]*/ + +static PyObject * +_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, + PyObject *n_obj, PyObject *r_obj, PyObject *p_obj, + long maxmem, long dklen) +/*[clinic end generated code: output=14849e2aa2b7b46c input=48a7d63bf3f75c42]*/ +{ + PyObject *key_obj = NULL; + char *key; + int retval; + unsigned long n, r, p; + + if (password->len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "password is too long."); + return NULL; + } + + if (salt->buf == NULL) { + PyErr_SetString(PyExc_TypeError, + "salt is required"); + return NULL; + } + if (salt->len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "salt is too long."); + return NULL; + } + + n = PyLong_AsUnsignedLong(n_obj); + if (n == (unsigned long) -1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "n is required and must be an unsigned int"); + return NULL; + } + if (n < 2 || n & (n - 1)) { + PyErr_SetString(PyExc_ValueError, + "n must be a power of 2."); + return NULL; + } + + r = PyLong_AsUnsignedLong(r_obj); + if (r == (unsigned long) -1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "r is required and must be an unsigned int"); + return NULL; + } + + p = PyLong_AsUnsignedLong(p_obj); + if (p == (unsigned long) -1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "p is required and must be an unsigned int"); + return NULL; + } + + if (maxmem < 0 || maxmem > INT_MAX) { + /* OpenSSL 1.1.0 restricts maxmem to 32MB. It may change in the + future. The maxmem constant is private to OpenSSL. */ + PyErr_Format(PyExc_ValueError, + "maxmem must be positive and smaller than %d", + INT_MAX); + return NULL; + } + + if (dklen < 1 || dklen > INT_MAX) { + PyErr_Format(PyExc_ValueError, + "dklen must be greater than 0 and smaller than %d", + INT_MAX); + return NULL; + } + + /* let OpenSSL validate the rest */ + retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p, maxmem, NULL, 0); + if (!retval) { + /* sorry, can't do much better */ + PyErr_SetString(PyExc_ValueError, + "Invalid paramemter combination for n, r, p, maxmem."); + return NULL; + } + + key_obj = PyBytes_FromStringAndSize(NULL, dklen); + if (key_obj == NULL) { + return NULL; + } + key = PyBytes_AS_STRING(key_obj); + + Py_BEGIN_ALLOW_THREADS + retval = EVP_PBE_scrypt( + (const char*)password->buf, (size_t)password->len, + (const unsigned char *)salt->buf, (size_t)salt->len, + n, r, p, maxmem, + (unsigned char *)key, (size_t)dklen + ); + Py_END_ALLOW_THREADS + + if (!retval) { + Py_CLEAR(key_obj); + _setException(PyExc_ValueError); + return NULL; + } + return key_obj; +} +#endif + /* State for our callback function so that it can accumulate a result. */ typedef struct _internal_name_mapper_state { PyObject *set; @@ -836,6 +964,7 @@ static struct PyMethodDef EVP_functions[] = { {"pbkdf2_hmac", (PyCFunction)pbkdf2_hmac, METH_VARARGS|METH_KEYWORDS, pbkdf2_hmac__doc__}, #endif + _HASHLIB_SCRYPT_METHODDEF CONSTRUCTOR_METH_DEF(md5), CONSTRUCTOR_METH_DEF(sha1), CONSTRUCTOR_METH_DEF(sha224), diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c index 136abf5..b499e1f 100644 --- a/Modules/_heapqmodule.c +++ b/Modules/_heapqmodule.c @@ -66,7 +66,7 @@ siftup(PyListObject *heap, Py_ssize_t pos) /* Bubble up the smaller child until hitting a leaf. */ arr = _PyList_ITEMS(heap); - limit = endpos / 2; /* smallest pos that has no child */ + limit = endpos >> 1; /* smallest pos that has no child */ while (pos < limit) { /* Set childpos to index of smaller child. */ childpos = 2*pos + 1; /* leftmost child position */ @@ -78,6 +78,7 @@ siftup(PyListObject *heap, Py_ssize_t pos) if (cmp < 0) return -1; childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ + arr = _PyList_ITEMS(heap); /* arr may have changed */ if (endpos != PyList_GET_SIZE(heap)) { PyErr_SetString(PyExc_RuntimeError, "list changed size during iteration"); @@ -85,7 +86,6 @@ siftup(PyListObject *heap, Py_ssize_t pos) } } /* Move the smaller child up. */ - arr = _PyList_ITEMS(heap); tmp1 = arr[childpos]; tmp2 = arr[pos]; arr[childpos] = tmp2; @@ -347,7 +347,7 @@ heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) n is odd = 2*j+1, this is (2*j+1-1)/2 = j so j-1 is the largest, and that's again n//2-1. */ - for (i = n/2 - 1 ; i >= 0 ; i--) + for (i = (n >> 1) - 1 ; i >= 0 ; i--) if (siftup_func((PyListObject *)heap, i)) return NULL; Py_RETURN_NONE; @@ -420,7 +420,7 @@ siftup_max(PyListObject *heap, Py_ssize_t pos) /* Bubble up the smaller child until hitting a leaf. */ arr = _PyList_ITEMS(heap); - limit = endpos / 2; /* smallest pos that has no child */ + limit = endpos >> 1; /* smallest pos that has no child */ while (pos < limit) { /* Set childpos to index of smaller child. */ childpos = 2*pos + 1; /* leftmost child position */ @@ -432,6 +432,7 @@ siftup_max(PyListObject *heap, Py_ssize_t pos) if (cmp < 0) return -1; childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ + arr = _PyList_ITEMS(heap); /* arr may have changed */ if (endpos != PyList_GET_SIZE(heap)) { PyErr_SetString(PyExc_RuntimeError, "list changed size during iteration"); @@ -439,7 +440,6 @@ siftup_max(PyListObject *heap, Py_ssize_t pos) } } /* Move the smaller child up. */ - arr = _PyList_ITEMS(heap); tmp1 = arr[childpos]; tmp2 = arr[pos]; arr[childpos] = tmp2; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 65c955a..60f8b54 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -20,6 +20,9 @@ #include <sys/stat.h> #endif /* HAVE_SYS_STAT_H */ +#ifdef MS_WINDOWS +#include <consoleapi.h> +#endif /* Various interned strings */ @@ -52,7 +55,6 @@ PyObject *_PyIO_empty_str; PyObject *_PyIO_empty_bytes; PyObject *_PyIO_zero; - PyDoc_STRVAR(module_doc, "The io module provides the Python interfaces to stream handling. The\n" "builtin open function is defined in this module.\n" @@ -238,20 +240,33 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, int text = 0, binary = 0, universal = 0; char rawmode[6], *m; - int line_buffering, isatty; + int line_buffering, is_number; + long isatty; - PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL; + PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL; _Py_IDENTIFIER(_blksize); _Py_IDENTIFIER(isatty); _Py_IDENTIFIER(mode); _Py_IDENTIFIER(close); - if (!PyUnicode_Check(file) && - !PyBytes_Check(file) && - !PyNumber_Check(file)) { + is_number = PyNumber_Check(file); + + if (is_number) { + path_or_fd = file; + Py_INCREF(path_or_fd); + } else { + path_or_fd = PyOS_FSPath(file); + if (path_or_fd == NULL) { + return NULL; + } + } + + if (!is_number && + !PyUnicode_Check(path_or_fd) && + !PyBytes_Check(path_or_fd)) { PyErr_Format(PyExc_TypeError, "invalid file: %R", file); - return NULL; + goto error; } /* Decode mode */ @@ -292,7 +307,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, if (strchr(mode+i+1, c)) { invalid_mode: PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode); - return NULL; + goto error; } } @@ -307,54 +322,67 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, /* Parameters validation */ if (universal) { - if (writing || appending) { + if (creating || writing || appending || updating) { PyErr_SetString(PyExc_ValueError, - "can't use U and writing mode at once"); - return NULL; + "mode U cannot be combined with x', 'w', 'a', or '+'"); + goto error; } if (PyErr_WarnEx(PyExc_DeprecationWarning, "'U' mode is deprecated", 1) < 0) - return NULL; + goto error; reading = 1; } if (text && binary) { PyErr_SetString(PyExc_ValueError, "can't have text and binary mode at once"); - return NULL; + goto error; } if (creating + reading + writing + appending > 1) { PyErr_SetString(PyExc_ValueError, "must have exactly one of create/read/write/append mode"); - return NULL; + goto error; } if (binary && encoding != NULL) { PyErr_SetString(PyExc_ValueError, "binary mode doesn't take an encoding argument"); - return NULL; + goto error; } if (binary && errors != NULL) { PyErr_SetString(PyExc_ValueError, "binary mode doesn't take an errors argument"); - return NULL; + goto error; } if (binary && newline != NULL) { PyErr_SetString(PyExc_ValueError, "binary mode doesn't take a newline argument"); - return NULL; + goto error; } /* Create the Raw file stream */ - raw = PyObject_CallFunction((PyObject *)&PyFileIO_Type, - "OsiO", file, rawmode, closefd, opener); + { + PyObject *RawIO_class = (PyObject *)&PyFileIO_Type; +#ifdef MS_WINDOWS + if (!Py_LegacyWindowsStdioFlag && _PyIO_get_console_type(path_or_fd) != '\0') { + RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type; + encoding = "utf-8"; + } +#endif + raw = PyObject_CallFunction(RawIO_class, + "OsiO", path_or_fd, rawmode, closefd, opener); + } + if (raw == NULL) - return NULL; + goto error; result = raw; + Py_DECREF(path_or_fd); + path_or_fd = NULL; + modeobj = PyUnicode_FromString(mode); if (modeobj == NULL) goto error; @@ -437,10 +465,10 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, /* wraps into a TextIOWrapper */ wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type, - "Osssi", - buffer, - encoding, errors, newline, - line_buffering); + "Osssi", + buffer, + encoding, errors, newline, + line_buffering); if (wrapper == NULL) goto error; result = wrapper; @@ -460,6 +488,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, Py_XDECREF(close_result); Py_DECREF(result); } + Py_XDECREF(path_or_fd); Py_XDECREF(modeobj); return NULL; } @@ -691,6 +720,12 @@ PyInit__io(void) PyStringIO_Type.tp_base = &PyTextIOBase_Type; ADD_TYPE(&PyStringIO_Type, "StringIO"); +#ifdef MS_WINDOWS + /* WindowsConsoleIO */ + PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type; + ADD_TYPE(&PyWindowsConsoleIO_Type, "_WindowsConsoleIO"); +#endif + /* BufferedReader */ PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type; ADD_TYPE(&PyBufferedReader_Type, "BufferedReader"); diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index 0c6eae2..5d3da29 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -19,6 +19,12 @@ extern PyTypeObject PyBufferedRandom_Type; extern PyTypeObject PyTextIOWrapper_Type; extern PyTypeObject PyIncrementalNewlineDecoder_Type; +#ifndef Py_LIMITED_API +#ifdef MS_WINDOWS +extern PyTypeObject PyWindowsConsoleIO_Type; +#define PyWindowsConsoleIO_Check(op) (PyObject_TypeCheck((op), &PyWindowsConsoleIO_Type)) +#endif /* MS_WINDOWS */ +#endif /* Py_LIMITED_API */ extern int _PyIO_ConvertSsize_t(PyObject *, void *); @@ -60,7 +66,7 @@ extern PyObject *_PyIncrementalNewlineDecoder_decode( * Otherwise, the line ending is specified by readnl, a str object */ extern Py_ssize_t _PyIO_find_line_ending( int translated, int universal, PyObject *readnl, - int kind, char *start, char *end, Py_ssize_t *consumed); + int kind, const char *start, const char *end, Py_ssize_t *consumed); /* Return 1 if an EnvironmentError with errno == EINTR is set (and then clears the error indicator), 0 otherwise. @@ -85,12 +91,12 @@ extern int _PyIO_trap_eintr(void); #ifdef MS_WINDOWS /* Windows uses long long for offsets */ -typedef PY_LONG_LONG Py_off_t; +typedef long long Py_off_t; # define PyLong_AsOff_t PyLong_AsLongLong # define PyLong_FromOff_t PyLong_FromLongLong -# define PY_OFF_T_MAX PY_LLONG_MAX -# define PY_OFF_T_MIN PY_LLONG_MIN -# define PY_OFF_T_COMPAT PY_LONG_LONG /* type compatible with off_t */ +# define PY_OFF_T_MAX LLONG_MAX +# define PY_OFF_T_MIN LLONG_MIN +# define PY_OFF_T_COMPAT long long /* type compatible with off_t */ # define PY_PRIdOFF "lld" /* format to use for that type */ #else @@ -104,12 +110,12 @@ typedef off_t Py_off_t; # define PY_OFF_T_MIN PY_SSIZE_T_MIN # define PY_OFF_T_COMPAT Py_ssize_t # define PY_PRIdOFF "zd" -#elif (HAVE_LONG_LONG && SIZEOF_OFF_T == SIZEOF_LONG_LONG) +#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG) # define PyLong_AsOff_t PyLong_AsLongLong # define PyLong_FromOff_t PyLong_FromLongLong -# define PY_OFF_T_MAX PY_LLONG_MAX -# define PY_OFF_T_MIN PY_LLONG_MIN -# define PY_OFF_T_COMPAT PY_LONG_LONG +# define PY_OFF_T_MAX LLONG_MAX +# define PY_OFF_T_MIN LLONG_MIN +# define PY_OFF_T_COMPAT long long # define PY_PRIdOFF "lld" #elif (SIZEOF_OFF_T == SIZEOF_LONG) # define PyLong_AsOff_t PyLong_AsLong @@ -145,6 +151,10 @@ typedef struct { extern _PyIO_State *_PyIO_get_module_state(void); extern PyObject *_PyIO_get_locale_module(_PyIO_State *); +#ifdef MS_WINDOWS +extern char _PyIO_get_console_type(PyObject *); +#endif + extern PyObject *_PyIO_str_close; extern PyObject *_PyIO_str_closed; extern PyObject *_PyIO_str_decode; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 6d67751..cbe7425 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -659,7 +659,7 @@ _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len); /* Sets the current error to BlockingIOError */ static void -_set_BlockingIOError(char *msg, Py_ssize_t written) +_set_BlockingIOError(const char *msg, Py_ssize_t written) { PyObject *err; PyErr_Clear(); diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 9e5d78b..a1ba121 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -87,7 +87,7 @@ scan_eol(bytesio *self, Py_ssize_t len) static int unshare_buffer(bytesio *self, size_t size) { - PyObject *new_buf, *old_buf; + PyObject *new_buf; assert(SHARED_BUF(self)); assert(self->exports == 0); assert(size >= (size_t)self->string_size); @@ -96,9 +96,7 @@ unshare_buffer(bytesio *self, size_t size) return -1; memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf), self->string_size); - old_buf = self->buf; - self->buf = new_buf; - Py_DECREF(old_buf); + Py_SETREF(self->buf, new_buf); return 0; } diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h index 6c88e32..50891c5 100644 --- a/Modules/_io/clinic/_iomodule.c.h +++ b/Modules/_io/clinic/_iomodule.c.h @@ -138,7 +138,8 @@ static PyObject * _io_open(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; + static const char * const _keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; + static _PyArg_Parser _parser = {"O|sizzziO:open", _keywords, 0}; PyObject *file; const char *mode = "r"; int buffering = -1; @@ -148,12 +149,13 @@ _io_open(PyObject *module, PyObject *args, PyObject *kwargs) int closefd = 1; PyObject *opener = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|sizzziO:open", _keywords, - &file, &mode, &buffering, &encoding, &errors, &newline, &closefd, &opener)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &file, &mode, &buffering, &encoding, &errors, &newline, &closefd, &opener)) { goto exit; + } return_value = _io_open_impl(module, file, mode, buffering, encoding, errors, newline, closefd, opener); exit: return return_value; } -/*[clinic end generated code: output=bc2c003cb7daeafe input=a9049054013a1b77]*/ +/*[clinic end generated code: output=14769629391a3130 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index 437e275..58144a4 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -19,14 +19,16 @@ _io__BufferedIOBase_readinto(PyObject *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer buffer = {NULL, NULL}; - if (!PyArg_Parse(arg, "w*:readinto", &buffer)) + if (!PyArg_Parse(arg, "w*:readinto", &buffer)) { goto exit; + } return_value = _io__BufferedIOBase_readinto_impl(self, &buffer); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -48,14 +50,16 @@ _io__BufferedIOBase_readinto1(PyObject *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer buffer = {NULL, NULL}; - if (!PyArg_Parse(arg, "w*:readinto1", &buffer)) + if (!PyArg_Parse(arg, "w*:readinto1", &buffer)) { goto exit; + } return_value = _io__BufferedIOBase_readinto1_impl(self, &buffer); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -99,8 +103,9 @@ _io__Buffered_peek(buffered *self, PyObject *args) Py_ssize_t size = 0; if (!PyArg_ParseTuple(args, "|n:peek", - &size)) + &size)) { goto exit; + } return_value = _io__Buffered_peek_impl(self, size); exit: @@ -125,8 +130,9 @@ _io__Buffered_read(buffered *self, PyObject *args) Py_ssize_t n = -1; if (!PyArg_ParseTuple(args, "|O&:read", - _PyIO_ConvertSsize_t, &n)) + _PyIO_ConvertSsize_t, &n)) { goto exit; + } return_value = _io__Buffered_read_impl(self, n); exit: @@ -150,8 +156,9 @@ _io__Buffered_read1(buffered *self, PyObject *arg) PyObject *return_value = NULL; Py_ssize_t n; - if (!PyArg_Parse(arg, "n:read1", &n)) + if (!PyArg_Parse(arg, "n:read1", &n)) { goto exit; + } return_value = _io__Buffered_read1_impl(self, n); exit: @@ -175,14 +182,16 @@ _io__Buffered_readinto(buffered *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer buffer = {NULL, NULL}; - if (!PyArg_Parse(arg, "w*:readinto", &buffer)) + if (!PyArg_Parse(arg, "w*:readinto", &buffer)) { goto exit; + } return_value = _io__Buffered_readinto_impl(self, &buffer); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -204,14 +213,16 @@ _io__Buffered_readinto1(buffered *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer buffer = {NULL, NULL}; - if (!PyArg_Parse(arg, "w*:readinto1", &buffer)) + if (!PyArg_Parse(arg, "w*:readinto1", &buffer)) { goto exit; + } return_value = _io__Buffered_readinto1_impl(self, &buffer); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -234,8 +245,9 @@ _io__Buffered_readline(buffered *self, PyObject *args) Py_ssize_t size = -1; if (!PyArg_ParseTuple(args, "|O&:readline", - _PyIO_ConvertSsize_t, &size)) + _PyIO_ConvertSsize_t, &size)) { goto exit; + } return_value = _io__Buffered_readline_impl(self, size); exit: @@ -261,8 +273,9 @@ _io__Buffered_seek(buffered *self, PyObject *args) int whence = 0; if (!PyArg_ParseTuple(args, "O|i:seek", - &targetobj, &whence)) + &targetobj, &whence)) { goto exit; + } return_value = _io__Buffered_seek_impl(self, targetobj, whence); exit: @@ -288,8 +301,9 @@ _io__Buffered_truncate(buffered *self, PyObject *args) if (!PyArg_UnpackTuple(args, "truncate", 0, 1, - &pos)) + &pos)) { goto exit; + } return_value = _io__Buffered_truncate_impl(self, pos); exit: @@ -310,13 +324,15 @@ static int _io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"raw", "buffer_size", NULL}; + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; + static _PyArg_Parser _parser = {"O|n:BufferedReader", _keywords, 0}; PyObject *raw; Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|n:BufferedReader", _keywords, - &raw, &buffer_size)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &raw, &buffer_size)) { goto exit; + } return_value = _io_BufferedReader___init___impl((buffered *)self, raw, buffer_size); exit: @@ -341,13 +357,15 @@ static int _io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"raw", "buffer_size", NULL}; + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; + static _PyArg_Parser _parser = {"O|n:BufferedWriter", _keywords, 0}; PyObject *raw; Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|n:BufferedWriter", _keywords, - &raw, &buffer_size)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &raw, &buffer_size)) { goto exit; + } return_value = _io_BufferedWriter___init___impl((buffered *)self, raw, buffer_size); exit: @@ -371,14 +389,16 @@ _io_BufferedWriter_write(buffered *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer buffer = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:write", &buffer)) + if (!PyArg_Parse(arg, "y*:write", &buffer)) { goto exit; + } return_value = _io_BufferedWriter_write_impl(self, &buffer); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -410,11 +430,13 @@ _io_BufferedRWPair___init__(PyObject *self, PyObject *args, PyObject *kwargs) Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; if ((Py_TYPE(self) == &PyBufferedRWPair_Type) && - !_PyArg_NoKeywords("BufferedRWPair", kwargs)) + !_PyArg_NoKeywords("BufferedRWPair", kwargs)) { goto exit; + } if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", - &reader, &writer, &buffer_size)) + &reader, &writer, &buffer_size)) { goto exit; + } return_value = _io_BufferedRWPair___init___impl((rwpair *)self, reader, writer, buffer_size); exit: @@ -439,16 +461,18 @@ static int _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"raw", "buffer_size", NULL}; + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; + static _PyArg_Parser _parser = {"O|n:BufferedRandom", _keywords, 0}; PyObject *raw; Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|n:BufferedRandom", _keywords, - &raw, &buffer_size)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &raw, &buffer_size)) { goto exit; + } return_value = _io_BufferedRandom___init___impl((buffered *)self, raw, buffer_size); exit: return return_value; } -/*[clinic end generated code: output=2bbb5e239b4ffe6f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a956f394ecde4cf9 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 5f2abb0..c64ce5c 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -171,8 +171,9 @@ _io_BytesIO_read(bytesio *self, PyObject *args) if (!PyArg_UnpackTuple(args, "read", 0, 1, - &arg)) + &arg)) { goto exit; + } return_value = _io_BytesIO_read_impl(self, arg); exit: @@ -215,8 +216,9 @@ _io_BytesIO_readline(bytesio *self, PyObject *args) if (!PyArg_UnpackTuple(args, "readline", 0, 1, - &arg)) + &arg)) { goto exit; + } return_value = _io_BytesIO_readline_impl(self, arg); exit: @@ -247,8 +249,9 @@ _io_BytesIO_readlines(bytesio *self, PyObject *args) if (!PyArg_UnpackTuple(args, "readlines", 0, 1, - &arg)) + &arg)) { goto exit; + } return_value = _io_BytesIO_readlines_impl(self, arg); exit: @@ -276,14 +279,16 @@ _io_BytesIO_readinto(bytesio *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer buffer = {NULL, NULL}; - if (!PyArg_Parse(arg, "w*:readinto", &buffer)) + if (!PyArg_Parse(arg, "w*:readinto", &buffer)) { goto exit; + } return_value = _io_BytesIO_readinto_impl(self, &buffer); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -311,8 +316,9 @@ _io_BytesIO_truncate(bytesio *self, PyObject *args) if (!PyArg_UnpackTuple(args, "truncate", 0, 1, - &arg)) + &arg)) { goto exit; + } return_value = _io_BytesIO_truncate_impl(self, arg); exit: @@ -345,8 +351,9 @@ _io_BytesIO_seek(bytesio *self, PyObject *args) int whence = 0; if (!PyArg_ParseTuple(args, "n|i:seek", - &pos, &whence)) + &pos, &whence)) { goto exit; + } return_value = _io_BytesIO_seek_impl(self, pos, whence); exit: @@ -408,15 +415,17 @@ static int _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"initial_bytes", NULL}; + static const char * const _keywords[] = {"initial_bytes", NULL}; + static _PyArg_Parser _parser = {"|O:BytesIO", _keywords, 0}; PyObject *initvalue = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:BytesIO", _keywords, - &initvalue)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &initvalue)) { goto exit; + } return_value = _io_BytesIO___init___impl((bytesio *)self, initvalue); exit: return return_value; } -/*[clinic end generated code: output=60ce2c6272718431 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6382e8eb578eea64 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index 1042008..908fe0f 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -49,15 +49,17 @@ static int _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"file", "mode", "closefd", "opener", NULL}; + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; + static _PyArg_Parser _parser = {"O|siO:FileIO", _keywords, 0}; PyObject *nameobj; const char *mode = "r"; int closefd = 1; PyObject *opener = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|siO:FileIO", _keywords, - &nameobj, &mode, &closefd, &opener)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &nameobj, &mode, &closefd, &opener)) { goto exit; + } return_value = _io_FileIO___init___impl((fileio *)self, nameobj, mode, closefd, opener); exit: @@ -154,14 +156,16 @@ _io_FileIO_readinto(fileio *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer buffer = {NULL, NULL}; - if (!PyArg_Parse(arg, "w*:readinto", &buffer)) + if (!PyArg_Parse(arg, "w*:readinto", &buffer)) { goto exit; + } return_value = _io_FileIO_readinto_impl(self, &buffer); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -210,8 +214,9 @@ _io_FileIO_read(fileio *self, PyObject *args) Py_ssize_t size = -1; if (!PyArg_ParseTuple(args, "|O&:read", - _PyIO_ConvertSsize_t, &size)) + _PyIO_ConvertSsize_t, &size)) { goto exit; + } return_value = _io_FileIO_read_impl(self, size); exit: @@ -240,14 +245,16 @@ _io_FileIO_write(fileio *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer b = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:write", &b)) + if (!PyArg_Parse(arg, "y*:write", &b)) { goto exit; + } return_value = _io_FileIO_write_impl(self, &b); exit: /* Cleanup for b */ - if (b.obj) + if (b.obj) { PyBuffer_Release(&b); + } return return_value; } @@ -280,8 +287,9 @@ _io_FileIO_seek(fileio *self, PyObject *args) int whence = 0; if (!PyArg_ParseTuple(args, "O|i:seek", - &pos, &whence)) + &pos, &whence)) { goto exit; + } return_value = _io_FileIO_seek_impl(self, pos, whence); exit: @@ -333,8 +341,9 @@ _io_FileIO_truncate(fileio *self, PyObject *args) if (!PyArg_UnpackTuple(args, "truncate", 0, 1, - &posobj)) + &posobj)) { goto exit; + } return_value = _io_FileIO_truncate_impl(self, posobj); exit: @@ -364,4 +373,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO_FILEIO_TRUNCATE_METHODDEF #define _IO_FILEIO_TRUNCATE_METHODDEF #endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */ -/*[clinic end generated code: output=dcbc39b466598492 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=51924bc0ee11d58e input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index 9762f11..edbf73a 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -186,8 +186,9 @@ _io__IOBase_readline(PyObject *self, PyObject *args) Py_ssize_t limit = -1; if (!PyArg_ParseTuple(args, "|O&:readline", - _PyIO_ConvertSsize_t, &limit)) + _PyIO_ConvertSsize_t, &limit)) { goto exit; + } return_value = _io__IOBase_readline_impl(self, limit); exit: @@ -217,8 +218,9 @@ _io__IOBase_readlines(PyObject *self, PyObject *args) Py_ssize_t hint = -1; if (!PyArg_ParseTuple(args, "|O&:readlines", - _PyIO_ConvertSsize_t, &hint)) + _PyIO_ConvertSsize_t, &hint)) { goto exit; + } return_value = _io__IOBase_readlines_impl(self, hint); exit: @@ -251,8 +253,9 @@ _io__RawIOBase_read(PyObject *self, PyObject *args) Py_ssize_t n = -1; if (!PyArg_ParseTuple(args, "|n:read", - &n)) + &n)) { goto exit; + } return_value = _io__RawIOBase_read_impl(self, n); exit: @@ -276,4 +279,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=b874952f5cc248a4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0f53fed928d8e02f input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h index a8e32a3..d2c05d7 100644 --- a/Modules/_io/clinic/stringio.c.h +++ b/Modules/_io/clinic/stringio.c.h @@ -61,8 +61,9 @@ _io_StringIO_read(stringio *self, PyObject *args) if (!PyArg_UnpackTuple(args, "read", 0, 1, - &arg)) + &arg)) { goto exit; + } return_value = _io_StringIO_read_impl(self, arg); exit: @@ -91,8 +92,9 @@ _io_StringIO_readline(stringio *self, PyObject *args) if (!PyArg_UnpackTuple(args, "readline", 0, 1, - &arg)) + &arg)) { goto exit; + } return_value = _io_StringIO_readline_impl(self, arg); exit: @@ -123,8 +125,9 @@ _io_StringIO_truncate(stringio *self, PyObject *args) if (!PyArg_UnpackTuple(args, "truncate", 0, 1, - &arg)) + &arg)) { goto exit; + } return_value = _io_StringIO_truncate_impl(self, arg); exit: @@ -157,8 +160,9 @@ _io_StringIO_seek(stringio *self, PyObject *args) int whence = 0; if (!PyArg_ParseTuple(args, "n|i:seek", - &pos, &whence)) + &pos, &whence)) { goto exit; + } return_value = _io_StringIO_seek_impl(self, pos, whence); exit: @@ -217,13 +221,15 @@ static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"initial_value", "newline", NULL}; + static const char * const _keywords[] = {"initial_value", "newline", NULL}; + static _PyArg_Parser _parser = {"|OO:StringIO", _keywords, 0}; PyObject *value = NULL; PyObject *newline_obj = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO:StringIO", _keywords, - &value, &newline_obj)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &value, &newline_obj)) { goto exit; + } return_value = _io_StringIO___init___impl((stringio *)self, value, newline_obj); exit: @@ -283,4 +289,4 @@ _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) { return _io_StringIO_seekable_impl(self); } -/*[clinic end generated code: output=f061cf3a20cd14ed input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5dd5c2a213e75405 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index dc7e8c7..6c40819 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -24,14 +24,16 @@ static int _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"decoder", "translate", "errors", NULL}; + static const char * const _keywords[] = {"decoder", "translate", "errors", NULL}; + static _PyArg_Parser _parser = {"Oi|O:IncrementalNewlineDecoder", _keywords, 0}; PyObject *decoder; int translate; PyObject *errors = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|O:IncrementalNewlineDecoder", _keywords, - &decoder, &translate, &errors)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &decoder, &translate, &errors)) { goto exit; + } return_value = _io_IncrementalNewlineDecoder___init___impl((nldecoder_object *)self, decoder, translate, errors); exit: @@ -54,13 +56,15 @@ static PyObject * _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"input", "final", NULL}; + static const char * const _keywords[] = {"input", "final", NULL}; + static _PyArg_Parser _parser = {"O|i:decode", _keywords, 0}; PyObject *input; int final = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:decode", _keywords, - &input, &final)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &input, &final)) { goto exit; + } return_value = _io_IncrementalNewlineDecoder_decode_impl(self, input, final); exit: @@ -153,7 +157,8 @@ static int _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; + static const char * const _keywords[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; + static _PyArg_Parser _parser = {"O|zzzii:TextIOWrapper", _keywords, 0}; PyObject *buffer; const char *encoding = NULL; const char *errors = NULL; @@ -161,9 +166,10 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) int line_buffering = 0; int write_through = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|zzzii:TextIOWrapper", _keywords, - &buffer, &encoding, &errors, &newline, &line_buffering, &write_through)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &buffer, &encoding, &errors, &newline, &line_buffering, &write_through)) { goto exit; + } return_value = _io_TextIOWrapper___init___impl((textio *)self, buffer, encoding, errors, newline, line_buffering, write_through); exit: @@ -204,8 +210,9 @@ _io_TextIOWrapper_write(textio *self, PyObject *arg) PyObject *return_value = NULL; PyObject *text; - if (!PyArg_Parse(arg, "U:write", &text)) + if (!PyArg_Parse(arg, "U:write", &text)) { goto exit; + } return_value = _io_TextIOWrapper_write_impl(self, text); exit: @@ -230,8 +237,9 @@ _io_TextIOWrapper_read(textio *self, PyObject *args) Py_ssize_t n = -1; if (!PyArg_ParseTuple(args, "|O&:read", - _PyIO_ConvertSsize_t, &n)) + _PyIO_ConvertSsize_t, &n)) { goto exit; + } return_value = _io_TextIOWrapper_read_impl(self, n); exit: @@ -256,8 +264,9 @@ _io_TextIOWrapper_readline(textio *self, PyObject *args) Py_ssize_t size = -1; if (!PyArg_ParseTuple(args, "|n:readline", - &size)) + &size)) { goto exit; + } return_value = _io_TextIOWrapper_readline_impl(self, size); exit: @@ -283,8 +292,9 @@ _io_TextIOWrapper_seek(textio *self, PyObject *args) int whence = 0; if (!PyArg_ParseTuple(args, "O|i:seek", - &cookieObj, &whence)) + &cookieObj, &whence)) { goto exit; + } return_value = _io_TextIOWrapper_seek_impl(self, cookieObj, whence); exit: @@ -327,8 +337,9 @@ _io_TextIOWrapper_truncate(textio *self, PyObject *args) if (!PyArg_UnpackTuple(args, "truncate", 0, 1, - &pos)) + &pos)) { goto exit; + } return_value = _io_TextIOWrapper_truncate_impl(self, pos); exit: @@ -453,4 +464,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=690608f85aab8ba5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7ec624a9bf6393f5 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h new file mode 100644 index 0000000..e44fcbb --- /dev/null +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -0,0 +1,331 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the handle.\n" +"\n" +"A closed handle cannot be used for further I/O operations. close() may be\n" +"called more than once without error."); + +#define _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF \ + {"close", (PyCFunction)_io__WindowsConsoleIO_close, METH_NOARGS, _io__WindowsConsoleIO_close__doc__}, + +static PyObject * +_io__WindowsConsoleIO_close_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_close(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_close_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO___init____doc__, +"_WindowsConsoleIO(file, mode=\'r\', closefd=True, opener=None)\n" +"--\n" +"\n" +"Open a console buffer by file descriptor.\n" +"\n" +"The mode can be \'rb\' (default), or \'wb\' for reading or writing bytes. All\n" +"other mode characters will be ignored. Mode \'b\' will be assumed if it is\n" +"omitted. The *opener* parameter is always ignored."); + +static int +_io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, + const char *mode, int closefd, + PyObject *opener); + +static int +_io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; + static _PyArg_Parser _parser = {"O|siO:_WindowsConsoleIO", _keywords, 0}; + PyObject *nameobj; + const char *mode = "r"; + int closefd = 1; + PyObject *opener = Py_None; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &nameobj, &mode, &closefd, &opener)) { + goto exit; + } + return_value = _io__WindowsConsoleIO___init___impl((winconsoleio *)self, nameobj, mode, closefd, opener); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the underlying file descriptor (an integer).\n" +"\n" +"fileno is only set when a file descriptor is used to open\n" +"one of the standard streams."); + +#define _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF \ + {"fileno", (PyCFunction)_io__WindowsConsoleIO_fileno, METH_NOARGS, _io__WindowsConsoleIO_fileno__doc__}, + +static PyObject * +_io__WindowsConsoleIO_fileno_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_fileno(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_fileno_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_readable__doc__, +"readable($self, /)\n" +"--\n" +"\n" +"True if console is an input buffer."); + +#define _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF \ + {"readable", (PyCFunction)_io__WindowsConsoleIO_readable, METH_NOARGS, _io__WindowsConsoleIO_readable__doc__}, + +static PyObject * +_io__WindowsConsoleIO_readable_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_readable(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_readable_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_writable__doc__, +"writable($self, /)\n" +"--\n" +"\n" +"True if console is an output buffer."); + +#define _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF \ + {"writable", (PyCFunction)_io__WindowsConsoleIO_writable, METH_NOARGS, _io__WindowsConsoleIO_writable__doc__}, + +static PyObject * +_io__WindowsConsoleIO_writable_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_writable(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_writable_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_readinto__doc__, +"readinto($self, buffer, /)\n" +"--\n" +"\n" +"Same as RawIOBase.readinto()."); + +#define _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF \ + {"readinto", (PyCFunction)_io__WindowsConsoleIO_readinto, METH_O, _io__WindowsConsoleIO_readinto__doc__}, + +static PyObject * +_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, Py_buffer *buffer); + +static PyObject * +_io__WindowsConsoleIO_readinto(winconsoleio *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + + if (!PyArg_Parse(arg, "w*:readinto", &buffer)) { + goto exit; + } + return_value = _io__WindowsConsoleIO_readinto_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_readall__doc__, +"readall($self, /)\n" +"--\n" +"\n" +"Read all data from the console, returned as bytes.\n" +"\n" +"Return an empty bytes object at EOF."); + +#define _IO__WINDOWSCONSOLEIO_READALL_METHODDEF \ + {"readall", (PyCFunction)_io__WindowsConsoleIO_readall, METH_NOARGS, _io__WindowsConsoleIO_readall__doc__}, + +static PyObject * +_io__WindowsConsoleIO_readall_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_readall(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_readall_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n" +"Read at most size bytes, returned as bytes.\n" +"\n" +"Only makes one system call when size is a positive integer,\n" +"so less data may be returned than requested.\n" +"Return an empty bytes object at EOF."); + +#define _IO__WINDOWSCONSOLEIO_READ_METHODDEF \ + {"read", (PyCFunction)_io__WindowsConsoleIO_read, METH_VARARGS, _io__WindowsConsoleIO_read__doc__}, + +static PyObject * +_io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size); + +static PyObject * +_io__WindowsConsoleIO_read(winconsoleio *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + + if (!PyArg_ParseTuple(args, "|O&:read", + _PyIO_ConvertSsize_t, &size)) { + goto exit; + } + return_value = _io__WindowsConsoleIO_read_impl(self, size); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_write__doc__, +"write($self, b, /)\n" +"--\n" +"\n" +"Write buffer b to file, return number of bytes written.\n" +"\n" +"Only makes one system call, so not all of the data may be written.\n" +"The number of bytes actually written is returned."); + +#define _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF \ + {"write", (PyCFunction)_io__WindowsConsoleIO_write, METH_O, _io__WindowsConsoleIO_write__doc__}, + +static PyObject * +_io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b); + +static PyObject * +_io__WindowsConsoleIO_write(winconsoleio *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer b = {NULL, NULL}; + + if (!PyArg_Parse(arg, "y*:write", &b)) { + goto exit; + } + return_value = _io__WindowsConsoleIO_write_impl(self, &b); + +exit: + /* Cleanup for b */ + if (b.obj) { + PyBuffer_Release(&b); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_isatty__doc__, +"isatty($self, /)\n" +"--\n" +"\n" +"Always True."); + +#define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)_io__WindowsConsoleIO_isatty, METH_NOARGS, _io__WindowsConsoleIO_isatty__doc__}, + +static PyObject * +_io__WindowsConsoleIO_isatty_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_isatty_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#ifndef _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF + #define _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF + #define _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_FILENO_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF + #define _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_READABLE_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF + #define _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF + #define _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_READINTO_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_READALL_METHODDEF + #define _IO__WINDOWSCONSOLEIO_READALL_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_READALL_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_READ_METHODDEF + #define _IO__WINDOWSCONSOLEIO_READ_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_READ_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF + #define _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_WRITE_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF + #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ +/*[clinic end generated code: output=9eba916f8537fff7 input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 919cf50..54cfb7f 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -92,8 +92,7 @@ fileio_dealloc_warn(fileio *self, PyObject *source) if (self->fd >= 0 && self->closefd) { PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); - if (PyErr_WarnFormat(PyExc_ResourceWarning, 1, - "unclosed file %R", source)) { + if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) { /* Spurious errors can appear at shutdown */ if (PyErr_ExceptionMatches(PyExc_Warning)) PyErr_WriteUnraisable((PyObject *) self); @@ -118,18 +117,13 @@ internal_close(fileio *self) int fd = self->fd; self->fd = -1; /* fd is accessible and someone else may have closed it */ - if (_PyVerify_fd(fd)) { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - err = close(fd); - if (err < 0) - save_errno = errno; - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } else { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + err = close(fd); + if (err < 0) save_errno = errno; - err = -1; - } + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS } if (err < 0) { errno = save_errno; @@ -546,7 +540,7 @@ err_closed(void) } static PyObject * -err_mode(char *action) +err_mode(const char *action) { _PyIO_State *state = IO_STATE(); if (state != NULL) @@ -701,8 +695,6 @@ _io_FileIO_readall_impl(fileio *self) if (self->fd < 0) return err_closed(); - if (!_PyVerify_fd(self->fd)) - return PyErr_SetFromErrno(PyExc_IOError); _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS @@ -915,18 +907,15 @@ portable_lseek(int fd, PyObject *posobj, int whence) return NULL; } - if (_PyVerify_fd(fd)) { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS - res = _lseeki64(fd, pos, whence); + res = _lseeki64(fd, pos, whence); #else - res = lseek(fd, pos, whence); + res = lseek(fd, pos, whence); #endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } else - res = -1; + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS if (res < 0) return PyErr_SetFromErrno(PyExc_IOError); @@ -1049,7 +1038,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) } #endif /* HAVE_FTRUNCATE */ -static char * +static const char * mode_string(fileio *self) { if (self->created) { @@ -1117,10 +1106,7 @@ _io_FileIO_isatty_impl(fileio *self) return err_closed(); Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH - if (_PyVerify_fd(self->fd)) - res = isatty(self->fd); - else - res = 0; + res = isatty(self->fd); _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS return PyBool_FromLong(res); diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 57541a8..472ef3b 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -828,7 +828,7 @@ PyTypeObject PyIOBase_Type = { 0, /* tp_weaklist */ 0, /* tp_del */ 0, /* tp_version_tag */ - (destructor)iobase_finalize, /* tp_finalize */ + iobase_finalize, /* tp_finalize */ }; diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 06b4144..ecf6dc1 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -438,7 +438,7 @@ stringio_iternext(stringio *self) _PyIO_str_readline, NULL); if (line && !PyUnicode_Check(line)) { PyErr_Format(PyExc_IOError, - "readline() should have returned an str object, " + "readline() should have returned a str object, " "not '%.200s'", Py_TYPE(line)->tp_name); Py_DECREF(line); return NULL; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 063caa6..508e46e 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -531,7 +531,7 @@ _io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) /*[clinic end generated code: output=f0d2c9c136f4e0d0 input=f8ff101825e32e7f]*/ { PyObject *buffer; - unsigned PY_LONG_LONG flag; + unsigned long long flag; if (self->decoder != Py_None) { PyObject *state = PyObject_CallMethodObjArgs(self->decoder, @@ -567,7 +567,7 @@ _io_IncrementalNewlineDecoder_setstate(nldecoder_object *self, /*[clinic end generated code: output=c10c622508b576cb input=c53fb505a76dbbe2]*/ { PyObject *buffer; - unsigned PY_LONG_LONG flag; + unsigned long long flag; if (!PyArg_ParseTuple(state, "OK", &buffer, &flag)) return NULL; @@ -772,7 +772,7 @@ typedef struct { encodefunc_t encodefunc; } encodefuncentry; -static encodefuncentry encodefuncs[] = { +static const encodefuncentry encodefuncs[] = { {"ascii", (encodefunc_t) ascii_encode}, {"iso8859-1", (encodefunc_t) latin1_encode}, {"utf-8", (encodefunc_t) utf8_encode}, @@ -1021,7 +1021,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, goto error; } else if (PyUnicode_Check(res)) { - encodefuncentry *e = encodefuncs; + const encodefuncentry *e = encodefuncs; while (e->name != NULL) { if (!PyUnicode_CompareWithASCIIString(res, e->name)) { self->encodefunc = e->encodefunc; @@ -1644,8 +1644,8 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) /* NOTE: `end` must point to the real end of the Py_UCS4 storage, that is to the NUL character. Otherwise the function will produce incorrect results. */ -static char * -find_control_char(int kind, char *s, char *end, Py_UCS4 ch) +static const char * +find_control_char(int kind, const char *s, const char *end, Py_UCS4 ch) { if (kind == PyUnicode_1BYTE_KIND) { assert(ch < 256); @@ -1665,13 +1665,13 @@ find_control_char(int kind, char *s, char *end, Py_UCS4 ch) Py_ssize_t _PyIO_find_line_ending( int translated, int universal, PyObject *readnl, - int kind, char *start, char *end, Py_ssize_t *consumed) + int kind, const char *start, const char *end, Py_ssize_t *consumed) { Py_ssize_t len = ((char*)end - (char*)start)/kind; if (translated) { /* Newlines are already translated, only search for \n */ - char *pos = find_control_char(kind, start, end, '\n'); + const char *pos = find_control_char(kind, start, end, '\n'); if (pos != NULL) return (pos - start)/kind + 1; else { @@ -1683,7 +1683,7 @@ _PyIO_find_line_ending( /* Universal newline search. Find any of \r, \r\n, \n * The decoder ensures that \r\n are not split in two pieces */ - char *s = start; + const char *s = start; for (;;) { Py_UCS4 ch; /* Fast path for non-control chars. The loop always ends @@ -1713,21 +1713,21 @@ _PyIO_find_line_ending( /* Assume that readnl is an ASCII character. */ assert(PyUnicode_KIND(readnl) == PyUnicode_1BYTE_KIND); if (readnl_len == 1) { - char *pos = find_control_char(kind, start, end, nl[0]); + const char *pos = find_control_char(kind, start, end, nl[0]); if (pos != NULL) return (pos - start)/kind + 1; *consumed = len; return -1; } else { - char *s = start; - char *e = end - (readnl_len - 1)*kind; - char *pos; + const char *s = start; + const char *e = end - (readnl_len - 1)*kind; + const char *pos; if (e < s) e = s; while (s < e) { Py_ssize_t i; - char *pos = find_control_char(kind, s, end, nl[0]); + const char *pos = find_control_char(kind, s, end, nl[0]); if (pos == NULL || pos >= e) break; for (i = 1; i < readnl_len; i++) { @@ -2689,7 +2689,7 @@ textiowrapper_iternext(textio *self) _PyIO_str_readline, NULL); if (line && !PyUnicode_Check(line)) { PyErr_Format(PyExc_IOError, - "readline() should have returned an str object, " + "readline() should have returned a str object, " "not '%.200s'", Py_TYPE(line)->tp_name); Py_DECREF(line); return NULL; diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c new file mode 100644 index 0000000..2527ff1 --- /dev/null +++ b/Modules/_io/winconsoleio.c @@ -0,0 +1,1096 @@ +/* + An implementation of Windows console I/O + + Classes defined here: _WindowsConsoleIO + + Written by Steve Dower +*/ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" + +#ifdef MS_WINDOWS + +#include "structmember.h" +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#include <stddef.h> /* For offsetof */ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include "_iomodule.h" + +/* BUFSIZ determines how many characters can be typed at the console + before it starts blocking. */ +#if BUFSIZ < (16*1024) +#define SMALLCHUNK (2*1024) +#elif (BUFSIZ >= (2 << 25)) +#error "unreasonable BUFSIZ > 64MB defined" +#else +#define SMALLCHUNK BUFSIZ +#endif + +/* BUFMAX determines how many bytes can be read in one go. */ +#define BUFMAX (32*1024*1024) + +char _get_console_type(HANDLE handle) { + DWORD mode, peek_count; + + if (handle == INVALID_HANDLE_VALUE) + return '\0'; + + if (!GetConsoleMode(handle, &mode)) + return '\0'; + + /* Peek at the handle to see whether it is an input or output handle */ + if (GetNumberOfConsoleInputEvents(handle, &peek_count)) + return 'r'; + return 'w'; +} + +char _PyIO_get_console_type(PyObject *path_or_fd) { + int fd; + + fd = PyLong_AsLong(path_or_fd); + PyErr_Clear(); + if (fd >= 0) { + HANDLE handle; + _Py_BEGIN_SUPPRESS_IPH + handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + if (!handle) + return '\0'; + return _get_console_type(handle); + } + + PyObject *decoded = Py_None; + Py_INCREF(decoded); + + int d = PyUnicode_FSDecoder(path_or_fd, &decoded); + if (!d) { + PyErr_Clear(); + Py_CLEAR(decoded); + return '\0'; + } + + char m = '\0'; + if (!PyUnicode_Check(decoded)) { + return '\0'; + } else if (PyUnicode_CompareWithASCIIString(decoded, "CONIN$") == 0) { + m = 'r'; + } else if (PyUnicode_CompareWithASCIIString(decoded, "CONOUT$") == 0 || + PyUnicode_CompareWithASCIIString(decoded, "CON") == 0) { + m = 'w'; + } + + Py_CLEAR(decoded); + return m; +} + +/*[clinic input] +module _io +class _io._WindowsConsoleIO "winconsoleio *" "&PyWindowsConsoleIO_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e897fdc1fba4e131]*/ + +/*[python input] +class io_ssize_t_converter(CConverter): + type = 'Py_ssize_t' + converter = '_PyIO_ConvertSsize_t' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/ + +typedef struct { + PyObject_HEAD + HANDLE handle; + int fd; + unsigned int created : 1; + unsigned int readable : 1; + unsigned int writable : 1; + unsigned int closehandle : 1; + char finalizing; + unsigned int blksize; + PyObject *weakreflist; + PyObject *dict; + char buf[4]; +} winconsoleio; + +PyTypeObject PyWindowsConsoleIO_Type; + +_Py_IDENTIFIER(name); + +int +_PyWindowsConsoleIO_closed(PyObject *self) +{ + return ((winconsoleio *)self)->handle == INVALID_HANDLE_VALUE; +} + + +/* Returns 0 on success, -1 with exception set on failure. */ +static int +internal_close(winconsoleio *self) +{ + if (self->handle != INVALID_HANDLE_VALUE) { + if (self->closehandle) { + if (self->fd >= 0) { + _Py_BEGIN_SUPPRESS_IPH + close(self->fd); + _Py_END_SUPPRESS_IPH + } + CloseHandle(self->handle); + } + self->handle = INVALID_HANDLE_VALUE; + self->fd = -1; + } + return 0; +} + +/*[clinic input] +_io._WindowsConsoleIO.close + +Close the handle. + +A closed handle cannot be used for further I/O operations. close() may be +called more than once without error. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_close_impl(winconsoleio *self) +/*[clinic end generated code: output=27ef95b66c29057b input=185617e349ae4c7b]*/ +{ + PyObject *res; + PyObject *exc, *val, *tb; + int rc; + _Py_IDENTIFIER(close); + res = _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, + &PyId_close, "O", self); + if (!self->closehandle) { + self->handle = INVALID_HANDLE_VALUE; + return res; + } + if (res == NULL) + PyErr_Fetch(&exc, &val, &tb); + rc = internal_close(self); + if (res == NULL) + _PyErr_ChainExceptions(exc, val, tb); + if (rc < 0) + Py_CLEAR(res); + return res; +} + +static PyObject * +winconsoleio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + winconsoleio *self; + + assert(type != NULL && type->tp_alloc != NULL); + + self = (winconsoleio *) type->tp_alloc(type, 0); + if (self != NULL) { + self->handle = INVALID_HANDLE_VALUE; + self->fd = -1; + self->created = 0; + self->readable = 0; + self->writable = 0; + self->closehandle = 0; + self->blksize = 0; + self->weakreflist = NULL; + } + + return (PyObject *) self; +} + +/*[clinic input] +_io._WindowsConsoleIO.__init__ + file as nameobj: object + mode: str = "r" + closefd: int(c_default="1") = True + opener: object = None + +Open a console buffer by file descriptor. + +The mode can be 'rb' (default), or 'wb' for reading or writing bytes. All +other mode characters will be ignored. Mode 'b' will be assumed if it is +omitted. The *opener* parameter is always ignored. +[clinic start generated code]*/ + +static int +_io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, + const char *mode, int closefd, + PyObject *opener) +/*[clinic end generated code: output=3fd9cbcdd8d95429 input=61be39633a86f5d7]*/ +{ + const char *s; + wchar_t *name = NULL; + int ret = 0; + int rwa = 0; + int fd = -1; + int fd_is_own = 0; + + assert(PyWindowsConsoleIO_Check(self)); + if (self->handle >= 0) { + if (self->closehandle) { + /* Have to close the existing file first. */ + if (internal_close(self) < 0) + return -1; + } + else + self->handle = INVALID_HANDLE_VALUE; + } + + if (PyFloat_Check(nameobj)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float"); + return -1; + } + + fd = _PyLong_AsInt(nameobj); + if (fd < 0) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "negative file descriptor"); + return -1; + } + PyErr_Clear(); + } + self->fd = fd; + + if (fd < 0) { + PyObject *decodedname = Py_None; + Py_INCREF(decodedname); + + int d = PyUnicode_FSDecoder(nameobj, (void*)&decodedname); + if (!d) + return -1; + + Py_ssize_t length; + name = PyUnicode_AsWideCharString(decodedname, &length); + Py_CLEAR(decodedname); + if (name == NULL) + return -1; + + if (wcslen(name) != length) { + PyMem_Free(name); + PyErr_SetString(PyExc_ValueError, "embedded null character"); + return -1; + } + } + + s = mode; + while (*s) { + switch (*s++) { + case '+': + case 'a': + case 'b': + case 'x': + break; + case 'r': + if (rwa) + goto bad_mode; + rwa = 1; + self->readable = 1; + break; + case 'w': + if (rwa) + goto bad_mode; + rwa = 1; + self->writable = 1; + break; + default: + PyErr_Format(PyExc_ValueError, + "invalid mode: %.200s", mode); + goto error; + } + } + + if (!rwa) + goto bad_mode; + + if (fd >= 0) { + _Py_BEGIN_SUPPRESS_IPH + self->handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + self->closehandle = 0; + } else { + DWORD access = GENERIC_READ; + + self->closehandle = 1; + if (!closefd) { + PyErr_SetString(PyExc_ValueError, + "Cannot use closefd=False with file name"); + goto error; + } + + if (self->writable) + access |= GENERIC_WRITE; + + Py_BEGIN_ALLOW_THREADS + /* Attempt to open for read/write initially, then fall back + on the specific access. This is required for modern names + CONIN$ and CONOUT$, which allow reading/writing state as + well as reading/writing content. */ + self->handle = CreateFileW(name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (self->handle == INVALID_HANDLE_VALUE) + self->handle = CreateFileW(name, access, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + Py_END_ALLOW_THREADS + + if (self->handle == INVALID_HANDLE_VALUE) { + PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, GetLastError(), nameobj); + goto error; + } + } + + if (self->writable && _get_console_type(self->handle) != 'w') { + PyErr_SetString(PyExc_ValueError, + "Cannot open console input buffer for writing"); + goto error; + } + if (self->readable && _get_console_type(self->handle) != 'r') { + PyErr_SetString(PyExc_ValueError, + "Cannot open console output buffer for reading"); + goto error; + } + + self->blksize = DEFAULT_BUFFER_SIZE; + memset(self->buf, 0, 4); + + if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0) + goto error; + + goto done; + +bad_mode: + PyErr_SetString(PyExc_ValueError, + "Must have exactly one of read or write mode"); +error: + ret = -1; + internal_close(self); + +done: + if (name) + PyMem_Free(name); + return ret; +} + +static int +winconsoleio_traverse(winconsoleio *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + return 0; +} + +static int +winconsoleio_clear(winconsoleio *self) +{ + Py_CLEAR(self->dict); + return 0; +} + +static void +winconsoleio_dealloc(winconsoleio *self) +{ + self->finalizing = 1; + if (_PyIOBase_finalize((PyObject *) self) < 0) + return; + _PyObject_GC_UNTRACK(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_CLEAR(self->dict); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject * +err_closed(void) +{ + PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); + return NULL; +} + +static PyObject * +err_mode(const char *action) +{ + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_Format(state->unsupported_operation, + "Console buffer does not support %s", action); + return NULL; +} + +/*[clinic input] +_io._WindowsConsoleIO.fileno + +Return the underlying file descriptor (an integer). + +fileno is only set when a file descriptor is used to open +one of the standard streams. + +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_fileno_impl(winconsoleio *self) +/*[clinic end generated code: output=006fa74ce3b5cfbf input=079adc330ddaabe6]*/ +{ + if (self->fd < 0 && self->handle != INVALID_HANDLE_VALUE) { + _Py_BEGIN_SUPPRESS_IPH + if (self->writable) + self->fd = _open_osfhandle((intptr_t)self->handle, 'wb'); + else + self->fd = _open_osfhandle((intptr_t)self->handle, 'rb'); + _Py_END_SUPPRESS_IPH + } + if (self->fd < 0) + return err_mode("fileno"); + return PyLong_FromLong(self->fd); +} + +/*[clinic input] +_io._WindowsConsoleIO.readable + +True if console is an input buffer. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_readable_impl(winconsoleio *self) +/*[clinic end generated code: output=daf9cef2743becf0 input=6be9defb5302daae]*/ +{ + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + return PyBool_FromLong((long) self->readable); +} + +/*[clinic input] +_io._WindowsConsoleIO.writable + +True if console is an output buffer. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_writable_impl(winconsoleio *self) +/*[clinic end generated code: output=e0a2ad7eae5abf67 input=cefbd8abc24df6a0]*/ +{ + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + return PyBool_FromLong((long) self->writable); +} + +static DWORD +_buflen(winconsoleio *self) +{ + for (DWORD i = 0; i < 4; ++i) { + if (!self->buf[i]) + return i; + } + return 4; +} + +static DWORD +_copyfrombuf(winconsoleio *self, char *buf, DWORD len) +{ + DWORD n = 0; + + while (self->buf[0] && len--) { + n += 1; + buf[0] = self->buf[0]; + self->buf[0] = self->buf[1]; + self->buf[1] = self->buf[2]; + self->buf[2] = self->buf[3]; + self->buf[3] = 0; + } + + return n; +} + +static wchar_t * +read_console_w(HANDLE handle, DWORD maxlen, DWORD *readlen) { + int err = 0, sig = 0; + + wchar_t *buf = (wchar_t*)PyMem_Malloc(maxlen * sizeof(wchar_t)); + if (!buf) + goto error; + *readlen = 0; + + Py_BEGIN_ALLOW_THREADS + for (DWORD off = 0; off < maxlen; off += BUFSIZ) { + DWORD n, len = min(maxlen - off, BUFSIZ); + SetLastError(0); + BOOL res = ReadConsoleW(handle, &buf[off], len, &n, NULL); + + if (!res) { + err = GetLastError(); + break; + } + if (n == 0) { + err = GetLastError(); + if (err != ERROR_OPERATION_ABORTED) + break; + err = 0; + HANDLE hInterruptEvent = _PyOS_SigintEvent(); + if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE) + == WAIT_OBJECT_0) { + ResetEvent(hInterruptEvent); + Py_BLOCK_THREADS + sig = PyErr_CheckSignals(); + Py_UNBLOCK_THREADS + if (sig < 0) + break; + } + } + *readlen += n; + + /* If we didn't read a full buffer that time, don't try + again or we will block a second time. */ + if (n < len) + break; + /* If the buffer ended with a newline, break out */ + if (buf[*readlen - 1] == '\n') + break; + } + Py_END_ALLOW_THREADS + + if (sig) + goto error; + if (err) { + PyErr_SetFromWindowsErr(err); + goto error; + } + + if (*readlen > 0 && buf[0] == L'\x1a') { + PyMem_Free(buf); + buf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t)); + if (!buf) + goto error; + buf[0] = L'\0'; + *readlen = 0; + } + + return buf; + +error: + if (buf) + PyMem_Free(buf); + return NULL; +} + + +static Py_ssize_t +readinto(winconsoleio *self, char *buf, Py_ssize_t len) +{ + if (self->handle == INVALID_HANDLE_VALUE) { + err_closed(); + return -1; + } + if (!self->readable) { + err_mode("reading"); + return -1; + } + if (len == 0) + return 0; + if (len > BUFMAX) { + PyErr_Format(PyExc_ValueError, "cannot read more than %d bytes", BUFMAX); + return -1; + } + + /* Each character may take up to 4 bytes in the final buffer. + This is highly conservative, but necessary to avoid + failure for any given Unicode input (e.g. \U0010ffff). + If the caller requests fewer than 4 bytes, we buffer one + character. + */ + DWORD wlen = (DWORD)(len / 4); + if (wlen == 0) { + wlen = 1; + } + + DWORD read_len = _copyfrombuf(self, buf, (DWORD)len); + if (read_len) { + buf = &buf[read_len]; + len -= read_len; + wlen -= 1; + } + if (len == read_len || wlen == 0) + return read_len; + + DWORD n; + wchar_t *wbuf = read_console_w(self->handle, wlen, &n); + if (wbuf == NULL) + return -1; + if (n == 0) { + PyMem_Free(wbuf); + return read_len; + } + + int err = 0; + DWORD u8n = 0; + + Py_BEGIN_ALLOW_THREADS + if (len < 4) { + if (WideCharToMultiByte(CP_UTF8, 0, wbuf, n, + self->buf, sizeof(self->buf) / sizeof(self->buf[0]), + NULL, NULL)) + u8n = _copyfrombuf(self, buf, (DWORD)len); + } else { + u8n = WideCharToMultiByte(CP_UTF8, 0, wbuf, n, + buf, (DWORD)len, NULL, NULL); + } + + if (u8n) { + read_len += u8n; + u8n = 0; + } else { + err = GetLastError(); + if (err == ERROR_INSUFFICIENT_BUFFER) { + /* Calculate the needed buffer for a more useful error, as this + means our "/ 4" logic above is insufficient for some input. + */ + u8n = WideCharToMultiByte(CP_UTF8, 0, wbuf, n, + NULL, 0, NULL, NULL); + } + } + Py_END_ALLOW_THREADS + + PyMem_Free(wbuf); + + if (u8n) { + PyErr_Format(PyExc_SystemError, + "Buffer had room for %d bytes but %d bytes required", + len, u8n); + return -1; + } + if (err) { + PyErr_SetFromWindowsErr(err); + return -1; + } + + return read_len; +} + +/*[clinic input] +_io._WindowsConsoleIO.readinto + buffer: Py_buffer(accept={rwbuffer}) + / + +Same as RawIOBase.readinto(). +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, Py_buffer *buffer) +/*[clinic end generated code: output=66d1bdfa3f20af39 input=4ed68da48a6baffe]*/ +{ + Py_ssize_t len = readinto(self, buffer->buf, buffer->len); + if (len < 0) + return NULL; + + return PyLong_FromSsize_t(len); +} + +static DWORD +new_buffersize(winconsoleio *self, DWORD currentsize) +{ + DWORD addend; + + /* Expand the buffer by an amount proportional to the current size, + giving us amortized linear-time behavior. For bigger sizes, use a + less-than-double growth factor to avoid excessive allocation. */ + if (currentsize > 65536) + addend = currentsize >> 3; + else + addend = 256 + currentsize; + if (addend < SMALLCHUNK) + /* Avoid tiny read() calls. */ + addend = SMALLCHUNK; + return addend + currentsize; +} + +/*[clinic input] +_io._WindowsConsoleIO.readall + +Read all data from the console, returned as bytes. + +Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_readall_impl(winconsoleio *self) +/*[clinic end generated code: output=e6d312c684f6e23b input=4024d649a1006e69]*/ +{ + wchar_t *buf; + DWORD bufsize, n, len = 0; + PyObject *bytes; + DWORD bytes_size, rn; + + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + + bufsize = BUFSIZ; + + buf = (wchar_t*)PyMem_Malloc((bufsize + 1) * sizeof(wchar_t)); + if (buf == NULL) + return NULL; + + while (1) { + wchar_t *subbuf; + + if (len >= (Py_ssize_t)bufsize) { + DWORD newsize = new_buffersize(self, len); + if (newsize > BUFMAX) + break; + if (newsize < bufsize) { + PyErr_SetString(PyExc_OverflowError, + "unbounded read returned more bytes " + "than a Python bytes object can hold"); + PyMem_Free(buf); + return NULL; + } + bufsize = newsize; + + buf = PyMem_Realloc(buf, (bufsize + 1) * sizeof(wchar_t)); + if (!buf) { + PyMem_Free(buf); + return NULL; + } + } + + subbuf = read_console_w(self->handle, bufsize - len, &n); + + if (subbuf == NULL) { + PyMem_Free(buf); + return NULL; + } + + if (n > 0) + wcsncpy_s(&buf[len], bufsize - len + 1, subbuf, n); + + PyMem_Free(subbuf); + + /* when the read starts with ^Z or is empty we break */ + if (n == 0 || buf[len] == '\x1a') + break; + + len += n; + } + + if (len > 0 && buf[0] == '\x1a' && _buflen(self) == 0) { + /* when the result starts with ^Z we return an empty buffer */ + PyMem_Free(buf); + return PyBytes_FromStringAndSize(NULL, 0); + } + + Py_BEGIN_ALLOW_THREADS + bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, + NULL, 0, NULL, NULL); + Py_END_ALLOW_THREADS + + if (!bytes_size) { + DWORD err = GetLastError(); + PyMem_Free(buf); + return PyErr_SetFromWindowsErr(err); + } + + bytes_size += _buflen(self); + bytes = PyBytes_FromStringAndSize(NULL, bytes_size); + rn = _copyfrombuf(self, PyBytes_AS_STRING(bytes), bytes_size); + + Py_BEGIN_ALLOW_THREADS + bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, + &PyBytes_AS_STRING(bytes)[rn], bytes_size - rn, NULL, NULL); + Py_END_ALLOW_THREADS + + if (!bytes_size) { + DWORD err = GetLastError(); + PyMem_Free(buf); + Py_CLEAR(bytes); + return PyErr_SetFromWindowsErr(err); + } + + PyMem_Free(buf); + if (bytes_size < (size_t)PyBytes_GET_SIZE(bytes)) { + if (_PyBytes_Resize(&bytes, n * sizeof(wchar_t)) < 0) { + Py_CLEAR(bytes); + return NULL; + } + } + return bytes; +} + +/*[clinic input] +_io._WindowsConsoleIO.read + size: io_ssize_t = -1 + / + +Read at most size bytes, returned as bytes. + +Only makes one system call when size is a positive integer, +so less data may be returned than requested. +Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size) +/*[clinic end generated code: output=57df68af9f4b22d0 input=6c56fceec460f1dd]*/ +{ + PyObject *bytes; + Py_ssize_t bytes_size; + + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + if (!self->readable) + return err_mode("reading"); + + if (size < 0) + return _io__WindowsConsoleIO_readall_impl(self); + if (size > BUFMAX) { + PyErr_Format(PyExc_ValueError, "cannot read more than %d bytes", BUFMAX); + return NULL; + } + + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) + return NULL; + + bytes_size = readinto(self, PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes)); + if (bytes_size < 0) { + Py_CLEAR(bytes); + return NULL; + } + + if (bytes_size < PyBytes_GET_SIZE(bytes)) { + if (_PyBytes_Resize(&bytes, bytes_size) < 0) { + Py_CLEAR(bytes); + return NULL; + } + } + + return bytes; +} + +/*[clinic input] +_io._WindowsConsoleIO.write + b: Py_buffer + / + +Write buffer b to file, return number of bytes written. + +Only makes one system call, so not all of the data may be written. +The number of bytes actually written is returned. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) +/*[clinic end generated code: output=775bdb16fbf9137b input=be35fb624f97c941]*/ +{ + BOOL res = TRUE; + wchar_t *wbuf; + DWORD len, wlen, n = 0; + + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + if (!self->writable) + return err_mode("writing"); + + if (b->len > BUFMAX) + len = BUFMAX; + else + len = (DWORD)b->len; + + Py_BEGIN_ALLOW_THREADS + wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0); + + /* issue11395 there is an unspecified upper bound on how many bytes + can be written at once. We cap at 32k - the caller will have to + handle partial writes. + Since we don't know how many input bytes are being ignored, we + have to reduce and recalculate. */ + while (wlen > 32766 / sizeof(wchar_t)) { + len /= 2; + wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0); + } + Py_END_ALLOW_THREADS + + if (!wlen) + return PyErr_SetFromWindowsErr(0); + + wbuf = (wchar_t*)PyMem_Malloc(wlen * sizeof(wchar_t)); + + Py_BEGIN_ALLOW_THREADS + wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, wbuf, wlen); + if (wlen) { + res = WriteConsoleW(self->handle, wbuf, wlen, &n, NULL); + if (n < wlen) { + /* Wrote fewer characters than expected, which means our + * len value may be wrong. So recalculate it from the + * characters that were written. As this could potentially + * result in a different value, we also validate that value. + */ + len = WideCharToMultiByte(CP_UTF8, 0, wbuf, n, + NULL, 0, NULL, NULL); + if (len) { + wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, + NULL, 0); + assert(wlen == len); + } + } + } else + res = 0; + Py_END_ALLOW_THREADS + + if (!res) { + DWORD err = GetLastError(); + PyMem_Free(wbuf); + return PyErr_SetFromWindowsErr(err); + } + + PyMem_Free(wbuf); + return PyLong_FromSsize_t(len); +} + +static PyObject * +winconsoleio_repr(winconsoleio *self) +{ + if (self->handle == INVALID_HANDLE_VALUE) + return PyUnicode_FromFormat("<_io._WindowsConsoleIO [closed]>"); + + if (self->readable) + return PyUnicode_FromFormat("<_io._WindowsConsoleIO mode='rb' closefd=%s>", + self->closehandle ? "True" : "False"); + if (self->writable) + return PyUnicode_FromFormat("<_io._WindowsConsoleIO mode='wb' closefd=%s>", + self->closehandle ? "True" : "False"); + + PyErr_SetString(PyExc_SystemError, "_WindowsConsoleIO has invalid mode"); + return NULL; +} + +/*[clinic input] +_io._WindowsConsoleIO.isatty + +Always True. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_isatty_impl(winconsoleio *self) +/*[clinic end generated code: output=9eac09d287c11bd7 input=9b91591dbe356f86]*/ +{ + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + + Py_RETURN_TRUE; +} + +static PyObject * +winconsoleio_getstate(winconsoleio *self) +{ + PyErr_Format(PyExc_TypeError, + "cannot serialize '%s' object", Py_TYPE(self)->tp_name); + return NULL; +} + +#include "clinic/winconsoleio.c.h" + +static PyMethodDef winconsoleio_methods[] = { + _IO__WINDOWSCONSOLEIO_READ_METHODDEF + _IO__WINDOWSCONSOLEIO_READALL_METHODDEF + _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF + _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF + _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF + _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF + _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF + _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF + _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF + {"__getstate__", (PyCFunction)winconsoleio_getstate, METH_NOARGS, NULL}, + {NULL, NULL} /* sentinel */ +}; + +/* 'closed' and 'mode' are attributes for compatibility with FileIO. */ + +static PyObject * +get_closed(winconsoleio *self, void *closure) +{ + return PyBool_FromLong((long)(self->handle == INVALID_HANDLE_VALUE)); +} + +static PyObject * +get_closefd(winconsoleio *self, void *closure) +{ + return PyBool_FromLong((long)(self->closehandle)); +} + +static PyObject * +get_mode(winconsoleio *self, void *closure) +{ + return PyUnicode_FromString(self->readable ? "rb" : "wb"); +} + +static PyGetSetDef winconsoleio_getsetlist[] = { + {"closed", (getter)get_closed, NULL, "True if the file is closed"}, + {"closefd", (getter)get_closefd, NULL, + "True if the file descriptor will be closed by close()."}, + {"mode", (getter)get_mode, NULL, "String giving the file mode"}, + {NULL}, +}; + +static PyMemberDef winconsoleio_members[] = { + {"_blksize", T_UINT, offsetof(winconsoleio, blksize), 0}, + {"_finalizing", T_BOOL, offsetof(winconsoleio, finalizing), 0}, + {NULL} +}; + +PyTypeObject PyWindowsConsoleIO_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io._WindowsConsoleIO", + sizeof(winconsoleio), + 0, + (destructor)winconsoleio_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)winconsoleio_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + _io__WindowsConsoleIO___init____doc__, /* tp_doc */ + (traverseproc)winconsoleio_traverse, /* tp_traverse */ + (inquiry)winconsoleio_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(winconsoleio, weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + winconsoleio_methods, /* tp_methods */ + winconsoleio_members, /* tp_members */ + winconsoleio_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(winconsoleio, dict), /* tp_dictoffset */ + _io__WindowsConsoleIO___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + winconsoleio_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; + +#endif /* MS_WINDOWS */ diff --git a/Modules/_json.c b/Modules/_json.c index f82af34..d3dbf98 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -112,7 +112,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *dct, Py_ssiz static PyObject * _encoded_const(PyObject *obj); static void -raise_errmsg(char *msg, PyObject *s, Py_ssize_t end); +raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end); static PyObject * encoder_encode_string(PyEncoderObject *s, PyObject *obj); static PyObject * @@ -321,7 +321,7 @@ escape_unicode(PyObject *pystr) } static void -raise_errmsg(char *msg, PyObject *s, Py_ssize_t end) +raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end) { /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */ static PyObject *JSONDecodeError = NULL; diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index b1d6add..8259180 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -49,7 +49,7 @@ PyDoc_STRVAR(setlocale__doc__, /* the grouping is terminated by either 0 or CHAR_MAX */ static PyObject* -copy_grouping(char* s) +copy_grouping(const char* s) { int i; PyObject *result, *val = NULL; @@ -621,53 +621,34 @@ static struct PyModuleDef _localemodule = { PyMODINIT_FUNC PyInit__locale(void) { - PyObject *m, *d, *x; + PyObject *m; #ifdef HAVE_LANGINFO_H int i; #endif m = PyModule_Create(&_localemodule); if (m == NULL) - return NULL; - - d = PyModule_GetDict(m); - - x = PyLong_FromLong(LC_CTYPE); - PyDict_SetItemString(d, "LC_CTYPE", x); - Py_XDECREF(x); - - x = PyLong_FromLong(LC_TIME); - PyDict_SetItemString(d, "LC_TIME", x); - Py_XDECREF(x); - - x = PyLong_FromLong(LC_COLLATE); - PyDict_SetItemString(d, "LC_COLLATE", x); - Py_XDECREF(x); + return NULL; - x = PyLong_FromLong(LC_MONETARY); - PyDict_SetItemString(d, "LC_MONETARY", x); - Py_XDECREF(x); + PyModule_AddIntMacro(m, LC_CTYPE); + PyModule_AddIntMacro(m, LC_TIME); + PyModule_AddIntMacro(m, LC_COLLATE); + PyModule_AddIntMacro(m, LC_MONETARY); #ifdef LC_MESSAGES - x = PyLong_FromLong(LC_MESSAGES); - PyDict_SetItemString(d, "LC_MESSAGES", x); - Py_XDECREF(x); + PyModule_AddIntMacro(m, LC_MESSAGES); #endif /* LC_MESSAGES */ - x = PyLong_FromLong(LC_NUMERIC); - PyDict_SetItemString(d, "LC_NUMERIC", x); - Py_XDECREF(x); - - x = PyLong_FromLong(LC_ALL); - PyDict_SetItemString(d, "LC_ALL", x); - Py_XDECREF(x); - - x = PyLong_FromLong(CHAR_MAX); - PyDict_SetItemString(d, "CHAR_MAX", x); - Py_XDECREF(x); + PyModule_AddIntMacro(m, LC_NUMERIC); + PyModule_AddIntMacro(m, LC_ALL); + PyModule_AddIntMacro(m, CHAR_MAX); Error = PyErr_NewException("locale.Error", NULL, NULL); - PyDict_SetItemString(d, "Error", Error); + if (Error == NULL) { + Py_DECREF(m); + return NULL; + } + PyModule_AddObject(m, "Error", Error); #ifdef HAVE_LANGINFO_H for (i = 0; langinfo_constants[i].name; i++) { @@ -675,6 +656,11 @@ PyInit__locale(void) langinfo_constants[i].value); } #endif + + if (PyErr_Occurred()) { + Py_DECREF(m); + return NULL; + } return m; } diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 66e534f..dc3f8ab 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -2,17 +2,13 @@ #include "frameobject.h" #include "rotatingtree.h" -#if !defined(HAVE_LONG_LONG) -#error "This module requires long longs!" -#endif - /*** Selection of a high-precision timer ***/ #ifdef MS_WINDOWS #include <windows.h> -static PY_LONG_LONG +static long long hpTimer(void) { LARGE_INTEGER li; @@ -39,11 +35,11 @@ hpTimerUnit(void) #include <sys/resource.h> #include <sys/times.h> -static PY_LONG_LONG +static long long hpTimer(void) { struct timeval tv; - PY_LONG_LONG ret; + long long ret; #ifdef GETTIMEOFDAY_NO_TZ gettimeofday(&tv); #else @@ -70,8 +66,8 @@ struct _ProfilerEntry; /* represents a function called from another function */ typedef struct _ProfilerSubEntry { rotating_node_t header; - PY_LONG_LONG tt; - PY_LONG_LONG it; + long long tt; + long long it; long callcount; long recursivecallcount; long recursionLevel; @@ -81,8 +77,8 @@ typedef struct _ProfilerSubEntry { typedef struct _ProfilerEntry { rotating_node_t header; PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */ - PY_LONG_LONG tt; /* total time in this entry */ - PY_LONG_LONG it; /* inline time in this entry (not in subcalls) */ + long long tt; /* total time in this entry */ + long long it; /* inline time in this entry (not in subcalls) */ long callcount; /* how many times this was called */ long recursivecallcount; /* how many times called recursively */ long recursionLevel; @@ -90,8 +86,8 @@ typedef struct _ProfilerEntry { } ProfilerEntry; typedef struct _ProfilerContext { - PY_LONG_LONG t0; - PY_LONG_LONG subt; + long long t0; + long long subt; struct _ProfilerContext *previous; ProfilerEntry *ctxEntry; } ProfilerContext; @@ -121,9 +117,9 @@ static PyTypeObject PyProfiler_Type; #define DOUBLE_TIMER_PRECISION 4294967296.0 static PyObject *empty_tuple; -static PY_LONG_LONG CallExternalTimer(ProfilerObject *pObj) +static long long CallExternalTimer(ProfilerObject *pObj) { - PY_LONG_LONG result; + long long result; PyObject *o = PyObject_Call(pObj->externalTimer, empty_tuple, NULL); if (o == NULL) { PyErr_WriteUnraisable(pObj->externalTimer); @@ -136,11 +132,11 @@ static PY_LONG_LONG CallExternalTimer(ProfilerObject *pObj) } else { /* interpret the result as a double measured in seconds. - As the profiler works with PY_LONG_LONG internally + As the profiler works with long long internally we convert it to a large integer */ double val = PyFloat_AsDouble(o); /* error handling delayed to the code below */ - result = (PY_LONG_LONG) (val * DOUBLE_TIMER_PRECISION); + result = (long long) (val * DOUBLE_TIMER_PRECISION); } Py_DECREF(o); if (PyErr_Occurred()) { @@ -342,8 +338,8 @@ initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) static void Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) { - PY_LONG_LONG tt = CALL_TIMER(pObj) - self->t0; - PY_LONG_LONG it = tt - self->subt; + long long tt = CALL_TIMER(pObj) - self->t0; + long long it = tt - self->subt; if (self->previous) self->previous->subt += tt; pObj->currentProfilerContext = self->previous; @@ -762,7 +758,6 @@ profiler_dealloc(ProfilerObject *op) static int profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) { - PyObject *o; PyObject *timer = NULL; double timeunit = 0.0; int subcalls = 1; @@ -777,11 +772,9 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) return -1; - o = pObj->externalTimer; - pObj->externalTimer = timer; - Py_XINCREF(timer); - Py_XDECREF(o); pObj->externalTimerUnit = timeunit; + Py_XINCREF(timer); + Py_XSETREF(pObj->externalTimer, timer); return 0; } diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index bc01ffe..5e158fd 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -18,12 +18,6 @@ #include <lzma.h> - -#ifndef PY_LONG_LONG -#error "This module requires PY_LONG_LONG to be defined" -#endif - - #ifdef WITH_THREAD #define ACQUIRE_LOCK(obj) do { \ if (!PyThread_acquire_lock((obj)->lock, 0)) { \ @@ -163,7 +157,7 @@ grow_buffer(PyObject **buf, Py_ssize_t max_length) uint32_t - the "I" (unsigned int) specifier is the right size, but silently ignores overflows on conversion. - lzma_vli - the "K" (unsigned PY_LONG_LONG) specifier is the right + lzma_vli - the "K" (unsigned long long) specifier is the right size, but like "I" it silently ignores overflows on conversion. lzma_mode and lzma_match_finder - these are enumeration types, and @@ -176,12 +170,12 @@ grow_buffer(PyObject **buf, Py_ssize_t max_length) static int \ FUNCNAME(PyObject *obj, void *ptr) \ { \ - unsigned PY_LONG_LONG val; \ + unsigned long long val; \ \ val = PyLong_AsUnsignedLongLong(obj); \ if (PyErr_Occurred()) \ return 0; \ - if ((unsigned PY_LONG_LONG)(TYPE)val != val) { \ + if ((unsigned long long)(TYPE)val != val) { \ PyErr_SetString(PyExc_OverflowError, \ "Value too large for " #TYPE " type"); \ return 0; \ @@ -398,7 +392,7 @@ parse_filter_chain_spec(lzma_filter filters[], PyObject *filterspecs) Python-level filter specifiers (represented as dicts). */ static int -spec_add_field(PyObject *spec, _Py_Identifier *key, unsigned PY_LONG_LONG value) +spec_add_field(PyObject *spec, _Py_Identifier *key, unsigned long long value) { int status; PyObject *value_object; @@ -553,7 +547,6 @@ error: /*[clinic input] _lzma.LZMACompressor.compress - self: self(type="Compressor *") data: Py_buffer / @@ -567,7 +560,7 @@ flush() method to finish the compression process. static PyObject * _lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data) -/*[clinic end generated code: output=31f615136963e00f input=8b60cb13e0ce6420]*/ +/*[clinic end generated code: output=31f615136963e00f input=64019eac7f2cc8d0]*/ { PyObject *result = NULL; @@ -583,8 +576,6 @@ _lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data) /*[clinic input] _lzma.LZMACompressor.flush - self: self(type="Compressor *") - Finish the compression process. Returns the compressed data left in internal buffers. @@ -594,7 +585,7 @@ The compressor object may not be used after this method is called. static PyObject * _lzma_LZMACompressor_flush_impl(Compressor *self) -/*[clinic end generated code: output=fec21f3e22504f50 input=3060fb26f9b4042c]*/ +/*[clinic end generated code: output=fec21f3e22504f50 input=6b369303f67ad0a8]*/ { PyObject *result = NULL; @@ -698,7 +689,6 @@ Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) /*[-clinic input] _lzma.LZMACompressor.__init__ - self: self(type="Compressor *") format: int(c_default="FORMAT_XZ") = FORMAT_XZ The container format to use for the output. This can be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW. @@ -1063,7 +1053,6 @@ error: /*[clinic input] _lzma.LZMADecompressor.decompress - self: self(type="Decompressor *") data: Py_buffer max_length: Py_ssize_t=-1 @@ -1086,7 +1075,7 @@ the unused_data attribute. static PyObject * _lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, Py_ssize_t max_length) -/*[clinic end generated code: output=ef4e20ec7122241d input=f2bb902cc1caf203]*/ +/*[clinic end generated code: output=ef4e20ec7122241d input=60c1f135820e309d]*/ { PyObject *result = NULL; @@ -1126,7 +1115,6 @@ Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) /*[clinic input] _lzma.LZMADecompressor.__init__ - self: self(type="Decompressor *") format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO Specifies the container format of the input stream. If this is FORMAT_AUTO (the default), the decompressor will automatically detect @@ -1152,7 +1140,7 @@ For one-shot decompression, use the decompress() function instead. static int _lzma_LZMADecompressor___init___impl(Decompressor *self, int format, PyObject *memlimit, PyObject *filters) -/*[clinic end generated code: output=3e1821f8aa36564c input=458ca6132ef29801]*/ +/*[clinic end generated code: output=3e1821f8aa36564c input=81fe684a6c2f8a27]*/ { const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK; uint64_t memlimit_ = UINT64_MAX; @@ -1447,7 +1435,7 @@ static PyModuleDef _lzmamodule = { /* Some of our constants are more than 32 bits wide, so PyModule_AddIntConstant would not work correctly on platforms with 32-bit longs. */ static int -module_add_int_constant(PyObject *m, const char *name, PY_LONG_LONG value) +module_add_int_constant(PyObject *m, const char *name, long long value) { PyObject *o = PyLong_FromLongLong(value); if (o == NULL) diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c index 4ae638e..d92a8bf 100644 --- a/Modules/_multiprocessing/multiprocessing.c +++ b/Modules/_multiprocessing/multiprocessing.c @@ -128,7 +128,7 @@ static PyMethodDef module_methods[] = { {"recv", multiprocessing_recv, METH_VARARGS, ""}, {"send", multiprocessing_send, METH_VARARGS, ""}, #endif -#ifndef POSIX_SEMAPHORES_NOT_ENABLED +#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__) {"sem_unlink", _PyMp_sem_unlink, METH_VARARGS, ""}, #endif {NULL} diff --git a/Modules/_multiprocessing/multiprocessing.h b/Modules/_multiprocessing/multiprocessing.h index 9aeea8d..512bc17 100644 --- a/Modules/_multiprocessing/multiprocessing.h +++ b/Modules/_multiprocessing/multiprocessing.h @@ -60,7 +60,7 @@ #if SIZEOF_VOID_P == SIZEOF_LONG # define F_POINTER "k" # define T_POINTER T_ULONG -#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P == SIZEOF_LONG_LONG) +#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG # define F_POINTER "K" # define T_POINTER T_ULONGLONG #else diff --git a/Modules/_operator.c b/Modules/_operator.c index dfff1d2..fb8eafc 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -1111,6 +1111,8 @@ methodcaller_reduce(methodcallerobject *mc) PyObject *functools; PyObject *partial; PyObject *constructor; + PyObject *newargs[2]; + _Py_IDENTIFIER(partial); functools = PyImport_ImportModule("functools"); if (!functools) @@ -1119,17 +1121,11 @@ methodcaller_reduce(methodcallerobject *mc) Py_DECREF(functools); if (!partial) return NULL; - newargs = PyTuple_New(2); - if (newargs == NULL) { - Py_DECREF(partial); - return NULL; - } - Py_INCREF(Py_TYPE(mc)); - PyTuple_SET_ITEM(newargs, 0, (PyObject *)Py_TYPE(mc)); - Py_INCREF(mc->name); - PyTuple_SET_ITEM(newargs, 1, mc->name); - constructor = PyObject_Call(partial, newargs, mc->kwds); - Py_DECREF(newargs); + + newargs[0] = (PyObject *)Py_TYPE(mc); + newargs[1] = mc->name; + constructor = _PyObject_FastCallDict(partial, newargs, 2, mc->kwds); + Py_DECREF(partial); return Py_BuildValue("NO", constructor, mc->args); } diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 3c21b6a..fc16c63 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -153,6 +153,9 @@ typedef struct { PyObject *codecs_encode; /* builtins.getattr, used for saving nested names with protocol < 4 */ PyObject *getattr; + /* functools.partial, used for implementing __newobj_ex__ with protocols + 2 and 3 */ + PyObject *partial; } PickleState; /* Forward declaration of the _pickle module definition. */ @@ -190,6 +193,7 @@ _Pickle_ClearState(PickleState *st) Py_CLEAR(st->import_mapping_3to2); Py_CLEAR(st->codecs_encode); Py_CLEAR(st->getattr); + Py_CLEAR(st->partial); } /* Initialize the given pickle module state. */ @@ -200,6 +204,7 @@ _Pickle_InitState(PickleState *st) PyObject *copyreg = NULL; PyObject *compat_pickle = NULL; PyObject *codecs = NULL; + PyObject *functools = NULL; builtins = PyEval_GetBuiltins(); if (builtins == NULL) @@ -314,12 +319,21 @@ _Pickle_InitState(PickleState *st) } Py_CLEAR(codecs); + functools = PyImport_ImportModule("functools"); + if (!functools) + goto error; + st->partial = PyObject_GetAttrString(functools, "partial"); + if (!st->partial) + goto error; + Py_CLEAR(functools); + return 0; error: Py_CLEAR(copyreg); Py_CLEAR(compat_pickle); Py_CLEAR(codecs); + Py_CLEAR(functools); _Pickle_ClearState(st); return -1; } @@ -331,43 +345,20 @@ static PyObject * _Pickle_FastCall(PyObject *func, PyObject *obj) { PyObject *result; - PyObject *arg_tuple = PyTuple_New(1); - - /* Note: this function used to reuse the argument tuple. This used to give - a slight performance boost with older pickle implementations where many - unbuffered reads occurred (thus needing many function calls). - - However, this optimization was removed because it was too complicated - to get right. It abused the C API for tuples to mutate them which led - to subtle reference counting and concurrency bugs. Furthermore, the - introduction of protocol 4 and the prefetching optimization via peek() - significantly reduced the number of function calls we do. Thus, the - benefits became marginal at best. */ - if (arg_tuple == NULL) { - Py_DECREF(obj); - return NULL; - } - PyTuple_SET_ITEM(arg_tuple, 0, obj); - result = PyObject_Call(func, arg_tuple, NULL); - Py_CLEAR(arg_tuple); + result = _PyObject_CallArg1(func, obj); + Py_DECREF(obj); return result; } /*************************************************************************/ -static int -stack_underflow(void) -{ - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, "unpickling stack underflow"); - return -1; -} - /* Internal data type used as the unpickling stack. */ typedef struct { PyObject_VAR_HEAD PyObject **data; + int mark_set; /* is MARK set? */ + Py_ssize_t fence; /* position of top MARK or 0 */ Py_ssize_t allocated; /* number of slots in data allocated */ } Pdata; @@ -398,6 +389,8 @@ Pdata_New(void) if (!(self = PyObject_New(Pdata, &Pdata_Type))) return NULL; Py_SIZE(self) = 0; + self->mark_set = 0; + self->fence = 0; self->allocated = 8; self->data = PyMem_MALLOC(self->allocated * sizeof(PyObject *)); if (self->data) @@ -415,8 +408,7 @@ Pdata_clear(Pdata *self, Py_ssize_t clearto) { Py_ssize_t i = Py_SIZE(self); - if (clearto < 0) - return stack_underflow(); + assert(clearto >= self->fence); if (clearto >= i) return 0; @@ -452,6 +444,17 @@ Pdata_grow(Pdata *self) return -1; } +static int +Pdata_stack_underflow(Pdata *self) +{ + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + self->mark_set ? + "unexpected MARK found" : + "unpickling stack underflow"); + return -1; +} + /* D is a Pdata*. Pop the topmost element and store it into V, which * must be an lvalue holding PyObject*. On stack underflow, UnpicklingError * is raised and V is set to NULL. @@ -459,9 +462,8 @@ Pdata_grow(Pdata *self) static PyObject * Pdata_pop(Pdata *self) { - if (Py_SIZE(self) == 0) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, "bad pickle data"); + if (Py_SIZE(self) <= self->fence) { + Pdata_stack_underflow(self); return NULL; } return self->data[--Py_SIZE(self)]; @@ -493,6 +495,10 @@ Pdata_poptuple(Pdata *self, Py_ssize_t start) PyObject *tuple; Py_ssize_t len, i, j; + if (start < self->fence) { + Pdata_stack_underflow(self); + return NULL; + } len = Py_SIZE(self) - start; tuple = PyTuple_New(len); if (tuple == NULL) @@ -860,7 +866,7 @@ _write_size64(char *out, size_t value) { size_t i; - assert(sizeof(size_t) <= 8); + Py_BUILD_ASSERT(sizeof(size_t) <= 8); for (i = 0; i < sizeof(size_t); i++) { out[i] = (unsigned char)((value >> (8 * i)) & 0xff); @@ -1086,6 +1092,14 @@ _Unpickler_SetStringInput(UnpicklerObject *self, PyObject *input) } static int +bad_readline(void) +{ + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, "pickle data was truncated"); + return -1; +} + +static int _Unpickler_SkipConsumed(UnpicklerObject *self) { Py_ssize_t consumed; @@ -1134,9 +1148,7 @@ _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n) return -1; if (n == READ_WHOLE_LINE) { - PyObject *empty_tuple = PyTuple_New(0); - data = PyObject_Call(self->readline, empty_tuple, NULL); - Py_DECREF(empty_tuple); + data = _PyObject_CallNoArg(self->readline); } else { PyObject *len; @@ -1174,21 +1186,9 @@ _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n) return read_size; } -/* Read `n` bytes from the unpickler's data source, storing the result in `*s`. - - This should be used for all data reads, rather than accessing the unpickler's - input buffer directly. This method deals correctly with reading from input - streams, which the input buffer doesn't deal with. - - Note that when reading from a file-like object, self->next_read_idx won't - be updated (it should remain at 0 for the entire unpickling process). You - should use this function's return value to know how many bytes you can - consume. - - Returns -1 (with an exception set) on failure. On success, return the - number of chars read. */ +/* Don't call it directly: use _Unpickler_Read() */ static Py_ssize_t -_Unpickler_Read(UnpicklerObject *self, char **s, Py_ssize_t n) +_Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n) { Py_ssize_t num_read; @@ -1199,27 +1199,43 @@ _Unpickler_Read(UnpicklerObject *self, char **s, Py_ssize_t n) "read would overflow (invalid bytecode)"); return -1; } - if (self->next_read_idx + n <= self->input_len) { - *s = self->input_buffer + self->next_read_idx; - self->next_read_idx += n; - return n; - } - if (!self->read) { - PyErr_Format(PyExc_EOFError, "Ran out of input"); - return -1; - } + + /* This case is handled by the _Unpickler_Read() macro for efficiency */ + assert(self->next_read_idx + n > self->input_len); + + if (!self->read) + return bad_readline(); + num_read = _Unpickler_ReadFromFile(self, n); if (num_read < 0) return -1; - if (num_read < n) { - PyErr_Format(PyExc_EOFError, "Ran out of input"); - return -1; - } + if (num_read < n) + return bad_readline(); *s = self->input_buffer; self->next_read_idx = n; return n; } +/* Read `n` bytes from the unpickler's data source, storing the result in `*s`. + + This should be used for all data reads, rather than accessing the unpickler's + input buffer directly. This method deals correctly with reading from input + streams, which the input buffer doesn't deal with. + + Note that when reading from a file-like object, self->next_read_idx won't + be updated (it should remain at 0 for the entire unpickling process). You + should use this function's return value to know how many bytes you can + consume. + + Returns -1 (with an exception set) on failure. On success, return the + number of chars read. */ +#define _Unpickler_Read(self, s, n) \ + (((n) <= (self)->input_len - (self)->next_read_idx) \ + ? (*(s) = (self)->input_buffer + (self)->next_read_idx, \ + (self)->next_read_idx += (n), \ + (n)) \ + : _Unpickler_ReadImpl(self, (s), (n))) + static Py_ssize_t _Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len, char **result) @@ -1238,7 +1254,7 @@ _Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len, } /* Read a line from the input stream/buffer. If we run off the end of the input - before hitting \n, return the data we found. + before hitting \n, raise an error. Returns the number of chars read, or -1 on failure. */ static Py_ssize_t @@ -1254,20 +1270,16 @@ _Unpickler_Readline(UnpicklerObject *self, char **result) return _Unpickler_CopyLine(self, line_start, num_read, result); } } - if (self->read) { - num_read = _Unpickler_ReadFromFile(self, READ_WHOLE_LINE); - if (num_read < 0) - return -1; - self->next_read_idx = num_read; - return _Unpickler_CopyLine(self, self->input_buffer, num_read, result); - } + if (!self->read) + return bad_readline(); - /* If we get here, we've run off the end of the input string. Return the - remaining string and let the caller figure it out. */ - *result = self->input_buffer + self->next_read_idx; - num_read = i - self->next_read_idx; - self->next_read_idx = i; - return num_read; + num_read = _Unpickler_ReadFromFile(self, READ_WHOLE_LINE); + if (num_read < 0) + return -1; + if (num_read == 0 || self->input_buffer[num_read - 1] != '\n') + return bad_readline(); + self->next_read_idx = num_read; + return _Unpickler_CopyLine(self, self->input_buffer, num_read, result); } /* Returns -1 (with an exception set) on failure, 0 on success. The memo array @@ -2096,38 +2108,35 @@ save_bytes(PicklerObject *self, PyObject *obj) static PyObject * raw_unicode_escape(PyObject *obj) { - PyObject *repr; char *p; Py_ssize_t i, size; - size_t expandsize; void *data; unsigned int kind; + _PyBytesWriter writer; if (PyUnicode_READY(obj)) return NULL; + _PyBytesWriter_Init(&writer); + size = PyUnicode_GET_LENGTH(obj); data = PyUnicode_DATA(obj); kind = PyUnicode_KIND(obj); - if (kind == PyUnicode_4BYTE_KIND) - expandsize = 10; - else - expandsize = 6; - if ((size_t)size > (size_t)PY_SSIZE_T_MAX / expandsize) - return PyErr_NoMemory(); - repr = PyBytes_FromStringAndSize(NULL, expandsize * size); - if (repr == NULL) - return NULL; - if (size == 0) - return repr; - assert(Py_REFCNT(repr) == 1); + p = _PyBytesWriter_Alloc(&writer, size); + if (p == NULL) + goto error; + writer.overallocate = 1; - p = PyBytes_AS_STRING(repr); for (i=0; i < size; i++) { Py_UCS4 ch = PyUnicode_READ(kind, data, i); /* Map 32-bit characters to '\Uxxxxxxxx' */ if (ch >= 0x10000) { + /* -1: subtract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 10-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'U'; *p++ = Py_hexdigits[(ch >> 28) & 0xf]; @@ -2139,8 +2148,13 @@ raw_unicode_escape(PyObject *obj) *p++ = Py_hexdigits[(ch >> 4) & 0xf]; *p++ = Py_hexdigits[ch & 15]; } - /* Map 16-bit characters to '\uxxxx' */ + /* Map 16-bit characters, '\\' and '\n' to '\uxxxx' */ else if (ch >= 256 || ch == '\\' || ch == '\n') { + /* -1: subtract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 6-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'u'; *p++ = Py_hexdigits[(ch >> 12) & 0xf]; @@ -2152,14 +2166,16 @@ raw_unicode_escape(PyObject *obj) else *p++ = (char) ch; } - size = p - PyBytes_AS_STRING(repr); - if (_PyBytes_Resize(&repr, size) < 0) - return NULL; - return repr; + + return _PyBytesWriter_Finish(&writer, p); + +error: + _PyBytesWriter_Dealloc(&writer); + return NULL; } static int -write_utf8(PicklerObject *self, char *data, Py_ssize_t size) +write_utf8(PicklerObject *self, const char *data, Py_ssize_t size) { char header[9]; Py_ssize_t len; @@ -2858,7 +2874,7 @@ save_dict(PicklerObject *self, PyObject *obj) } else { _Py_IDENTIFIER(items); - items = _PyObject_CallMethodId(obj, &PyId_items, "()"); + items = _PyObject_CallMethodId(obj, &PyId_items, NULL); if (items == NULL) goto error; iter = PyObject_GetIter(items); @@ -3535,11 +3551,9 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) PyErr_Clear(); } else if (PyUnicode_Check(name)) { - if (self->proto >= 4) { - _Py_IDENTIFIER(__newobj_ex__); - use_newobj_ex = PyUnicode_Compare( - name, _PyUnicode_FromId(&PyId___newobj_ex__)) == 0; - } + _Py_IDENTIFIER(__newobj_ex__); + use_newobj_ex = PyUnicode_Compare( + name, _PyUnicode_FromId(&PyId___newobj_ex__)) == 0; if (!use_newobj_ex) { _Py_IDENTIFIER(__newobj__); use_newobj = PyUnicode_Compare( @@ -3583,11 +3597,58 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) return -1; } - if (save(self, cls, 0) < 0 || - save(self, args, 0) < 0 || - save(self, kwargs, 0) < 0 || - _Pickler_Write(self, &newobj_ex_op, 1) < 0) { - return -1; + if (self->proto >= 4) { + if (save(self, cls, 0) < 0 || + save(self, args, 0) < 0 || + save(self, kwargs, 0) < 0 || + _Pickler_Write(self, &newobj_ex_op, 1) < 0) { + return -1; + } + } + else { + PyObject *newargs; + PyObject *cls_new; + Py_ssize_t i; + _Py_IDENTIFIER(__new__); + + newargs = PyTuple_New(Py_SIZE(args) + 2); + if (newargs == NULL) + return -1; + + cls_new = _PyObject_GetAttrId(cls, &PyId___new__); + if (cls_new == NULL) { + Py_DECREF(newargs); + return -1; + } + PyTuple_SET_ITEM(newargs, 0, cls_new); + Py_INCREF(cls); + PyTuple_SET_ITEM(newargs, 1, cls); + for (i = 0; i < Py_SIZE(args); i++) { + PyObject *item = PyTuple_GET_ITEM(args, i); + Py_INCREF(item); + PyTuple_SET_ITEM(newargs, i + 2, item); + } + + callable = PyObject_Call(st->partial, newargs, kwargs); + Py_DECREF(newargs); + if (callable == NULL) + return -1; + + newargs = PyTuple_New(0); + if (newargs == NULL) { + Py_DECREF(callable); + return -1; + } + + if (save(self, callable, 0) < 0 || + save(self, newargs, 0) < 0 || + _Pickler_Write(self, &reduce_op, 1) < 0) { + Py_DECREF(newargs); + Py_DECREF(callable); + return -1; + } + Py_DECREF(newargs); + Py_DECREF(callable); } } else if (use_newobj) { @@ -3877,10 +3938,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save) /* Check for a __reduce__ method. */ reduce_func = _PyObject_GetAttrId(obj, &PyId___reduce__); if (reduce_func != NULL) { - PyObject *empty_tuple = PyTuple_New(0); - reduce_value = PyObject_Call(reduce_func, empty_tuple, - NULL); - Py_DECREF(empty_tuple); + reduce_value = _PyObject_CallNoArg(reduce_func); } else { PyErr_Format(st->PicklingError, @@ -4397,7 +4455,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj) } else { PyErr_Format(PyExc_TypeError, - "'memo' attribute must be an PicklerMemoProxy object" + "'memo' attribute must be a PicklerMemoProxy object" "or dict, not %.200s", Py_TYPE(obj)->tp_name); return -1; } @@ -4426,8 +4484,6 @@ Pickler_get_persid(PicklerObject *self) static int Pickler_set_persid(PicklerObject *self, PyObject *value) { - PyObject *tmp; - if (value == NULL) { PyErr_SetString(PyExc_TypeError, "attribute deletion is not supported"); @@ -4439,10 +4495,8 @@ Pickler_set_persid(PicklerObject *self, PyObject *value) return -1; } - tmp = self->pers_func; Py_INCREF(value); - self->pers_func = value; - Py_XDECREF(tmp); /* self->pers_func can be NULL, so be careful. */ + Py_XSETREF(self->pers_func, value); return 0; } @@ -4524,13 +4578,19 @@ find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) static Py_ssize_t marker(UnpicklerObject *self) { - PickleState *st = _Pickle_GetGlobalState(); + Py_ssize_t mark; + if (self->num_marks < 1) { + PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "could not find MARK"); return -1; } - return self->marks[--self->num_marks]; + mark = self->marks[--self->num_marks]; + self->stack->mark_set = self->num_marks != 0; + self->stack->fence = self->num_marks ? + self->marks[self->num_marks - 1] : 0; + return mark; } static int @@ -4541,14 +4601,6 @@ load_none(UnpicklerObject *self) } static int -bad_readline(void) -{ - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, "pickle data was truncated"); - return -1; -} - -static int load_int(UnpicklerObject *self) { PyObject *value; @@ -4991,7 +5043,7 @@ load_counted_tuple(UnpicklerObject *self, Py_ssize_t len) PyObject *tuple; if (Py_SIZE(self->stack) < len) - return stack_underflow(); + return Pdata_stack_underflow(self->stack); tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len); if (tuple == NULL) @@ -5073,6 +5125,13 @@ load_dict(UnpicklerObject *self) if ((dict = PyDict_New()) == NULL) return -1; + if ((j - i) % 2 != 0) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, "odd number of items for DICT"); + Py_DECREF(dict); + return -1; + } + for (k = i + 1; k < j; k += 2) { key = self->stack->data[k - 1]; value = self->stack->data[k]; @@ -5140,7 +5199,7 @@ load_obj(UnpicklerObject *self) return -1; if (Py_SIZE(self->stack) - i < 1) - return stack_underflow(); + return Pdata_stack_underflow(self->stack); args = Pdata_poptuple(self->stack, i + 1); if (args == NULL) @@ -5463,12 +5522,15 @@ load_pop(UnpicklerObject *self) */ if (self->num_marks > 0 && self->marks[self->num_marks - 1] == len) { self->num_marks--; - } else if (len > 0) { + self->stack->mark_set = self->num_marks != 0; + self->stack->fence = self->num_marks ? + self->marks[self->num_marks - 1] : 0; + } else if (len <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + else { len--; Py_DECREF(self->stack->data[len]); Py_SIZE(self->stack) = len; - } else { - return stack_underflow(); } return 0; } @@ -5490,10 +5552,10 @@ static int load_dup(UnpicklerObject *self) { PyObject *last; - Py_ssize_t len; + Py_ssize_t len = Py_SIZE(self->stack); - if ((len = Py_SIZE(self->stack)) <= 0) - return stack_underflow(); + if (len <= self->stack->fence) + return Pdata_stack_underflow(self->stack); last = self->stack->data[len - 1]; PDATA_APPEND(self->stack, last, -1); return 0; @@ -5676,8 +5738,8 @@ load_put(UnpicklerObject *self) return -1; if (len < 2) return bad_readline(); - if (Py_SIZE(self->stack) <= 0) - return stack_underflow(); + if (Py_SIZE(self->stack) <= self->stack->fence) + return Pdata_stack_underflow(self->stack); value = self->stack->data[Py_SIZE(self->stack) - 1]; key = PyLong_FromString(s, NULL, 10); @@ -5705,8 +5767,8 @@ load_binput(UnpicklerObject *self) if (_Unpickler_Read(self, &s, 1) < 0) return -1; - if (Py_SIZE(self->stack) <= 0) - return stack_underflow(); + if (Py_SIZE(self->stack) <= self->stack->fence) + return Pdata_stack_underflow(self->stack); value = self->stack->data[Py_SIZE(self->stack) - 1]; idx = Py_CHARMASK(s[0]); @@ -5724,8 +5786,8 @@ load_long_binput(UnpicklerObject *self) if (_Unpickler_Read(self, &s, 4) < 0) return -1; - if (Py_SIZE(self->stack) <= 0) - return stack_underflow(); + if (Py_SIZE(self->stack) <= self->stack->fence) + return Pdata_stack_underflow(self->stack); value = self->stack->data[Py_SIZE(self->stack) - 1]; idx = calc_binsize(s, 4); @@ -5743,8 +5805,8 @@ load_memoize(UnpicklerObject *self) { PyObject *value; - if (Py_SIZE(self->stack) <= 0) - return stack_underflow(); + if (Py_SIZE(self->stack) <= self->stack->fence) + return Pdata_stack_underflow(self->stack); value = self->stack->data[Py_SIZE(self->stack) - 1]; return _Unpickler_MemoPut(self, self->memo_len, value); @@ -5758,8 +5820,8 @@ do_append(UnpicklerObject *self, Py_ssize_t x) Py_ssize_t len, i; len = Py_SIZE(self->stack); - if (x > len || x <= 0) - return stack_underflow(); + if (x > len || x <= self->stack->fence) + return Pdata_stack_underflow(self->stack); if (len == x) /* nothing to do */ return 0; @@ -5808,8 +5870,8 @@ do_append(UnpicklerObject *self, Py_ssize_t x) static int load_append(UnpicklerObject *self) { - if (Py_SIZE(self->stack) - 1 <= 0) - return stack_underflow(); + if (Py_SIZE(self->stack) - 1 <= self->stack->fence) + return Pdata_stack_underflow(self->stack); return do_append(self, Py_SIZE(self->stack) - 1); } @@ -5831,8 +5893,8 @@ do_setitems(UnpicklerObject *self, Py_ssize_t x) int status = 0; len = Py_SIZE(self->stack); - if (x > len || x <= 0) - return stack_underflow(); + if (x > len || x <= self->stack->fence) + return Pdata_stack_underflow(self->stack); if (len == x) /* nothing to do */ return 0; if ((len - x) % 2 != 0) { @@ -5885,8 +5947,8 @@ load_additems(UnpicklerObject *self) if (mark < 0) return -1; len = Py_SIZE(self->stack); - if (mark > len || mark <= 0) - return stack_underflow(); + if (mark > len || mark <= self->stack->fence) + return Pdata_stack_underflow(self->stack); if (len == mark) /* nothing to do */ return 0; @@ -5941,8 +6003,8 @@ load_build(UnpicklerObject *self) /* Stack is ... instance, state. We want to leave instance at * the stack top, possibly mutated via instance.__setstate__(state). */ - if (Py_SIZE(self->stack) < 2) - return stack_underflow(); + if (Py_SIZE(self->stack) - 2 < self->stack->fence) + return Pdata_stack_underflow(self->stack); PDATA_POP(self->stack, state); if (state == NULL) @@ -6078,7 +6140,8 @@ load_mark(UnpicklerObject *self) self->marks_size = (Py_ssize_t)alloc; } - self->marks[self->num_marks++] = Py_SIZE(self->stack); + self->stack->mark_set = 1; + self->marks[self->num_marks++] = self->stack->fence = Py_SIZE(self->stack); return 0; } @@ -6161,6 +6224,8 @@ load(UnpicklerObject *self) char *s = NULL; self->num_marks = 0; + self->stack->mark_set = 0; + self->stack->fence = 0; self->proto = 0; if (Py_SIZE(self->stack)) Pdata_clear(self->stack, 0); @@ -6173,8 +6238,13 @@ load(UnpicklerObject *self) case opcode: if (load_func(self, (arg)) < 0) break; continue; while (1) { - if (_Unpickler_Read(self, &s, 1) < 0) - break; + if (_Unpickler_Read(self, &s, 1) < 0) { + PickleState *st = _Pickle_GetGlobalState(); + if (PyErr_ExceptionMatches(st->UnpicklingError)) { + PyErr_Format(PyExc_EOFError, "Ran out of input"); + } + return NULL; + } switch ((enum opcode)s[0]) { OP(NONE, load_none) @@ -6246,15 +6316,19 @@ load(UnpicklerObject *self) break; default: - if (s[0] == '\0') { - PyErr_SetNone(PyExc_EOFError); - } - else { + { PickleState *st = _Pickle_GetGlobalState(); - PyErr_Format(st->UnpicklingError, - "invalid load key, '%c'.", s[0]); + unsigned char c = (unsigned char) *s; + if (0x20 <= c && c <= 0x7e && c != '\'' && c != '\\') { + PyErr_Format(st->UnpicklingError, + "invalid load key, '%c'.", c); + } + else { + PyErr_Format(st->UnpicklingError, + "invalid load key, '\\x%02x'.", c); + } + return NULL; } - return NULL; } break; /* and we are done! */ @@ -6865,8 +6939,6 @@ Unpickler_get_persload(UnpicklerObject *self) static int Unpickler_set_persload(UnpicklerObject *self, PyObject *value) { - PyObject *tmp; - if (value == NULL) { PyErr_SetString(PyExc_TypeError, "attribute deletion is not supported"); @@ -6879,10 +6951,8 @@ Unpickler_set_persload(UnpicklerObject *self, PyObject *value) return -1; } - tmp = self->pers_func; Py_INCREF(value); - self->pers_func = value; - Py_XDECREF(tmp); /* self->pers_func can be NULL, so be careful. */ + Py_XSETREF(self->pers_func, value); return 0; } diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 8bedab5..0ca0aa5 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -21,8 +21,7 @@ #include <dirent.h> #endif -#if defined(__ANDROID__) && !defined(SYS_getdents64) -/* Android doesn't expose syscalls, add the definition manually. */ +#if defined(__ANDROID__) && __ANDROID_API__ < 21 && !defined(SYS_getdents64) # include <sys/linux-syscalls.h> # define SYS_getdents64 __NR_getdents64 #endif @@ -72,7 +71,7 @@ _enable_gc(int need_to_reenable_gc, PyObject *gc_module) /* Convert ASCII to a positive int, no libc call. no overflow. -1 on error. */ static int -_pos_int_from_ascii(char *name) +_pos_int_from_ascii(const char *name) { int num = 0; while (*name >= '0' && *name <= '9') { diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 95ad4a4..63759d5 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -68,9 +68,8 @@ #include "Python.h" #include <time.h> /* for seeding to current time */ - -#ifndef PY_UINT32_T -# error "Failed to find an exact-width 32-bit integer type" +#ifdef HAVE_PROCESS_H +# include <process.h> /* needed for getpid() */ #endif /* Period parameters -- These are all magic. Don't change. */ @@ -83,7 +82,7 @@ typedef struct { PyObject_HEAD int index; - PY_UINT32_T state[N]; + uint32_t state[N]; } RandomObject; static PyTypeObject Random_Type; @@ -95,13 +94,13 @@ static PyTypeObject Random_Type; /* generates a random number on [0,0xffffffff]-interval */ -static PY_UINT32_T +static uint32_t genrand_int32(RandomObject *self) { - PY_UINT32_T y; - static PY_UINT32_T mag01[2]={0x0U, MATRIX_A}; + uint32_t y; + static const uint32_t mag01[2] = {0x0U, MATRIX_A}; /* mag01[x] = x * MATRIX_A for x=0,1 */ - PY_UINT32_T *mt; + uint32_t *mt; mt = self->state; if (self->index >= N) { /* generate N words at one time */ @@ -136,21 +135,21 @@ genrand_int32(RandomObject *self) * optimize the division away at compile-time. 67108864 is 2**26. In * effect, a contains 27 random bits shifted left 26, and b fills in the * lower 26 bits of the 53-bit numerator. - * The orginal code credited Isaku Wada for this algorithm, 2002/01/09. + * The original code credited Isaku Wada for this algorithm, 2002/01/09. */ static PyObject * random_random(RandomObject *self) { - PY_UINT32_T a=genrand_int32(self)>>5, b=genrand_int32(self)>>6; + uint32_t a=genrand_int32(self)>>5, b=genrand_int32(self)>>6; return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); } /* initializes mt[N] with a seed */ static void -init_genrand(RandomObject *self, PY_UINT32_T s) +init_genrand(RandomObject *self, uint32_t s) { int mti; - PY_UINT32_T *mt; + uint32_t *mt; mt = self->state; mt[0]= s; @@ -169,11 +168,11 @@ init_genrand(RandomObject *self, PY_UINT32_T s) /* initialize by an array with array-length */ /* init_key is the array for initializing keys */ /* key_length is its length */ -static PyObject * -init_by_array(RandomObject *self, PY_UINT32_T init_key[], size_t key_length) +static void +init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) { size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */ - PY_UINT32_T *mt; + uint32_t *mt; mt = self->state; init_genrand(self, 19650218U); @@ -181,21 +180,19 @@ init_by_array(RandomObject *self, PY_UINT32_T init_key[], size_t key_length) k = (N>key_length ? N : key_length); for (; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U)) - + init_key[j] + (PY_UINT32_T)j; /* non linear */ + + init_key[j] + (uint32_t)j; /* non linear */ i++; j++; if (i>=N) { mt[0] = mt[N-1]; i=1; } if (j>=key_length) j=0; } for (k=N-1; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U)) - - (PY_UINT32_T)i; /* non linear */ + - (uint32_t)i; /* non linear */ i++; if (i>=N) { mt[0] = mt[N-1]; i=1; } } mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ - Py_INCREF(Py_None); - return Py_None; } /* @@ -203,12 +200,43 @@ init_by_array(RandomObject *self, PY_UINT32_T init_key[], size_t key_length) * Twister download. */ +static int +random_seed_urandom(RandomObject *self) +{ + PY_UINT32_T key[N]; + + if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) { + return -1; + } + init_by_array(self, key, Py_ARRAY_LENGTH(key)); + return 0; +} + +static void +random_seed_time_pid(RandomObject *self) +{ + _PyTime_t now; + uint32_t key[5]; + + now = _PyTime_GetSystemClock(); + key[0] = (PY_UINT32_T)(now & 0xffffffffU); + key[1] = (PY_UINT32_T)(now >> 32); + + key[2] = (PY_UINT32_T)getpid(); + + now = _PyTime_GetMonotonicClock(); + key[3] = (PY_UINT32_T)(now & 0xffffffffU); + key[4] = (PY_UINT32_T)(now >> 32); + + init_by_array(self, key, Py_ARRAY_LENGTH(key)); +} + static PyObject * random_seed(RandomObject *self, PyObject *args) { PyObject *result = NULL; /* guilty until proved innocent */ PyObject *n = NULL; - PY_UINT32_T *key = NULL; + uint32_t *key = NULL; size_t bits, keyused; int res; PyObject *arg = NULL; @@ -216,14 +244,17 @@ random_seed(RandomObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "seed", 0, 1, &arg)) return NULL; - if (arg == NULL || arg == Py_None) { - time_t now; + if (arg == NULL || arg == Py_None) { + if (random_seed_urandom(self) >= 0) { + PyErr_Clear(); - time(&now); - init_genrand(self, (PY_UINT32_T)now); - Py_INCREF(Py_None); - return Py_None; + /* Reading system entropy failed, fall back on the worst entropy: + use the current time and process identifier. */ + random_seed_time_pid(self); + } + Py_RETURN_NONE; } + /* This algorithm relies on the number being unsigned. * So: if the arg is a PyLong, use its absolute value. * Otherwise use its hash value, cast to unsigned. @@ -248,7 +279,7 @@ random_seed(RandomObject *self, PyObject *args) keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1; /* Convert seed to byte sequence. */ - key = (PY_UINT32_T *)PyMem_Malloc((size_t)4 * keyused); + key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused); if (key == NULL) { PyErr_NoMemory(); goto Done; @@ -267,13 +298,17 @@ random_seed(RandomObject *self, PyObject *args) size_t i, j; /* Reverse an array. */ for (i = 0, j = keyused - 1; i < j; i++, j--) { - PY_UINT32_T tmp = key[i]; + uint32_t tmp = key[i]; key[i] = key[j]; key[j] = tmp; } } #endif - result = init_by_array(self, key, keyused); + init_by_array(self, key, keyused); + + Py_INCREF(Py_None); + result = Py_None; + Done: Py_XDECREF(n); PyMem_Free(key); @@ -329,7 +364,7 @@ random_setstate(RandomObject *self, PyObject *state) element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i)); if (element == (unsigned long)-1 && PyErr_Occurred()) return NULL; - self->state[i] = (PY_UINT32_T)element; + self->state[i] = (uint32_t)element; } index = PyLong_AsLong(PyTuple_GET_ITEM(state, i)); @@ -349,8 +384,8 @@ static PyObject * random_getrandbits(RandomObject *self, PyObject *args) { int k, i, words; - PY_UINT32_T r; - PY_UINT32_T *wordarray; + uint32_t r; + uint32_t *wordarray; PyObject *result; if (!PyArg_ParseTuple(args, "i:getrandbits", &k)) @@ -366,7 +401,7 @@ random_getrandbits(RandomObject *self, PyObject *args) return PyLong_FromUnsignedLong(genrand_int32(self) >> (32 - k)); words = (k - 1) / 32 + 1; - wordarray = (PY_UINT32_T *)PyMem_Malloc(words * 4); + wordarray = (uint32_t *)PyMem_Malloc(words * 4); if (wordarray == NULL) { PyErr_NoMemory(); return NULL; diff --git a/Modules/_scproxy.c b/Modules/_scproxy.c index 66b6e34..1ce4b77 100644 --- a/Modules/_scproxy.c +++ b/Modules/_scproxy.c @@ -71,16 +71,12 @@ get_proxy_settings(PyObject* mod __attribute__((__unused__))) result = PyDict_New(); if (result == NULL) goto error; - if (&kSCPropNetProxiesExcludeSimpleHostnames != NULL) { - aNum = CFDictionaryGetValue(proxyDict, - kSCPropNetProxiesExcludeSimpleHostnames); - if (aNum == NULL) { - v = PyBool_FromLong(0); - } else { - v = PyBool_FromLong(cfnum_to_int32(aNum)); - } - } else { + aNum = CFDictionaryGetValue(proxyDict, + kSCPropNetProxiesExcludeSimpleHostnames); + if (aNum == NULL) { v = PyBool_FromLong(0); + } else { + v = PyBool_FromLong(cfnum_to_int32(aNum)); } if (v == NULL) goto error; @@ -130,7 +126,7 @@ error: } static int -set_proxy(PyObject* proxies, char* proto, CFDictionaryRef proxyDict, +set_proxy(PyObject* proxies, const char* proto, CFDictionaryRef proxyDict, CFStringRef enabledKey, CFStringRef hostKey, CFStringRef portKey) { diff --git a/Modules/_sha3/README.txt b/Modules/_sha3/README.txt new file mode 100644 index 0000000..e34b1d1 --- /dev/null +++ b/Modules/_sha3/README.txt @@ -0,0 +1,11 @@ +Keccak Code Package +=================== + +The files in kcp are taken from the Keccak Code Package. They have been +slightly to be C89 compatible. The architecture specific header file +KeccakP-1600-SnP.h ha been renamed to KeccakP-1600-SnP-opt32.h or +KeccakP-1600-SnP-opt64.h. + +The 64bit files were generated with generic64lc/libkeccak.a.pack target, the +32bit files with generic32lc/libkeccak.a.pack. + diff --git a/Modules/_sha3/cleanup.py b/Modules/_sha3/cleanup.py new file mode 100755 index 0000000..17c56b3 --- /dev/null +++ b/Modules/_sha3/cleanup.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Christian Heimes (christian@python.org) +# Licensed to PSF under a Contributor Agreement. +# +# cleanup Keccak sources + +import os +import re + +CPP1 = re.compile("^//(.*)") +CPP2 = re.compile("\ //(.*)") + +STATICS = ("void ", "int ", "HashReturn ", + "const UINT64 ", "UINT16 ", " int prefix##") + +HERE = os.path.dirname(os.path.abspath(__file__)) +KECCAK = os.path.join(HERE, "kcp") + +def getfiles(): + for name in os.listdir(KECCAK): + name = os.path.join(KECCAK, name) + if os.path.isfile(name): + yield name + +def cleanup(f): + buf = [] + for line in f: + # mark all functions and global data as static + #if line.startswith(STATICS): + # buf.append("static " + line) + # continue + # remove UINT64 typedef, we have our own + if line.startswith("typedef unsigned long long int"): + buf.append("/* %s */\n" % line.strip()) + continue + ## remove #include "brg_endian.h" + if "brg_endian.h" in line: + buf.append("/* %s */\n" % line.strip()) + continue + # transform C++ comments into ANSI C comments + line = CPP1.sub(r"/*\1 */\n", line) + line = CPP2.sub(r" /*\1 */\n", line) + buf.append(line) + return "".join(buf) + +for name in getfiles(): + with open(name) as f: + res = cleanup(f) + with open(name, "w") as f: + f.write(res) diff --git a/Modules/_sha3/clinic/sha3module.c.h b/Modules/_sha3/clinic/sha3module.c.h new file mode 100644 index 0000000..704dc00 --- /dev/null +++ b/Modules/_sha3/clinic/sha3module.c.h @@ -0,0 +1,154 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(py_sha3_new__doc__, +"sha3_224(string=None)\n" +"--\n" +"\n" +"Return a new SHA3 hash object with a hashbit length of 28 bytes."); + +static PyObject * +py_sha3_new_impl(PyTypeObject *type, PyObject *data); + +static PyObject * +py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {"|O:sha3_224", _keywords, 0}; + PyObject *data = NULL; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data)) { + goto exit; + } + return_value = py_sha3_new_impl(type, data); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sha3_sha3_224_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define _SHA3_SHA3_224_COPY_METHODDEF \ + {"copy", (PyCFunction)_sha3_sha3_224_copy, METH_NOARGS, _sha3_sha3_224_copy__doc__}, + +static PyObject * +_sha3_sha3_224_copy_impl(SHA3object *self); + +static PyObject * +_sha3_sha3_224_copy(SHA3object *self, PyObject *Py_UNUSED(ignored)) +{ + return _sha3_sha3_224_copy_impl(self); +} + +PyDoc_STRVAR(_sha3_sha3_224_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of binary data."); + +#define _SHA3_SHA3_224_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_sha3_sha3_224_digest, METH_NOARGS, _sha3_sha3_224_digest__doc__}, + +static PyObject * +_sha3_sha3_224_digest_impl(SHA3object *self); + +static PyObject * +_sha3_sha3_224_digest(SHA3object *self, PyObject *Py_UNUSED(ignored)) +{ + return _sha3_sha3_224_digest_impl(self); +} + +PyDoc_STRVAR(_sha3_sha3_224_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define _SHA3_SHA3_224_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_sha3_sha3_224_hexdigest, METH_NOARGS, _sha3_sha3_224_hexdigest__doc__}, + +static PyObject * +_sha3_sha3_224_hexdigest_impl(SHA3object *self); + +static PyObject * +_sha3_sha3_224_hexdigest(SHA3object *self, PyObject *Py_UNUSED(ignored)) +{ + return _sha3_sha3_224_hexdigest_impl(self); +} + +PyDoc_STRVAR(_sha3_sha3_224_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define _SHA3_SHA3_224_UPDATE_METHODDEF \ + {"update", (PyCFunction)_sha3_sha3_224_update, METH_O, _sha3_sha3_224_update__doc__}, + +PyDoc_STRVAR(_sha3_shake_128_digest__doc__, +"digest($self, /, length)\n" +"--\n" +"\n" +"Return the digest value as a string of binary data."); + +#define _SHA3_SHAKE_128_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_sha3_shake_128_digest, METH_VARARGS|METH_KEYWORDS, _sha3_shake_128_digest__doc__}, + +static PyObject * +_sha3_shake_128_digest_impl(SHA3object *self, unsigned long length); + +static PyObject * +_sha3_shake_128_digest(SHA3object *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"length", NULL}; + static _PyArg_Parser _parser = {"k:digest", _keywords, 0}; + unsigned long length; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &length)) { + goto exit; + } + return_value = _sha3_shake_128_digest_impl(self, length); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sha3_shake_128_hexdigest__doc__, +"hexdigest($self, /, length)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define _SHA3_SHAKE_128_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_sha3_shake_128_hexdigest, METH_VARARGS|METH_KEYWORDS, _sha3_shake_128_hexdigest__doc__}, + +static PyObject * +_sha3_shake_128_hexdigest_impl(SHA3object *self, unsigned long length); + +static PyObject * +_sha3_shake_128_hexdigest(SHA3object *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"length", NULL}; + static _PyArg_Parser _parser = {"k:hexdigest", _keywords, 0}; + unsigned long length; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &length)) { + goto exit; + } + return_value = _sha3_shake_128_hexdigest_impl(self, length); + +exit: + return return_value; +} +/*[clinic end generated code: output=50cff05f2c74d41e input=a9049054013a1b77]*/ diff --git a/Modules/_sha3/kcp/KeccakHash.c b/Modules/_sha3/kcp/KeccakHash.c new file mode 100644 index 0000000..e09fb43 --- /dev/null +++ b/Modules/_sha3/kcp/KeccakHash.c @@ -0,0 +1,82 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include <string.h> +#include "KeccakHash.h" + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix) +{ + HashReturn result; + + if (delimitedSuffix == 0) + return FAIL; + result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, capacity); + if (result != SUCCESS) + return result; + instance->fixedOutputLength = hashbitlen; + instance->delimitedSuffix = delimitedSuffix; + return SUCCESS; +} + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, DataLength databitlen) +{ + if ((databitlen % 8) == 0) + return (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); + else { + HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); + if (ret == SUCCESS) { + /* The last partial byte is assumed to be aligned on the least significant bits */ + + unsigned char lastByte = data[databitlen/8]; + /* Concatenate the last few bits provided here with those of the suffix */ + + unsigned short delimitedLastBytes = (unsigned short)((unsigned short)lastByte | ((unsigned short)instance->delimitedSuffix << (databitlen % 8))); + if ((delimitedLastBytes & 0xFF00) == 0x0000) { + instance->delimitedSuffix = delimitedLastBytes & 0xFF; + } + else { + unsigned char oneByte[1]; + oneByte[0] = delimitedLastBytes & 0xFF; + ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, oneByte, 1); + instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF; + } + } + return ret; + } +} + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval) +{ + HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix); + if (ret == SUCCESS) + return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8); + else + return ret; +} + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, DataLength databitlen) +{ + if ((databitlen % 8) != 0) + return FAIL; + return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8); +} diff --git a/Modules/_sha3/kcp/KeccakHash.h b/Modules/_sha3/kcp/KeccakHash.h new file mode 100644 index 0000000..bbd3dc6 --- /dev/null +++ b/Modules/_sha3/kcp/KeccakHash.h @@ -0,0 +1,114 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakHashInterface_h_ +#define _KeccakHashInterface_h_ + +#ifndef KeccakP1600_excluded + +#include "KeccakSponge.h" +#include <string.h> + +typedef unsigned char BitSequence; +typedef size_t DataLength; +typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; + +typedef struct { + KeccakWidth1600_SpongeInstance sponge; + unsigned int fixedOutputLength; + unsigned char delimitedSuffix; +} Keccak_HashInstance; + +/** + * Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode. + * @param hashInstance Pointer to the hash instance to be initialized. + * @param rate The value of the rate r. + * @param capacity The value of the capacity c. + * @param hashbitlen The desired number of output bits, + * or 0 for an arbitrarily-long output. + * @param delimitedSuffix Bits that will be automatically appended to the end + * of the input message, as in domain separation. + * This is a byte containing from 0 to 7 bits + * formatted like the @a delimitedData parameter of + * the Keccak_SpongeAbsorbLastFewBits() function. + * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix); + +/** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHAKE128(hashInstance) Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F) + +/** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHAKE256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F) + +/** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_224(hashInstance) Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06) + +/** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06) + +/** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_384(hashInstance) Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06) + +/** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_512(hashInstance) Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06) + +/** + * Function to give input data to be absorbed. + * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). + * @param data Pointer to the input data. + * When @a databitLen is not a multiple of 8, the last bits of data must be + * in the least significant bits of the last byte (little-endian convention). + * @param databitLen The number of input bits provided in the input data. + * @pre In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, DataLength databitlen); + +/** + * Function to call after all input blocks have been input and to get + * output bits if the length was specified when calling Keccak_HashInitialize(). + * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). + * If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of + * output bits is equal to @a hashbitlen. + * If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits + * must be extracted using the Keccak_HashSqueeze() function. + * @param state Pointer to the state of the sponge function initialized by Init(). + * @param hashval Pointer to the buffer where to store the output data. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval); + + /** + * Function to squeeze output data. + * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). + * @param data Pointer to the buffer where to store the output data. + * @param databitlen The number of output bits desired (must be a multiple of 8). + * @pre Keccak_HashFinal() must have been already called. + * @pre @a databitlen is a multiple of 8. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen); + +#endif + +#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-64.macros b/Modules/_sha3/kcp/KeccakP-1600-64.macros new file mode 100644 index 0000000..1f11fe3 --- /dev/null +++ b/Modules/_sha3/kcp/KeccakP-1600-64.macros @@ -0,0 +1,2208 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#define declareABCDE \ + UINT64 Aba, Abe, Abi, Abo, Abu; \ + UINT64 Aga, Age, Agi, Ago, Agu; \ + UINT64 Aka, Ake, Aki, Ako, Aku; \ + UINT64 Ama, Ame, Ami, Amo, Amu; \ + UINT64 Asa, Ase, Asi, Aso, Asu; \ + UINT64 Bba, Bbe, Bbi, Bbo, Bbu; \ + UINT64 Bga, Bge, Bgi, Bgo, Bgu; \ + UINT64 Bka, Bke, Bki, Bko, Bku; \ + UINT64 Bma, Bme, Bmi, Bmo, Bmu; \ + UINT64 Bsa, Bse, Bsi, Bso, Bsu; \ + UINT64 Ca, Ce, Ci, Co, Cu; \ + UINT64 Da, De, Di, Do, Du; \ + UINT64 Eba, Ebe, Ebi, Ebo, Ebu; \ + UINT64 Ega, Ege, Egi, Ego, Egu; \ + UINT64 Eka, Eke, Eki, Eko, Eku; \ + UINT64 Ema, Eme, Emi, Emo, Emu; \ + UINT64 Esa, Ese, Esi, Eso, Esu; \ + +#define prepareTheta \ + Ca = Aba^Aga^Aka^Ama^Asa; \ + Ce = Abe^Age^Ake^Ame^Ase; \ + Ci = Abi^Agi^Aki^Ami^Asi; \ + Co = Abo^Ago^Ako^Amo^Aso; \ + Cu = Abu^Agu^Aku^Amu^Asu; \ + +#ifdef UseBebigokimisa +/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ + +/* --- 64-bit lanes mapped to 64-bit words */ + +#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^( Bbe | Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + Ca = E##ba; \ + E##be = Bbe ^((~Bbi)| Bbo ); \ + Ce = E##be; \ + E##bi = Bbi ^( Bbo & Bbu ); \ + Ci = E##bi; \ + E##bo = Bbo ^( Bbu | Bba ); \ + Co = E##bo; \ + E##bu = Bbu ^( Bba & Bbe ); \ + Cu = E##bu; \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^( Bge | Bgi ); \ + Ca ^= E##ga; \ + E##ge = Bge ^( Bgi & Bgo ); \ + Ce ^= E##ge; \ + E##gi = Bgi ^( Bgo |(~Bgu)); \ + Ci ^= E##gi; \ + E##go = Bgo ^( Bgu | Bga ); \ + Co ^= E##go; \ + E##gu = Bgu ^( Bga & Bge ); \ + Cu ^= E##gu; \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^( Bke | Bki ); \ + Ca ^= E##ka; \ + E##ke = Bke ^( Bki & Bko ); \ + Ce ^= E##ke; \ + E##ki = Bki ^((~Bko)& Bku ); \ + Ci ^= E##ki; \ + E##ko = (~Bko)^( Bku | Bka ); \ + Co ^= E##ko; \ + E##ku = Bku ^( Bka & Bke ); \ + Cu ^= E##ku; \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^( Bme & Bmi ); \ + Ca ^= E##ma; \ + E##me = Bme ^( Bmi | Bmo ); \ + Ce ^= E##me; \ + E##mi = Bmi ^((~Bmo)| Bmu ); \ + Ci ^= E##mi; \ + E##mo = (~Bmo)^( Bmu & Bma ); \ + Co ^= E##mo; \ + E##mu = Bmu ^( Bma | Bme ); \ + Cu ^= E##mu; \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + Ca ^= E##sa; \ + E##se = (~Bse)^( Bsi | Bso ); \ + Ce ^= E##se; \ + E##si = Bsi ^( Bso & Bsu ); \ + Ci ^= E##si; \ + E##so = Bso ^( Bsu | Bsa ); \ + Co ^= E##so; \ + E##su = Bsu ^( Bsa & Bse ); \ + Cu ^= E##su; \ +\ + +/* --- Code for round (lane complementing pattern 'bebigokimisa') */ + +/* --- 64-bit lanes mapped to 64-bit words */ + +#define thetaRhoPiChiIota(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^( Bbe | Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + E##be = Bbe ^((~Bbi)| Bbo ); \ + E##bi = Bbi ^( Bbo & Bbu ); \ + E##bo = Bbo ^( Bbu | Bba ); \ + E##bu = Bbu ^( Bba & Bbe ); \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^( Bge | Bgi ); \ + E##ge = Bge ^( Bgi & Bgo ); \ + E##gi = Bgi ^( Bgo |(~Bgu)); \ + E##go = Bgo ^( Bgu | Bga ); \ + E##gu = Bgu ^( Bga & Bge ); \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^( Bke | Bki ); \ + E##ke = Bke ^( Bki & Bko ); \ + E##ki = Bki ^((~Bko)& Bku ); \ + E##ko = (~Bko)^( Bku | Bka ); \ + E##ku = Bku ^( Bka & Bke ); \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^( Bme & Bmi ); \ + E##me = Bme ^( Bmi | Bmo ); \ + E##mi = Bmi ^((~Bmo)| Bmu ); \ + E##mo = (~Bmo)^( Bmu & Bma ); \ + E##mu = Bmu ^( Bma | Bme ); \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + E##se = (~Bse)^( Bsi | Bso ); \ + E##si = Bsi ^( Bso & Bsu ); \ + E##so = Bso ^( Bsu | Bsa ); \ + E##su = Bsu ^( Bsa & Bse ); \ +\ + +#else /* UseBebigokimisa */ + +/* --- Code for round, with prepare-theta */ + +/* --- 64-bit lanes mapped to 64-bit words */ + +#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^((~Bbe)& Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + Ca = E##ba; \ + E##be = Bbe ^((~Bbi)& Bbo ); \ + Ce = E##be; \ + E##bi = Bbi ^((~Bbo)& Bbu ); \ + Ci = E##bi; \ + E##bo = Bbo ^((~Bbu)& Bba ); \ + Co = E##bo; \ + E##bu = Bbu ^((~Bba)& Bbe ); \ + Cu = E##bu; \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^((~Bge)& Bgi ); \ + Ca ^= E##ga; \ + E##ge = Bge ^((~Bgi)& Bgo ); \ + Ce ^= E##ge; \ + E##gi = Bgi ^((~Bgo)& Bgu ); \ + Ci ^= E##gi; \ + E##go = Bgo ^((~Bgu)& Bga ); \ + Co ^= E##go; \ + E##gu = Bgu ^((~Bga)& Bge ); \ + Cu ^= E##gu; \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^((~Bke)& Bki ); \ + Ca ^= E##ka; \ + E##ke = Bke ^((~Bki)& Bko ); \ + Ce ^= E##ke; \ + E##ki = Bki ^((~Bko)& Bku ); \ + Ci ^= E##ki; \ + E##ko = Bko ^((~Bku)& Bka ); \ + Co ^= E##ko; \ + E##ku = Bku ^((~Bka)& Bke ); \ + Cu ^= E##ku; \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^((~Bme)& Bmi ); \ + Ca ^= E##ma; \ + E##me = Bme ^((~Bmi)& Bmo ); \ + Ce ^= E##me; \ + E##mi = Bmi ^((~Bmo)& Bmu ); \ + Ci ^= E##mi; \ + E##mo = Bmo ^((~Bmu)& Bma ); \ + Co ^= E##mo; \ + E##mu = Bmu ^((~Bma)& Bme ); \ + Cu ^= E##mu; \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + Ca ^= E##sa; \ + E##se = Bse ^((~Bsi)& Bso ); \ + Ce ^= E##se; \ + E##si = Bsi ^((~Bso)& Bsu ); \ + Ci ^= E##si; \ + E##so = Bso ^((~Bsu)& Bsa ); \ + Co ^= E##so; \ + E##su = Bsu ^((~Bsa)& Bse ); \ + Cu ^= E##su; \ +\ + +/* --- Code for round */ + +/* --- 64-bit lanes mapped to 64-bit words */ + +#define thetaRhoPiChiIota(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^((~Bbe)& Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + E##be = Bbe ^((~Bbi)& Bbo ); \ + E##bi = Bbi ^((~Bbo)& Bbu ); \ + E##bo = Bbo ^((~Bbu)& Bba ); \ + E##bu = Bbu ^((~Bba)& Bbe ); \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^((~Bge)& Bgi ); \ + E##ge = Bge ^((~Bgi)& Bgo ); \ + E##gi = Bgi ^((~Bgo)& Bgu ); \ + E##go = Bgo ^((~Bgu)& Bga ); \ + E##gu = Bgu ^((~Bga)& Bge ); \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^((~Bke)& Bki ); \ + E##ke = Bke ^((~Bki)& Bko ); \ + E##ki = Bki ^((~Bko)& Bku ); \ + E##ko = Bko ^((~Bku)& Bka ); \ + E##ku = Bku ^((~Bka)& Bke ); \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^((~Bme)& Bmi ); \ + E##me = Bme ^((~Bmi)& Bmo ); \ + E##mi = Bmi ^((~Bmo)& Bmu ); \ + E##mo = Bmo ^((~Bmu)& Bma ); \ + E##mu = Bmu ^((~Bma)& Bme ); \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + E##se = Bse ^((~Bsi)& Bso ); \ + E##si = Bsi ^((~Bso)& Bsu ); \ + E##so = Bso ^((~Bsu)& Bsa ); \ + E##su = Bsu ^((~Bsa)& Bse ); \ +\ + +#endif /* UseBebigokimisa */ + + +#define copyFromState(X, state) \ + X##ba = state[ 0]; \ + X##be = state[ 1]; \ + X##bi = state[ 2]; \ + X##bo = state[ 3]; \ + X##bu = state[ 4]; \ + X##ga = state[ 5]; \ + X##ge = state[ 6]; \ + X##gi = state[ 7]; \ + X##go = state[ 8]; \ + X##gu = state[ 9]; \ + X##ka = state[10]; \ + X##ke = state[11]; \ + X##ki = state[12]; \ + X##ko = state[13]; \ + X##ku = state[14]; \ + X##ma = state[15]; \ + X##me = state[16]; \ + X##mi = state[17]; \ + X##mo = state[18]; \ + X##mu = state[19]; \ + X##sa = state[20]; \ + X##se = state[21]; \ + X##si = state[22]; \ + X##so = state[23]; \ + X##su = state[24]; \ + +#define copyToState(state, X) \ + state[ 0] = X##ba; \ + state[ 1] = X##be; \ + state[ 2] = X##bi; \ + state[ 3] = X##bo; \ + state[ 4] = X##bu; \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + state[ 7] = X##gi; \ + state[ 8] = X##go; \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + state[15] = X##ma; \ + state[16] = X##me; \ + state[17] = X##mi; \ + state[18] = X##mo; \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + state[23] = X##so; \ + state[24] = X##su; \ + +#define copyStateVariables(X, Y) \ + X##ba = Y##ba; \ + X##be = Y##be; \ + X##bi = Y##bi; \ + X##bo = Y##bo; \ + X##bu = Y##bu; \ + X##ga = Y##ga; \ + X##ge = Y##ge; \ + X##gi = Y##gi; \ + X##go = Y##go; \ + X##gu = Y##gu; \ + X##ka = Y##ka; \ + X##ke = Y##ke; \ + X##ki = Y##ki; \ + X##ko = Y##ko; \ + X##ku = Y##ku; \ + X##ma = Y##ma; \ + X##me = Y##me; \ + X##mi = Y##mi; \ + X##mo = Y##mo; \ + X##mu = Y##mu; \ + X##sa = Y##sa; \ + X##se = Y##se; \ + X##si = Y##si; \ + X##so = Y##so; \ + X##su = Y##su; \ + +#define copyFromStateAndAdd(X, state, input, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount < 1) { \ + X##ba = state[ 0]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + } \ + X##be = state[ 1]; \ + X##bi = state[ 2]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + X##be = state[ 1]^input[ 1]; \ + if (laneCount < 3) { \ + X##bi = state[ 2]; \ + } \ + else { \ + X##bi = state[ 2]^input[ 2]; \ + } \ + } \ + X##bo = state[ 3]; \ + X##bu = state[ 4]; \ + X##ga = state[ 5]; \ + X##ge = state[ 6]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + X##be = state[ 1]^input[ 1]; \ + X##bi = state[ 2]^input[ 2]; \ + X##bo = state[ 3]^input[ 3]; \ + if (laneCount < 6) { \ + if (laneCount < 5) { \ + X##bu = state[ 4]; \ + } \ + else { \ + X##bu = state[ 4]^input[ 4]; \ + } \ + X##ga = state[ 5]; \ + X##ge = state[ 6]; \ + } \ + else { \ + X##bu = state[ 4]^input[ 4]; \ + X##ga = state[ 5]^input[ 5]; \ + if (laneCount < 7) { \ + X##ge = state[ 6]; \ + } \ + else { \ + X##ge = state[ 6]^input[ 6]; \ + } \ + } \ + } \ + X##gi = state[ 7]; \ + X##go = state[ 8]; \ + X##gu = state[ 9]; \ + X##ka = state[10]; \ + X##ke = state[11]; \ + X##ki = state[12]; \ + X##ko = state[13]; \ + X##ku = state[14]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + X##be = state[ 1]^input[ 1]; \ + X##bi = state[ 2]^input[ 2]; \ + X##bo = state[ 3]^input[ 3]; \ + X##bu = state[ 4]^input[ 4]; \ + X##ga = state[ 5]^input[ 5]; \ + X##ge = state[ 6]^input[ 6]; \ + X##gi = state[ 7]^input[ 7]; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount < 9) { \ + X##go = state[ 8]; \ + } \ + else { \ + X##go = state[ 8]^input[ 8]; \ + } \ + X##gu = state[ 9]; \ + X##ka = state[10]; \ + } \ + else { \ + X##go = state[ 8]^input[ 8]; \ + X##gu = state[ 9]^input[ 9]; \ + if (laneCount < 11) { \ + X##ka = state[10]; \ + } \ + else { \ + X##ka = state[10]^input[10]; \ + } \ + } \ + X##ke = state[11]; \ + X##ki = state[12]; \ + X##ko = state[13]; \ + X##ku = state[14]; \ + } \ + else { \ + X##go = state[ 8]^input[ 8]; \ + X##gu = state[ 9]^input[ 9]; \ + X##ka = state[10]^input[10]; \ + X##ke = state[11]^input[11]; \ + if (laneCount < 14) { \ + if (laneCount < 13) { \ + X##ki = state[12]; \ + } \ + else { \ + X##ki = state[12]^input[12]; \ + } \ + X##ko = state[13]; \ + X##ku = state[14]; \ + } \ + else { \ + X##ki = state[12]^input[12]; \ + X##ko = state[13]^input[13]; \ + if (laneCount < 15) { \ + X##ku = state[14]; \ + } \ + else { \ + X##ku = state[14]^input[14]; \ + } \ + } \ + } \ + } \ + X##ma = state[15]; \ + X##me = state[16]; \ + X##mi = state[17]; \ + X##mo = state[18]; \ + X##mu = state[19]; \ + X##sa = state[20]; \ + X##se = state[21]; \ + X##si = state[22]; \ + X##so = state[23]; \ + X##su = state[24]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + X##be = state[ 1]^input[ 1]; \ + X##bi = state[ 2]^input[ 2]; \ + X##bo = state[ 3]^input[ 3]; \ + X##bu = state[ 4]^input[ 4]; \ + X##ga = state[ 5]^input[ 5]; \ + X##ge = state[ 6]^input[ 6]; \ + X##gi = state[ 7]^input[ 7]; \ + X##go = state[ 8]^input[ 8]; \ + X##gu = state[ 9]^input[ 9]; \ + X##ka = state[10]^input[10]; \ + X##ke = state[11]^input[11]; \ + X##ki = state[12]^input[12]; \ + X##ko = state[13]^input[13]; \ + X##ku = state[14]^input[14]; \ + X##ma = state[15]^input[15]; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount < 17) { \ + X##me = state[16]; \ + } \ + else { \ + X##me = state[16]^input[16]; \ + } \ + X##mi = state[17]; \ + X##mo = state[18]; \ + } \ + else { \ + X##me = state[16]^input[16]; \ + X##mi = state[17]^input[17]; \ + if (laneCount < 19) { \ + X##mo = state[18]; \ + } \ + else { \ + X##mo = state[18]^input[18]; \ + } \ + } \ + X##mu = state[19]; \ + X##sa = state[20]; \ + X##se = state[21]; \ + X##si = state[22]; \ + } \ + else { \ + X##me = state[16]^input[16]; \ + X##mi = state[17]^input[17]; \ + X##mo = state[18]^input[18]; \ + X##mu = state[19]^input[19]; \ + if (laneCount < 22) { \ + if (laneCount < 21) { \ + X##sa = state[20]; \ + } \ + else { \ + X##sa = state[20]^input[20]; \ + } \ + X##se = state[21]; \ + X##si = state[22]; \ + } \ + else { \ + X##sa = state[20]^input[20]; \ + X##se = state[21]^input[21]; \ + if (laneCount < 23) { \ + X##si = state[22]; \ + } \ + else { \ + X##si = state[22]^input[22]; \ + } \ + } \ + } \ + X##so = state[23]; \ + X##su = state[24]; \ + } \ + else { \ + X##me = state[16]^input[16]; \ + X##mi = state[17]^input[17]; \ + X##mo = state[18]^input[18]; \ + X##mu = state[19]^input[19]; \ + X##sa = state[20]^input[20]; \ + X##se = state[21]^input[21]; \ + X##si = state[22]^input[22]; \ + X##so = state[23]^input[23]; \ + if (laneCount < 25) { \ + X##su = state[24]; \ + } \ + else { \ + X##su = state[24]^input[24]; \ + } \ + } \ + } + +#define addInput(X, input, laneCount) \ + if (laneCount == 21) { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + X##bi ^= input[ 2]; \ + X##bo ^= input[ 3]; \ + X##bu ^= input[ 4]; \ + X##ga ^= input[ 5]; \ + X##ge ^= input[ 6]; \ + X##gi ^= input[ 7]; \ + X##go ^= input[ 8]; \ + X##gu ^= input[ 9]; \ + X##ka ^= input[10]; \ + X##ke ^= input[11]; \ + X##ki ^= input[12]; \ + X##ko ^= input[13]; \ + X##ku ^= input[14]; \ + X##ma ^= input[15]; \ + X##me ^= input[16]; \ + X##mi ^= input[17]; \ + X##mo ^= input[18]; \ + X##mu ^= input[19]; \ + X##sa ^= input[20]; \ + } \ + else if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount < 1) { \ + } \ + else { \ + X##ba ^= input[ 0]; \ + } \ + } \ + else { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + if (laneCount < 3) { \ + } \ + else { \ + X##bi ^= input[ 2]; \ + } \ + } \ + } \ + else { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + X##bi ^= input[ 2]; \ + X##bo ^= input[ 3]; \ + if (laneCount < 6) { \ + if (laneCount < 5) { \ + } \ + else { \ + X##bu ^= input[ 4]; \ + } \ + } \ + else { \ + X##bu ^= input[ 4]; \ + X##ga ^= input[ 5]; \ + if (laneCount < 7) { \ + } \ + else { \ + X##ge ^= input[ 6]; \ + } \ + } \ + } \ + } \ + else { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + X##bi ^= input[ 2]; \ + X##bo ^= input[ 3]; \ + X##bu ^= input[ 4]; \ + X##ga ^= input[ 5]; \ + X##ge ^= input[ 6]; \ + X##gi ^= input[ 7]; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount < 9) { \ + } \ + else { \ + X##go ^= input[ 8]; \ + } \ + } \ + else { \ + X##go ^= input[ 8]; \ + X##gu ^= input[ 9]; \ + if (laneCount < 11) { \ + } \ + else { \ + X##ka ^= input[10]; \ + } \ + } \ + } \ + else { \ + X##go ^= input[ 8]; \ + X##gu ^= input[ 9]; \ + X##ka ^= input[10]; \ + X##ke ^= input[11]; \ + if (laneCount < 14) { \ + if (laneCount < 13) { \ + } \ + else { \ + X##ki ^= input[12]; \ + } \ + } \ + else { \ + X##ki ^= input[12]; \ + X##ko ^= input[13]; \ + if (laneCount < 15) { \ + } \ + else { \ + X##ku ^= input[14]; \ + } \ + } \ + } \ + } \ + } \ + else { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + X##bi ^= input[ 2]; \ + X##bo ^= input[ 3]; \ + X##bu ^= input[ 4]; \ + X##ga ^= input[ 5]; \ + X##ge ^= input[ 6]; \ + X##gi ^= input[ 7]; \ + X##go ^= input[ 8]; \ + X##gu ^= input[ 9]; \ + X##ka ^= input[10]; \ + X##ke ^= input[11]; \ + X##ki ^= input[12]; \ + X##ko ^= input[13]; \ + X##ku ^= input[14]; \ + X##ma ^= input[15]; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount < 17) { \ + } \ + else { \ + X##me ^= input[16]; \ + } \ + } \ + else { \ + X##me ^= input[16]; \ + X##mi ^= input[17]; \ + if (laneCount < 19) { \ + } \ + else { \ + X##mo ^= input[18]; \ + } \ + } \ + } \ + else { \ + X##me ^= input[16]; \ + X##mi ^= input[17]; \ + X##mo ^= input[18]; \ + X##mu ^= input[19]; \ + if (laneCount < 22) { \ + if (laneCount < 21) { \ + } \ + else { \ + X##sa ^= input[20]; \ + } \ + } \ + else { \ + X##sa ^= input[20]; \ + X##se ^= input[21]; \ + if (laneCount < 23) { \ + } \ + else { \ + X##si ^= input[22]; \ + } \ + } \ + } \ + } \ + else { \ + X##me ^= input[16]; \ + X##mi ^= input[17]; \ + X##mo ^= input[18]; \ + X##mu ^= input[19]; \ + X##sa ^= input[20]; \ + X##se ^= input[21]; \ + X##si ^= input[22]; \ + X##so ^= input[23]; \ + if (laneCount < 25) { \ + } \ + else { \ + X##su ^= input[24]; \ + } \ + } \ + } + +#ifdef UseBebigokimisa + +#define copyToStateAndOutput(X, state, output, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + state[ 0] = X##ba; \ + if (laneCount >= 1) { \ + output[ 0] = X##ba; \ + } \ + state[ 1] = X##be; \ + state[ 2] = X##bi; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = ~X##be; \ + state[ 2] = X##bi; \ + if (laneCount >= 3) { \ + output[ 2] = ~X##bi; \ + } \ + } \ + state[ 3] = X##bo; \ + state[ 4] = X##bu; \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = ~X##be; \ + state[ 2] = X##bi; \ + output[ 2] = ~X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + if (laneCount < 6) { \ + state[ 4] = X##bu; \ + if (laneCount >= 5) { \ + output[ 4] = X##bu; \ + } \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + } \ + else { \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + if (laneCount >= 7) { \ + output[ 6] = X##ge; \ + } \ + } \ + } \ + state[ 7] = X##gi; \ + state[ 8] = X##go; \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = ~X##be; \ + state[ 2] = X##bi; \ + output[ 2] = ~X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + output[ 6] = X##ge; \ + state[ 7] = X##gi; \ + output[ 7] = X##gi; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + state[ 8] = X##go; \ + if (laneCount >= 9) { \ + output[ 8] = ~X##go; \ + } \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + } \ + else { \ + state[ 8] = X##go; \ + output[ 8] = ~X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + if (laneCount >= 11) { \ + output[10] = X##ka; \ + } \ + } \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[ 8] = X##go; \ + output[ 8] = ~X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + output[10] = X##ka; \ + state[11] = X##ke; \ + output[11] = X##ke; \ + if (laneCount < 14) { \ + state[12] = X##ki; \ + if (laneCount >= 13) { \ + output[12] = ~X##ki; \ + } \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[12] = X##ki; \ + output[12] = ~X##ki; \ + state[13] = X##ko; \ + output[13] = X##ko; \ + state[14] = X##ku; \ + if (laneCount >= 15) { \ + output[14] = X##ku; \ + } \ + } \ + } \ + } \ + state[15] = X##ma; \ + state[16] = X##me; \ + state[17] = X##mi; \ + state[18] = X##mo; \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + state[23] = X##so; \ + state[24] = X##su; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = ~X##be; \ + state[ 2] = X##bi; \ + output[ 2] = ~X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + output[ 6] = X##ge; \ + state[ 7] = X##gi; \ + output[ 7] = X##gi; \ + state[ 8] = X##go; \ + output[ 8] = ~X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + output[10] = X##ka; \ + state[11] = X##ke; \ + output[11] = X##ke; \ + state[12] = X##ki; \ + output[12] = ~X##ki; \ + state[13] = X##ko; \ + output[13] = X##ko; \ + state[14] = X##ku; \ + output[14] = X##ku; \ + state[15] = X##ma; \ + output[15] = X##ma; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + state[16] = X##me; \ + if (laneCount >= 17) { \ + output[16] = X##me; \ + } \ + state[17] = X##mi; \ + state[18] = X##mo; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = ~X##mi; \ + state[18] = X##mo; \ + if (laneCount >= 19) { \ + output[18] = X##mo; \ + } \ + } \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = ~X##mi; \ + state[18] = X##mo; \ + output[18] = X##mo; \ + state[19] = X##mu; \ + output[19] = X##mu; \ + if (laneCount < 22) { \ + state[20] = X##sa; \ + if (laneCount >= 21) { \ + output[20] = ~X##sa; \ + } \ + state[21] = X##se; \ + state[22] = X##si; \ + } \ + else { \ + state[20] = X##sa; \ + output[20] = ~X##sa; \ + state[21] = X##se; \ + output[21] = X##se; \ + state[22] = X##si; \ + if (laneCount >= 23) { \ + output[22] = X##si; \ + } \ + } \ + } \ + state[23] = X##so; \ + state[24] = X##su; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = ~X##mi; \ + state[18] = X##mo; \ + output[18] = X##mo; \ + state[19] = X##mu; \ + output[19] = X##mu; \ + state[20] = X##sa; \ + output[20] = ~X##sa; \ + state[21] = X##se; \ + output[21] = X##se; \ + state[22] = X##si; \ + output[22] = X##si; \ + state[23] = X##so; \ + output[23] = X##so; \ + state[24] = X##su; \ + if (laneCount >= 25) { \ + output[24] = X##su; \ + } \ + } \ + } + +#define output(X, output, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount >= 1) { \ + output[ 0] = X##ba; \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = ~X##be; \ + if (laneCount >= 3) { \ + output[ 2] = ~X##bi; \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = ~X##be; \ + output[ 2] = ~X##bi; \ + output[ 3] = X##bo; \ + if (laneCount < 6) { \ + if (laneCount >= 5) { \ + output[ 4] = X##bu; \ + } \ + } \ + else { \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + if (laneCount >= 7) { \ + output[ 6] = X##ge; \ + } \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = ~X##be; \ + output[ 2] = ~X##bi; \ + output[ 3] = X##bo; \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + output[ 6] = X##ge; \ + output[ 7] = X##gi; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount >= 9) { \ + output[ 8] = ~X##go; \ + } \ + } \ + else { \ + output[ 8] = ~X##go; \ + output[ 9] = X##gu; \ + if (laneCount >= 11) { \ + output[10] = X##ka; \ + } \ + } \ + } \ + else { \ + output[ 8] = ~X##go; \ + output[ 9] = X##gu; \ + output[10] = X##ka; \ + output[11] = X##ke; \ + if (laneCount < 14) { \ + if (laneCount >= 13) { \ + output[12] = ~X##ki; \ + } \ + } \ + else { \ + output[12] = ~X##ki; \ + output[13] = X##ko; \ + if (laneCount >= 15) { \ + output[14] = X##ku; \ + } \ + } \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = ~X##be; \ + output[ 2] = ~X##bi; \ + output[ 3] = X##bo; \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + output[ 6] = X##ge; \ + output[ 7] = X##gi; \ + output[ 8] = ~X##go; \ + output[ 9] = X##gu; \ + output[10] = X##ka; \ + output[11] = X##ke; \ + output[12] = ~X##ki; \ + output[13] = X##ko; \ + output[14] = X##ku; \ + output[15] = X##ma; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount >= 17) { \ + output[16] = X##me; \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = ~X##mi; \ + if (laneCount >= 19) { \ + output[18] = X##mo; \ + } \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = ~X##mi; \ + output[18] = X##mo; \ + output[19] = X##mu; \ + if (laneCount < 22) { \ + if (laneCount >= 21) { \ + output[20] = ~X##sa; \ + } \ + } \ + else { \ + output[20] = ~X##sa; \ + output[21] = X##se; \ + if (laneCount >= 23) { \ + output[22] = X##si; \ + } \ + } \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = ~X##mi; \ + output[18] = X##mo; \ + output[19] = X##mu; \ + output[20] = ~X##sa; \ + output[21] = X##se; \ + output[22] = X##si; \ + output[23] = X##so; \ + if (laneCount >= 25) { \ + output[24] = X##su; \ + } \ + } \ + } + +#define wrapOne(X, input, output, index, name) \ + X##name ^= input[index]; \ + output[index] = X##name; + +#define wrapOneInvert(X, input, output, index, name) \ + X##name ^= input[index]; \ + output[index] = ~X##name; + +#define unwrapOne(X, input, output, index, name) \ + output[index] = input[index] ^ X##name; \ + X##name ^= output[index]; + +#define unwrapOneInvert(X, input, output, index, name) \ + output[index] = ~(input[index] ^ X##name); \ + X##name ^= output[index]; \ + +#else /* UseBebigokimisa */ + + +#define copyToStateAndOutput(X, state, output, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + state[ 0] = X##ba; \ + if (laneCount >= 1) { \ + output[ 0] = X##ba; \ + } \ + state[ 1] = X##be; \ + state[ 2] = X##bi; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = X##be; \ + state[ 2] = X##bi; \ + if (laneCount >= 3) { \ + output[ 2] = X##bi; \ + } \ + } \ + state[ 3] = X##bo; \ + state[ 4] = X##bu; \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = X##be; \ + state[ 2] = X##bi; \ + output[ 2] = X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + if (laneCount < 6) { \ + state[ 4] = X##bu; \ + if (laneCount >= 5) { \ + output[ 4] = X##bu; \ + } \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + } \ + else { \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + if (laneCount >= 7) { \ + output[ 6] = X##ge; \ + } \ + } \ + } \ + state[ 7] = X##gi; \ + state[ 8] = X##go; \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = X##be; \ + state[ 2] = X##bi; \ + output[ 2] = X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + output[ 6] = X##ge; \ + state[ 7] = X##gi; \ + output[ 7] = X##gi; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + state[ 8] = X##go; \ + if (laneCount >= 9) { \ + output[ 8] = X##go; \ + } \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + } \ + else { \ + state[ 8] = X##go; \ + output[ 8] = X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + if (laneCount >= 11) { \ + output[10] = X##ka; \ + } \ + } \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[ 8] = X##go; \ + output[ 8] = X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + output[10] = X##ka; \ + state[11] = X##ke; \ + output[11] = X##ke; \ + if (laneCount < 14) { \ + state[12] = X##ki; \ + if (laneCount >= 13) { \ + output[12]= X##ki; \ + } \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[12] = X##ki; \ + output[12]= X##ki; \ + state[13] = X##ko; \ + output[13] = X##ko; \ + state[14] = X##ku; \ + if (laneCount >= 15) { \ + output[14] = X##ku; \ + } \ + } \ + } \ + } \ + state[15] = X##ma; \ + state[16] = X##me; \ + state[17] = X##mi; \ + state[18] = X##mo; \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + state[23] = X##so; \ + state[24] = X##su; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = X##be; \ + state[ 2] = X##bi; \ + output[ 2] = X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + output[ 6] = X##ge; \ + state[ 7] = X##gi; \ + output[ 7] = X##gi; \ + state[ 8] = X##go; \ + output[ 8] = X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + output[10] = X##ka; \ + state[11] = X##ke; \ + output[11] = X##ke; \ + state[12] = X##ki; \ + output[12]= X##ki; \ + state[13] = X##ko; \ + output[13] = X##ko; \ + state[14] = X##ku; \ + output[14] = X##ku; \ + state[15] = X##ma; \ + output[15] = X##ma; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + state[16] = X##me; \ + if (laneCount >= 17) { \ + output[16] = X##me; \ + } \ + state[17] = X##mi; \ + state[18] = X##mo; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = X##mi; \ + state[18] = X##mo; \ + if (laneCount >= 19) { \ + output[18] = X##mo; \ + } \ + } \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = X##mi; \ + state[18] = X##mo; \ + output[18] = X##mo; \ + state[19] = X##mu; \ + output[19] = X##mu; \ + if (laneCount < 22) { \ + state[20] = X##sa; \ + if (laneCount >= 21) { \ + output[20] = X##sa; \ + } \ + state[21] = X##se; \ + state[22] = X##si; \ + } \ + else { \ + state[20] = X##sa; \ + output[20] = X##sa; \ + state[21] = X##se; \ + output[21] = X##se; \ + state[22] = X##si; \ + if (laneCount >= 23) { \ + output[22] = X##si; \ + } \ + } \ + } \ + state[23] = X##so; \ + state[24] = X##su; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = X##mi; \ + state[18] = X##mo; \ + output[18] = X##mo; \ + state[19] = X##mu; \ + output[19] = X##mu; \ + state[20] = X##sa; \ + output[20] = X##sa; \ + state[21] = X##se; \ + output[21] = X##se; \ + state[22] = X##si; \ + output[22] = X##si; \ + state[23] = X##so; \ + output[23] = X##so; \ + state[24] = X##su; \ + if (laneCount >= 25) { \ + output[24] = X##su; \ + } \ + } \ + } + +#define output(X, output, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount >= 1) { \ + output[ 0] = X##ba; \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = X##be; \ + if (laneCount >= 3) { \ + output[ 2] = X##bi; \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = X##be; \ + output[ 2] = X##bi; \ + output[ 3] = X##bo; \ + if (laneCount < 6) { \ + if (laneCount >= 5) { \ + output[ 4] = X##bu; \ + } \ + } \ + else { \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + if (laneCount >= 7) { \ + output[ 6] = X##ge; \ + } \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = X##be; \ + output[ 2] = X##bi; \ + output[ 3] = X##bo; \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + output[ 6] = X##ge; \ + output[ 7] = X##gi; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount >= 9) { \ + output[ 8] = X##go; \ + } \ + } \ + else { \ + output[ 8] = X##go; \ + output[ 9] = X##gu; \ + if (laneCount >= 11) { \ + output[10] = X##ka; \ + } \ + } \ + } \ + else { \ + output[ 8] = X##go; \ + output[ 9] = X##gu; \ + output[10] = X##ka; \ + output[11] = X##ke; \ + if (laneCount < 14) { \ + if (laneCount >= 13) { \ + output[12] = X##ki; \ + } \ + } \ + else { \ + output[12] = X##ki; \ + output[13] = X##ko; \ + if (laneCount >= 15) { \ + output[14] = X##ku; \ + } \ + } \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = X##be; \ + output[ 2] = X##bi; \ + output[ 3] = X##bo; \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + output[ 6] = X##ge; \ + output[ 7] = X##gi; \ + output[ 8] = X##go; \ + output[ 9] = X##gu; \ + output[10] = X##ka; \ + output[11] = X##ke; \ + output[12] = X##ki; \ + output[13] = X##ko; \ + output[14] = X##ku; \ + output[15] = X##ma; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount >= 17) { \ + output[16] = X##me; \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = X##mi; \ + if (laneCount >= 19) { \ + output[18] = X##mo; \ + } \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = X##mi; \ + output[18] = X##mo; \ + output[19] = X##mu; \ + if (laneCount < 22) { \ + if (laneCount >= 21) { \ + output[20] = X##sa; \ + } \ + } \ + else { \ + output[20] = X##sa; \ + output[21] = X##se; \ + if (laneCount >= 23) { \ + output[22] = X##si; \ + } \ + } \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = X##mi; \ + output[18] = X##mo; \ + output[19] = X##mu; \ + output[20] = X##sa; \ + output[21] = X##se; \ + output[22] = X##si; \ + output[23] = X##so; \ + if (laneCount >= 25) { \ + output[24] = X##su; \ + } \ + } \ + } + +#define wrapOne(X, input, output, index, name) \ + X##name ^= input[index]; \ + output[index] = X##name; + +#define wrapOneInvert(X, input, output, index, name) \ + X##name ^= input[index]; \ + output[index] = X##name; + +#define unwrapOne(X, input, output, index, name) \ + output[index] = input[index] ^ X##name; \ + X##name ^= output[index]; + +#define unwrapOneInvert(X, input, output, index, name) \ + output[index] = input[index] ^ X##name; \ + X##name ^= output[index]; + +#endif + +#define wrap(X, input, output, laneCount, trailingBits) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount < 1) { \ + X##ba ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + X##be ^= trailingBits; \ + } \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + wrapOneInvert(X, input, output, 1, be) \ + if (laneCount < 3) { \ + X##bi ^= trailingBits; \ + } \ + else { \ + wrapOneInvert(X, input, output, 2, bi) \ + X##bo ^= trailingBits; \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + wrapOneInvert(X, input, output, 1, be) \ + wrapOneInvert(X, input, output, 2, bi) \ + wrapOne(X, input, output, 3, bo) \ + if (laneCount < 6) { \ + if (laneCount < 5) { \ + X##bu ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 4, bu) \ + X##ga ^= trailingBits; \ + } \ + } \ + else { \ + wrapOne(X, input, output, 4, bu) \ + wrapOne(X, input, output, 5, ga) \ + if (laneCount < 7) { \ + X##ge ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 6, ge) \ + X##gi ^= trailingBits; \ + } \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + wrapOneInvert(X, input, output, 1, be) \ + wrapOneInvert(X, input, output, 2, bi) \ + wrapOne(X, input, output, 3, bo) \ + wrapOne(X, input, output, 4, bu) \ + wrapOne(X, input, output, 5, ga) \ + wrapOne(X, input, output, 6, ge) \ + wrapOne(X, input, output, 7, gi) \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount < 9) { \ + X##go ^= trailingBits; \ + } \ + else { \ + wrapOneInvert(X, input, output, 8, go) \ + X##gu ^= trailingBits; \ + } \ + } \ + else { \ + wrapOneInvert(X, input, output, 8, go) \ + wrapOne(X, input, output, 9, gu) \ + if (laneCount < 11) { \ + X##ka ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 10, ka) \ + X##ke ^= trailingBits; \ + } \ + } \ + } \ + else { \ + wrapOneInvert(X, input, output, 8, go) \ + wrapOne(X, input, output, 9, gu) \ + wrapOne(X, input, output, 10, ka) \ + wrapOne(X, input, output, 11, ke) \ + if (laneCount < 14) { \ + if (laneCount < 13) { \ + X##ki ^= trailingBits; \ + } \ + else { \ + wrapOneInvert(X, input, output, 12, ki) \ + X##ko ^= trailingBits; \ + } \ + } \ + else { \ + wrapOneInvert(X, input, output, 12, ki) \ + wrapOne(X, input, output, 13, ko) \ + if (laneCount < 15) { \ + X##ku ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 14, ku) \ + X##ma ^= trailingBits; \ + } \ + } \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + wrapOneInvert(X, input, output, 1, be) \ + wrapOneInvert(X, input, output, 2, bi) \ + wrapOne(X, input, output, 3, bo) \ + wrapOne(X, input, output, 4, bu) \ + wrapOne(X, input, output, 5, ga) \ + wrapOne(X, input, output, 6, ge) \ + wrapOne(X, input, output, 7, gi) \ + wrapOneInvert(X, input, output, 8, go) \ + wrapOne(X, input, output, 9, gu) \ + wrapOne(X, input, output, 10, ka) \ + wrapOne(X, input, output, 11, ke) \ + wrapOneInvert(X, input, output, 12, ki) \ + wrapOne(X, input, output, 13, ko) \ + wrapOne(X, input, output, 14, ku) \ + wrapOne(X, input, output, 15, ma) \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount < 17) { \ + X##me ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 16, me) \ + X##mi ^= trailingBits; \ + } \ + } \ + else { \ + wrapOne(X, input, output, 16, me) \ + wrapOneInvert(X, input, output, 17, mi) \ + if (laneCount < 19) { \ + X##mo ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 18, mo) \ + X##mu ^= trailingBits; \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 16, me) \ + wrapOneInvert(X, input, output, 17, mi) \ + wrapOne(X, input, output, 18, mo) \ + wrapOne(X, input, output, 19, mu) \ + if (laneCount < 22) { \ + if (laneCount < 21) { \ + X##sa ^= trailingBits; \ + } \ + else { \ + wrapOneInvert(X, input, output, 20, sa) \ + X##se ^= trailingBits; \ + } \ + } \ + else { \ + wrapOneInvert(X, input, output, 20, sa) \ + wrapOne(X, input, output, 21, se) \ + if (laneCount < 23) { \ + X##si ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 22, si) \ + X##so ^= trailingBits; \ + } \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 16, me) \ + wrapOneInvert(X, input, output, 17, mi) \ + wrapOne(X, input, output, 18, mo) \ + wrapOne(X, input, output, 19, mu) \ + wrapOneInvert(X, input, output, 20, sa) \ + wrapOne(X, input, output, 21, se) \ + wrapOne(X, input, output, 22, si) \ + wrapOne(X, input, output, 23, so) \ + if (laneCount < 25) { \ + X##su ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 24, su) \ + } \ + } \ + } + +#define unwrap(X, input, output, laneCount, trailingBits) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount < 1) { \ + X##ba ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + X##be ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + unwrapOneInvert(X, input, output, 1, be) \ + if (laneCount < 3) { \ + X##bi ^= trailingBits; \ + } \ + else { \ + unwrapOneInvert(X, input, output, 2, bi) \ + X##bo ^= trailingBits; \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + unwrapOneInvert(X, input, output, 1, be) \ + unwrapOneInvert(X, input, output, 2, bi) \ + unwrapOne(X, input, output, 3, bo) \ + if (laneCount < 6) { \ + if (laneCount < 5) { \ + X##bu ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 4, bu) \ + X##ga ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 4, bu) \ + unwrapOne(X, input, output, 5, ga) \ + if (laneCount < 7) { \ + X##ge ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 6, ge) \ + X##gi ^= trailingBits; \ + } \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + unwrapOneInvert(X, input, output, 1, be) \ + unwrapOneInvert(X, input, output, 2, bi) \ + unwrapOne(X, input, output, 3, bo) \ + unwrapOne(X, input, output, 4, bu) \ + unwrapOne(X, input, output, 5, ga) \ + unwrapOne(X, input, output, 6, ge) \ + unwrapOne(X, input, output, 7, gi) \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount < 9) { \ + X##go ^= trailingBits; \ + } \ + else { \ + unwrapOneInvert(X, input, output, 8, go) \ + X##gu ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOneInvert(X, input, output, 8, go) \ + unwrapOne(X, input, output, 9, gu) \ + if (laneCount < 11) { \ + X##ka ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 10, ka) \ + X##ke ^= trailingBits; \ + } \ + } \ + } \ + else { \ + unwrapOneInvert(X, input, output, 8, go) \ + unwrapOne(X, input, output, 9, gu) \ + unwrapOne(X, input, output, 10, ka) \ + unwrapOne(X, input, output, 11, ke) \ + if (laneCount < 14) { \ + if (laneCount < 13) { \ + X##ki ^= trailingBits; \ + } \ + else { \ + unwrapOneInvert(X, input, output, 12, ki) \ + X##ko ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOneInvert(X, input, output, 12, ki) \ + unwrapOne(X, input, output, 13, ko) \ + if (laneCount < 15) { \ + X##ku ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 14, ku) \ + X##ma ^= trailingBits; \ + } \ + } \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + unwrapOneInvert(X, input, output, 1, be) \ + unwrapOneInvert(X, input, output, 2, bi) \ + unwrapOne(X, input, output, 3, bo) \ + unwrapOne(X, input, output, 4, bu) \ + unwrapOne(X, input, output, 5, ga) \ + unwrapOne(X, input, output, 6, ge) \ + unwrapOne(X, input, output, 7, gi) \ + unwrapOneInvert(X, input, output, 8, go) \ + unwrapOne(X, input, output, 9, gu) \ + unwrapOne(X, input, output, 10, ka) \ + unwrapOne(X, input, output, 11, ke) \ + unwrapOneInvert(X, input, output, 12, ki) \ + unwrapOne(X, input, output, 13, ko) \ + unwrapOne(X, input, output, 14, ku) \ + unwrapOne(X, input, output, 15, ma) \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount < 17) { \ + X##me ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 16, me) \ + X##mi ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 16, me) \ + unwrapOneInvert(X, input, output, 17, mi) \ + if (laneCount < 19) { \ + X##mo ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 18, mo) \ + X##mu ^= trailingBits; \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 16, me) \ + unwrapOneInvert(X, input, output, 17, mi) \ + unwrapOne(X, input, output, 18, mo) \ + unwrapOne(X, input, output, 19, mu) \ + if (laneCount < 22) { \ + if (laneCount < 21) { \ + X##sa ^= trailingBits; \ + } \ + else { \ + unwrapOneInvert(X, input, output, 20, sa) \ + X##se ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOneInvert(X, input, output, 20, sa) \ + unwrapOne(X, input, output, 21, se) \ + if (laneCount < 23) { \ + X##si ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 22, si) \ + X##so ^= trailingBits; \ + } \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 16, me) \ + unwrapOneInvert(X, input, output, 17, mi) \ + unwrapOne(X, input, output, 18, mo) \ + unwrapOne(X, input, output, 19, mu) \ + unwrapOneInvert(X, input, output, 20, sa) \ + unwrapOne(X, input, output, 21, se) \ + unwrapOne(X, input, output, 22, si) \ + unwrapOne(X, input, output, 23, so) \ + if (laneCount < 25) { \ + X##su ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 24, su) \ + } \ + } \ + } diff --git a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h b/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h new file mode 100644 index 0000000..6cf765e --- /dev/null +++ b/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h @@ -0,0 +1,37 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakP_1600_SnP_h_ +#define _KeccakP_1600_SnP_h_ + +/** For the documentation, see SnP-documentation.h. + */ + +#define KeccakP1600_implementation "in-place 32-bit optimized implementation" +#define KeccakP1600_stateSizeInBytes 200 +#define KeccakP1600_stateAlignment 8 + +#define KeccakP1600_StaticInitialize() +void KeccakP1600_Initialize(void *state); +void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); +void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); +void KeccakP1600_Permute_12rounds(void *state); +void KeccakP1600_Permute_24rounds(void *state); +void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); + +#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h b/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h new file mode 100644 index 0000000..889a31a --- /dev/null +++ b/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h @@ -0,0 +1,49 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakP_1600_SnP_h_ +#define _KeccakP_1600_SnP_h_ + +/** For the documentation, see SnP-documentation.h. + */ + +/* #include "brg_endian.h" */ +#include "KeccakP-1600-opt64-config.h" + +#define KeccakP1600_implementation "generic 64-bit optimized implementation (" KeccakP1600_implementation_config ")" +#define KeccakP1600_stateSizeInBytes 200 +#define KeccakP1600_stateAlignment 8 +#define KeccakF1600_FastLoop_supported + +#include <stddef.h> + +#define KeccakP1600_StaticInitialize() +void KeccakP1600_Initialize(void *state); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#define KeccakP1600_AddByte(state, byte, offset) \ + ((unsigned char*)(state))[(offset)] ^= (byte) +#else +void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); +#endif +void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); +void KeccakP1600_Permute_12rounds(void *state); +void KeccakP1600_Permute_24rounds(void *state); +void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); +size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen); + +#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-SnP.h b/Modules/_sha3/kcp/KeccakP-1600-SnP.h new file mode 100644 index 0000000..0b23f09 --- /dev/null +++ b/Modules/_sha3/kcp/KeccakP-1600-SnP.h @@ -0,0 +1,7 @@ +#if KeccakOpt == 64 + #include "KeccakP-1600-SnP-opt64.h" +#elif KeccakOpt == 32 + #include "KeccakP-1600-SnP-opt32.h" +#else + #error "No KeccakOpt" +#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c b/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c new file mode 100644 index 0000000..a2f9ffe --- /dev/null +++ b/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c @@ -0,0 +1,1162 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include <string.h> +/* #include "brg_endian.h" */ +#include "KeccakP-1600-SnP.h" +#include "SnP-Relaned.h" + +typedef unsigned char UINT8; +typedef unsigned int UINT32; +/* WARNING: on 8-bit and 16-bit platforms, this should be replaced by: */ + +/*typedef unsigned long UINT32; */ + + +#define ROL32(a, offset) ((((UINT32)a) << (offset)) ^ (((UINT32)a) >> (32-(offset)))) + +/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ + +#define prepareToBitInterleaving(low, high, temp, temp0, temp1) \ + temp0 = (low); \ + temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ + temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ + temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ + temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ + temp1 = (high); \ + temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); \ + temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ + temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ + temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); + +#define toBitInterleavingAndXOR(low, high, even, odd, temp, temp0, temp1) \ + prepareToBitInterleaving(low, high, temp, temp0, temp1) \ + even ^= (temp0 & 0x0000FFFF) | (temp1 << 16); \ + odd ^= (temp0 >> 16) | (temp1 & 0xFFFF0000); + +#define toBitInterleavingAndAND(low, high, even, odd, temp, temp0, temp1) \ + prepareToBitInterleaving(low, high, temp, temp0, temp1) \ + even &= (temp0 & 0x0000FFFF) | (temp1 << 16); \ + odd &= (temp0 >> 16) | (temp1 & 0xFFFF0000); + +#define toBitInterleavingAndSet(low, high, even, odd, temp, temp0, temp1) \ + prepareToBitInterleaving(low, high, temp, temp0, temp1) \ + even = (temp0 & 0x0000FFFF) | (temp1 << 16); \ + odd = (temp0 >> 16) | (temp1 & 0xFFFF0000); + +/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ + +#define prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ + temp0 = (even); \ + temp1 = (odd); \ + temp = (temp0 & 0x0000FFFF) | (temp1 << 16); \ + temp1 = (temp0 >> 16) | (temp1 & 0xFFFF0000); \ + temp0 = temp; \ + temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ + temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ + temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ + temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ + temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); \ + temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ + temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ + temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); + +#define fromBitInterleaving(even, odd, low, high, temp, temp0, temp1) \ + prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ + low = temp0; \ + high = temp1; + +#define fromBitInterleavingAndXOR(even, odd, lowIn, highIn, lowOut, highOut, temp, temp0, temp1) \ + prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ + lowOut = lowIn ^ temp0; \ + highOut = highIn ^ temp1; + +void KeccakP1600_SetBytesInLaneToZero(void *state, unsigned int lanePosition, unsigned int offset, unsigned int length) +{ + UINT8 laneAsBytes[8]; + UINT32 low, high; + UINT32 temp, temp0, temp1; + UINT32 *stateAsHalfLanes = (UINT32*)state; + + memset(laneAsBytes, 0xFF, offset); + memset(laneAsBytes+offset, 0x00, length); + memset(laneAsBytes+offset+length, 0xFF, 8-offset-length); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + low = *((UINT32*)(laneAsBytes+0)); + high = *((UINT32*)(laneAsBytes+4)); +#else + low = laneAsBytes[0] + | ((UINT32)(laneAsBytes[1]) << 8) + | ((UINT32)(laneAsBytes[2]) << 16) + | ((UINT32)(laneAsBytes[3]) << 24); + high = laneAsBytes[4] + | ((UINT32)(laneAsBytes[5]) << 8) + | ((UINT32)(laneAsBytes[6]) << 16) + | ((UINT32)(laneAsBytes[7]) << 24); +#endif + toBitInterleavingAndAND(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Initialize(void *state) +{ + memset(state, 0, 200); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset) +{ + unsigned int lanePosition = offset/8; + unsigned int offsetInLane = offset%8; + UINT32 low, high; + UINT32 temp, temp0, temp1; + UINT32 *stateAsHalfLanes = (UINT32*)state; + + if (offsetInLane < 4) { + low = (UINT32)byte << (offsetInLane*8); + high = 0; + } + else { + low = 0; + high = (UINT32)byte << ((offsetInLane-4)*8); + } + toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) +{ + UINT8 laneAsBytes[8]; + UINT32 low, high; + UINT32 temp, temp0, temp1; + UINT32 *stateAsHalfLanes = (UINT32*)state; + + memset(laneAsBytes, 0, 8); + memcpy(laneAsBytes+offset, data, length); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + low = *((UINT32*)(laneAsBytes+0)); + high = *((UINT32*)(laneAsBytes+4)); +#else + low = laneAsBytes[0] + | ((UINT32)(laneAsBytes[1]) << 8) + | ((UINT32)(laneAsBytes[2]) << 16) + | ((UINT32)(laneAsBytes[3]) << 24); + high = laneAsBytes[4] + | ((UINT32)(laneAsBytes[5]) << 8) + | ((UINT32)(laneAsBytes[6]) << 16) + | ((UINT32)(laneAsBytes[7]) << 24); +#endif + toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + const UINT32 * pI = (const UINT32 *)data; + UINT32 * pS = (UINT32*)state; + UINT32 t, x0, x1; + int i; + for (i = laneCount-1; i >= 0; --i) { +#ifdef NO_MISALIGNED_ACCESSES + UINT32 low; + UINT32 high; + memcpy(&low, pI++, 4); + memcpy(&high, pI++, 4); + toBitInterleavingAndXOR(low, high, *(pS++), *(pS++), t, x0, x1); +#else + toBitInterleavingAndXOR(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) +#endif + } +#else + unsigned int lanePosition; + for(lanePosition=0; lanePosition<laneCount; lanePosition++) { + UINT8 laneAsBytes[8]; + UINT32 low, high, temp, temp0, temp1; + UINT32 *stateAsHalfLanes; + memcpy(laneAsBytes, data+lanePosition*8, 8); + low = laneAsBytes[0] + | ((UINT32)(laneAsBytes[1]) << 8) + | ((UINT32)(laneAsBytes[2]) << 16) + | ((UINT32)(laneAsBytes[3]) << 24); + high = laneAsBytes[4] + | ((UINT32)(laneAsBytes[5]) << 8) + | ((UINT32)(laneAsBytes[6]) << 16) + | ((UINT32)(laneAsBytes[7]) << 24); + stateAsHalfLanes = (UINT32*)state; + toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_AddBytes(state, data, offset, length, KeccakP1600_AddLanes, KeccakP1600_AddBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) +{ + KeccakP1600_SetBytesInLaneToZero(state, lanePosition, offset, length); + KeccakP1600_AddBytesInLane(state, lanePosition, data, offset, length); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteLanes(void *state, const unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + const UINT32 * pI = (const UINT32 *)data; + UINT32 * pS = (UINT32 *)state; + UINT32 t, x0, x1; + int i; + for (i = laneCount-1; i >= 0; --i) { +#ifdef NO_MISALIGNED_ACCESSES + UINT32 low; + UINT32 high; + memcpy(&low, pI++, 4); + memcpy(&high, pI++, 4); + toBitInterleavingAndSet(low, high, *(pS++), *(pS++), t, x0, x1); +#else + toBitInterleavingAndSet(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) +#endif + } +#else + unsigned int lanePosition; + for(lanePosition=0; lanePosition<laneCount; lanePosition++) { + UINT8 laneAsBytes[8]; + UINT32 low, high, temp, temp0, temp1; + UINT32 *stateAsHalfLanes; + memcpy(laneAsBytes, data+lanePosition*8, 8); + low = laneAsBytes[0] + | ((UINT32)(laneAsBytes[1]) << 8) + | ((UINT32)(laneAsBytes[2]) << 16) + | ((UINT32)(laneAsBytes[3]) << 24); + high = laneAsBytes[4] + | ((UINT32)(laneAsBytes[5]) << 8) + | ((UINT32)(laneAsBytes[6]) << 16) + | ((UINT32)(laneAsBytes[7]) << 24); + stateAsHalfLanes = (UINT32*)state; + toBitInterleavingAndSet(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_OverwriteBytes(state, data, offset, length, KeccakP1600_OverwriteLanes, KeccakP1600_OverwriteBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount) +{ + UINT32 *stateAsHalfLanes = (UINT32*)state; + unsigned int i; + + for(i=0; i<byteCount/8; i++) { + stateAsHalfLanes[i*2+0] = 0; + stateAsHalfLanes[i*2+1] = 0; + } + if (byteCount%8 != 0) + KeccakP1600_SetBytesInLaneToZero(state, byteCount/8, 0, byteCount%8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length) +{ + UINT32 *stateAsHalfLanes = (UINT32*)state; + UINT32 low, high, temp, temp0, temp1; + UINT8 laneAsBytes[8]; + + fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + *((UINT32*)(laneAsBytes+0)) = low; + *((UINT32*)(laneAsBytes+4)) = high; +#else + laneAsBytes[0] = low & 0xFF; + laneAsBytes[1] = (low >> 8) & 0xFF; + laneAsBytes[2] = (low >> 16) & 0xFF; + laneAsBytes[3] = (low >> 24) & 0xFF; + laneAsBytes[4] = high & 0xFF; + laneAsBytes[5] = (high >> 8) & 0xFF; + laneAsBytes[6] = (high >> 16) & 0xFF; + laneAsBytes[7] = (high >> 24) & 0xFF; +#endif + memcpy(data, laneAsBytes+offset, length); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + UINT32 * pI = (UINT32 *)data; + const UINT32 * pS = ( const UINT32 *)state; + UINT32 t, x0, x1; + int i; + for (i = laneCount-1; i >= 0; --i) { +#ifdef NO_MISALIGNED_ACCESSES + UINT32 low; + UINT32 high; + fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); + memcpy(pI++, &low, 4); + memcpy(pI++, &high, 4); +#else + fromBitInterleaving(*(pS++), *(pS++), *(pI++), *(pI++), t, x0, x1) +#endif + } +#else + unsigned int lanePosition; + for(lanePosition=0; lanePosition<laneCount; lanePosition++) { + UINT32 *stateAsHalfLanes = (UINT32*)state; + UINT32 low, high, temp, temp0, temp1; + UINT8 laneAsBytes[8]; + fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1); + laneAsBytes[0] = low & 0xFF; + laneAsBytes[1] = (low >> 8) & 0xFF; + laneAsBytes[2] = (low >> 16) & 0xFF; + laneAsBytes[3] = (low >> 24) & 0xFF; + laneAsBytes[4] = high & 0xFF; + laneAsBytes[5] = (high >> 8) & 0xFF; + laneAsBytes[6] = (high >> 16) & 0xFF; + laneAsBytes[7] = (high >> 24) & 0xFF; + memcpy(data+lanePosition*8, laneAsBytes, 8); + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + UINT32 *stateAsHalfLanes = (UINT32*)state; + UINT32 low, high, temp, temp0, temp1; + UINT8 laneAsBytes[8]; + unsigned int i; + + fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + *((UINT32*)(laneAsBytes+0)) = low; + *((UINT32*)(laneAsBytes+4)) = high; +#else + laneAsBytes[0] = low & 0xFF; + laneAsBytes[1] = (low >> 8) & 0xFF; + laneAsBytes[2] = (low >> 16) & 0xFF; + laneAsBytes[3] = (low >> 24) & 0xFF; + laneAsBytes[4] = high & 0xFF; + laneAsBytes[5] = (high >> 8) & 0xFF; + laneAsBytes[6] = (high >> 16) & 0xFF; + laneAsBytes[7] = (high >> 24) & 0xFF; +#endif + for(i=0; i<length; i++) + output[i] = input[i] ^ laneAsBytes[offset+i]; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + const UINT32 * pI = (const UINT32 *)input; + UINT32 * pO = (UINT32 *)output; + const UINT32 * pS = (const UINT32 *)state; + UINT32 t, x0, x1; + int i; + for (i = laneCount-1; i >= 0; --i) { +#ifdef NO_MISALIGNED_ACCESSES + UINT32 low; + UINT32 high; + fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); + *(pO++) = *(pI++) ^ low; + *(pO++) = *(pI++) ^ high; +#else + fromBitInterleavingAndXOR(*(pS++), *(pS++), *(pI++), *(pI++), *(pO++), *(pO++), t, x0, x1) +#endif + } +#else + unsigned int lanePosition; + for(lanePosition=0; lanePosition<laneCount; lanePosition++) { + UINT32 *stateAsHalfLanes = (UINT32*)state; + UINT32 low, high, temp, temp0, temp1; + UINT8 laneAsBytes[8]; + fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1); + laneAsBytes[0] = low & 0xFF; + laneAsBytes[1] = (low >> 8) & 0xFF; + laneAsBytes[2] = (low >> 16) & 0xFF; + laneAsBytes[3] = (low >> 24) & 0xFF; + laneAsBytes[4] = high & 0xFF; + laneAsBytes[5] = (high >> 8) & 0xFF; + laneAsBytes[6] = (high >> 16) & 0xFF; + laneAsBytes[7] = (high >> 24) & 0xFF; + ((UINT32*)(output+lanePosition*8))[0] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+0)); + ((UINT32*)(output+lanePosition*8))[1] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+4)); + } +#endif +} +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +static const UINT32 KeccakF1600RoundConstants_int2[2*24+1] = +{ + 0x00000001UL, 0x00000000UL, + 0x00000000UL, 0x00000089UL, + 0x00000000UL, 0x8000008bUL, + 0x00000000UL, 0x80008080UL, + 0x00000001UL, 0x0000008bUL, + 0x00000001UL, 0x00008000UL, + 0x00000001UL, 0x80008088UL, + 0x00000001UL, 0x80000082UL, + 0x00000000UL, 0x0000000bUL, + 0x00000000UL, 0x0000000aUL, + 0x00000001UL, 0x00008082UL, + 0x00000000UL, 0x00008003UL, + 0x00000001UL, 0x0000808bUL, + 0x00000001UL, 0x8000000bUL, + 0x00000001UL, 0x8000008aUL, + 0x00000001UL, 0x80000081UL, + 0x00000000UL, 0x80000081UL, + 0x00000000UL, 0x80000008UL, + 0x00000000UL, 0x00000083UL, + 0x00000000UL, 0x80008003UL, + 0x00000001UL, 0x80008088UL, + 0x00000000UL, 0x80000088UL, + 0x00000001UL, 0x00008000UL, + 0x00000000UL, 0x80008082UL, + 0x000000FFUL +}; + +#define KeccakAtoD_round0() \ + Cx = Abu0^Agu0^Aku0^Amu0^Asu0; \ + Du1 = Abe1^Age1^Ake1^Ame1^Ase1; \ + Da0 = Cx^ROL32(Du1, 1); \ + Cz = Abu1^Agu1^Aku1^Amu1^Asu1; \ + Du0 = Abe0^Age0^Ake0^Ame0^Ase0; \ + Da1 = Cz^Du0; \ +\ + Cw = Abi0^Agi0^Aki0^Ami0^Asi0; \ + Do0 = Cw^ROL32(Cz, 1); \ + Cy = Abi1^Agi1^Aki1^Ami1^Asi1; \ + Do1 = Cy^Cx; \ +\ + Cx = Aba0^Aga0^Aka0^Ama0^Asa0; \ + De0 = Cx^ROL32(Cy, 1); \ + Cz = Aba1^Aga1^Aka1^Ama1^Asa1; \ + De1 = Cz^Cw; \ +\ + Cy = Abo1^Ago1^Ako1^Amo1^Aso1; \ + Di0 = Du0^ROL32(Cy, 1); \ + Cw = Abo0^Ago0^Ako0^Amo0^Aso0; \ + Di1 = Du1^Cw; \ +\ + Du0 = Cw^ROL32(Cz, 1); \ + Du1 = Cy^Cx; \ + +#define KeccakAtoD_round1() \ + Cx = Asu0^Agu0^Amu0^Abu1^Aku1; \ + Du1 = Age1^Ame0^Abe0^Ake1^Ase1; \ + Da0 = Cx^ROL32(Du1, 1); \ + Cz = Asu1^Agu1^Amu1^Abu0^Aku0; \ + Du0 = Age0^Ame1^Abe1^Ake0^Ase0; \ + Da1 = Cz^Du0; \ +\ + Cw = Aki1^Asi1^Agi0^Ami1^Abi0; \ + Do0 = Cw^ROL32(Cz, 1); \ + Cy = Aki0^Asi0^Agi1^Ami0^Abi1; \ + Do1 = Cy^Cx; \ +\ + Cx = Aba0^Aka1^Asa0^Aga0^Ama1; \ + De0 = Cx^ROL32(Cy, 1); \ + Cz = Aba1^Aka0^Asa1^Aga1^Ama0; \ + De1 = Cz^Cw; \ +\ + Cy = Amo0^Abo1^Ako0^Aso1^Ago0; \ + Di0 = Du0^ROL32(Cy, 1); \ + Cw = Amo1^Abo0^Ako1^Aso0^Ago1; \ + Di1 = Du1^Cw; \ +\ + Du0 = Cw^ROL32(Cz, 1); \ + Du1 = Cy^Cx; \ + +#define KeccakAtoD_round2() \ + Cx = Aku1^Agu0^Abu1^Asu1^Amu1; \ + Du1 = Ame0^Ake0^Age0^Abe0^Ase1; \ + Da0 = Cx^ROL32(Du1, 1); \ + Cz = Aku0^Agu1^Abu0^Asu0^Amu0; \ + Du0 = Ame1^Ake1^Age1^Abe1^Ase0; \ + Da1 = Cz^Du0; \ +\ + Cw = Agi1^Abi1^Asi1^Ami0^Aki1; \ + Do0 = Cw^ROL32(Cz, 1); \ + Cy = Agi0^Abi0^Asi0^Ami1^Aki0; \ + Do1 = Cy^Cx; \ +\ + Cx = Aba0^Asa1^Ama1^Aka1^Aga1; \ + De0 = Cx^ROL32(Cy, 1); \ + Cz = Aba1^Asa0^Ama0^Aka0^Aga0; \ + De1 = Cz^Cw; \ +\ + Cy = Aso0^Amo0^Ako1^Ago0^Abo0; \ + Di0 = Du0^ROL32(Cy, 1); \ + Cw = Aso1^Amo1^Ako0^Ago1^Abo1; \ + Di1 = Du1^Cw; \ +\ + Du0 = Cw^ROL32(Cz, 1); \ + Du1 = Cy^Cx; \ + +#define KeccakAtoD_round3() \ + Cx = Amu1^Agu0^Asu1^Aku0^Abu0; \ + Du1 = Ake0^Abe1^Ame1^Age0^Ase1; \ + Da0 = Cx^ROL32(Du1, 1); \ + Cz = Amu0^Agu1^Asu0^Aku1^Abu1; \ + Du0 = Ake1^Abe0^Ame0^Age1^Ase0; \ + Da1 = Cz^Du0; \ +\ + Cw = Asi0^Aki0^Abi1^Ami1^Agi1; \ + Do0 = Cw^ROL32(Cz, 1); \ + Cy = Asi1^Aki1^Abi0^Ami0^Agi0; \ + Do1 = Cy^Cx; \ +\ + Cx = Aba0^Ama0^Aga1^Asa1^Aka0; \ + De0 = Cx^ROL32(Cy, 1); \ + Cz = Aba1^Ama1^Aga0^Asa0^Aka1; \ + De1 = Cz^Cw; \ +\ + Cy = Ago1^Aso0^Ako0^Abo0^Amo1; \ + Di0 = Du0^ROL32(Cy, 1); \ + Cw = Ago0^Aso1^Ako1^Abo1^Amo0; \ + Di1 = Du1^Cw; \ +\ + Du0 = Cw^ROL32(Cz, 1); \ + Du1 = Cy^Cx; \ + +void KeccakP1600_Permute_Nrounds(void *state, unsigned int nRounds) +{ + { + UINT32 Da0, De0, Di0, Do0, Du0; + UINT32 Da1, De1, Di1, Do1, Du1; + UINT32 Ca0, Ce0, Ci0, Co0, Cu0; + UINT32 Cx, Cy, Cz, Cw; + #define Ba Ca0 + #define Be Ce0 + #define Bi Ci0 + #define Bo Co0 + #define Bu Cu0 + const UINT32 *pRoundConstants = KeccakF1600RoundConstants_int2+(24-nRounds)*2; + UINT32 *stateAsHalfLanes = (UINT32*)state; + #define Aba0 stateAsHalfLanes[ 0] + #define Aba1 stateAsHalfLanes[ 1] + #define Abe0 stateAsHalfLanes[ 2] + #define Abe1 stateAsHalfLanes[ 3] + #define Abi0 stateAsHalfLanes[ 4] + #define Abi1 stateAsHalfLanes[ 5] + #define Abo0 stateAsHalfLanes[ 6] + #define Abo1 stateAsHalfLanes[ 7] + #define Abu0 stateAsHalfLanes[ 8] + #define Abu1 stateAsHalfLanes[ 9] + #define Aga0 stateAsHalfLanes[10] + #define Aga1 stateAsHalfLanes[11] + #define Age0 stateAsHalfLanes[12] + #define Age1 stateAsHalfLanes[13] + #define Agi0 stateAsHalfLanes[14] + #define Agi1 stateAsHalfLanes[15] + #define Ago0 stateAsHalfLanes[16] + #define Ago1 stateAsHalfLanes[17] + #define Agu0 stateAsHalfLanes[18] + #define Agu1 stateAsHalfLanes[19] + #define Aka0 stateAsHalfLanes[20] + #define Aka1 stateAsHalfLanes[21] + #define Ake0 stateAsHalfLanes[22] + #define Ake1 stateAsHalfLanes[23] + #define Aki0 stateAsHalfLanes[24] + #define Aki1 stateAsHalfLanes[25] + #define Ako0 stateAsHalfLanes[26] + #define Ako1 stateAsHalfLanes[27] + #define Aku0 stateAsHalfLanes[28] + #define Aku1 stateAsHalfLanes[29] + #define Ama0 stateAsHalfLanes[30] + #define Ama1 stateAsHalfLanes[31] + #define Ame0 stateAsHalfLanes[32] + #define Ame1 stateAsHalfLanes[33] + #define Ami0 stateAsHalfLanes[34] + #define Ami1 stateAsHalfLanes[35] + #define Amo0 stateAsHalfLanes[36] + #define Amo1 stateAsHalfLanes[37] + #define Amu0 stateAsHalfLanes[38] + #define Amu1 stateAsHalfLanes[39] + #define Asa0 stateAsHalfLanes[40] + #define Asa1 stateAsHalfLanes[41] + #define Ase0 stateAsHalfLanes[42] + #define Ase1 stateAsHalfLanes[43] + #define Asi0 stateAsHalfLanes[44] + #define Asi1 stateAsHalfLanes[45] + #define Aso0 stateAsHalfLanes[46] + #define Aso1 stateAsHalfLanes[47] + #define Asu0 stateAsHalfLanes[48] + #define Asu1 stateAsHalfLanes[49] + + do + { + /* --- Code for 4 rounds */ + + /* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ + + KeccakAtoD_round0(); + + Ba = (Aba0^Da0); + Be = ROL32((Age0^De0), 22); + Bi = ROL32((Aki1^Di1), 22); + Bo = ROL32((Amo1^Do1), 11); + Bu = ROL32((Asu0^Du0), 7); + Aba0 = Ba ^((~Be)& Bi ); + Aba0 ^= *(pRoundConstants++); + Age0 = Be ^((~Bi)& Bo ); + Aki1 = Bi ^((~Bo)& Bu ); + Amo1 = Bo ^((~Bu)& Ba ); + Asu0 = Bu ^((~Ba)& Be ); + + Ba = (Aba1^Da1); + Be = ROL32((Age1^De1), 22); + Bi = ROL32((Aki0^Di0), 21); + Bo = ROL32((Amo0^Do0), 10); + Bu = ROL32((Asu1^Du1), 7); + Aba1 = Ba ^((~Be)& Bi ); + Aba1 ^= *(pRoundConstants++); + Age1 = Be ^((~Bi)& Bo ); + Aki0 = Bi ^((~Bo)& Bu ); + Amo0 = Bo ^((~Bu)& Ba ); + Asu1 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Aka1^Da1), 2); + Bo = ROL32((Ame1^De1), 23); + Bu = ROL32((Asi1^Di1), 31); + Ba = ROL32((Abo0^Do0), 14); + Be = ROL32((Agu0^Du0), 10); + Aka1 = Ba ^((~Be)& Bi ); + Ame1 = Be ^((~Bi)& Bo ); + Asi1 = Bi ^((~Bo)& Bu ); + Abo0 = Bo ^((~Bu)& Ba ); + Agu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Aka0^Da0), 1); + Bo = ROL32((Ame0^De0), 22); + Bu = ROL32((Asi0^Di0), 30); + Ba = ROL32((Abo1^Do1), 14); + Be = ROL32((Agu1^Du1), 10); + Aka0 = Ba ^((~Be)& Bi ); + Ame0 = Be ^((~Bi)& Bo ); + Asi0 = Bi ^((~Bo)& Bu ); + Abo1 = Bo ^((~Bu)& Ba ); + Agu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Asa0^Da0), 9); + Ba = ROL32((Abe1^De1), 1); + Be = ROL32((Agi0^Di0), 3); + Bi = ROL32((Ako1^Do1), 13); + Bo = ROL32((Amu0^Du0), 4); + Asa0 = Ba ^((~Be)& Bi ); + Abe1 = Be ^((~Bi)& Bo ); + Agi0 = Bi ^((~Bo)& Bu ); + Ako1 = Bo ^((~Bu)& Ba ); + Amu0 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Asa1^Da1), 9); + Ba = (Abe0^De0); + Be = ROL32((Agi1^Di1), 3); + Bi = ROL32((Ako0^Do0), 12); + Bo = ROL32((Amu1^Du1), 4); + Asa1 = Ba ^((~Be)& Bi ); + Abe0 = Be ^((~Bi)& Bo ); + Agi1 = Bi ^((~Bo)& Bu ); + Ako0 = Bo ^((~Bu)& Ba ); + Amu1 = Bu ^((~Ba)& Be ); + + Be = ROL32((Aga0^Da0), 18); + Bi = ROL32((Ake0^De0), 5); + Bo = ROL32((Ami1^Di1), 8); + Bu = ROL32((Aso0^Do0), 28); + Ba = ROL32((Abu1^Du1), 14); + Aga0 = Ba ^((~Be)& Bi ); + Ake0 = Be ^((~Bi)& Bo ); + Ami1 = Bi ^((~Bo)& Bu ); + Aso0 = Bo ^((~Bu)& Ba ); + Abu1 = Bu ^((~Ba)& Be ); + + Be = ROL32((Aga1^Da1), 18); + Bi = ROL32((Ake1^De1), 5); + Bo = ROL32((Ami0^Di0), 7); + Bu = ROL32((Aso1^Do1), 28); + Ba = ROL32((Abu0^Du0), 13); + Aga1 = Ba ^((~Be)& Bi ); + Ake1 = Be ^((~Bi)& Bo ); + Ami0 = Bi ^((~Bo)& Bu ); + Aso1 = Bo ^((~Bu)& Ba ); + Abu0 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Ama1^Da1), 21); + Bu = ROL32((Ase0^De0), 1); + Ba = ROL32((Abi0^Di0), 31); + Be = ROL32((Ago1^Do1), 28); + Bi = ROL32((Aku1^Du1), 20); + Ama1 = Ba ^((~Be)& Bi ); + Ase0 = Be ^((~Bi)& Bo ); + Abi0 = Bi ^((~Bo)& Bu ); + Ago1 = Bo ^((~Bu)& Ba ); + Aku1 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Ama0^Da0), 20); + Bu = ROL32((Ase1^De1), 1); + Ba = ROL32((Abi1^Di1), 31); + Be = ROL32((Ago0^Do0), 27); + Bi = ROL32((Aku0^Du0), 19); + Ama0 = Ba ^((~Be)& Bi ); + Ase1 = Be ^((~Bi)& Bo ); + Abi1 = Bi ^((~Bo)& Bu ); + Ago0 = Bo ^((~Bu)& Ba ); + Aku0 = Bu ^((~Ba)& Be ); + + KeccakAtoD_round1(); + + Ba = (Aba0^Da0); + Be = ROL32((Ame1^De0), 22); + Bi = ROL32((Agi1^Di1), 22); + Bo = ROL32((Aso1^Do1), 11); + Bu = ROL32((Aku1^Du0), 7); + Aba0 = Ba ^((~Be)& Bi ); + Aba0 ^= *(pRoundConstants++); + Ame1 = Be ^((~Bi)& Bo ); + Agi1 = Bi ^((~Bo)& Bu ); + Aso1 = Bo ^((~Bu)& Ba ); + Aku1 = Bu ^((~Ba)& Be ); + + Ba = (Aba1^Da1); + Be = ROL32((Ame0^De1), 22); + Bi = ROL32((Agi0^Di0), 21); + Bo = ROL32((Aso0^Do0), 10); + Bu = ROL32((Aku0^Du1), 7); + Aba1 = Ba ^((~Be)& Bi ); + Aba1 ^= *(pRoundConstants++); + Ame0 = Be ^((~Bi)& Bo ); + Agi0 = Bi ^((~Bo)& Bu ); + Aso0 = Bo ^((~Bu)& Ba ); + Aku0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Asa1^Da1), 2); + Bo = ROL32((Ake1^De1), 23); + Bu = ROL32((Abi1^Di1), 31); + Ba = ROL32((Amo1^Do0), 14); + Be = ROL32((Agu0^Du0), 10); + Asa1 = Ba ^((~Be)& Bi ); + Ake1 = Be ^((~Bi)& Bo ); + Abi1 = Bi ^((~Bo)& Bu ); + Amo1 = Bo ^((~Bu)& Ba ); + Agu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Asa0^Da0), 1); + Bo = ROL32((Ake0^De0), 22); + Bu = ROL32((Abi0^Di0), 30); + Ba = ROL32((Amo0^Do1), 14); + Be = ROL32((Agu1^Du1), 10); + Asa0 = Ba ^((~Be)& Bi ); + Ake0 = Be ^((~Bi)& Bo ); + Abi0 = Bi ^((~Bo)& Bu ); + Amo0 = Bo ^((~Bu)& Ba ); + Agu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Ama1^Da0), 9); + Ba = ROL32((Age1^De1), 1); + Be = ROL32((Asi1^Di0), 3); + Bi = ROL32((Ako0^Do1), 13); + Bo = ROL32((Abu1^Du0), 4); + Ama1 = Ba ^((~Be)& Bi ); + Age1 = Be ^((~Bi)& Bo ); + Asi1 = Bi ^((~Bo)& Bu ); + Ako0 = Bo ^((~Bu)& Ba ); + Abu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Ama0^Da1), 9); + Ba = (Age0^De0); + Be = ROL32((Asi0^Di1), 3); + Bi = ROL32((Ako1^Do0), 12); + Bo = ROL32((Abu0^Du1), 4); + Ama0 = Ba ^((~Be)& Bi ); + Age0 = Be ^((~Bi)& Bo ); + Asi0 = Bi ^((~Bo)& Bu ); + Ako1 = Bo ^((~Bu)& Ba ); + Abu0 = Bu ^((~Ba)& Be ); + + Be = ROL32((Aka1^Da0), 18); + Bi = ROL32((Abe1^De0), 5); + Bo = ROL32((Ami0^Di1), 8); + Bu = ROL32((Ago1^Do0), 28); + Ba = ROL32((Asu1^Du1), 14); + Aka1 = Ba ^((~Be)& Bi ); + Abe1 = Be ^((~Bi)& Bo ); + Ami0 = Bi ^((~Bo)& Bu ); + Ago1 = Bo ^((~Bu)& Ba ); + Asu1 = Bu ^((~Ba)& Be ); + + Be = ROL32((Aka0^Da1), 18); + Bi = ROL32((Abe0^De1), 5); + Bo = ROL32((Ami1^Di0), 7); + Bu = ROL32((Ago0^Do1), 28); + Ba = ROL32((Asu0^Du0), 13); + Aka0 = Ba ^((~Be)& Bi ); + Abe0 = Be ^((~Bi)& Bo ); + Ami1 = Bi ^((~Bo)& Bu ); + Ago0 = Bo ^((~Bu)& Ba ); + Asu0 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Aga1^Da1), 21); + Bu = ROL32((Ase0^De0), 1); + Ba = ROL32((Aki1^Di0), 31); + Be = ROL32((Abo1^Do1), 28); + Bi = ROL32((Amu1^Du1), 20); + Aga1 = Ba ^((~Be)& Bi ); + Ase0 = Be ^((~Bi)& Bo ); + Aki1 = Bi ^((~Bo)& Bu ); + Abo1 = Bo ^((~Bu)& Ba ); + Amu1 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Aga0^Da0), 20); + Bu = ROL32((Ase1^De1), 1); + Ba = ROL32((Aki0^Di1), 31); + Be = ROL32((Abo0^Do0), 27); + Bi = ROL32((Amu0^Du0), 19); + Aga0 = Ba ^((~Be)& Bi ); + Ase1 = Be ^((~Bi)& Bo ); + Aki0 = Bi ^((~Bo)& Bu ); + Abo0 = Bo ^((~Bu)& Ba ); + Amu0 = Bu ^((~Ba)& Be ); + + KeccakAtoD_round2(); + + Ba = (Aba0^Da0); + Be = ROL32((Ake1^De0), 22); + Bi = ROL32((Asi0^Di1), 22); + Bo = ROL32((Ago0^Do1), 11); + Bu = ROL32((Amu1^Du0), 7); + Aba0 = Ba ^((~Be)& Bi ); + Aba0 ^= *(pRoundConstants++); + Ake1 = Be ^((~Bi)& Bo ); + Asi0 = Bi ^((~Bo)& Bu ); + Ago0 = Bo ^((~Bu)& Ba ); + Amu1 = Bu ^((~Ba)& Be ); + + Ba = (Aba1^Da1); + Be = ROL32((Ake0^De1), 22); + Bi = ROL32((Asi1^Di0), 21); + Bo = ROL32((Ago1^Do0), 10); + Bu = ROL32((Amu0^Du1), 7); + Aba1 = Ba ^((~Be)& Bi ); + Aba1 ^= *(pRoundConstants++); + Ake0 = Be ^((~Bi)& Bo ); + Asi1 = Bi ^((~Bo)& Bu ); + Ago1 = Bo ^((~Bu)& Ba ); + Amu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Ama0^Da1), 2); + Bo = ROL32((Abe0^De1), 23); + Bu = ROL32((Aki0^Di1), 31); + Ba = ROL32((Aso1^Do0), 14); + Be = ROL32((Agu0^Du0), 10); + Ama0 = Ba ^((~Be)& Bi ); + Abe0 = Be ^((~Bi)& Bo ); + Aki0 = Bi ^((~Bo)& Bu ); + Aso1 = Bo ^((~Bu)& Ba ); + Agu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Ama1^Da0), 1); + Bo = ROL32((Abe1^De0), 22); + Bu = ROL32((Aki1^Di0), 30); + Ba = ROL32((Aso0^Do1), 14); + Be = ROL32((Agu1^Du1), 10); + Ama1 = Ba ^((~Be)& Bi ); + Abe1 = Be ^((~Bi)& Bo ); + Aki1 = Bi ^((~Bo)& Bu ); + Aso0 = Bo ^((~Bu)& Ba ); + Agu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Aga1^Da0), 9); + Ba = ROL32((Ame0^De1), 1); + Be = ROL32((Abi1^Di0), 3); + Bi = ROL32((Ako1^Do1), 13); + Bo = ROL32((Asu1^Du0), 4); + Aga1 = Ba ^((~Be)& Bi ); + Ame0 = Be ^((~Bi)& Bo ); + Abi1 = Bi ^((~Bo)& Bu ); + Ako1 = Bo ^((~Bu)& Ba ); + Asu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Aga0^Da1), 9); + Ba = (Ame1^De0); + Be = ROL32((Abi0^Di1), 3); + Bi = ROL32((Ako0^Do0), 12); + Bo = ROL32((Asu0^Du1), 4); + Aga0 = Ba ^((~Be)& Bi ); + Ame1 = Be ^((~Bi)& Bo ); + Abi0 = Bi ^((~Bo)& Bu ); + Ako0 = Bo ^((~Bu)& Ba ); + Asu0 = Bu ^((~Ba)& Be ); + + Be = ROL32((Asa1^Da0), 18); + Bi = ROL32((Age1^De0), 5); + Bo = ROL32((Ami1^Di1), 8); + Bu = ROL32((Abo1^Do0), 28); + Ba = ROL32((Aku0^Du1), 14); + Asa1 = Ba ^((~Be)& Bi ); + Age1 = Be ^((~Bi)& Bo ); + Ami1 = Bi ^((~Bo)& Bu ); + Abo1 = Bo ^((~Bu)& Ba ); + Aku0 = Bu ^((~Ba)& Be ); + + Be = ROL32((Asa0^Da1), 18); + Bi = ROL32((Age0^De1), 5); + Bo = ROL32((Ami0^Di0), 7); + Bu = ROL32((Abo0^Do1), 28); + Ba = ROL32((Aku1^Du0), 13); + Asa0 = Ba ^((~Be)& Bi ); + Age0 = Be ^((~Bi)& Bo ); + Ami0 = Bi ^((~Bo)& Bu ); + Abo0 = Bo ^((~Bu)& Ba ); + Aku1 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Aka0^Da1), 21); + Bu = ROL32((Ase0^De0), 1); + Ba = ROL32((Agi1^Di0), 31); + Be = ROL32((Amo0^Do1), 28); + Bi = ROL32((Abu0^Du1), 20); + Aka0 = Ba ^((~Be)& Bi ); + Ase0 = Be ^((~Bi)& Bo ); + Agi1 = Bi ^((~Bo)& Bu ); + Amo0 = Bo ^((~Bu)& Ba ); + Abu0 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Aka1^Da0), 20); + Bu = ROL32((Ase1^De1), 1); + Ba = ROL32((Agi0^Di1), 31); + Be = ROL32((Amo1^Do0), 27); + Bi = ROL32((Abu1^Du0), 19); + Aka1 = Ba ^((~Be)& Bi ); + Ase1 = Be ^((~Bi)& Bo ); + Agi0 = Bi ^((~Bo)& Bu ); + Amo1 = Bo ^((~Bu)& Ba ); + Abu1 = Bu ^((~Ba)& Be ); + + KeccakAtoD_round3(); + + Ba = (Aba0^Da0); + Be = ROL32((Abe0^De0), 22); + Bi = ROL32((Abi0^Di1), 22); + Bo = ROL32((Abo0^Do1), 11); + Bu = ROL32((Abu0^Du0), 7); + Aba0 = Ba ^((~Be)& Bi ); + Aba0 ^= *(pRoundConstants++); + Abe0 = Be ^((~Bi)& Bo ); + Abi0 = Bi ^((~Bo)& Bu ); + Abo0 = Bo ^((~Bu)& Ba ); + Abu0 = Bu ^((~Ba)& Be ); + + Ba = (Aba1^Da1); + Be = ROL32((Abe1^De1), 22); + Bi = ROL32((Abi1^Di0), 21); + Bo = ROL32((Abo1^Do0), 10); + Bu = ROL32((Abu1^Du1), 7); + Aba1 = Ba ^((~Be)& Bi ); + Aba1 ^= *(pRoundConstants++); + Abe1 = Be ^((~Bi)& Bo ); + Abi1 = Bi ^((~Bo)& Bu ); + Abo1 = Bo ^((~Bu)& Ba ); + Abu1 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Aga0^Da1), 2); + Bo = ROL32((Age0^De1), 23); + Bu = ROL32((Agi0^Di1), 31); + Ba = ROL32((Ago0^Do0), 14); + Be = ROL32((Agu0^Du0), 10); + Aga0 = Ba ^((~Be)& Bi ); + Age0 = Be ^((~Bi)& Bo ); + Agi0 = Bi ^((~Bo)& Bu ); + Ago0 = Bo ^((~Bu)& Ba ); + Agu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Aga1^Da0), 1); + Bo = ROL32((Age1^De0), 22); + Bu = ROL32((Agi1^Di0), 30); + Ba = ROL32((Ago1^Do1), 14); + Be = ROL32((Agu1^Du1), 10); + Aga1 = Ba ^((~Be)& Bi ); + Age1 = Be ^((~Bi)& Bo ); + Agi1 = Bi ^((~Bo)& Bu ); + Ago1 = Bo ^((~Bu)& Ba ); + Agu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Aka0^Da0), 9); + Ba = ROL32((Ake0^De1), 1); + Be = ROL32((Aki0^Di0), 3); + Bi = ROL32((Ako0^Do1), 13); + Bo = ROL32((Aku0^Du0), 4); + Aka0 = Ba ^((~Be)& Bi ); + Ake0 = Be ^((~Bi)& Bo ); + Aki0 = Bi ^((~Bo)& Bu ); + Ako0 = Bo ^((~Bu)& Ba ); + Aku0 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Aka1^Da1), 9); + Ba = (Ake1^De0); + Be = ROL32((Aki1^Di1), 3); + Bi = ROL32((Ako1^Do0), 12); + Bo = ROL32((Aku1^Du1), 4); + Aka1 = Ba ^((~Be)& Bi ); + Ake1 = Be ^((~Bi)& Bo ); + Aki1 = Bi ^((~Bo)& Bu ); + Ako1 = Bo ^((~Bu)& Ba ); + Aku1 = Bu ^((~Ba)& Be ); + + Be = ROL32((Ama0^Da0), 18); + Bi = ROL32((Ame0^De0), 5); + Bo = ROL32((Ami0^Di1), 8); + Bu = ROL32((Amo0^Do0), 28); + Ba = ROL32((Amu0^Du1), 14); + Ama0 = Ba ^((~Be)& Bi ); + Ame0 = Be ^((~Bi)& Bo ); + Ami0 = Bi ^((~Bo)& Bu ); + Amo0 = Bo ^((~Bu)& Ba ); + Amu0 = Bu ^((~Ba)& Be ); + + Be = ROL32((Ama1^Da1), 18); + Bi = ROL32((Ame1^De1), 5); + Bo = ROL32((Ami1^Di0), 7); + Bu = ROL32((Amo1^Do1), 28); + Ba = ROL32((Amu1^Du0), 13); + Ama1 = Ba ^((~Be)& Bi ); + Ame1 = Be ^((~Bi)& Bo ); + Ami1 = Bi ^((~Bo)& Bu ); + Amo1 = Bo ^((~Bu)& Ba ); + Amu1 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Asa0^Da1), 21); + Bu = ROL32((Ase0^De0), 1); + Ba = ROL32((Asi0^Di0), 31); + Be = ROL32((Aso0^Do1), 28); + Bi = ROL32((Asu0^Du1), 20); + Asa0 = Ba ^((~Be)& Bi ); + Ase0 = Be ^((~Bi)& Bo ); + Asi0 = Bi ^((~Bo)& Bu ); + Aso0 = Bo ^((~Bu)& Ba ); + Asu0 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Asa1^Da0), 20); + Bu = ROL32((Ase1^De1), 1); + Ba = ROL32((Asi1^Di1), 31); + Be = ROL32((Aso1^Do0), 27); + Bi = ROL32((Asu1^Du0), 19); + Asa1 = Ba ^((~Be)& Bi ); + Ase1 = Be ^((~Bi)& Bo ); + Asi1 = Bi ^((~Bo)& Bu ); + Aso1 = Bo ^((~Bu)& Ba ); + Asu1 = Bu ^((~Ba)& Be ); + } + while ( *pRoundConstants != 0xFF ); + + #undef Aba0 + #undef Aba1 + #undef Abe0 + #undef Abe1 + #undef Abi0 + #undef Abi1 + #undef Abo0 + #undef Abo1 + #undef Abu0 + #undef Abu1 + #undef Aga0 + #undef Aga1 + #undef Age0 + #undef Age1 + #undef Agi0 + #undef Agi1 + #undef Ago0 + #undef Ago1 + #undef Agu0 + #undef Agu1 + #undef Aka0 + #undef Aka1 + #undef Ake0 + #undef Ake1 + #undef Aki0 + #undef Aki1 + #undef Ako0 + #undef Ako1 + #undef Aku0 + #undef Aku1 + #undef Ama0 + #undef Ama1 + #undef Ame0 + #undef Ame1 + #undef Ami0 + #undef Ami1 + #undef Amo0 + #undef Amo1 + #undef Amu0 + #undef Amu1 + #undef Asa0 + #undef Asa1 + #undef Ase0 + #undef Ase1 + #undef Asi0 + #undef Asi1 + #undef Aso0 + #undef Aso1 + #undef Asu0 + #undef Asu1 + } +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Permute_12rounds(void *state) +{ + KeccakP1600_Permute_Nrounds(state, 12); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Permute_24rounds(void *state) +{ + KeccakP1600_Permute_Nrounds(state, 24); +} diff --git a/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h b/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h new file mode 100644 index 0000000..9501c64 --- /dev/null +++ b/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h @@ -0,0 +1,3 @@ +#define KeccakP1600_implementation_config "lane complementing, all rounds unrolled" +#define KeccakP1600_fullUnrolling +#define KeccakP1600_useLaneComplementing diff --git a/Modules/_sha3/kcp/KeccakP-1600-opt64.c b/Modules/_sha3/kcp/KeccakP-1600-opt64.c new file mode 100644 index 0000000..c90010d --- /dev/null +++ b/Modules/_sha3/kcp/KeccakP-1600-opt64.c @@ -0,0 +1,474 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include <string.h> +#include <stdlib.h> +/* #include "brg_endian.h" */ +#include "KeccakP-1600-opt64-config.h" + +#if NOT_PYTHON +typedef unsigned char UINT8; +/* typedef unsigned long long int UINT64; */ +#endif + +#if defined(KeccakP1600_useLaneComplementing) +#define UseBebigokimisa +#endif + +#if defined(_MSC_VER) +#define ROL64(a, offset) _rotl64(a, offset) +#elif defined(KeccakP1600_useSHLD) + #define ROL64(x,N) ({ \ + register UINT64 __out; \ + register UINT64 __in = x; \ + __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \ + __out; \ + }) +#else +#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) +#endif + +#include "KeccakP-1600-64.macros" +#ifdef KeccakP1600_fullUnrolling +#define FullUnrolling +#else +#define Unrolling KeccakP1600_unrolling +#endif +#include "KeccakP-1600-unrolling.macros" +#include "SnP-Relaned.h" + +static const UINT64 KeccakF1600RoundConstants[24] = { + 0x0000000000000001ULL, + 0x0000000000008082ULL, + 0x800000000000808aULL, + 0x8000000080008000ULL, + 0x000000000000808bULL, + 0x0000000080000001ULL, + 0x8000000080008081ULL, + 0x8000000000008009ULL, + 0x000000000000008aULL, + 0x0000000000000088ULL, + 0x0000000080008009ULL, + 0x000000008000000aULL, + 0x000000008000808bULL, + 0x800000000000008bULL, + 0x8000000000008089ULL, + 0x8000000000008003ULL, + 0x8000000000008002ULL, + 0x8000000000000080ULL, + 0x000000000000800aULL, + 0x800000008000000aULL, + 0x8000000080008081ULL, + 0x8000000000008080ULL, + 0x0000000080000001ULL, + 0x8000000080008008ULL }; + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Initialize(void *state) +{ + memset(state, 0, 200); +#ifdef KeccakP1600_useLaneComplementing + ((UINT64*)state)[ 1] = ~(UINT64)0; + ((UINT64*)state)[ 2] = ~(UINT64)0; + ((UINT64*)state)[ 8] = ~(UINT64)0; + ((UINT64*)state)[12] = ~(UINT64)0; + ((UINT64*)state)[17] = ~(UINT64)0; + ((UINT64*)state)[20] = ~(UINT64)0; +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + UINT64 lane; + if (length == 0) + return; + if (length == 1) + lane = data[0]; + else { + lane = 0; + memcpy(&lane, data, length); + } + lane <<= offset*8; +#else + UINT64 lane = 0; + unsigned int i; + for(i=0; i<length; i++) + lane |= ((UINT64)data[i]) << ((i+offset)*8); +#endif + ((UINT64*)state)[lanePosition] ^= lane; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + unsigned int i = 0; +#ifdef NO_MISALIGNED_ACCESSES + /* If either pointer is misaligned, fall back to byte-wise xor. */ + + if (((((uintptr_t)state) & 7) != 0) || ((((uintptr_t)data) & 7) != 0)) { + for (i = 0; i < laneCount * 8; i++) { + ((unsigned char*)state)[i] ^= data[i]; + } + } + else +#endif + { + /* Otherwise... */ + + for( ; (i+8)<=laneCount; i+=8) { + ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0]; + ((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1]; + ((UINT64*)state)[i+2] ^= ((UINT64*)data)[i+2]; + ((UINT64*)state)[i+3] ^= ((UINT64*)data)[i+3]; + ((UINT64*)state)[i+4] ^= ((UINT64*)data)[i+4]; + ((UINT64*)state)[i+5] ^= ((UINT64*)data)[i+5]; + ((UINT64*)state)[i+6] ^= ((UINT64*)data)[i+6]; + ((UINT64*)state)[i+7] ^= ((UINT64*)data)[i+7]; + } + for( ; (i+4)<=laneCount; i+=4) { + ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0]; + ((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1]; + ((UINT64*)state)[i+2] ^= ((UINT64*)data)[i+2]; + ((UINT64*)state)[i+3] ^= ((UINT64*)data)[i+3]; + } + for( ; (i+2)<=laneCount; i+=2) { + ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0]; + ((UINT64*)state)[i+1] ^= ((UINT64*)data)[i+1]; + } + if (i<laneCount) { + ((UINT64*)state)[i+0] ^= ((UINT64*)data)[i+0]; + } + } +#else + unsigned int i; + UINT8 *curData = data; + for(i=0; i<laneCount; i++, curData+=8) { + UINT64 lane = (UINT64)curData[0] + | ((UINT64)curData[1] << 8) + | ((UINT64)curData[2] << 16) + | ((UINT64)curData[3] << 24) + | ((UINT64)curData[4] <<32) + | ((UINT64)curData[5] << 40) + | ((UINT64)curData[6] << 48) + | ((UINT64)curData[7] << 56); + ((UINT64*)state)[i] ^= lane; + } +#endif +} + +/* ---------------------------------------------------------------- */ + +#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) +void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset) +{ + UINT64 lane = byte; + lane <<= (offset%8)*8; + ((UINT64*)state)[offset/8] ^= lane; +} +#endif + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_AddBytes(state, data, offset, length, KeccakP1600_AddLanes, KeccakP1600_AddBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#ifdef KeccakP1600_useLaneComplementing + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) { + unsigned int i; + for(i=0; i<length; i++) + ((unsigned char*)state)[lanePosition*8+offset+i] = ~data[i]; + } + else +#endif + { + memcpy((unsigned char*)state+lanePosition*8+offset, data, length); + } +#else +#error "Not yet implemented" +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteLanes(void *state, const unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#ifdef KeccakP1600_useLaneComplementing + unsigned int lanePosition; + + for(lanePosition=0; lanePosition<laneCount; lanePosition++) + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) + ((UINT64*)state)[lanePosition] = ~((const UINT64*)data)[lanePosition]; + else + ((UINT64*)state)[lanePosition] = ((const UINT64*)data)[lanePosition]; +#else + memcpy(state, data, laneCount*8); +#endif +#else +#error "Not yet implemented" +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_OverwriteBytes(state, data, offset, length, KeccakP1600_OverwriteLanes, KeccakP1600_OverwriteBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#ifdef KeccakP1600_useLaneComplementing + unsigned int lanePosition; + + for(lanePosition=0; lanePosition<byteCount/8; lanePosition++) + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) + ((UINT64*)state)[lanePosition] = ~0; + else + ((UINT64*)state)[lanePosition] = 0; + if (byteCount%8 != 0) { + lanePosition = byteCount/8; + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) + memset((unsigned char*)state+lanePosition*8, 0xFF, byteCount%8); + else + memset((unsigned char*)state+lanePosition*8, 0, byteCount%8); + } +#else + memset(state, 0, byteCount); +#endif +#else +#error "Not yet implemented" +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Permute_24rounds(void *state) +{ + declareABCDE + #ifndef KeccakP1600_fullUnrolling + unsigned int i; + #endif + UINT64 *stateAsLanes = (UINT64*)state; + + copyFromState(A, stateAsLanes) + rounds24 + copyToState(stateAsLanes, A) +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Permute_12rounds(void *state) +{ + declareABCDE + #ifndef KeccakP1600_fullUnrolling + unsigned int i; + #endif + UINT64 *stateAsLanes = (UINT64*)state; + + copyFromState(A, stateAsLanes) + rounds12 + copyToState(stateAsLanes, A) +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length) +{ + UINT64 lane = ((UINT64*)state)[lanePosition]; +#ifdef KeccakP1600_useLaneComplementing + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) + lane = ~lane; +#endif +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + { + UINT64 lane1[1]; + lane1[0] = lane; + memcpy(data, (UINT8*)lane1+offset, length); + } +#else + unsigned int i; + lane >>= offset*8; + for(i=0; i<length; i++) { + data[i] = lane & 0xFF; + lane >>= 8; + } +#endif +} + +/* ---------------------------------------------------------------- */ + +#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) +void fromWordToBytes(UINT8 *bytes, const UINT64 word) +{ + unsigned int i; + + for(i=0; i<(64/8); i++) + bytes[i] = (word >> (8*i)) & 0xFF; +} +#endif + +void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + memcpy(data, state, laneCount*8); +#else + unsigned int i; + + for(i=0; i<laneCount; i++) + fromWordToBytes(data+(i*8), ((const UINT64*)state)[i]); +#endif +#ifdef KeccakP1600_useLaneComplementing + if (laneCount > 1) { + ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1]; + if (laneCount > 2) { + ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2]; + if (laneCount > 8) { + ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8]; + if (laneCount > 12) { + ((UINT64*)data)[12] = ~((UINT64*)data)[12]; + if (laneCount > 17) { + ((UINT64*)data)[17] = ~((UINT64*)data)[17]; + if (laneCount > 20) { + ((UINT64*)data)[20] = ~((UINT64*)data)[20]; + } + } + } + } + } + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + UINT64 lane = ((UINT64*)state)[lanePosition]; +#ifdef KeccakP1600_useLaneComplementing + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) + lane = ~lane; +#endif +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + { + unsigned int i; + UINT64 lane1[1]; + lane1[0] = lane; + for(i=0; i<length; i++) + output[i] = input[i] ^ ((UINT8*)lane1)[offset+i]; + } +#else + unsigned int i; + lane >>= offset*8; + for(i=0; i<length; i++) { + output[i] = input[i] ^ (lane & 0xFF); + lane >>= 8; + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount) +{ + unsigned int i; +#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) + unsigned char temp[8]; + unsigned int j; +#endif + + for(i=0; i<laneCount; i++) { +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + ((UINT64*)output)[i] = ((UINT64*)input)[i] ^ ((const UINT64*)state)[i]; +#else + fromWordToBytes(temp, ((const UINT64*)state)[i]); + for(j=0; j<8; j++) + output[i*8+j] = input[i*8+j] ^ temp[j]; +#endif + } +#ifdef KeccakP1600_useLaneComplementing + if (laneCount > 1) { + ((UINT64*)output)[ 1] = ~((UINT64*)output)[ 1]; + if (laneCount > 2) { + ((UINT64*)output)[ 2] = ~((UINT64*)output)[ 2]; + if (laneCount > 8) { + ((UINT64*)output)[ 8] = ~((UINT64*)output)[ 8]; + if (laneCount > 12) { + ((UINT64*)output)[12] = ~((UINT64*)output)[12]; + if (laneCount > 17) { + ((UINT64*)output)[17] = ~((UINT64*)output)[17]; + if (laneCount > 20) { + ((UINT64*)output)[20] = ~((UINT64*)output)[20]; + } + } + } + } + } + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen) +{ + size_t originalDataByteLen = dataByteLen; + declareABCDE + #ifndef KeccakP1600_fullUnrolling + unsigned int i; + #endif + UINT64 *stateAsLanes = (UINT64*)state; + UINT64 *inDataAsLanes = (UINT64*)data; + + copyFromState(A, stateAsLanes) + while(dataByteLen >= laneCount*8) { + addInput(A, inDataAsLanes, laneCount) + rounds24 + inDataAsLanes += laneCount; + dataByteLen -= laneCount*8; + } + copyToState(stateAsLanes, A) + return originalDataByteLen - dataByteLen; +} diff --git a/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros b/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros new file mode 100644 index 0000000..405ce29 --- /dev/null +++ b/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros @@ -0,0 +1,185 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#if (defined(FullUnrolling)) +#define rounds24 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta( 0, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 1, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 2, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 3, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 4, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 5, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 6, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 7, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 8, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 9, E, A) \ + thetaRhoPiChiIotaPrepareTheta(10, A, E) \ + thetaRhoPiChiIotaPrepareTheta(11, E, A) \ + thetaRhoPiChiIotaPrepareTheta(12, A, E) \ + thetaRhoPiChiIotaPrepareTheta(13, E, A) \ + thetaRhoPiChiIotaPrepareTheta(14, A, E) \ + thetaRhoPiChiIotaPrepareTheta(15, E, A) \ + thetaRhoPiChiIotaPrepareTheta(16, A, E) \ + thetaRhoPiChiIotaPrepareTheta(17, E, A) \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#define rounds12 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(12, A, E) \ + thetaRhoPiChiIotaPrepareTheta(13, E, A) \ + thetaRhoPiChiIotaPrepareTheta(14, A, E) \ + thetaRhoPiChiIotaPrepareTheta(15, E, A) \ + thetaRhoPiChiIotaPrepareTheta(16, A, E) \ + thetaRhoPiChiIotaPrepareTheta(17, E, A) \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#elif (Unrolling == 12) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=12) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(12, A, E) \ + thetaRhoPiChiIotaPrepareTheta(13, E, A) \ + thetaRhoPiChiIotaPrepareTheta(14, A, E) \ + thetaRhoPiChiIotaPrepareTheta(15, E, A) \ + thetaRhoPiChiIotaPrepareTheta(16, A, E) \ + thetaRhoPiChiIotaPrepareTheta(17, E, A) \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#elif (Unrolling == 6) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=6) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=6) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ + } \ + +#elif (Unrolling == 4) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=4) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=4) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + } \ + +#elif (Unrolling == 3) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=3) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=3) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + copyStateVariables(A, E) \ + } \ + +#elif (Unrolling == 2) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#elif (Unrolling == 1) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i++) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i++) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + copyStateVariables(A, E) \ + } \ + +#else +#error "Unrolling is not correctly specified!" +#endif diff --git a/Modules/_sha3/kcp/KeccakSponge.c b/Modules/_sha3/kcp/KeccakSponge.c new file mode 100644 index 0000000..afdb731 --- /dev/null +++ b/Modules/_sha3/kcp/KeccakSponge.c @@ -0,0 +1,92 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "KeccakSponge.h" + +#ifdef KeccakReference + #include "displayIntermediateValues.h" +#endif + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + + #define prefix KeccakWidth200 + #define SnP KeccakP200 + #define SnP_width 200 + #define SnP_Permute KeccakP200_Permute_18rounds + #if defined(KeccakF200_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF200_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif + +#ifndef KeccakP400_excluded + #include "KeccakP-400-SnP.h" + + #define prefix KeccakWidth400 + #define SnP KeccakP400 + #define SnP_width 400 + #define SnP_Permute KeccakP400_Permute_20rounds + #if defined(KeccakF400_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF400_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif + +#ifndef KeccakP800_excluded + #include "KeccakP-800-SnP.h" + + #define prefix KeccakWidth800 + #define SnP KeccakP800 + #define SnP_width 800 + #define SnP_Permute KeccakP800_Permute_22rounds + #if defined(KeccakF800_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF800_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif + +#ifndef KeccakP1600_excluded + #include "KeccakP-1600-SnP.h" + + #define prefix KeccakWidth1600 + #define SnP KeccakP1600 + #define SnP_width 1600 + #define SnP_Permute KeccakP1600_Permute_24rounds + #if defined(KeccakF1600_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF1600_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif diff --git a/Modules/_sha3/kcp/KeccakSponge.h b/Modules/_sha3/kcp/KeccakSponge.h new file mode 100644 index 0000000..0f4badc --- /dev/null +++ b/Modules/_sha3/kcp/KeccakSponge.h @@ -0,0 +1,172 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakSponge_h_ +#define _KeccakSponge_h_ + +/** General information + * + * The following type and functions are not actually implemented. Their + * documentation is generic, with the prefix Prefix replaced by + * - KeccakWidth200 for a sponge function based on Keccak-f[200] + * - KeccakWidth400 for a sponge function based on Keccak-f[400] + * - KeccakWidth800 for a sponge function based on Keccak-f[800] + * - KeccakWidth1600 for a sponge function based on Keccak-f[1600] + * + * In all these functions, the rate and capacity must sum to the width of the + * chosen permutation. For instance, to use the sponge function + * Keccak[r=1344, c=256], one must use KeccakWidth1600_Sponge() or a combination + * of KeccakWidth1600_SpongeInitialize(), KeccakWidth1600_SpongeAbsorb(), + * KeccakWidth1600_SpongeAbsorbLastFewBits() and + * KeccakWidth1600_SpongeSqueeze(). + * + * The Prefix_SpongeInstance contains the sponge instance attributes for use + * with the Prefix_Sponge* functions. + * It gathers the state processed by the permutation as well as the rate, + * the position of input/output bytes in the state and the phase + * (absorbing or squeezing). + */ + +#ifdef DontReallyInclude_DocumentationOnly +/** Function to evaluate the sponge function Keccak[r, c] in a single call. + * @param rate The value of the rate r. + * @param capacity The value of the capacity c. + * @param input Pointer to the input message (before the suffix). + * @param inputByteLen The length of the input message in bytes. + * @param suffix Byte containing from 0 to 7 suffix bits + * that must be absorbed after @a input. + * These <i>n</i> bits must be in the least significant bit positions. + * These bits must be delimited with a bit 1 at position <i>n</i> + * (counting from 0=LSB to 7=MSB) and followed by bits 0 + * from position <i>n</i>+1 to position 7. + * Some examples: + * - If no bits are to be absorbed, then @a suffix must be 0x01. + * - If the 2-bit sequence 0,0 is to be absorbed, @a suffix must be 0x04. + * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a suffix must be 0x32. + * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a suffix must be 0x8B. + * . + * @param output Pointer to the output buffer. + * @param outputByteLen The desired number of output bytes. + * @pre One must have r+c equal to the supported width of this implementation + * and the rate a multiple of 8 bits (one byte) in this implementation. + * @pre @a suffix ≠0x00 + * @return Zero if successful, 1 otherwise. + */ +int Prefix_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); + +/** + * Function to initialize the state of the Keccak[r, c] sponge function. + * The phase of the sponge function is set to absorbing. + * @param spongeInstance Pointer to the sponge instance to be initialized. + * @param rate The value of the rate r. + * @param capacity The value of the capacity c. + * @pre One must have r+c equal to the supported width of this implementation + * and the rate a multiple of 8 bits (one byte) in this implementation. + * @return Zero if successful, 1 otherwise. + */ +int Prefix_SpongeInitialize(Prefix_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); + +/** + * Function to give input data bytes for the sponge function to absorb. + * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). + * @param data Pointer to the input data. + * @param dataByteLen The number of input bytes provided in the input data. + * @pre The sponge function must be in the absorbing phase, + * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() + * must not have been called before. + * @return Zero if successful, 1 otherwise. + */ +int Prefix_SpongeAbsorb(Prefix_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); + +/** + * Function to give input data bits for the sponge function to absorb + * and then to switch to the squeezing phase. + * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). + * @param delimitedData Byte containing from 0 to 7 trailing bits + * that must be absorbed. + * These <i>n</i> bits must be in the least significant bit positions. + * These bits must be delimited with a bit 1 at position <i>n</i> + * (counting from 0=LSB to 7=MSB) and followed by bits 0 + * from position <i>n</i>+1 to position 7. + * Some examples: + * - If no bits are to be absorbed, then @a delimitedData must be 0x01. + * - If the 2-bit sequence 0,0 is to be absorbed, @a delimitedData must be 0x04. + * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a delimitedData must be 0x32. + * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedData must be 0x8B. + * . + * @pre The sponge function must be in the absorbing phase, + * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() + * must not have been called before. + * @pre @a delimitedData ≠0x00 + * @return Zero if successful, 1 otherwise. + */ +int Prefix_SpongeAbsorbLastFewBits(Prefix_SpongeInstance *spongeInstance, unsigned char delimitedData); + +/** + * Function to squeeze output data from the sponge function. + * If the sponge function was in the absorbing phase, this function + * switches it to the squeezing phase + * as if Prefix_SpongeAbsorbLastFewBits(spongeInstance, 0x01) was called. + * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). + * @param data Pointer to the buffer where to store the output data. + * @param dataByteLen The number of output bytes desired. + * @return Zero if successful, 1 otherwise. + */ +int Prefix_SpongeSqueeze(Prefix_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); +#endif + +#include <string.h> +#include "align.h" + +#define KCP_DeclareSpongeStructure(prefix, size, alignment) \ + ALIGN(alignment) typedef struct prefix##_SpongeInstanceStruct { \ + unsigned char state[size]; \ + unsigned int rate; \ + unsigned int byteIOIndex; \ + int squeezing; \ + } prefix##_SpongeInstance; + +#define KCP_DeclareSpongeFunctions(prefix) \ + int prefix##_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); \ + int prefix##_SpongeInitialize(prefix##_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); \ + int prefix##_SpongeAbsorb(prefix##_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); \ + int prefix##_SpongeAbsorbLastFewBits(prefix##_SpongeInstance *spongeInstance, unsigned char delimitedData); \ + int prefix##_SpongeSqueeze(prefix##_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + KCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth200) +#endif + +#ifndef KeccakP400_excluded + #include "KeccakP-400-SnP.h" + KCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth400) +#endif + +#ifndef KeccakP800_excluded + #include "KeccakP-800-SnP.h" + KCP_DeclareSpongeStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth800) +#endif + +#ifndef KeccakP1600_excluded + #include "KeccakP-1600-SnP.h" + KCP_DeclareSpongeStructure(KeccakWidth1600, KeccakP1600_stateSizeInBytes, KeccakP1600_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth1600) +#endif + +#endif diff --git a/Modules/_sha3/kcp/KeccakSponge.inc b/Modules/_sha3/kcp/KeccakSponge.inc new file mode 100644 index 0000000..e10739d --- /dev/null +++ b/Modules/_sha3/kcp/KeccakSponge.inc @@ -0,0 +1,332 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#define JOIN0(a, b) a ## b +#define JOIN(a, b) JOIN0(a, b) + +#define Sponge JOIN(prefix, _Sponge) +#define SpongeInstance JOIN(prefix, _SpongeInstance) +#define SpongeInitialize JOIN(prefix, _SpongeInitialize) +#define SpongeAbsorb JOIN(prefix, _SpongeAbsorb) +#define SpongeAbsorbLastFewBits JOIN(prefix, _SpongeAbsorbLastFewBits) +#define SpongeSqueeze JOIN(prefix, _SpongeSqueeze) + +#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) +#define SnP_stateAlignment JOIN(SnP, _stateAlignment) +#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) +#define SnP_Initialize JOIN(SnP, _Initialize) +#define SnP_AddByte JOIN(SnP, _AddByte) +#define SnP_AddBytes JOIN(SnP, _AddBytes) +#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) + +int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen) +{ + ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes]; + unsigned int partialBlock; + const unsigned char *curInput = input; + unsigned char *curOutput = output; + unsigned int rateInBytes = rate/8; + + if (rate+capacity != SnP_width) + return 1; + if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) + return 1; + if (suffix == 0) + return 1; + + /* Initialize the state */ + + SnP_StaticInitialize(); + SnP_Initialize(state); + + /* First, absorb whole blocks */ + +#ifdef SnP_FastLoop_Absorb + if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) { + /* fast lane: whole lane rate */ + + size_t j; + j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen); + curInput += j; + inputByteLen -= j; + } +#endif + while(inputByteLen >= (size_t)rateInBytes) { + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed", curInput, rateInBytes); + #endif + SnP_AddBytes(state, curInput, 0, rateInBytes); + SnP_Permute(state); + curInput += rateInBytes; + inputByteLen -= rateInBytes; + } + + /* Then, absorb what remains */ + + partialBlock = (unsigned int)inputByteLen; + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock); + #endif + SnP_AddBytes(state, curInput, 0, partialBlock); + + /* Finally, absorb the suffix */ + + #ifdef KeccakReference + { + unsigned char delimitedData1[1]; + delimitedData1[0] = suffix; + displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); + } + #endif + /* Last few bits, whose delimiter coincides with first bit of padding */ + + SnP_AddByte(state, suffix, partialBlock); + /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ + + if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1))) + SnP_Permute(state); + /* Second bit of padding */ + + SnP_AddByte(state, 0x80, rateInBytes-1); + #ifdef KeccakReference + { + unsigned char block[SnP_width/8]; + memset(block, 0, SnP_width/8); + block[rateInBytes-1] = 0x80; + displayBytes(1, "Second bit of padding", block, rateInBytes); + } + #endif + SnP_Permute(state); + #ifdef KeccakReference + displayText(1, "--- Switching to squeezing phase ---"); + #endif + + /* First, output whole blocks */ + + while(outputByteLen > (size_t)rateInBytes) { + SnP_ExtractBytes(state, curOutput, 0, rateInBytes); + SnP_Permute(state); + #ifdef KeccakReference + displayBytes(1, "Squeezed block", curOutput, rateInBytes); + #endif + curOutput += rateInBytes; + outputByteLen -= rateInBytes; + } + + /* Finally, output what remains */ + + partialBlock = (unsigned int)outputByteLen; + SnP_ExtractBytes(state, curOutput, 0, partialBlock); + #ifdef KeccakReference + displayBytes(1, "Squeezed block (part)", curOutput, partialBlock); + #endif + + return 0; +} + +/* ---------------------------------------------------------------- */ +/* ---------------------------------------------------------------- */ +/* ---------------------------------------------------------------- */ + +int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity) +{ + if (rate+capacity != SnP_width) + return 1; + if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) + return 1; + SnP_StaticInitialize(); + SnP_Initialize(instance->state); + instance->rate = rate; + instance->byteIOIndex = 0; + instance->squeezing = 0; + + return 0; +} + +/* ---------------------------------------------------------------- */ + +int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen) +{ + size_t i, j; + unsigned int partialBlock; + const unsigned char *curData; + unsigned int rateInBytes = instance->rate/8; + + if (instance->squeezing) + return 1; /* Too late for additional input */ + + + i = 0; + curData = data; + while(i < dataByteLen) { + if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { +#ifdef SnP_FastLoop_Absorb + /* processing full blocks first */ + + if ((rateInBytes % (SnP_width/200)) == 0) { + /* fast lane: whole lane rate */ + + j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i); + i += j; + curData += j; + } + else { +#endif + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed", curData, rateInBytes); + #endif + SnP_AddBytes(instance->state, curData, 0, rateInBytes); + SnP_Permute(instance->state); + curData+=rateInBytes; + } + i = dataByteLen - j; +#ifdef SnP_FastLoop_Absorb + } +#endif + } + else { + /* normal lane: using the message queue */ + + partialBlock = (unsigned int)(dataByteLen - i); + if (partialBlock+instance->byteIOIndex > rateInBytes) + partialBlock = rateInBytes-instance->byteIOIndex; + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); + #endif + i += partialBlock; + + SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock); + curData += partialBlock; + instance->byteIOIndex += partialBlock; + if (instance->byteIOIndex == rateInBytes) { + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + } + } + } + return 0; +} + +/* ---------------------------------------------------------------- */ + +int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData) +{ + unsigned int rateInBytes = instance->rate/8; + + if (delimitedData == 0) + return 1; + if (instance->squeezing) + return 1; /* Too late for additional input */ + + + #ifdef KeccakReference + { + unsigned char delimitedData1[1]; + delimitedData1[0] = delimitedData; + displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); + } + #endif + /* Last few bits, whose delimiter coincides with first bit of padding */ + + SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex); + /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ + + if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1))) + SnP_Permute(instance->state); + /* Second bit of padding */ + + SnP_AddByte(instance->state, 0x80, rateInBytes-1); + #ifdef KeccakReference + { + unsigned char block[SnP_width/8]; + memset(block, 0, SnP_width/8); + block[rateInBytes-1] = 0x80; + displayBytes(1, "Second bit of padding", block, rateInBytes); + } + #endif + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + instance->squeezing = 1; + #ifdef KeccakReference + displayText(1, "--- Switching to squeezing phase ---"); + #endif + return 0; +} + +/* ---------------------------------------------------------------- */ + +int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen) +{ + size_t i, j; + unsigned int partialBlock; + unsigned int rateInBytes = instance->rate/8; + unsigned char *curData; + + if (!instance->squeezing) + SpongeAbsorbLastFewBits(instance, 0x01); + + i = 0; + curData = data; + while(i < dataByteLen) { + if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + SnP_Permute(instance->state); + SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); + #ifdef KeccakReference + displayBytes(1, "Squeezed block", curData, rateInBytes); + #endif + curData+=rateInBytes; + } + i = dataByteLen - j; + } + else { + /* normal lane: using the message queue */ + + if (instance->byteIOIndex == rateInBytes) { + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + } + partialBlock = (unsigned int)(dataByteLen - i); + if (partialBlock+instance->byteIOIndex > rateInBytes) + partialBlock = rateInBytes-instance->byteIOIndex; + i += partialBlock; + + SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); + #ifdef KeccakReference + displayBytes(1, "Squeezed block (part)", curData, partialBlock); + #endif + curData += partialBlock; + instance->byteIOIndex += partialBlock; + } + } + return 0; +} + +/* ---------------------------------------------------------------- */ + +#undef Sponge +#undef SpongeInstance +#undef SpongeInitialize +#undef SpongeAbsorb +#undef SpongeAbsorbLastFewBits +#undef SpongeSqueeze +#undef SnP_stateSizeInBytes +#undef SnP_stateAlignment +#undef SnP_StaticInitialize +#undef SnP_Initialize +#undef SnP_AddByte +#undef SnP_AddBytes +#undef SnP_ExtractBytes diff --git a/Modules/_sha3/kcp/PlSnP-Fallback.inc b/Modules/_sha3/kcp/PlSnP-Fallback.inc new file mode 100644 index 0000000..3a9119a --- /dev/null +++ b/Modules/_sha3/kcp/PlSnP-Fallback.inc @@ -0,0 +1,257 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +/* expect PlSnP_baseParallelism, PlSnP_targetParallelism */ + +/* expect SnP_stateSizeInBytes, SnP_stateAlignment */ + +/* expect prefix */ + +/* expect SnP_* */ + + +#define JOIN0(a, b) a ## b +#define JOIN(a, b) JOIN0(a, b) + +#define PlSnP_StaticInitialize JOIN(prefix, _StaticInitialize) +#define PlSnP_InitializeAll JOIN(prefix, _InitializeAll) +#define PlSnP_AddByte JOIN(prefix, _AddByte) +#define PlSnP_AddBytes JOIN(prefix, _AddBytes) +#define PlSnP_AddLanesAll JOIN(prefix, _AddLanesAll) +#define PlSnP_OverwriteBytes JOIN(prefix, _OverwriteBytes) +#define PlSnP_OverwriteLanesAll JOIN(prefix, _OverwriteLanesAll) +#define PlSnP_OverwriteWithZeroes JOIN(prefix, _OverwriteWithZeroes) +#define PlSnP_ExtractBytes JOIN(prefix, _ExtractBytes) +#define PlSnP_ExtractLanesAll JOIN(prefix, _ExtractLanesAll) +#define PlSnP_ExtractAndAddBytes JOIN(prefix, _ExtractAndAddBytes) +#define PlSnP_ExtractAndAddLanesAll JOIN(prefix, _ExtractAndAddLanesAll) + +#if (PlSnP_baseParallelism == 1) + #define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) + #define SnP_stateAlignment JOIN(SnP, _stateAlignment) +#else + #define SnP_stateSizeInBytes JOIN(SnP, _statesSizeInBytes) + #define SnP_stateAlignment JOIN(SnP, _statesAlignment) +#endif +#define PlSnP_factor ((PlSnP_targetParallelism)/(PlSnP_baseParallelism)) +#define SnP_stateOffset (((SnP_stateSizeInBytes+(SnP_stateAlignment-1))/SnP_stateAlignment)*SnP_stateAlignment) +#define stateWithIndex(i) ((unsigned char *)states+((i)*SnP_stateOffset)) + +#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) +#define SnP_Initialize JOIN(SnP, _Initialize) +#define SnP_InitializeAll JOIN(SnP, _InitializeAll) +#define SnP_AddByte JOIN(SnP, _AddByte) +#define SnP_AddBytes JOIN(SnP, _AddBytes) +#define SnP_AddLanesAll JOIN(SnP, _AddLanesAll) +#define SnP_OverwriteBytes JOIN(SnP, _OverwriteBytes) +#define SnP_OverwriteLanesAll JOIN(SnP, _OverwriteLanesAll) +#define SnP_OverwriteWithZeroes JOIN(SnP, _OverwriteWithZeroes) +#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) +#define SnP_ExtractLanesAll JOIN(SnP, _ExtractLanesAll) +#define SnP_ExtractAndAddBytes JOIN(SnP, _ExtractAndAddBytes) +#define SnP_ExtractAndAddLanesAll JOIN(SnP, _ExtractAndAddLanesAll) + +void PlSnP_StaticInitialize( void ) +{ + SnP_StaticInitialize(); +} + +void PlSnP_InitializeAll(void *states) +{ + unsigned int i; + + for(i=0; i<PlSnP_factor; i++) + #if (PlSnP_baseParallelism == 1) + SnP_Initialize(stateWithIndex(i)); + #else + SnP_InitializeAll(stateWithIndex(i)); + #endif +} + +void PlSnP_AddByte(void *states, unsigned int instanceIndex, unsigned char byte, unsigned int offset) +{ + #if (PlSnP_baseParallelism == 1) + SnP_AddByte(stateWithIndex(instanceIndex), byte, offset); + #else + SnP_AddByte(stateWithIndex(instanceIndex/PlSnP_baseParallelism), instanceIndex%PlSnP_baseParallelism, byte, offset); + #endif +} + +void PlSnP_AddBytes(void *states, unsigned int instanceIndex, const unsigned char *data, unsigned int offset, unsigned int length) +{ + #if (PlSnP_baseParallelism == 1) + SnP_AddBytes(stateWithIndex(instanceIndex), data, offset, length); + #else + SnP_AddBytes(stateWithIndex(instanceIndex/PlSnP_baseParallelism), instanceIndex%PlSnP_baseParallelism, data, offset, length); + #endif +} + +void PlSnP_AddLanesAll(void *states, const unsigned char *data, unsigned int laneCount, unsigned int laneOffset) +{ + unsigned int i; + + for(i=0; i<PlSnP_factor; i++) { + #if (PlSnP_baseParallelism == 1) + SnP_AddBytes(stateWithIndex(i), data, 0, laneCount*SnP_laneLengthInBytes); + #else + SnP_AddLanesAll(stateWithIndex(i), data, laneCount, laneOffset); + #endif + data += PlSnP_baseParallelism*laneOffset*SnP_laneLengthInBytes; + } +} + +void PlSnP_OverwriteBytes(void *states, unsigned int instanceIndex, const unsigned char *data, unsigned int offset, unsigned int length) +{ + #if (PlSnP_baseParallelism == 1) + SnP_OverwriteBytes(stateWithIndex(instanceIndex), data, offset, length); + #else + SnP_OverwriteBytes(stateWithIndex(instanceIndex/PlSnP_baseParallelism), instanceIndex%PlSnP_baseParallelism, data, offset, length); + #endif +} + +void PlSnP_OverwriteLanesAll(void *states, const unsigned char *data, unsigned int laneCount, unsigned int laneOffset) +{ + unsigned int i; + + for(i=0; i<PlSnP_factor; i++) { + #if (PlSnP_baseParallelism == 1) + SnP_OverwriteBytes(stateWithIndex(i), data, 0, laneCount*SnP_laneLengthInBytes); + #else + SnP_OverwriteLanesAll(stateWithIndex(i), data, laneCount, laneOffset); + #endif + data += PlSnP_baseParallelism*laneOffset*SnP_laneLengthInBytes; + } +} + +void PlSnP_OverwriteWithZeroes(void *states, unsigned int instanceIndex, unsigned int byteCount) +{ + #if (PlSnP_baseParallelism == 1) + SnP_OverwriteWithZeroes(stateWithIndex(instanceIndex), byteCount); + #else + SnP_OverwriteWithZeroes(stateWithIndex(instanceIndex/PlSnP_baseParallelism), instanceIndex%PlSnP_baseParallelism, byteCount); + #endif +} + +void PlSnP_PermuteAll(void *states) +{ + unsigned int i; + + for(i=0; i<PlSnP_factor; i++) { + #if (PlSnP_baseParallelism == 1) + SnP_Permute(stateWithIndex(i)); + #else + SnP_PermuteAll(stateWithIndex(i)); + #endif + } +} + +#if (defined(SnP_Permute_12rounds) || defined(SnP_PermuteAll_12rounds)) +void PlSnP_PermuteAll_12rounds(void *states) +{ + unsigned int i; + + for(i=0; i<PlSnP_factor; i++) { + #if (PlSnP_baseParallelism == 1) + SnP_Permute_12rounds(stateWithIndex(i)); + #else + SnP_PermuteAll_12rounds(stateWithIndex(i)); + #endif + } +} +#endif + +void PlSnP_ExtractBytes(void *states, unsigned int instanceIndex, unsigned char *data, unsigned int offset, unsigned int length) +{ + #if (PlSnP_baseParallelism == 1) + SnP_ExtractBytes(stateWithIndex(instanceIndex), data, offset, length); + #else + SnP_ExtractBytes(stateWithIndex(instanceIndex/PlSnP_baseParallelism), instanceIndex%PlSnP_baseParallelism, data, offset, length); + #endif +} + +void PlSnP_ExtractLanesAll(const void *states, unsigned char *data, unsigned int laneCount, unsigned int laneOffset) +{ + unsigned int i; + + for(i=0; i<PlSnP_factor; i++) { + #if (PlSnP_baseParallelism == 1) + SnP_ExtractBytes(stateWithIndex(i), data, 0, laneCount*SnP_laneLengthInBytes); + #else + SnP_ExtractLanesAll(stateWithIndex(i), data, laneCount, laneOffset); + #endif + data += laneOffset*SnP_laneLengthInBytes*PlSnP_baseParallelism; + } +} + +void PlSnP_ExtractAndAddBytes(void *states, unsigned int instanceIndex, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + #if (PlSnP_baseParallelism == 1) + SnP_ExtractAndAddBytes(stateWithIndex(instanceIndex), input, output, offset, length); + #else + SnP_ExtractAndAddBytes(stateWithIndex(instanceIndex/PlSnP_baseParallelism), instanceIndex%PlSnP_baseParallelism, input, output, offset, length); + #endif +} + +void PlSnP_ExtractAndAddLanesAll(const void *states, const unsigned char *input, unsigned char *output, unsigned int laneCount, unsigned int laneOffset) +{ + unsigned int i; + + for(i=0; i<PlSnP_factor; i++) { + #if (PlSnP_baseParallelism == 1) + SnP_ExtractAndAddBytes(stateWithIndex(i), input, output, 0, laneCount*SnP_laneLengthInBytes); + #else + SnP_ExtractAndAddLanesAll(stateWithIndex(i), input, output, laneCount, laneOffset); + #endif + input += laneOffset*SnP_laneLengthInBytes*PlSnP_baseParallelism; + output += laneOffset*SnP_laneLengthInBytes*PlSnP_baseParallelism; + } +} + +#undef PlSnP_factor +#undef SnP_stateOffset +#undef stateWithIndex +#undef JOIN0 +#undef JOIN +#undef PlSnP_StaticInitialize +#undef PlSnP_InitializeAll +#undef PlSnP_AddByte +#undef PlSnP_AddBytes +#undef PlSnP_AddLanesAll +#undef PlSnP_OverwriteBytes +#undef PlSnP_OverwriteLanesAll +#undef PlSnP_OverwriteWithZeroes +#undef PlSnP_PermuteAll +#undef PlSnP_ExtractBytes +#undef PlSnP_ExtractLanesAll +#undef PlSnP_ExtractAndAddBytes +#undef PlSnP_ExtractAndAddLanesAll +#undef SnP_stateAlignment +#undef SnP_stateSizeInBytes +#undef PlSnP_factor +#undef SnP_stateOffset +#undef stateWithIndex +#undef SnP_StaticInitialize +#undef SnP_Initialize +#undef SnP_InitializeAll +#undef SnP_AddByte +#undef SnP_AddBytes +#undef SnP_AddLanesAll +#undef SnP_OverwriteBytes +#undef SnP_OverwriteWithZeroes +#undef SnP_OverwriteLanesAll +#undef SnP_ExtractBytes +#undef SnP_ExtractLanesAll +#undef SnP_ExtractAndAddBytes +#undef SnP_ExtractAndAddLanesAll diff --git a/Modules/_sha3/kcp/SnP-Relaned.h b/Modules/_sha3/kcp/SnP-Relaned.h new file mode 100644 index 0000000..086e635 --- /dev/null +++ b/Modules/_sha3/kcp/SnP-Relaned.h @@ -0,0 +1,134 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _SnP_Relaned_h_ +#define _SnP_Relaned_h_ + +#define SnP_AddBytes(state, data, offset, length, SnP_AddLanes, SnP_AddBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_AddLanes(state, data, (length)/SnP_laneLengthInBytes); \ + SnP_AddBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + const unsigned char *_curData = (data); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curData += _bytesInLane; \ + } \ + } \ + } + +#define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \ + SnP_OverwriteBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + const unsigned char *_curData = (data); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curData += _bytesInLane; \ + } \ + } \ + } + +#define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \ + SnP_ExtractBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + unsigned char *_curData = (data); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curData += _bytesInLane; \ + } \ + } \ + } + +#define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \ + SnP_ExtractAndAddBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + (output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + const unsigned char *_curInput = (input); \ + unsigned char *_curOutput = (output); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curInput += _bytesInLane; \ + _curOutput += _bytesInLane; \ + } \ + } \ + } + +#endif diff --git a/Modules/_sha3/kcp/align.h b/Modules/_sha3/kcp/align.h new file mode 100644 index 0000000..6650fe8 --- /dev/null +++ b/Modules/_sha3/kcp/align.h @@ -0,0 +1,35 @@ +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _align_h_ +#define _align_h_ + +/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */ + +#ifdef ALIGN +#undef ALIGN +#endif + +#if defined(__GNUC__) +#define ALIGN(x) __attribute__ ((aligned(x))) +#elif defined(_MSC_VER) +#define ALIGN(x) __declspec(align(x)) +#elif defined(__ARMCC_VERSION) +#define ALIGN(x) __align(x) +#else +#define ALIGN(x) +#endif + +#endif diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c new file mode 100644 index 0000000..04ac631 --- /dev/null +++ b/Modules/_sha3/sha3module.c @@ -0,0 +1,759 @@ +/* SHA3 module + * + * This module provides an interface to the SHA3 algorithm + * + * See below for information about the original code this module was + * based upon. Additional work performed by: + * + * Andrew Kuchling (amk@amk.ca) + * Greg Stein (gstein@lyra.org) + * Trevor Perrin (trevp@trevp.net) + * Gregory P. Smith (greg@krypto.org) + * + * Copyright (C) 2012-2016 Christian Heimes (christian@python.org) + * Licensed to PSF under a Contributor Agreement. + * + */ + +#include "Python.h" +#include "pystrhex.h" +#include "../hashlib.h" + +/* ************************************************************************** + * SHA-3 (Keccak) and SHAKE + * + * The code is based on KeccakCodePackage from 2016-04-23 + * commit 647f93079afc4ada3d23737477a6e52511ca41fd + * + * The reference implementation is altered in this points: + * - C++ comments are converted to ANSI C comments. + * - all function names are mangled + * - typedef for UINT64 is commented out. + * - brg_endian.h is removed + * + * *************************************************************************/ + +#ifdef __sparc + /* opt64 uses un-aligned memory access that causes a BUS error with msg + * 'invalid address alignment' on SPARC. */ + #define KeccakOpt 32 +#elif PY_BIG_ENDIAN + /* opt64 is not yet supported on big endian platforms */ + #define KeccakOpt 32 +#elif SIZEOF_VOID_P == 8 && defined(PY_UINT64_T) + /* opt64 works only on little-endian 64bit platforms with unsigned int64 */ + #define KeccakOpt 64 +#else + /* opt32 is used for the remaining 32 and 64bit platforms */ + #define KeccakOpt 32 +#endif + +#if KeccakOpt == 64 && defined(PY_UINT64_T) + /* 64bit platforms with unsigned int64 */ + typedef PY_UINT64_T UINT64; + typedef unsigned char UINT8; +#endif + +/* replacement for brg_endian.h */ +#define IS_LITTLE_ENDIAN 1234 +#define IS_BIG_ENDIAN 4321 +#if PY_LITTLE_ENDIAN +#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif +#if PY_BIG_ENDIAN +#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#endif + +/* mangle names */ +#define KeccakF1600_FastLoop_Absorb _PySHA3_KeccakF1600_FastLoop_Absorb +#define Keccak_HashFinal _PySHA3_Keccak_HashFinal +#define Keccak_HashInitialize _PySHA3_Keccak_HashInitialize +#define Keccak_HashSqueeze _PySHA3_Keccak_HashSqueeze +#define Keccak_HashUpdate _PySHA3_Keccak_HashUpdate +#define KeccakP1600_AddBytes _PySHA3_KeccakP1600_AddBytes +#define KeccakP1600_AddBytesInLane _PySHA3_KeccakP1600_AddBytesInLane +#define KeccakP1600_AddLanes _PySHA3_KeccakP1600_AddLanes +#define KeccakP1600_ExtractAndAddBytes _PySHA3_KeccakP1600_ExtractAndAddBytes +#define KeccakP1600_ExtractAndAddBytesInLane _PySHA3_KeccakP1600_ExtractAndAddBytesInLane +#define KeccakP1600_ExtractAndAddLanes _PySHA3_KeccakP1600_ExtractAndAddLanes +#define KeccakP1600_ExtractBytes _PySHA3_KeccakP1600_ExtractBytes +#define KeccakP1600_ExtractBytesInLane _PySHA3_KeccakP1600_ExtractBytesInLane +#define KeccakP1600_ExtractLanes _PySHA3_KeccakP1600_ExtractLanes +#define KeccakP1600_Initialize _PySHA3_KeccakP1600_Initialize +#define KeccakP1600_OverwriteBytes _PySHA3_KeccakP1600_OverwriteBytes +#define KeccakP1600_OverwriteBytesInLane _PySHA3_KeccakP1600_OverwriteBytesInLane +#define KeccakP1600_OverwriteLanes _PySHA3_KeccakP1600_OverwriteLanes +#define KeccakP1600_OverwriteWithZeroes _PySHA3_KeccakP1600_OverwriteWithZeroes +#define KeccakP1600_Permute_12rounds _PySHA3_KeccakP1600_Permute_12rounds +#define KeccakP1600_Permute_24rounds _PySHA3_KeccakP1600_Permute_24rounds +#define KeccakWidth1600_Sponge _PySHA3_KeccakWidth1600_Sponge +#define KeccakWidth1600_SpongeAbsorb _PySHA3_KeccakWidth1600_SpongeAbsorb +#define KeccakWidth1600_SpongeAbsorbLastFewBits _PySHA3_KeccakWidth1600_SpongeAbsorbLastFewBits +#define KeccakWidth1600_SpongeInitialize _PySHA3_KeccakWidth1600_SpongeInitialize +#define KeccakWidth1600_SpongeSqueeze _PySHA3_KeccakWidth1600_SpongeSqueeze +#if KeccakOpt == 32 +#define KeccakP1600_AddByte _PySHA3_KeccakP1600_AddByte +#define KeccakP1600_Permute_Nrounds _PySHA3_KeccakP1600_Permute_Nrounds +#define KeccakP1600_SetBytesInLaneToZero _PySHA3_KeccakP1600_SetBytesInLaneToZero +#endif + +/* we are only interested in KeccakP1600 */ +#define KeccakP200_excluded 1 +#define KeccakP400_excluded 1 +#define KeccakP800_excluded 1 + +/* inline all Keccak dependencies */ +#include "kcp/KeccakHash.h" +#include "kcp/KeccakSponge.h" +#include "kcp/KeccakHash.c" +#include "kcp/KeccakSponge.c" +#if KeccakOpt == 64 + #include "kcp/KeccakP-1600-opt64.c" +#elif KeccakOpt == 32 + #include "kcp/KeccakP-1600-inplace32BI.c" +#endif + +#define SHA3_MAX_DIGESTSIZE 64 /* 64 Bytes (512 Bits) for 224 to 512 */ +#define SHA3_LANESIZE (20 * 8) /* ExtractLane needs max uint64_t[20] extra. */ +#define SHA3_state Keccak_HashInstance +#define SHA3_init Keccak_HashInitialize +#define SHA3_process Keccak_HashUpdate +#define SHA3_done Keccak_HashFinal +#define SHA3_squeeze Keccak_HashSqueeze +#define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) + + +/*[clinic input] +module _sha3 +class _sha3.sha3_224 "SHA3object *" "&SHA3_224typ" +class _sha3.sha3_256 "SHA3object *" "&SHA3_256typ" +class _sha3.sha3_384 "SHA3object *" "&SHA3_384typ" +class _sha3.sha3_512 "SHA3object *" "&SHA3_512typ" +class _sha3.shake_128 "SHA3object *" "&SHAKE128type" +class _sha3.shake_256 "SHA3object *" "&SHAKE256type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b8a53680f370285a]*/ + +/* The structure for storing SHA3 info */ + +#define PY_WITH_KECCAK 0 + +typedef struct { + PyObject_HEAD + SHA3_state hash_state; +#ifdef WITH_THREAD + PyThread_type_lock lock; +#endif +} SHA3object; + +static PyTypeObject SHA3_224type; +static PyTypeObject SHA3_256type; +static PyTypeObject SHA3_384type; +static PyTypeObject SHA3_512type; +#ifdef PY_WITH_KECCAK +static PyTypeObject Keccak_224type; +static PyTypeObject Keccak_256type; +static PyTypeObject Keccak_384type; +static PyTypeObject Keccak_512type; +#endif +static PyTypeObject SHAKE128type; +static PyTypeObject SHAKE256type; + +#include "clinic/sha3module.c.h" + +static SHA3object * +newSHA3object(PyTypeObject *type) +{ + SHA3object *newobj; + newobj = (SHA3object *)PyObject_New(SHA3object, type); + if (newobj == NULL) { + return NULL; + } +#ifdef WITH_THREAD + newobj->lock = NULL; +#endif + return newobj; +} + + +/*[clinic input] +@classmethod +_sha3.sha3_224.__new__ as py_sha3_new + string as data: object = NULL + +Return a new SHA3 hash object with a hashbit length of 28 bytes. +[clinic start generated code]*/ + +static PyObject * +py_sha3_new_impl(PyTypeObject *type, PyObject *data) +/*[clinic end generated code: output=8d5c34279e69bf09 input=d7c582b950a858b6]*/ +{ + SHA3object *self = NULL; + Py_buffer buf = {NULL, NULL}; + HashReturn res; + + self = newSHA3object(type); + if (self == NULL) { + goto error; + } + + if (type == &SHA3_224type) { + res = Keccak_HashInitialize_SHA3_224(&self->hash_state); + } else if (type == &SHA3_256type) { + res = Keccak_HashInitialize_SHA3_256(&self->hash_state); + } else if (type == &SHA3_384type) { + res = Keccak_HashInitialize_SHA3_384(&self->hash_state); + } else if (type == &SHA3_512type) { + res = Keccak_HashInitialize_SHA3_512(&self->hash_state); +#ifdef PY_WITH_KECCAK + } else if (type == &Keccak_224type) { + res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); + } else if (type == &Keccak_256type) { + res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); + } else if (type == &Keccak_384type) { + res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); + } else if (type == &Keccak_512type) { + res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); +#endif + } else if (type == &SHAKE128type) { + res = Keccak_HashInitialize_SHAKE128(&self->hash_state); + } else if (type == &SHAKE256type) { + res = Keccak_HashInitialize_SHAKE256(&self->hash_state); + } else { + PyErr_BadInternalCall(); + goto error; + } + + if (data) { + GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); +#ifdef WITH_THREAD + if (buf.len >= HASHLIB_GIL_MINSIZE) { + /* invariant: New objects can't be accessed by other code yet, + * thus it's safe to release the GIL without locking the object. + */ + Py_BEGIN_ALLOW_THREADS + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + Py_END_ALLOW_THREADS + } + else { + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + } +#else + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); +#endif + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, + "internal error in SHA3 Update()"); + goto error; + } + PyBuffer_Release(&buf); + } + + return (PyObject *)self; + + error: + if (self) { + Py_DECREF(self); + } + if (data && buf.obj) { + PyBuffer_Release(&buf); + } + return NULL; +} + + +/* Internal methods for a hash object */ + +static void +SHA3_dealloc(SHA3object *self) +{ +#ifdef WITH_THREAD + if (self->lock) { + PyThread_free_lock(self->lock); + } +#endif + PyObject_Del(self); +} + + +/* External methods for a hash object */ + + +/*[clinic input] +_sha3.sha3_224.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +_sha3_sha3_224_copy_impl(SHA3object *self) +/*[clinic end generated code: output=6c537411ecdcda4c input=93a44aaebea51ba8]*/ +{ + SHA3object *newobj; + + if ((newobj = newSHA3object(Py_TYPE(self))) == NULL) { + return NULL; + } + ENTER_HASHLIB(self); + SHA3_copystate(newobj->hash_state, self->hash_state); + LEAVE_HASHLIB(self); + return (PyObject *)newobj; +} + + +/*[clinic input] +_sha3.sha3_224.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ + +static PyObject * +_sha3_sha3_224_digest_impl(SHA3object *self) +/*[clinic end generated code: output=fd531842e20b2d5b input=a5807917d219b30e]*/ +{ + unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE]; + SHA3_state temp; + HashReturn res; + + ENTER_HASHLIB(self); + SHA3_copystate(temp, self->hash_state); + LEAVE_HASHLIB(self); + res = SHA3_done(&temp, digest); + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); + return NULL; + } + return PyBytes_FromStringAndSize((const char *)digest, + self->hash_state.fixedOutputLength / 8); +} + + +/*[clinic input] +_sha3.sha3_224.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +_sha3_sha3_224_hexdigest_impl(SHA3object *self) +/*[clinic end generated code: output=75ad03257906918d input=2d91bb6e0d114ee3]*/ +{ + unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE]; + SHA3_state temp; + HashReturn res; + + /* Get the raw (binary) digest value */ + ENTER_HASHLIB(self); + SHA3_copystate(temp, self->hash_state); + LEAVE_HASHLIB(self); + res = SHA3_done(&temp, digest); + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); + return NULL; + } + return _Py_strhex((const char *)digest, + self->hash_state.fixedOutputLength / 8); +} + + +/*[clinic input] +_sha3.sha3_224.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +_sha3_sha3_224_update(SHA3object *self, PyObject *obj) +/*[clinic end generated code: output=06721d55b483e0af input=be44bf0d1c279791]*/ +{ + Py_buffer buf; + HashReturn res; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + + /* add new data, the function takes the length in bits not bytes */ +#ifdef WITH_THREAD + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { + self->lock = PyThread_allocate_lock(); + } + /* Once a lock exists all code paths must be synchronized. We have to + * release the GIL even for small buffers as acquiring the lock may take + * an unlimited amount of time when another thread updates this object + * with lots of data. */ + if (self->lock) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } + else { + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + } +#else + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); +#endif + + if (res != SUCCESS) { + PyBuffer_Release(&buf); + PyErr_SetString(PyExc_RuntimeError, + "internal error in SHA3 Update()"); + return NULL; + } + + PyBuffer_Release(&buf); + Py_INCREF(Py_None); + return Py_None; +} + + +static PyMethodDef SHA3_methods[] = { + _SHA3_SHA3_224_COPY_METHODDEF + _SHA3_SHA3_224_DIGEST_METHODDEF + _SHA3_SHA3_224_HEXDIGEST_METHODDEF + _SHA3_SHA3_224_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +static PyObject * +SHA3_get_block_size(SHA3object *self, void *closure) +{ + int rate = self->hash_state.sponge.rate; + return PyLong_FromLong(rate / 8); +} + + +static PyObject * +SHA3_get_name(SHA3object *self, void *closure) +{ + PyTypeObject *type = Py_TYPE(self); + if (type == &SHA3_224type) { + return PyUnicode_FromString("sha3_224"); + } else if (type == &SHA3_256type) { + return PyUnicode_FromString("sha3_256"); + } else if (type == &SHA3_384type) { + return PyUnicode_FromString("sha3_384"); + } else if (type == &SHA3_512type) { + return PyUnicode_FromString("sha3_512"); +#ifdef PY_WITH_KECCAK + } else if (type == &Keccak_224type) { + return PyUnicode_FromString("keccak_224"); + } else if (type == &Keccak_256type) { + return PyUnicode_FromString("keccak_256"); + } else if (type == &Keccak_384type) { + return PyUnicode_FromString("keccak_384"); + } else if (type == &Keccak_512type) { + return PyUnicode_FromString("keccak_512"); +#endif + } else if (type == &SHAKE128type) { + return PyUnicode_FromString("shake_128"); + } else if (type == &SHAKE256type) { + return PyUnicode_FromString("shake_256"); + } else { + PyErr_BadInternalCall(); + return NULL; + } +} + + +static PyObject * +SHA3_get_digest_size(SHA3object *self, void *closure) +{ + return PyLong_FromLong(self->hash_state.fixedOutputLength / 8); +} + + +static PyObject * +SHA3_get_capacity_bits(SHA3object *self, void *closure) +{ + int capacity = 1600 - self->hash_state.sponge.rate; + return PyLong_FromLong(capacity); +} + + +static PyObject * +SHA3_get_rate_bits(SHA3object *self, void *closure) +{ + unsigned int rate = self->hash_state.sponge.rate; + return PyLong_FromLong(rate); +} + +static PyObject * +SHA3_get_suffix(SHA3object *self, void *closure) +{ + unsigned char suffix[2]; + suffix[0] = self->hash_state.delimitedSuffix; + suffix[1] = 0; + return PyBytes_FromStringAndSize((const char *)suffix, 1); +} + + +static PyGetSetDef SHA3_getseters[] = { + {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL}, + {"name", (getter)SHA3_get_name, NULL, NULL, NULL}, + {"digest_size", (getter)SHA3_get_digest_size, NULL, NULL, NULL}, + {"_capacity_bits", (getter)SHA3_get_capacity_bits, NULL, NULL, NULL}, + {"_rate_bits", (getter)SHA3_get_rate_bits, NULL, NULL, NULL}, + {"_suffix", (getter)SHA3_get_suffix, NULL, NULL, NULL}, + {NULL} /* Sentinel */ +}; + + +#define SHA3_TYPE(type_obj, type_name, type_doc, type_methods) \ + static PyTypeObject type_obj = { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + type_name, /* tp_name */ \ + sizeof(SHA3object), /* tp_size */ \ + 0, /* tp_itemsize */ \ + /* methods */ \ + (destructor)SHA3_dealloc, /* tp_dealloc */ \ + 0, /* tp_print */ \ + 0, /* tp_getattr */ \ + 0, /* tp_setattr */ \ + 0, /* tp_reserved */ \ + 0, /* tp_repr */ \ + 0, /* tp_as_number */ \ + 0, /* tp_as_sequence */ \ + 0, /* tp_as_mapping */ \ + 0, /* tp_hash */ \ + 0, /* tp_call */ \ + 0, /* tp_str */ \ + 0, /* tp_getattro */ \ + 0, /* tp_setattro */ \ + 0, /* tp_as_buffer */ \ + Py_TPFLAGS_DEFAULT, /* tp_flags */ \ + type_doc, /* tp_doc */ \ + 0, /* tp_traverse */ \ + 0, /* tp_clear */ \ + 0, /* tp_richcompare */ \ + 0, /* tp_weaklistoffset */ \ + 0, /* tp_iter */ \ + 0, /* tp_iternext */ \ + type_methods, /* tp_methods */ \ + NULL, /* tp_members */ \ + SHA3_getseters, /* tp_getset */ \ + 0, /* tp_base */ \ + 0, /* tp_dict */ \ + 0, /* tp_descr_get */ \ + 0, /* tp_descr_set */ \ + 0, /* tp_dictoffset */ \ + 0, /* tp_init */ \ + 0, /* tp_alloc */ \ + py_sha3_new, /* tp_new */ \ + } + +PyDoc_STRVAR(sha3_256__doc__, +"sha3_256([string]) -> SHA3 object\n\ +\n\ +Return a new SHA3 hash object with a hashbit length of 32 bytes."); + +PyDoc_STRVAR(sha3_384__doc__, +"sha3_384([string]) -> SHA3 object\n\ +\n\ +Return a new SHA3 hash object with a hashbit length of 48 bytes."); + +PyDoc_STRVAR(sha3_512__doc__, +"sha3_512([string]) -> SHA3 object\n\ +\n\ +Return a new SHA3 hash object with a hashbit length of 64 bytes."); + +SHA3_TYPE(SHA3_224type, "_sha3.sha3_224", py_sha3_new__doc__, SHA3_methods); +SHA3_TYPE(SHA3_256type, "_sha3.sha3_256", sha3_256__doc__, SHA3_methods); +SHA3_TYPE(SHA3_384type, "_sha3.sha3_384", sha3_384__doc__, SHA3_methods); +SHA3_TYPE(SHA3_512type, "_sha3.sha3_512", sha3_512__doc__, SHA3_methods); + +#ifdef PY_WITH_KECCAK +PyDoc_STRVAR(keccak_224__doc__, +"keccak_224([string]) -> Keccak object\n\ +\n\ +Return a new Keccak hash object with a hashbit length of 28 bytes."); + +PyDoc_STRVAR(keccak_256__doc__, +"keccak_256([string]) -> Keccak object\n\ +\n\ +Return a new Keccak hash object with a hashbit length of 32 bytes."); + +PyDoc_STRVAR(keccak_384__doc__, +"keccak_384([string]) -> Keccak object\n\ +\n\ +Return a new Keccak hash object with a hashbit length of 48 bytes."); + +PyDoc_STRVAR(keccak_512__doc__, +"keccak_512([string]) -> Keccak object\n\ +\n\ +Return a new Keccak hash object with a hashbit length of 64 bytes."); + +SHA3_TYPE(Keccak_224type, "_sha3.keccak_224", keccak_224__doc__, SHA3_methods); +SHA3_TYPE(Keccak_256type, "_sha3.keccak_256", keccak_256__doc__, SHA3_methods); +SHA3_TYPE(Keccak_384type, "_sha3.keccak_384", keccak_384__doc__, SHA3_methods); +SHA3_TYPE(Keccak_512type, "_sha3.keccak_512", keccak_512__doc__, SHA3_methods); +#endif + + +static PyObject * +_SHAKE_digest(SHA3object *self, unsigned long digestlen, int hex) +{ + unsigned char *digest = NULL; + SHA3_state temp; + int res; + PyObject *result = NULL; + + /* ExtractLane needs at least SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE and + * SHA3_LANESIZE extra space. + */ + digest = (unsigned char*)PyMem_Malloc(digestlen + SHA3_LANESIZE); + if (digest == NULL) { + return PyErr_NoMemory(); + } + + /* Get the raw (binary) digest value */ + ENTER_HASHLIB(self); + SHA3_copystate(temp, self->hash_state); + LEAVE_HASHLIB(self); + res = SHA3_done(&temp, NULL); + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 done()"); + goto error; + } + res = SHA3_squeeze(&temp, digest, digestlen * 8); + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Squeeze()"); + return NULL; + } + if (hex) { + result = _Py_strhex((const char *)digest, digestlen); + } else { + result = PyBytes_FromStringAndSize((const char *)digest, + digestlen); + } + error: + if (digest != NULL) { + PyMem_Free(digest); + } + return result; +} + + +/*[clinic input] +_sha3.shake_128.digest + + length: unsigned_long(bitwise=True) + \ + +Return the digest value as a string of binary data. +[clinic start generated code]*/ + +static PyObject * +_sha3_shake_128_digest_impl(SHA3object *self, unsigned long length) +/*[clinic end generated code: output=2313605e2f87bb8f input=608c8ca80ae9d115]*/ +{ + return _SHAKE_digest(self, length, 0); +} + + +/*[clinic input] +_sha3.shake_128.hexdigest + + length: unsigned_long(bitwise=True) + \ + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +_sha3_shake_128_hexdigest_impl(SHA3object *self, unsigned long length) +/*[clinic end generated code: output=bf8e2f1e490944a8 input=64e56b4760db4573]*/ +{ + return _SHAKE_digest(self, length, 1); +} + + +static PyMethodDef SHAKE_methods[] = { + _SHA3_SHA3_224_COPY_METHODDEF + _SHA3_SHAKE_128_DIGEST_METHODDEF + _SHA3_SHAKE_128_HEXDIGEST_METHODDEF + _SHA3_SHA3_224_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(shake_128__doc__, +"shake_128([string]) -> SHAKE object\n\ +\n\ +Return a new SHAKE hash object."); + +PyDoc_STRVAR(shake_256__doc__, +"shake_256([string]) -> SHAKE object\n\ +\n\ +Return a new SHAKE hash object."); + +SHA3_TYPE(SHAKE128type, "_sha3.shake_128", shake_128__doc__, SHAKE_methods); +SHA3_TYPE(SHAKE256type, "_sha3.shake_256", shake_256__doc__, SHAKE_methods); + + +/* Initialize this module. */ +static struct PyModuleDef _SHA3module = { + PyModuleDef_HEAD_INIT, + "_sha3", + NULL, + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__sha3(void) +{ + PyObject *m = NULL; + + if ((m = PyModule_Create(&_SHA3module)) == NULL) { + return NULL; + } + +#define init_sha3type(name, type) \ + do { \ + Py_TYPE(type) = &PyType_Type; \ + if (PyType_Ready(type) < 0) { \ + goto error; \ + } \ + Py_INCREF((PyObject *)type); \ + if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \ + goto error; \ + } \ + } while(0) + + init_sha3type("sha3_224", &SHA3_224type); + init_sha3type("sha3_256", &SHA3_256type); + init_sha3type("sha3_384", &SHA3_384type); + init_sha3type("sha3_512", &SHA3_512type); +#ifdef PY_WITH_KECCAK + init_sha3type("keccak_224", &Keccak_224type); + init_sha3type("keccak_256", &Keccak_256type); + init_sha3type("keccak_384", &Keccak_384type); + init_sha3type("keccak_512", &Keccak_512type); +#endif + init_sha3type("shake_128", &SHAKE128type); + init_sha3type("shake_256", &SHAKE256type); + +#undef init_sha3type + + if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { + goto error; + } + if (PyModule_AddStringConstant(m, "implementation", + KeccakP1600_implementation) < 0) { + goto error; + } + + return m; + error: + Py_DECREF(m); + return NULL; +} diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 3689a4e..62c5893 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -244,8 +244,7 @@ PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) ptr = ptr->next; } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyMethodDef cache_methods[] = { diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 3c52108..4a10ce5 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -366,8 +366,7 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) } } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } /* @@ -673,7 +672,7 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_ aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); if (*aggregate_instance == 0) { - *aggregate_instance = PyObject_CallFunction(aggregate_class, ""); + *aggregate_instance = PyObject_CallFunction(aggregate_class, NULL); if (PyErr_Occurred()) { *aggregate_instance = 0; @@ -745,7 +744,7 @@ void _pysqlite_final_callback(sqlite3_context* context) PyErr_Fetch(&exception, &value, &tb); restore = 1; - function_result = _PyObject_CallMethodId(*aggregate_instance, &PyId_finalize, ""); + function_result = _PyObject_CallMethodId(*aggregate_instance, &PyId_finalize, NULL); Py_DECREF(*aggregate_instance); @@ -874,8 +873,7 @@ PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObjec if (PyDict_SetItem(self->function_pinboard, func, Py_None) == -1) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } } @@ -906,8 +904,7 @@ PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObje if (PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None) == -1) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } } @@ -963,7 +960,7 @@ static int _progress_handler(void* user_arg) gilstate = PyGILState_Ensure(); #endif - ret = PyObject_CallFunction((PyObject*)user_arg, ""); + ret = PyObject_CallFunction((PyObject*)user_arg, NULL); if (!ret) { if (_enable_callback_tracebacks) { @@ -1042,8 +1039,7 @@ static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, P if (PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None) == -1) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } } @@ -1072,8 +1068,7 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s return NULL; } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) @@ -1100,8 +1095,7 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel sqlite3_trace(self->db, _trace_callback, trace_callback); } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #ifdef HAVE_LOAD_EXTENSION @@ -1124,8 +1118,7 @@ static PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObj PyErr_SetString(pysqlite_OperationalError, "Error enabling load extension"); return NULL; } else { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } } @@ -1148,8 +1141,7 @@ static PyObject* pysqlite_load_extension(pysqlite_Connection* self, PyObject* ar PyErr_SetString(pysqlite_OperationalError, errmsg); return NULL; } else { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } } #endif @@ -1299,7 +1291,7 @@ PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args) PyObject* result = 0; PyObject* method = 0; - cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, ""); + cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, NULL); if (!cursor) { goto error; } @@ -1328,7 +1320,7 @@ PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* a PyObject* result = 0; PyObject* method = 0; - cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, ""); + cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, NULL); if (!cursor) { goto error; } @@ -1357,7 +1349,7 @@ PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* PyObject* result = 0; PyObject* method = 0; - cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, ""); + cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, NULL); if (!cursor) { goto error; } @@ -1527,7 +1519,7 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) goto finally; } - uppercase_name = _PyObject_CallMethodId(name, &PyId_upper, ""); + uppercase_name = _PyObject_CallMethodId(name, &PyId_upper, NULL); if (!uppercase_name) { goto finally; } @@ -1619,7 +1611,7 @@ pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) method_name = "rollback"; } - result = PyObject_CallMethod((PyObject*)self, method_name, ""); + result = PyObject_CallMethod((PyObject*)self, method_name, NULL); if (!result) { return NULL; } @@ -1628,7 +1620,7 @@ pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) Py_RETURN_FALSE; } -static char connection_doc[] = +static const char connection_doc[] = PyDoc_STR("SQLite database connection object."); static PyGetSetDef connection_getset[] = { diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index e1676de..e2c7a34 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -27,7 +27,7 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self); -static char* errmsg_fetch_across_rollback = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from."; +static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from."; static pysqlite_StatementKind detect_statement_type(const char* statement) { @@ -143,7 +143,7 @@ PyObject* _pysqlite_get_converter(PyObject* key) PyObject* retval; _Py_IDENTIFIER(upper); - upcase_key = _PyObject_CallMethodId(key, &PyId_upper, ""); + upcase_key = _PyObject_CallMethodId(key, &PyId_upper, NULL); if (!upcase_key) { return NULL; } @@ -242,8 +242,7 @@ PyObject* _pysqlite_build_column_name(const char* colname) const char* pos; if (!colname) { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } for (pos = colname;; pos++) { @@ -698,7 +697,9 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* } Py_DECREF(self->lastrowid); - if (!multiple && statement_type == STATEMENT_INSERT) { + if (!multiple && + /* REPLACE is an alias for INSERT OR REPLACE */ + (statement_type == STATEMENT_INSERT || statement_type == STATEMENT_REPLACE)) { sqlite_int64 lastrowid; Py_BEGIN_ALLOW_THREADS lastrowid = sqlite3_last_insert_rowid(self->connection->db); @@ -913,8 +914,7 @@ PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args) row = pysqlite_cursor_iternext(self); if (!row && !PyErr_Occurred()) { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } return row; @@ -995,8 +995,7 @@ PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args) PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args) { /* don't care, return None */ - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) @@ -1012,8 +1011,7 @@ PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) self->closed = 1; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyMethodDef cursor_methods[] = { @@ -1049,7 +1047,7 @@ static struct PyMemberDef cursor_members[] = {NULL} }; -static char cursor_doc[] = +static const char cursor_doc[] = PyDoc_STR("SQLite database cursor class."); PyTypeObject pysqlite_CursorType = { diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 7a7e860..cc45331 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -139,8 +139,7 @@ static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyOb PyErr_SetString(pysqlite_OperationalError, "Changing the shared_cache flag failed"); return NULL; } else { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } } @@ -172,8 +171,7 @@ static PyObject* module_register_adapter(PyObject* self, PyObject* args) if (rc == -1) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } PyDoc_STRVAR(module_register_adapter_doc, @@ -194,7 +192,7 @@ static PyObject* module_register_converter(PyObject* self, PyObject* args) } /* convert the name to upper case */ - name = _PyObject_CallMethodId(orig_name, &PyId_upper, ""); + name = _PyObject_CallMethodId(orig_name, &PyId_upper, NULL); if (!name) { goto error; } @@ -221,8 +219,7 @@ static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args) return NULL; } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } PyDoc_STRVAR(enable_callback_tracebacks_doc, @@ -261,13 +258,13 @@ static PyMethodDef module_methods[] = { }; struct _IntConstantPair { - char* constant_name; + const char *constant_name; int constant_value; }; typedef struct _IntConstantPair IntConstantPair; -static IntConstantPair _int_constants[] = { +static const IntConstantPair _int_constants[] = { {"PARSE_DECLTYPES", PARSE_DECLTYPES}, {"PARSE_COLNAMES", PARSE_COLNAMES}, diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c index 312fe3b..351b1b4 100644 --- a/Modules/_sqlite/util.c +++ b/Modules/_sqlite/util.c @@ -113,7 +113,6 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st) PyObject * _pysqlite_long_from_int64(sqlite_int64 value) { -#ifdef HAVE_LONG_LONG # if SIZEOF_LONG_LONG < 8 if (value > PY_LLONG_MAX || value < PY_LLONG_MIN) { return _PyLong_FromByteArray(&value, sizeof(value), @@ -124,14 +123,6 @@ _pysqlite_long_from_int64(sqlite_int64 value) if (value > LONG_MAX || value < LONG_MIN) return PyLong_FromLongLong(value); # endif -#else -# if SIZEOF_LONG < 8 - if (value > LONG_MAX || value < LONG_MIN) { - return _PyLong_FromByteArray(&value, sizeof(value), - IS_LITTLE_ENDIAN, 1 /* signed */); - } -# endif -#endif return PyLong_FromLong(Py_SAFE_DOWNCAST(value, sqlite_int64, long)); } @@ -139,23 +130,13 @@ sqlite_int64 _pysqlite_long_as_int64(PyObject * py_val) { int overflow; -#ifdef HAVE_LONG_LONG - PY_LONG_LONG value = PyLong_AsLongLongAndOverflow(py_val, &overflow); -#else - long value = PyLong_AsLongAndOverflow(py_val, &overflow); -#endif + long long value = PyLong_AsLongLongAndOverflow(py_val, &overflow); if (value == -1 && PyErr_Occurred()) return -1; if (!overflow) { -#ifdef HAVE_LONG_LONG # if SIZEOF_LONG_LONG > 8 if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL) # endif -#else -# if SIZEOF_LONG > 8 - if (-0x8000000000000000L <= value && value <= 0x7FFFFFFFFFFFFFFFL) -# endif -#endif return value; } else if (sizeof(value) < sizeof(sqlite_int64)) { diff --git a/Modules/_sre.c b/Modules/_sre.c index 09b5835..afa9099 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -35,7 +35,7 @@ * other compatibility work. */ -static char copyright[] = +static const char copyright[] = " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB "; #define PY_SSIZE_T_CLEAN @@ -62,9 +62,6 @@ static char copyright[] = /* -------------------------------------------------------------------- */ /* optional features */ -/* enables fast searching */ -#define USE_FAST_SEARCH - /* enables copy/deepcopy handling (work in progress) */ #undef USE_BUILTIN_COPY @@ -717,7 +714,7 @@ _sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, } static PyObject* -call(char* module, char* function, PyObject* args) +call(const char* module, const char* function, PyObject* args) { PyObject* name; PyObject* mod; @@ -1059,7 +1056,6 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, PyObject* joiner; PyObject* item; PyObject* filter; - PyObject* args; PyObject* match; void* ptr; Py_ssize_t status; @@ -1161,13 +1157,7 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, match = pattern_new_match(self, &state, 1); if (!match) goto error; - args = PyTuple_Pack(1, match); - if (!args) { - Py_DECREF(match); - goto error; - } - item = PyObject_CallObject(filter, args); - Py_DECREF(args); + item = _PyObject_CallArg1(filter, match); Py_DECREF(match); if (!item) goto error; @@ -1592,7 +1582,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, skip = *code; \ VTRACE(("%lu (skip to %p)\n", \ (unsigned long)skip, code+skip)); \ - if (skip-adj > (Py_uintptr_t)(end - code)) \ + if (skip-adj > (uintptr_t)(end - code)) \ FAIL; \ code++; \ } while (0) @@ -1626,7 +1616,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) case SRE_OP_CHARSET: offset = 256/SRE_CODE_BITS; /* 256-bit bitmap */ - if (offset > (Py_uintptr_t)(end - code)) + if (offset > (uintptr_t)(end - code)) FAIL; code += offset; break; @@ -1634,7 +1624,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) case SRE_OP_BIGCHARSET: GET_ARG; /* Number of blocks */ offset = 256/sizeof(SRE_CODE); /* 256-byte table */ - if (offset > (Py_uintptr_t)(end - code)) + if (offset > (uintptr_t)(end - code)) FAIL; /* Make sure that each byte points to a valid block */ for (i = 0; i < 256; i++) { @@ -1643,7 +1633,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) } code += offset; offset = arg * (256/SRE_CODE_BITS); /* 256-bit bitmap times arg */ - if (offset > (Py_uintptr_t)(end - code)) + if (offset > (uintptr_t)(end - code)) FAIL; code += offset; break; @@ -1794,11 +1784,11 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) GET_ARG; prefix_len = arg; GET_ARG; /* Here comes the prefix string */ - if (prefix_len > (Py_uintptr_t)(newcode - code)) + if (prefix_len > (uintptr_t)(newcode - code)) FAIL; code += prefix_len; /* And here comes the overlap table */ - if (prefix_len > (Py_uintptr_t)(newcode - code)) + if (prefix_len > (uintptr_t)(newcode - code)) FAIL; /* Each overlap value should be < prefix_len */ for (i = 0; i < prefix_len; i++) { @@ -1927,7 +1917,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) to allow arbitrary jumps anywhere in the code; so we just look for a JUMP opcode preceding our skip target. */ - if (skip >= 3 && skip-3 < (Py_uintptr_t)(end - code) && + if (skip >= 3 && skip-3 < (uintptr_t)(end - code) && code[skip-3] == SRE_OP_JUMP) { VTRACE(("both then and else parts present\n")); @@ -2052,8 +2042,9 @@ match_getindex(MatchObject* self, PyObject* index) /* Default value */ return 0; - if (PyLong_Check(index)) - return PyLong_AsSsize_t(index); + if (PyIndex_Check(index)) { + return PyNumber_AsSsize_t(index, NULL); + } i = -1; diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a79c3a8..b4fac44 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -455,7 +455,7 @@ fail: } static PyObject * -PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno) +PySSL_SetError(PySSLSocket *obj, int ret, const char *filename, int lineno) { PyObject *type = PySSLErrorObject; char *errstr = NULL; @@ -537,7 +537,7 @@ PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno) } static PyObject * -_setSSLError (char *errstr, int errcode, char *filename, int lineno) { +_setSSLError (const char *errstr, int errcode, const char *filename, int lineno) { if (errstr == NULL) errcode = ERR_peek_last_error(); @@ -1547,6 +1547,76 @@ cipher_to_tuple(const SSL_CIPHER *cipher) return NULL; } +#if OPENSSL_VERSION_NUMBER >= 0x10002000UL +static PyObject * +cipher_to_dict(const SSL_CIPHER *cipher) +{ + const char *cipher_name, *cipher_protocol; + + unsigned long cipher_id; + int alg_bits, strength_bits, len; + char buf[512] = {0}; +#if OPENSSL_VERSION_1_1 + int aead, nid; + const char *skcipher = NULL, *digest = NULL, *kx = NULL, *auth = NULL; +#endif + PyObject *retval; + + retval = PyDict_New(); + if (retval == NULL) { + goto error; + } + + /* can be NULL */ + cipher_name = SSL_CIPHER_get_name(cipher); + cipher_protocol = SSL_CIPHER_get_version(cipher); + cipher_id = SSL_CIPHER_get_id(cipher); + SSL_CIPHER_description(cipher, buf, sizeof(buf) - 1); + len = strlen(buf); + if (len > 1 && buf[len-1] == '\n') + buf[len-1] = '\0'; + strength_bits = SSL_CIPHER_get_bits(cipher, &alg_bits); + +#if OPENSSL_VERSION_1_1 + aead = SSL_CIPHER_is_aead(cipher); + nid = SSL_CIPHER_get_cipher_nid(cipher); + skcipher = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; + nid = SSL_CIPHER_get_digest_nid(cipher); + digest = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; + nid = SSL_CIPHER_get_kx_nid(cipher); + kx = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; + nid = SSL_CIPHER_get_auth_nid(cipher); + auth = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; +#endif + + retval = Py_BuildValue( + "{sksssssssisi" +#if OPENSSL_VERSION_1_1 + "sOssssssss" +#endif + "}", + "id", cipher_id, + "name", cipher_name, + "protocol", cipher_protocol, + "description", buf, + "strength_bits", strength_bits, + "alg_bits", alg_bits +#if OPENSSL_VERSION_1_1 + ,"aead", aead ? Py_True : Py_False, + "symmetric", skcipher, + "digest", digest, + "kea", kx, + "auth", auth +#endif + ); + return retval; + + error: + Py_XDECREF(retval); + return NULL; +} +#endif + /*[clinic input] _ssl._SSLSocket.shared_ciphers [clinic start generated code]*/ @@ -2506,6 +2576,52 @@ _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) Py_RETURN_NONE; } +#if OPENSSL_VERSION_NUMBER >= 0x10002000UL +/*[clinic input] +_ssl._SSLContext.get_ciphers +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_get_ciphers_impl(PySSLContext *self) +/*[clinic end generated code: output=a56e4d68a406dfc4 input=a2aadc9af89b79c5]*/ +{ + SSL *ssl = NULL; + STACK_OF(SSL_CIPHER) *sk = NULL; + SSL_CIPHER *cipher; + int i=0; + PyObject *result = NULL, *dct; + + ssl = SSL_new(self->ctx); + if (ssl == NULL) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto exit; + } + sk = SSL_get_ciphers(ssl); + + result = PyList_New(sk_SSL_CIPHER_num(sk)); + if (result == NULL) { + goto exit; + } + + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + cipher = sk_SSL_CIPHER_value(sk, i); + dct = cipher_to_dict(cipher); + if (dct == NULL) { + Py_CLEAR(result); + goto exit; + } + PyList_SET_ITEM(result, i, dct); + } + + exit: + if (ssl != NULL) + SSL_free(ssl); + return result; + +} +#endif + + #ifdef OPENSSL_NPN_NEGOTIATED static int do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen, @@ -3673,6 +3789,7 @@ static struct PyMethodDef context_methods[] = { _SSL__SSLCONTEXT_SET_SERVERNAME_CALLBACK_METHODDEF _SSL__SSLCONTEXT_CERT_STORE_STATS_METHODDEF _SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF + _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_struct.c b/Modules/_struct.c index f965541..0820961 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -60,6 +60,7 @@ typedef struct { char c; float x; } st_float; typedef struct { char c; double x; } st_double; typedef struct { char c; void *x; } st_void_p; typedef struct { char c; size_t x; } st_size_t; +typedef struct { char c; _Bool x; } st_bool; #define SHORT_ALIGN (sizeof(st_short) - sizeof(short)) #define INT_ALIGN (sizeof(st_int) - sizeof(int)) @@ -68,22 +69,12 @@ typedef struct { char c; size_t x; } st_size_t; #define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double)) #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *)) #define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t)) +#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool)) /* We can't support q and Q in native mode unless the compiler does; in std mode, they're 8 bytes on all platforms. */ -#ifdef HAVE_LONG_LONG -typedef struct { char c; PY_LONG_LONG x; } s_long_long; -#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG)) -#endif - -#ifdef HAVE_C99_BOOL -#define BOOL_TYPE _Bool -typedef struct { char c; _Bool x; } s_bool; -#define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE)) -#else -#define BOOL_TYPE char -#define BOOL_ALIGN 0 -#endif +typedef struct { char c; long long x; } s_long_long; +#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) #ifdef __powerc #pragma options align=reset @@ -164,14 +155,12 @@ get_ulong(PyObject *v, unsigned long *p) return 0; } -#ifdef HAVE_LONG_LONG - /* Same, but handling native long long. */ static int -get_longlong(PyObject *v, PY_LONG_LONG *p) +get_longlong(PyObject *v, long long *p) { - PY_LONG_LONG x; + long long x; v = get_pylong(v); if (v == NULL) @@ -179,7 +168,7 @@ get_longlong(PyObject *v, PY_LONG_LONG *p) assert(PyLong_Check(v)); x = PyLong_AsLongLong(v); Py_DECREF(v); - if (x == (PY_LONG_LONG)-1 && PyErr_Occurred()) { + if (x == (long long)-1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(StructError, "argument out of range"); @@ -192,9 +181,9 @@ get_longlong(PyObject *v, PY_LONG_LONG *p) /* Same, but handling native unsigned long long. */ static int -get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) +get_ulonglong(PyObject *v, unsigned long long *p) { - unsigned PY_LONG_LONG x; + unsigned long long x; v = get_pylong(v); if (v == NULL) @@ -202,7 +191,7 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) assert(PyLong_Check(v)); x = PyLong_AsUnsignedLongLong(v); Py_DECREF(v); - if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) { + if (x == (unsigned long long)-1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(StructError, "argument out of range"); @@ -212,8 +201,6 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) return 0; } -#endif - /* Same, but handling Py_ssize_t */ static int @@ -267,6 +254,33 @@ get_size_t(PyObject *v, size_t *p) /* Floating point helpers */ static PyObject * +unpack_halffloat(const char *p, /* start of 2-byte string */ + int le) /* true for little-endian, false for big-endian */ +{ + double x; + + x = _PyFloat_Unpack2((unsigned char *)p, le); + if (x == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(x); +} + +static int +pack_halffloat(char *p, /* start of 2-byte string */ + PyObject *v, /* value to pack */ + int le) /* true for little-endian, false for big-endian */ +{ + double x = PyFloat_AsDouble(v); + if (x == -1.0 && PyErr_Occurred()) { + PyErr_SetString(StructError, + "required argument is not a float"); + return -1; + } + return _PyFloat_Pack2(x, (unsigned char *)p, le); +} + +static PyObject * unpack_float(const char *p, /* start of 4-byte string */ int le) /* true for little-endian, false for big-endian */ { @@ -436,40 +450,46 @@ nu_size_t(const char *p, const formatdef *f) /* Native mode doesn't support q or Q unless the platform C supports long long (or, on Windows, __int64). */ -#ifdef HAVE_LONG_LONG - static PyObject * nu_longlong(const char *p, const formatdef *f) { - PY_LONG_LONG x; + long long x; memcpy((char *)&x, p, sizeof x); if (x >= LONG_MIN && x <= LONG_MAX) - return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long)); + return PyLong_FromLong(Py_SAFE_DOWNCAST(x, long long, long)); return PyLong_FromLongLong(x); } static PyObject * nu_ulonglong(const char *p, const formatdef *f) { - unsigned PY_LONG_LONG x; + unsigned long long x; memcpy((char *)&x, p, sizeof x); if (x <= LONG_MAX) - return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long)); + return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned long long, long)); return PyLong_FromUnsignedLongLong(x); } -#endif - static PyObject * nu_bool(const char *p, const formatdef *f) { - BOOL_TYPE x; + _Bool x; memcpy((char *)&x, p, sizeof x); return PyBool_FromLong(x != 0); } static PyObject * +nu_halffloat(const char *p, const formatdef *f) +{ +#if PY_LITTLE_ENDIAN + return unpack_halffloat(p, 1); +#else + return unpack_halffloat(p, 0); +#endif +} + +static PyObject * nu_float(const char *p, const formatdef *f) { float x; @@ -643,12 +663,10 @@ np_size_t(char *p, PyObject *v, const formatdef *f) return 0; } -#ifdef HAVE_LONG_LONG - static int np_longlong(char *p, PyObject *v, const formatdef *f) { - PY_LONG_LONG x; + long long x; if (get_longlong(v, &x) < 0) return -1; memcpy(p, (char *)&x, sizeof x); @@ -658,20 +676,19 @@ np_longlong(char *p, PyObject *v, const formatdef *f) static int np_ulonglong(char *p, PyObject *v, const formatdef *f) { - unsigned PY_LONG_LONG x; + unsigned long long x; if (get_ulonglong(v, &x) < 0) return -1; memcpy(p, (char *)&x, sizeof x); return 0; } -#endif static int np_bool(char *p, PyObject *v, const formatdef *f) { int y; - BOOL_TYPE x; + _Bool x; y = PyObject_IsTrue(v); if (y < 0) return -1; @@ -681,6 +698,16 @@ np_bool(char *p, PyObject *v, const formatdef *f) } static int +np_halffloat(char *p, PyObject *v, const formatdef *f) +{ +#if PY_LITTLE_ENDIAN + return pack_halffloat(p, v, 1); +#else + return pack_halffloat(p, v, 0); +#endif +} + +static int np_float(char *p, PyObject *v, const formatdef *f) { float x = (float)PyFloat_AsDouble(v); @@ -723,7 +750,7 @@ np_void_p(char *p, PyObject *v, const formatdef *f) return 0; } -static formatdef native_table[] = { +static const formatdef native_table[] = { {'x', sizeof(char), 0, NULL}, {'b', sizeof(char), 0, nu_byte, np_byte}, {'B', sizeof(char), 0, nu_ubyte, np_ubyte}, @@ -738,11 +765,10 @@ static formatdef native_table[] = { {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong}, {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t}, {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t}, -#ifdef HAVE_LONG_LONG - {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong}, - {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, -#endif - {'?', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool}, + {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong}, + {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, + {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool}, + {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat}, {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float}, {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double}, {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p}, @@ -783,8 +809,7 @@ bu_uint(const char *p, const formatdef *f) static PyObject * bu_longlong(const char *p, const formatdef *f) { -#ifdef HAVE_LONG_LONG - PY_LONG_LONG x = 0; + long long x = 0; Py_ssize_t i = f->size; const unsigned char *bytes = (const unsigned char *)p; do { @@ -792,37 +817,30 @@ bu_longlong(const char *p, const formatdef *f) } while (--i > 0); /* Extend the sign bit. */ if (SIZEOF_LONG_LONG > f->size) - x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1))); + x |= -(x & ((long long)1 << ((8 * f->size) - 1))); if (x >= LONG_MIN && x <= LONG_MAX) - return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long)); + return PyLong_FromLong(Py_SAFE_DOWNCAST(x, long long, long)); return PyLong_FromLongLong(x); -#else - return _PyLong_FromByteArray((const unsigned char *)p, - 8, - 0, /* little-endian */ - 1 /* signed */); -#endif } static PyObject * bu_ulonglong(const char *p, const formatdef *f) { -#ifdef HAVE_LONG_LONG - unsigned PY_LONG_LONG x = 0; + unsigned long long x = 0; Py_ssize_t i = f->size; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | *bytes++; } while (--i > 0); if (x <= LONG_MAX) - return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long)); + return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned long long, long)); return PyLong_FromUnsignedLongLong(x); -#else - return _PyLong_FromByteArray((const unsigned char *)p, - 8, - 0, /* little-endian */ - 0 /* signed */); -#endif +} + +static PyObject * +bu_halffloat(const char *p, const formatdef *f) +{ + return unpack_halffloat(p, 0); } static PyObject * @@ -922,6 +940,12 @@ bp_ulonglong(char *p, PyObject *v, const formatdef *f) } static int +bp_halffloat(char *p, PyObject *v, const formatdef *f) +{ + return pack_halffloat(p, v, 0); +} + +static int bp_float(char *p, PyObject *v, const formatdef *f) { double x = PyFloat_AsDouble(v); @@ -972,6 +996,7 @@ static formatdef bigendian_table[] = { {'q', 8, 0, bu_longlong, bp_longlong}, {'Q', 8, 0, bu_ulonglong, bp_ulonglong}, {'?', 1, 0, bu_bool, bp_bool}, + {'e', 2, 0, bu_halffloat, bp_halffloat}, {'f', 4, 0, bu_float, bp_float}, {'d', 8, 0, bu_double, bp_double}, {0} @@ -1011,8 +1036,7 @@ lu_uint(const char *p, const formatdef *f) static PyObject * lu_longlong(const char *p, const formatdef *f) { -#ifdef HAVE_LONG_LONG - PY_LONG_LONG x = 0; + long long x = 0; Py_ssize_t i = f->size; const unsigned char *bytes = (const unsigned char *)p; do { @@ -1020,37 +1044,30 @@ lu_longlong(const char *p, const formatdef *f) } while (i > 0); /* Extend the sign bit. */ if (SIZEOF_LONG_LONG > f->size) - x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1))); + x |= -(x & ((long long)1 << ((8 * f->size) - 1))); if (x >= LONG_MIN && x <= LONG_MAX) - return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long)); + return PyLong_FromLong(Py_SAFE_DOWNCAST(x, long long, long)); return PyLong_FromLongLong(x); -#else - return _PyLong_FromByteArray((const unsigned char *)p, - 8, - 1, /* little-endian */ - 1 /* signed */); -#endif } static PyObject * lu_ulonglong(const char *p, const formatdef *f) { -#ifdef HAVE_LONG_LONG - unsigned PY_LONG_LONG x = 0; + unsigned long long x = 0; Py_ssize_t i = f->size; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | bytes[--i]; } while (i > 0); if (x <= LONG_MAX) - return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long)); + return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned long long, long)); return PyLong_FromUnsignedLongLong(x); -#else - return _PyLong_FromByteArray((const unsigned char *)p, - 8, - 1, /* little-endian */ - 0 /* signed */); -#endif +} + +static PyObject * +lu_halffloat(const char *p, const formatdef *f) +{ + return unpack_halffloat(p, 1); } static PyObject * @@ -1142,6 +1159,12 @@ lp_ulonglong(char *p, PyObject *v, const formatdef *f) } static int +lp_halffloat(char *p, PyObject *v, const formatdef *f) +{ + return pack_halffloat(p, v, 1); +} + +static int lp_float(char *p, PyObject *v, const formatdef *f) { double x = PyFloat_AsDouble(v); @@ -1182,6 +1205,7 @@ static formatdef lilendian_table[] = { {'Q', 8, 0, lu_ulonglong, lp_ulonglong}, {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep, but potentially different from native rep -- reuse bx_bool funcs. */ + {'e', 2, 0, lu_halffloat, lp_halffloat}, {'f', 4, 0, lu_float, lp_float}, {'d', 8, 0, lu_double, lp_double}, {0} @@ -1189,7 +1213,7 @@ static formatdef lilendian_table[] = { static const formatdef * -whichtable(char **pfmt) +whichtable(const char **pfmt) { const char *fmt = (*pfmt)++; /* May be backed out of later */ switch (*fmt) { @@ -1268,7 +1292,7 @@ prepare_s(PyStructObject *self) fmt = PyBytes_AS_STRING(self->s_format); - f = whichtable((char **)&fmt); + f = whichtable(&fmt); s = fmt; size = 0; @@ -1456,7 +1480,7 @@ s_dealloc(PyStructObject *s) } static PyObject * -s_unpack_internal(PyStructObject *soself, char *startfrom) { +s_unpack_internal(PyStructObject *soself, const char *startfrom) { formatcode *code; Py_ssize_t i = 0; PyObject *result = PyTuple_New(soself->s_len); @@ -2239,7 +2263,7 @@ these can be preceded by a decimal repeat count:\n\ x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\ ?: _Bool (requires C99; if not available, char is used instead)\n\ h:short; H:unsigned short; i:int; I:unsigned int;\n\ - l:long; L:unsigned long; f:float; d:double.\n\ + l:long; L:unsigned long; f:float; d:double; e:half-float.\n\ Special cases (preceding decimal count indicates length):\n\ s:string (array of char); p: pascal string (with count byte).\n\ Special cases (only available in native format):\n\ @@ -2279,7 +2303,7 @@ PyInit__struct(void) /* Check endian and swap in faster functions */ { - formatdef *native = native_table; + const formatdef *native = native_table; formatdef *other, *ptr; #if PY_LITTLE_ENDIAN other = lilendian_table; diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 43db8a8..13d3ccc 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -13,7 +13,7 @@ PyObject *Struct = NULL; PyObject *calcsize = NULL; /* cache simple format string */ -static const char *simple_fmt = "B"; +static const char simple_fmt[] = "B"; PyObject *simple_format = NULL; #define SIMPLE_FORMAT(fmt) (fmt == NULL || strcmp(fmt, "B") == 0) #define FIX_FORMAT(fmt) (fmt == NULL ? "B" : fmt) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 81f5b1d..b5b8f1a 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -60,9 +60,7 @@ test_config(PyObject *self) CHECK_SIZEOF(SIZEOF_LONG, long); CHECK_SIZEOF(SIZEOF_VOID_P, void*); CHECK_SIZEOF(SIZEOF_TIME_T, time_t); -#ifdef HAVE_LONG_LONG - CHECK_SIZEOF(SIZEOF_LONG_LONG, PY_LONG_LONG); -#endif + CHECK_SIZEOF(SIZEOF_LONG_LONG, long long); #undef CHECK_SIZEOF @@ -100,22 +98,14 @@ test_sizeof_c_types(PyObject *self) CHECK_SIGNNESS(Py_UCS1, 0); CHECK_SIGNNESS(Py_UCS2, 0); CHECK_SIGNNESS(Py_UCS4, 0); -#ifdef HAVE_INT32_T - CHECK_SIZEOF(PY_INT32_T, 4); - CHECK_SIGNNESS(PY_INT32_T, 1); -#endif -#ifdef HAVE_UINT32_T - CHECK_SIZEOF(PY_UINT32_T, 4); - CHECK_SIGNNESS(PY_UINT32_T, 0); -#endif -#ifdef HAVE_INT64_T - CHECK_SIZEOF(PY_INT64_T, 8); - CHECK_SIGNNESS(PY_INT64_T, 1); -#endif -#ifdef HAVE_UINT64_T - CHECK_SIZEOF(PY_UINT64_T, 8); - CHECK_SIGNNESS(PY_UINT64_T, 0); -#endif + CHECK_SIZEOF(int32_t, 4); + CHECK_SIGNNESS(int32_t, 1); + CHECK_SIZEOF(uint32_t, 4); + CHECK_SIGNNESS(uint32_t, 0); + CHECK_SIZEOF(int64_t, 8); + CHECK_SIGNNESS(int64_t, 1); + CHECK_SIZEOF(uint64_t, 8); + CHECK_SIGNNESS(uint64_t, 0); /* pointer/size types */ CHECK_SIZEOF(size_t, sizeof(void *)); @@ -123,10 +113,10 @@ test_sizeof_c_types(PyObject *self) CHECK_SIZEOF(Py_ssize_t, sizeof(void *)); CHECK_SIGNNESS(Py_ssize_t, 1); - CHECK_SIZEOF(Py_uintptr_t, sizeof(void *)); - CHECK_SIGNNESS(Py_uintptr_t, 0); - CHECK_SIZEOF(Py_intptr_t, sizeof(void *)); - CHECK_SIGNNESS(Py_intptr_t, 1); + CHECK_SIZEOF(uintptr_t, sizeof(void *)); + CHECK_SIGNNESS(uintptr_t, 0); + CHECK_SIZEOF(intptr_t, sizeof(void *)); + CHECK_SIGNNESS(intptr_t, 1); Py_INCREF(Py_None); return Py_None; @@ -357,12 +347,12 @@ test_lazy_hash_inheritance(PyObject* self) } -/* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG) +/* Tests of PyLong_{As, From}{Unsigned,}Long(), and PyLong_{As, From}{Unsigned,}LongLong(). Note that the meat of the test is contained in testcapi_long.h. This is revolting, but delicate code duplication is worse: "almost - exactly the same" code is needed to test PY_LONG_LONG, but the ubiquitous + exactly the same" code is needed to test long long, but the ubiquitous dependence on type names makes it impossible to use a parameterized function. A giant macro would be even worse than this. A C++ template would be perfect. @@ -402,8 +392,6 @@ test_long_api(PyObject* self) #undef F_U_TO_PY #undef F_PY_TO_U -#ifdef HAVE_LONG_LONG - static PyObject * raise_test_longlong_error(const char* msg) { @@ -411,7 +399,7 @@ raise_test_longlong_error(const char* msg) } #define TESTNAME test_longlong_api_inner -#define TYPENAME PY_LONG_LONG +#define TYPENAME long long #define F_S_TO_PY PyLong_FromLongLong #define F_PY_TO_S PyLong_AsLongLong #define F_U_TO_PY PyLong_FromUnsignedLongLong @@ -598,7 +586,7 @@ test_long_and_overflow(PyObject *self) } /* Test the PyLong_AsLongLongAndOverflow API. General conversion to - PY_LONG_LONG is tested by test_long_api_inner. This test will + long long is tested by test_long_api_inner. This test will concentrate on proper handling of overflow. */ @@ -606,7 +594,7 @@ static PyObject * test_long_long_and_overflow(PyObject *self) { PyObject *num, *one, *temp; - PY_LONG_LONG value; + long long value; int overflow; /* Test that overflow is set properly for a large value. */ @@ -824,7 +812,7 @@ test_long_as_double(PyObject *self) return Py_None; } -/* Test the L code for PyArg_ParseTuple. This should deliver a PY_LONG_LONG +/* Test the L code for PyArg_ParseTuple. This should deliver a long long for both long and int arguments. The test may leak a little memory if it fails. */ @@ -832,7 +820,7 @@ static PyObject * test_L_code(PyObject *self) { PyObject *tuple, *num; - PY_LONG_LONG value; + long long value; tuple = PyTuple_New(1); if (tuple == NULL) @@ -870,8 +858,6 @@ test_L_code(PyObject *self) return Py_None; } -#endif /* ifdef HAVE_LONG_LONG */ - static PyObject * return_none(void *unused) { @@ -1001,7 +987,7 @@ static PyObject * getargs_keywords(PyObject *self, PyObject *args, PyObject *kwargs) { static char *keywords[] = {"arg1","arg2","arg3","arg4","arg5", NULL}; - static char *fmt="(ii)i|(i(ii))(iii)i"; + static const char fmt[] = "(ii)i|(i(ii))(iii)i"; int int_args[10]={-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, @@ -1028,6 +1014,21 @@ getargs_keyword_only(PyObject *self, PyObject *args, PyObject *kwargs) return Py_BuildValue("iii", required, optional, keyword_only); } +/* test PyArg_ParseTupleAndKeywords positional-only arguments */ +static PyObject * +getargs_positional_only_and_keywords(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = {"", "", "keyword", NULL}; + int required = -1; + int optional = -1; + int keyword = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii", keywords, + &required, &optional, &keyword)) + return NULL; + return Py_BuildValue("iii", required, optional, keyword); +} + /* Functions to call PyArg_ParseTuple with integer format codes, and return the result. */ @@ -1121,11 +1122,10 @@ getargs_p(PyObject *self, PyObject *args) return PyLong_FromLong(value); } -#ifdef HAVE_LONG_LONG static PyObject * getargs_L(PyObject *self, PyObject *args) { - PY_LONG_LONG value; + long long value; if (!PyArg_ParseTuple(args, "L", &value)) return NULL; return PyLong_FromLongLong(value); @@ -1134,12 +1134,11 @@ getargs_L(PyObject *self, PyObject *args) static PyObject * getargs_K(PyObject *self, PyObject *args) { - unsigned PY_LONG_LONG value; + unsigned long long value; if (!PyArg_ParseTuple(args, "K", &value)) return NULL; return PyLong_FromUnsignedLongLong(value); } -#endif /* This function not only tests the 'k' getargs code, but also the PyLong_AsUnsignedLongMask() and PyLong_AsUnsignedLongMask() functions. */ @@ -1161,7 +1160,7 @@ test_k_code(PyObject *self) value = PyLong_AsUnsignedLongMask(num); if (value != ULONG_MAX) return raiseTestError("test_k_code", - "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); + "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); PyTuple_SET_ITEM(tuple, 0, num); @@ -1180,7 +1179,7 @@ test_k_code(PyObject *self) value = PyLong_AsUnsignedLongMask(num); if (value != (unsigned long)-0x42) return raiseTestError("test_k_code", - "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); + "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); PyTuple_SET_ITEM(tuple, 0, num); @@ -2130,7 +2129,7 @@ _make_call(void *callable) PyObject *rc; int success; PyGILState_STATE s = PyGILState_Ensure(); - rc = PyObject_CallFunction((PyObject *)callable, ""); + rc = _PyObject_CallNoArg((PyObject *)callable); success = (rc != NULL); Py_XDECREF(rc); PyGILState_Release(s); @@ -2264,10 +2263,8 @@ test_string_from_format(PyObject *self, PyObject *args) CHECK_1_FORMAT("%zu", size_t); /* "%lld" and "%llu" support added in Python 2.7. */ -#ifdef HAVE_LONG_LONG - CHECK_1_FORMAT("%llu", unsigned PY_LONG_LONG); - CHECK_1_FORMAT("%lld", PY_LONG_LONG); -#endif + CHECK_1_FORMAT("%llu", unsigned long long); + CHECK_1_FORMAT("%lld", long long); Py_RETURN_NONE; @@ -2312,7 +2309,7 @@ test_string_to_double(PyObject *self) { result = PyOS_string_to_double(STR, NULL, NULL); \ if (result == -1.0 && PyErr_Occurred()) \ return NULL; \ - if (result != expected) { \ + if (result != (double)expected) { \ msg = "conversion of " STR " to float failed"; \ goto fail; \ } @@ -2904,7 +2901,9 @@ run_in_subinterp(PyObject *self, PyObject *args) static int check_time_rounding(int round) { - if (round != _PyTime_ROUND_FLOOR && round != _PyTime_ROUND_CEILING) { + if (round != _PyTime_ROUND_FLOOR + && round != _PyTime_ROUND_CEILING + && round != _PyTime_ROUND_HALF_EVEN) { PyErr_SetString(PyExc_ValueError, "invalid rounding"); return -1; } @@ -3399,7 +3398,7 @@ temporary_c_thread(void *data) /* Allocate a Python thread state for this thread */ state = PyGILState_Ensure(); - res = PyObject_CallFunction(test_c_thread->callback, "", NULL); + res = _PyObject_CallNoArg(test_c_thread->callback); Py_CLEAR(test_c_thread->callback); if (res == NULL) { @@ -3689,7 +3688,7 @@ test_pytime_fromsecondsobject(PyObject *self, PyObject *args) static PyObject * test_pytime_assecondsdouble(PyObject *self, PyObject *args) { - PY_LONG_LONG ns; + long long ns; _PyTime_t ts; double d; @@ -3703,7 +3702,7 @@ test_pytime_assecondsdouble(PyObject *self, PyObject *args) static PyObject * test_PyTime_AsTimeval(PyObject *self, PyObject *args) { - PY_LONG_LONG ns; + long long ns; int round; _PyTime_t t; struct timeval tv; @@ -3717,7 +3716,7 @@ test_PyTime_AsTimeval(PyObject *self, PyObject *args) if (_PyTime_AsTimeval(t, &tv, round) < 0) return NULL; - seconds = PyLong_FromLong((PY_LONG_LONG)tv.tv_sec); + seconds = PyLong_FromLong((long long)tv.tv_sec); if (seconds == NULL) return NULL; return Py_BuildValue("Nl", seconds, tv.tv_usec); @@ -3727,7 +3726,7 @@ test_PyTime_AsTimeval(PyObject *self, PyObject *args) static PyObject * test_PyTime_AsTimespec(PyObject *self, PyObject *args) { - PY_LONG_LONG ns; + long long ns; _PyTime_t t; struct timespec ts; @@ -3743,7 +3742,7 @@ test_PyTime_AsTimespec(PyObject *self, PyObject *args) static PyObject * test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) { - PY_LONG_LONG ns; + long long ns; int round; _PyTime_t t, ms; @@ -3761,7 +3760,7 @@ test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) static PyObject * test_PyTime_AsMicroseconds(PyObject *self, PyObject *args) { - PY_LONG_LONG ns; + long long ns; int round; _PyTime_t t, ms; @@ -3785,6 +3784,152 @@ get_recursion_depth(PyObject *self, PyObject *args) return PyLong_FromLong(tstate->recursion_depth - 1); } +static PyObject* +pymem_buffer_overflow(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate buffer overflow to check that PyMem_Free() detects + the overflow when debug hooks are installed. */ + buffer = PyMem_Malloc(16); + buffer[16] = 'x'; + PyMem_Free(buffer); + + Py_RETURN_NONE; +} + +static PyObject* +pymem_api_misuse(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate misusage of Python allocators: + allococate with PyMem but release with PyMem_Raw. */ + buffer = PyMem_Malloc(16); + PyMem_RawFree(buffer); + + Py_RETURN_NONE; +} + +static PyObject* +pymem_malloc_without_gil(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate bug to test debug hooks on Python memory allocators: + call PyMem_Malloc() without holding the GIL */ + Py_BEGIN_ALLOW_THREADS + buffer = PyMem_Malloc(10); + Py_END_ALLOW_THREADS + + PyMem_Free(buffer); + + Py_RETURN_NONE; +} + +static PyObject* +pyobject_malloc_without_gil(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate bug to test debug hooks on Python memory allocators: + call PyObject_Malloc() without holding the GIL */ + Py_BEGIN_ALLOW_THREADS + buffer = PyObject_Malloc(10); + Py_END_ALLOW_THREADS + + PyObject_Free(buffer); + + Py_RETURN_NONE; +} + +static PyObject * +tracemalloc_track(PyObject *self, PyObject *args) +{ + unsigned int domain; + PyObject *ptr_obj; + void *ptr; + Py_ssize_t size; + int release_gil = 0; + int res; + + if (!PyArg_ParseTuple(args, "IOn|i", &domain, &ptr_obj, &size, &release_gil)) + return NULL; + ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) + return NULL; + + if (release_gil) { + Py_BEGIN_ALLOW_THREADS + res = _PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); + Py_END_ALLOW_THREADS + } + else { + res = _PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); + } + + if (res < 0) { + PyErr_SetString(PyExc_RuntimeError, "_PyTraceMalloc_Track error"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject * +tracemalloc_untrack(PyObject *self, PyObject *args) +{ + unsigned int domain; + PyObject *ptr_obj; + void *ptr; + int res; + + if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) + return NULL; + ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) + return NULL; + + res = _PyTraceMalloc_Untrack(domain, (uintptr_t)ptr); + if (res < 0) { + PyErr_SetString(PyExc_RuntimeError, "_PyTraceMalloc_Track error"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject * +tracemalloc_get_traceback(PyObject *self, PyObject *args) +{ + unsigned int domain; + PyObject *ptr_obj; + void *ptr; + + if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) + return NULL; + ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) + return NULL; + + return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr); +} + +static PyObject * +dict_get_version(PyObject *self, PyObject *args) +{ + PyDictObject *dict; + uint64_t version; + + if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict)) + return NULL; + + version = dict->ma_version_tag; + + Py_BUILD_ASSERT(sizeof(unsigned PY_LONG_LONG) >= sizeof(version)); + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)version); +} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, @@ -3830,6 +3975,9 @@ static PyMethodDef TestMethods[] = { METH_VARARGS|METH_KEYWORDS}, {"getargs_keyword_only", (PyCFunction)getargs_keyword_only, METH_VARARGS|METH_KEYWORDS}, + {"getargs_positional_only_and_keywords", + (PyCFunction)getargs_positional_only_and_keywords, + METH_VARARGS|METH_KEYWORDS}, {"getargs_b", getargs_b, METH_VARARGS}, {"getargs_B", getargs_B, METH_VARARGS}, {"getargs_h", getargs_h, METH_VARARGS}, @@ -3840,14 +3988,12 @@ static PyMethodDef TestMethods[] = { {"getargs_l", getargs_l, METH_VARARGS}, {"getargs_n", getargs_n, METH_VARARGS}, {"getargs_p", getargs_p, METH_VARARGS}, -#ifdef HAVE_LONG_LONG {"getargs_L", getargs_L, METH_VARARGS}, {"getargs_K", getargs_K, METH_VARARGS}, {"test_longlong_api", test_longlong_api, METH_NOARGS}, {"test_long_long_and_overflow", (PyCFunction)test_long_long_and_overflow, METH_NOARGS}, {"test_L_code", (PyCFunction)test_L_code, METH_NOARGS}, -#endif {"getargs_f", getargs_f, METH_VARARGS}, {"getargs_d", getargs_d, METH_VARARGS}, {"getargs_D", getargs_D, METH_VARARGS}, @@ -3976,6 +4122,14 @@ static PyMethodDef TestMethods[] = { {"PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, {"PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, + {"pymem_buffer_overflow", pymem_buffer_overflow, METH_NOARGS}, + {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS}, + {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS}, + {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS}, + {"tracemalloc_track", tracemalloc_track, METH_VARARGS}, + {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS}, + {"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS}, + {"dict_get_version", dict_get_version, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; @@ -3995,10 +4149,8 @@ typedef struct { float float_member; double double_member; char inplace_member[6]; -#ifdef HAVE_LONG_LONG - PY_LONG_LONG longlong_member; - unsigned PY_LONG_LONG ulonglong_member; -#endif + long long longlong_member; + unsigned long long ulonglong_member; } all_structmembers; typedef struct { @@ -4020,10 +4172,8 @@ static struct PyMemberDef test_members[] = { {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, {"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL}, -#ifdef HAVE_LONG_LONG {"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL}, {"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL}, -#endif {NULL} }; @@ -4035,15 +4185,9 @@ test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET", "T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE", -#ifdef HAVE_LONG_LONG "T_LONGLONG", "T_ULONGLONG", -#endif NULL}; - static char *fmt = "|bbBhHiIlknfds#" -#ifdef HAVE_LONG_LONG - "LK" -#endif - ; + static const char fmt[] = "|bbBhHiIlknfds#LK"; test_structmembers *ob; const char *s = NULL; Py_ssize_t string_len = 0; @@ -4065,10 +4209,8 @@ test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) &ob->structmembers.float_member, &ob->structmembers.double_member, &s, &string_len -#ifdef HAVE_LONG_LONG , &ob->structmembers.longlong_member, &ob->structmembers.ulonglong_member -#endif )) { Py_DECREF(ob); return NULL; @@ -4394,6 +4536,7 @@ PyInit__testcapi(void) PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyLong_FromSsize_t(PY_SSIZE_T_MAX)); PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyLong_FromSsize_t(PY_SSIZE_T_MIN)); PyModule_AddObject(m, "SIZEOF_PYGC_HEAD", PyLong_FromSsize_t(sizeof(PyGC_Head))); + PyModule_AddObject(m, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t))); Py_INCREF(&PyInstanceMethod_Type); PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index 41da997..4daa34e 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -61,7 +61,7 @@ Example_getattro(ExampleObject *self, PyObject *name) } static int -Example_setattr(ExampleObject *self, char *name, PyObject *v) +Example_setattr(ExampleObject *self, const char *name, PyObject *v) { if (self->x_attr == NULL) { self->x_attr = PyDict_New(); diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 316f932..21f063d 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -462,7 +462,7 @@ Split(const char *list) v = NULL; break; } - PyTuple_SetItem(v, i, w); + PyTuple_SET_ITEM(v, i, w); } } Tcl_Free(FREECAST argv); @@ -480,13 +480,13 @@ SplitObj(PyObject *arg) Py_ssize_t i, size; PyObject *elem, *newelem, *result; - size = PyTuple_Size(arg); + size = PyTuple_GET_SIZE(arg); result = NULL; /* Recursively invoke SplitObj for all tuple items. If this does not return a new object, no action is needed. */ for(i = 0; i < size; i++) { - elem = PyTuple_GetItem(arg, i); + elem = PyTuple_GET_ITEM(arg, i); newelem = SplitObj(elem); if (!newelem) { Py_XDECREF(result); @@ -502,12 +502,12 @@ SplitObj(PyObject *arg) if (!result) return NULL; for(k = 0; k < i; k++) { - elem = PyTuple_GetItem(arg, k); + elem = PyTuple_GET_ITEM(arg, k); Py_INCREF(elem); - PyTuple_SetItem(result, k, elem); + PyTuple_SET_ITEM(result, k, elem); } } - PyTuple_SetItem(result, i, newelem); + PyTuple_SET_ITEM(result, i, newelem); } if (result) return result; @@ -529,7 +529,7 @@ SplitObj(PyObject *arg) Py_XDECREF(result); return NULL; } - PyTuple_SetItem(result, i, newelem); + PyTuple_SET_ITEM(result, i, newelem); } return result; } @@ -551,7 +551,7 @@ SplitObj(PyObject *arg) else if (PyBytes_Check(arg)) { int argc; const char **argv; - char *list = PyBytes_AsString(arg); + char *list = PyBytes_AS_STRING(arg); if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { Py_INCREF(arg); @@ -559,7 +559,7 @@ SplitObj(PyObject *arg) } Tcl_Free(FREECAST argv); if (argc > 1) - return Split(PyBytes_AsString(arg)); + return Split(PyBytes_AS_STRING(arg)); /* Fall through, returning arg. */ } Py_INCREF(arg); @@ -758,7 +758,7 @@ Tkapp_New(const char *screenName, const char *className, } Tcl_SetVar(v->interp, "tcl_library", - PyBytes_AsString(utf8_path), + PyBytes_AS_STRING(utf8_path), TCL_GLOBAL_ONLY); Py_DECREF(utf8_path); } @@ -841,7 +841,7 @@ PyTclObject_dealloc(PyTclObject *self) Py_DECREF(tp); } -static char* +static const char * PyTclObject_TclString(PyObject *self) { return Tcl_GetString(((PyTclObject*)self)->value); @@ -976,7 +976,7 @@ static PyType_Spec PyTclObject_Type_spec = { }; -#if PY_SIZE_MAX > INT_MAX +#if SIZE_MAX > INT_MAX #define CHECK_STRING_LENGTH(s) do { \ if (s != NULL && strlen(s) >= INT_MAX) { \ PyErr_SetString(PyExc_OverflowError, "string is too long"); \ @@ -1182,10 +1182,8 @@ fromWideIntObj(PyObject* tkapp, Tcl_Obj *value) { Tcl_WideInt wideValue; if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) { -#ifdef HAVE_LONG_LONG if (sizeof(wideValue) <= SIZEOF_LONG_LONG) return PyLong_FromLongLong(wideValue); -#endif return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue, sizeof(wideValue), PY_LITTLE_ENDIAN, @@ -1306,7 +1304,7 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) Py_DECREF(result); return NULL; } - PyTuple_SetItem(result, i, elem); + PyTuple_SET_ITEM(result, i, elem); } return result; } @@ -1517,8 +1515,8 @@ Tkapp_Call(PyObject *selfptr, PyObject *args) int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL; /* If args is a single tuple, replace with contents of tuple */ - if (1 == PyTuple_Size(args)){ - PyObject* item = PyTuple_GetItem(args, 0); + if (PyTuple_GET_SIZE(args) == 1) { + PyObject *item = PyTuple_GET_ITEM(args, 0); if (PyTuple_Check(item)) args = item; } @@ -1726,14 +1724,14 @@ static int varname_converter(PyObject *in, void *_out) { char *s; - char **out = (char**)_out; + const char **out = (const char**)_out; if (PyBytes_Check(in)) { - if (PyBytes_Size(in) > INT_MAX) { + if (PyBytes_GET_SIZE(in) > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); return 0; } - s = PyBytes_AsString(in); - if (strlen(s) != (size_t)PyBytes_Size(in)) { + s = PyBytes_AS_STRING(in); + if (strlen(s) != (size_t)PyBytes_GET_SIZE(in)) { PyErr_SetString(PyExc_ValueError, "embedded null byte"); return 0; } @@ -1846,7 +1844,7 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) static PyObject * SetVar(PyObject *self, PyObject *args, int flags) { - char *name1, *name2; + const char *name1, *name2; PyObject *newValue; PyObject *res = NULL; Tcl_Obj *newval, *ok; @@ -1915,7 +1913,7 @@ Tkapp_GlobalSetVar(PyObject *self, PyObject *args) static PyObject * GetVar(PyObject *self, PyObject *args, int flags) { - char *name1, *name2=NULL; + const char *name1, *name2=NULL; PyObject *res = NULL; Tcl_Obj *tres; @@ -2274,10 +2272,11 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) return NULL; for (i = 0; i < objc; i++) { PyObject *s = FromObj((PyObject*)self, objv[i]); - if (!s || PyTuple_SetItem(v, i, s)) { + if (!s) { Py_DECREF(v); return NULL; } + PyTuple_SET_ITEM(v, i, s); } return v; } @@ -2304,11 +2303,12 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) for (i = 0; i < argc; i++) { PyObject *s = unicodeFromTclString(argv[i]); - if (!s || PyTuple_SetItem(v, i, s)) { + if (!s) { Py_DECREF(v); v = NULL; goto finally; } + PyTuple_SET_ITEM(v, i, s); } finally: @@ -2349,10 +2349,11 @@ _tkinter_tkapp_split(TkappObject *self, PyObject *arg) return NULL; for (i = 0; i < objc; i++) { PyObject *s = FromObj((PyObject*)self, objv[i]); - if (!s || PyTuple_SetItem(v, i, s)) { + if (!s) { Py_DECREF(v); return NULL; } + PyTuple_SET_ITEM(v, i, s); } return v; } @@ -2410,10 +2411,11 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[ for (i = 0; i < (argc - 1); i++) { PyObject *s = unicodeFromTclString(argv[i + 1]); - if (!s || PyTuple_SetItem(arg, i, s)) { + if (!s) { Py_DECREF(arg); return PythonCmd_Error(interp); } + PyTuple_SET_ITEM(arg, i, s); } res = PyEval_CallObject(func, arg); Py_DECREF(arg); @@ -2485,7 +2487,6 @@ Tkapp_CommandProc(CommandEvent *ev, int flags) /*[clinic input] _tkinter.tkapp.createcommand - self: self(type="TkappObject *") name: str func: object / @@ -2495,7 +2496,7 @@ _tkinter.tkapp.createcommand static PyObject * _tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, PyObject *func) -/*[clinic end generated code: output=2a1c79a4ee2af410 input=2bc2c046a0914234]*/ +/*[clinic end generated code: output=2a1c79a4ee2af410 input=255785cb70edc6a0]*/ { PythonCmd_ClientData *data; int err; @@ -2561,7 +2562,6 @@ _tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, /*[clinic input] _tkinter.tkapp.deletecommand - self: self(type="TkappObject *") name: str / @@ -2569,7 +2569,7 @@ _tkinter.tkapp.deletecommand static PyObject * _tkinter_tkapp_deletecommand_impl(TkappObject *self, const char *name) -/*[clinic end generated code: output=a67e8cb5845e0d2d input=b6306468f10b219c]*/ +/*[clinic end generated code: output=a67e8cb5845e0d2d input=53e9952eae1f85f5]*/ { int err; @@ -2762,13 +2762,11 @@ typedef struct { /*[clinic input] _tkinter.tktimertoken.deletetimerhandler - self: self(type="TkttObject *") - [clinic start generated code]*/ static PyObject * _tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self) -/*[clinic end generated code: output=bd7fe17f328cfa55 input=25ba5dd594e52084]*/ +/*[clinic end generated code: output=bd7fe17f328cfa55 input=40bd070ff85f5cf3]*/ { TkttObject *v = self; PyObject *func = v->func; @@ -2894,7 +2892,6 @@ _tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds, /*[clinic input] _tkinter.tkapp.mainloop - self: self(type="TkappObject *") threshold: int = 0 / @@ -2902,7 +2899,7 @@ _tkinter.tkapp.mainloop static PyObject * _tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold) -/*[clinic end generated code: output=0ba8eabbe57841b0 input=ad57c9c1dd2b9470]*/ +/*[clinic end generated code: output=0ba8eabbe57841b0 input=036bcdcf03d5eca0]*/ { #ifdef WITH_THREAD PyThreadState *tstate = PyThreadState_Get(); @@ -3072,13 +3069,11 @@ Tkapp_WantObjects(PyObject *self, PyObject *args) /*[clinic input] _tkinter.tkapp.willdispatch - self: self(type="TkappObject *") - [clinic start generated code]*/ static PyObject * _tkinter_tkapp_willdispatch_impl(TkappObject *self) -/*[clinic end generated code: output=0e3f46d244642155 input=2630699767808970]*/ +/*[clinic end generated code: output=0e3f46d244642155 input=d88f5970843d6dab]*/ { self->dispatching = 1; @@ -3629,14 +3624,14 @@ PyInit__tkinter(void) } } - Tcl_FindExecutable(PyBytes_AsString(cexe)); + Tcl_FindExecutable(PyBytes_AS_STRING(cexe)); if (set_var) { SetEnvironmentVariableW(L"TCL_LIBRARY", NULL); PyMem_Free(wcs_path); } #else - Tcl_FindExecutable(PyBytes_AsString(cexe)); + Tcl_FindExecutable(PyBytes_AS_STRING(cexe)); #endif /* MS_WINDOWS */ } Py_XDECREF(cexe); diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 65bf7a3..ec8bd96 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -39,7 +39,11 @@ static struct { /* limit of the number of frames in a traceback, 1 by default. Variable protected by the GIL. */ int max_nframe; -} tracemalloc_config = {TRACEMALLOC_NOT_INITIALIZED, 0, 1}; + + /* use domain in trace key? + Variable protected by the GIL. */ + int use_domain; +} tracemalloc_config = {TRACEMALLOC_NOT_INITIALIZED, 0, 1, 0}; #if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) /* This lock is needed because tracemalloc_free() is called without @@ -54,10 +58,21 @@ static PyThread_type_lock tables_lock; # define TABLES_UNLOCK() #endif + +#define DEFAULT_DOMAIN 0 + +/* Pack the frame_t structure to reduce the memory footprint. */ +typedef struct +#ifdef __GNUC__ +__attribute__((packed)) +#endif +{ + uintptr_t ptr; + _PyTraceMalloc_domain_t domain; +} pointer_t; + /* Pack the frame_t structure to reduce the memory footprint on 64-bit - architectures: 12 bytes instead of 16. This optimization might produce - SIGBUS on architectures not supporting unaligned memory accesses (64-bit - MIPS CPU?): on such architecture, the structure must not be packed. */ + architectures: 12 bytes instead of 16. */ typedef struct #ifdef __GNUC__ __attribute__((packed)) @@ -65,10 +80,13 @@ __attribute__((packed)) _declspec(align(4)) #endif { + /* filename cannot be NULL: "<unknown>" is used if the Python frame + filename is NULL */ PyObject *filename; unsigned int lineno; } frame_t; + typedef struct { Py_uhash_t hash; int nframe; @@ -81,6 +99,7 @@ typedef struct { #define MAX_NFRAME \ ((INT_MAX - (int)sizeof(traceback_t)) / (int)sizeof(frame_t) + 1) + static PyObject *unknown_filename = NULL; static traceback_t tracemalloc_empty_traceback; @@ -93,6 +112,7 @@ typedef struct { traceback_t *traceback; } trace_t; + /* Size in bytes of currently traced memory. Protected by TABLES_LOCK(). */ static size_t tracemalloc_traced_memory = 0; @@ -119,6 +139,7 @@ static _Py_hashtable_t *tracemalloc_tracebacks = NULL; Protected by TABLES_LOCK(). */ static _Py_hashtable_t *tracemalloc_traces = NULL; + #ifdef TRACE_DEBUG static void tracemalloc_error(const char *format, ...) @@ -133,6 +154,7 @@ tracemalloc_error(const char *format, ...) } #endif + #if defined(WITH_THREAD) && defined(TRACE_RAW_MALLOC) #define REENTRANT_THREADLOCAL @@ -143,7 +165,7 @@ tracemalloc_error(const char *format, ...) # error "need native thread local storage (TLS)" #endif -static int tracemalloc_reentrant_key; +static int tracemalloc_reentrant_key = -1; /* Any non-NULL pointer can be used */ #define REENTRANT Py_True @@ -151,7 +173,10 @@ static int tracemalloc_reentrant_key; static int get_reentrant(void) { - void *ptr = PyThread_get_key_value(tracemalloc_reentrant_key); + void *ptr; + + assert(tracemalloc_reentrant_key != -1); + ptr = PyThread_get_key_value(tracemalloc_reentrant_key); if (ptr != NULL) { assert(ptr == REENTRANT); return 1; @@ -164,12 +189,14 @@ static void set_reentrant(int reentrant) { assert(reentrant == 0 || reentrant == 1); + assert(tracemalloc_reentrant_key != -1); + if (reentrant) { - assert(PyThread_get_key_value(tracemalloc_reentrant_key) == NULL); + assert(!get_reentrant()); PyThread_set_key_value(tracemalloc_reentrant_key, REENTRANT); } else { - assert(PyThread_get_key_value(tracemalloc_reentrant_key) == REENTRANT); + assert(get_reentrant()); PyThread_set_key_value(tracemalloc_reentrant_key, NULL); } } @@ -194,27 +221,75 @@ set_reentrant(int reentrant) } #endif + +static Py_uhash_t +hashtable_hash_pyobject(_Py_hashtable_t *ht, const void *pkey) +{ + PyObject *obj; + + _Py_HASHTABLE_READ_KEY(ht, pkey, obj); + return PyObject_Hash(obj); +} + + static int -hashtable_compare_unicode(const void *key, const _Py_hashtable_entry_t *entry) +hashtable_compare_unicode(_Py_hashtable_t *ht, const void *pkey, + const _Py_hashtable_entry_t *entry) { - if (key != NULL && entry->key != NULL) - return (PyUnicode_Compare((PyObject *)key, (PyObject *)entry->key) == 0); + PyObject *key1, *key2; + + _Py_HASHTABLE_READ_KEY(ht, pkey, key1); + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, key2); + + if (key1 != NULL && key2 != NULL) + return (PyUnicode_Compare(key1, key2) == 0); else - return key == entry->key; + return key1 == key2; +} + + +static Py_uhash_t +hashtable_hash_pointer_t(_Py_hashtable_t *ht, const void *pkey) +{ + pointer_t ptr; + Py_uhash_t hash; + + _Py_HASHTABLE_READ_KEY(ht, pkey, ptr); + + hash = (Py_uhash_t)_Py_HashPointer((void*)ptr.ptr); + hash ^= ptr.domain; + return hash; +} + + +static int +hashtable_compare_pointer_t(_Py_hashtable_t *ht, const void *pkey, + const _Py_hashtable_entry_t *entry) +{ + pointer_t ptr1, ptr2; + + _Py_HASHTABLE_READ_KEY(ht, pkey, ptr1); + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, ptr2); + + /* compare pointer before domain, because pointer is more likely to be + different */ + return (ptr1.ptr == ptr2.ptr && ptr1.domain == ptr2.domain); + } -static _Py_hashtable_allocator_t hashtable_alloc = {malloc, free}; static _Py_hashtable_t * -hashtable_new(size_t data_size, +hashtable_new(size_t key_size, size_t data_size, _Py_hashtable_hash_func hash_func, _Py_hashtable_compare_func compare_func) { - return _Py_hashtable_new_full(data_size, 0, + _Py_hashtable_allocator_t hashtable_alloc = {malloc, free}; + return _Py_hashtable_new_full(key_size, data_size, 0, hash_func, compare_func, - NULL, NULL, NULL, &hashtable_alloc); + &hashtable_alloc); } + static void* raw_malloc(size_t size) { @@ -227,21 +302,28 @@ raw_free(void *ptr) allocators.raw.free(allocators.raw.ctx, ptr); } + static Py_uhash_t -hashtable_hash_traceback(const void *key) +hashtable_hash_traceback(_Py_hashtable_t *ht, const void *pkey) { - const traceback_t *traceback = key; + traceback_t *traceback; + + _Py_HASHTABLE_READ_KEY(ht, pkey, traceback); return traceback->hash; } + static int -hashtable_compare_traceback(const traceback_t *traceback1, - const _Py_hashtable_entry_t *he) +hashtable_compare_traceback(_Py_hashtable_t *ht, const void *pkey, + const _Py_hashtable_entry_t *entry) { - const traceback_t *traceback2 = he->key; + traceback_t *traceback1, *traceback2; const frame_t *frame1, *frame2; int i; + _Py_HASHTABLE_READ_KEY(ht, pkey, traceback1); + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, traceback2); + if (traceback1->nframe != traceback2->nframe) return 0; @@ -260,6 +342,7 @@ hashtable_compare_traceback(const traceback_t *traceback1, return 1; } + static void tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame) { @@ -310,15 +393,15 @@ tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame) } /* intern the filename */ - entry = _Py_hashtable_get_entry(tracemalloc_filenames, filename); + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_filenames, filename); if (entry != NULL) { - filename = (PyObject *)entry->key; + _Py_HASHTABLE_ENTRY_READ_KEY(tracemalloc_filenames, entry, filename); } else { /* tracemalloc_filenames is responsible to keep a reference to the filename */ Py_INCREF(filename); - if (_Py_hashtable_set(tracemalloc_filenames, filename, NULL, 0) < 0) { + if (_Py_HASHTABLE_SET_NODATA(tracemalloc_filenames, filename) < 0) { Py_DECREF(filename); #ifdef TRACE_DEBUG tracemalloc_error("failed to intern the filename"); @@ -331,6 +414,7 @@ tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame) frame->filename = filename; } + static Py_uhash_t traceback_hash(traceback_t *traceback) { @@ -355,6 +439,7 @@ traceback_hash(traceback_t *traceback) return x; } + static void traceback_get_frames(traceback_t *traceback) { @@ -382,6 +467,7 @@ traceback_get_frames(traceback_t *traceback) } } + static traceback_t * traceback_new(void) { @@ -401,9 +487,9 @@ traceback_new(void) traceback->hash = traceback_hash(traceback); /* intern the traceback */ - entry = _Py_hashtable_get_entry(tracemalloc_tracebacks, traceback); + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_tracebacks, traceback); if (entry != NULL) { - traceback = (traceback_t *)entry->key; + _Py_HASHTABLE_ENTRY_READ_KEY(tracemalloc_tracebacks, entry, traceback); } else { traceback_t *copy; @@ -420,7 +506,7 @@ traceback_new(void) } memcpy(copy, traceback, traceback_size); - if (_Py_hashtable_set(tracemalloc_tracebacks, copy, NULL, 0) < 0) { + if (_Py_HASHTABLE_SET_NODATA(tracemalloc_tracebacks, copy) < 0) { raw_free(copy); #ifdef TRACE_DEBUG tracemalloc_error("failed to intern the traceback: putdata failed"); @@ -432,53 +518,161 @@ traceback_new(void) return traceback; } + static int -tracemalloc_add_trace(void *ptr, size_t size) +tracemalloc_use_domain_cb(_Py_hashtable_t *old_traces, + _Py_hashtable_entry_t *entry, void *user_data) { - traceback_t *traceback; - trace_t trace; - int res; + uintptr_t ptr; + pointer_t key; + _Py_hashtable_t *new_traces = (_Py_hashtable_t *)user_data; + const void *pdata = _Py_HASHTABLE_ENTRY_PDATA(old_traces, entry); + + _Py_HASHTABLE_ENTRY_READ_KEY(old_traces, entry, ptr); + key.ptr = ptr; + key.domain = DEFAULT_DOMAIN; + + return _Py_hashtable_set(new_traces, + sizeof(key), &key, + old_traces->data_size, pdata); +} -#ifdef WITH_THREAD - assert(PyGILState_Check()); -#endif - traceback = traceback_new(); - if (traceback == NULL) - return -1; +/* Convert tracemalloc_traces from compact key (uintptr_t) to pointer_t key. + * Return 0 on success, -1 on error. */ +static int +tracemalloc_use_domain(void) +{ + _Py_hashtable_t *new_traces = NULL; - trace.size = size; - trace.traceback = traceback; + assert(!tracemalloc_config.use_domain); - res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace); - if (res == 0) { - assert(tracemalloc_traced_memory <= PY_SIZE_MAX - size); - tracemalloc_traced_memory += size; - if (tracemalloc_traced_memory > tracemalloc_peak_traced_memory) - tracemalloc_peak_traced_memory = tracemalloc_traced_memory; + new_traces = hashtable_new(sizeof(pointer_t), + sizeof(trace_t), + hashtable_hash_pointer_t, + hashtable_compare_pointer_t); + if (new_traces == NULL) { + return -1; } - return res; + if (_Py_hashtable_foreach(tracemalloc_traces, tracemalloc_use_domain_cb, + new_traces) < 0) + { + _Py_hashtable_destroy(new_traces); + return -1; + } + + _Py_hashtable_destroy(tracemalloc_traces); + tracemalloc_traces = new_traces; + + tracemalloc_config.use_domain = 1; + + return 0; } + static void -tracemalloc_remove_trace(void *ptr) +tracemalloc_remove_trace(_PyTraceMalloc_domain_t domain, uintptr_t ptr) +{ + trace_t trace; + int removed; + + assert(tracemalloc_config.tracing); + + if (tracemalloc_config.use_domain) { + pointer_t key = {ptr, domain}; + removed = _Py_HASHTABLE_POP(tracemalloc_traces, key, trace); + } + else { + removed = _Py_HASHTABLE_POP(tracemalloc_traces, ptr, trace); + } + if (!removed) { + return; + } + + assert(tracemalloc_traced_memory >= trace.size); + tracemalloc_traced_memory -= trace.size; +} + +#define REMOVE_TRACE(ptr) \ + tracemalloc_remove_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr)) + + +static int +tracemalloc_add_trace(_PyTraceMalloc_domain_t domain, uintptr_t ptr, + size_t size) { + pointer_t key = {ptr, domain}; + traceback_t *traceback; trace_t trace; + _Py_hashtable_entry_t* entry; + int res; - if (_Py_hashtable_pop(tracemalloc_traces, ptr, &trace, sizeof(trace))) { + assert(tracemalloc_config.tracing); + + traceback = traceback_new(); + if (traceback == NULL) { + return -1; + } + + if (!tracemalloc_config.use_domain && domain != DEFAULT_DOMAIN) { + /* first trace using a non-zero domain whereas traces use compact + (uintptr_t) keys: switch to pointer_t keys. */ + if (tracemalloc_use_domain() < 0) { + return -1; + } + } + + if (tracemalloc_config.use_domain) { + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, key); + } + else { + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, ptr); + } + + if (entry != NULL) { + /* the memory block is already tracked */ + _Py_HASHTABLE_ENTRY_READ_DATA(tracemalloc_traces, entry, trace); assert(tracemalloc_traced_memory >= trace.size); tracemalloc_traced_memory -= trace.size; + + trace.size = size; + trace.traceback = traceback; + _Py_HASHTABLE_ENTRY_WRITE_DATA(tracemalloc_traces, entry, trace); } + else { + trace.size = size; + trace.traceback = traceback; + + if (tracemalloc_config.use_domain) { + res = _Py_HASHTABLE_SET(tracemalloc_traces, key, trace); + } + else { + res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace); + } + if (res != 0) { + return res; + } + } + + assert(tracemalloc_traced_memory <= SIZE_MAX - size); + tracemalloc_traced_memory += size; + if (tracemalloc_traced_memory > tracemalloc_peak_traced_memory) + tracemalloc_peak_traced_memory = tracemalloc_traced_memory; + return 0; } +#define ADD_TRACE(ptr, size) \ + tracemalloc_add_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr), size) + + static void* tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) { PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; void *ptr; - assert(elsize == 0 || nelem <= PY_SIZE_MAX / elsize); + assert(elsize == 0 || nelem <= SIZE_MAX / elsize); if (use_calloc) ptr = alloc->calloc(alloc->ctx, nelem, elsize); @@ -488,7 +682,7 @@ tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) return NULL; TABLES_LOCK(); - if (tracemalloc_add_trace(ptr, nelem * elsize) < 0) { + if (ADD_TRACE(ptr, nelem * elsize) < 0) { /* Failed to allocate a trace for the new memory block */ TABLES_UNLOCK(); alloc->free(alloc->ctx, ptr); @@ -498,6 +692,7 @@ tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) return ptr; } + static void* tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) { @@ -512,9 +707,14 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) /* an existing memory block has been resized */ TABLES_LOCK(); - tracemalloc_remove_trace(ptr); - if (tracemalloc_add_trace(ptr2, new_size) < 0) { + /* tracemalloc_add_trace() updates the trace if there is already + a trace at address (domain, ptr2) */ + if (ptr2 != ptr) { + REMOVE_TRACE(ptr); + } + + if (ADD_TRACE(ptr2, new_size) < 0) { /* Memory allocation failed. The error cannot be reported to the caller, because realloc() may already have shrunk the memory block and so removed bytes. @@ -532,7 +732,7 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) /* new allocation */ TABLES_LOCK(); - if (tracemalloc_add_trace(ptr2, new_size) < 0) { + if (ADD_TRACE(ptr2, new_size) < 0) { /* Failed to allocate a trace for the new memory block */ TABLES_UNLOCK(); alloc->free(alloc->ctx, ptr2); @@ -543,6 +743,7 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) return ptr2; } + static void tracemalloc_free(void *ctx, void *ptr) { @@ -557,10 +758,11 @@ tracemalloc_free(void *ctx, void *ptr) alloc->free(alloc->ctx, ptr); TABLES_LOCK(); - tracemalloc_remove_trace(ptr); + REMOVE_TRACE(ptr); TABLES_UNLOCK(); } + static void* tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize) { @@ -585,18 +787,21 @@ tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize) return ptr; } + static void* tracemalloc_malloc_gil(void *ctx, size_t size) { return tracemalloc_alloc_gil(0, ctx, 1, size); } + static void* tracemalloc_calloc_gil(void *ctx, size_t nelem, size_t elsize) { return tracemalloc_alloc_gil(1, ctx, nelem, elsize); } + static void* tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) { @@ -612,7 +817,7 @@ tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); if (ptr2 != NULL && ptr != NULL) { TABLES_LOCK(); - tracemalloc_remove_trace(ptr); + REMOVE_TRACE(ptr); TABLES_UNLOCK(); } return ptr2; @@ -629,6 +834,7 @@ tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) return ptr2; } + #ifdef TRACE_RAW_MALLOC static void* tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) @@ -663,18 +869,21 @@ tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) return ptr; } + static void* tracemalloc_raw_malloc(void *ctx, size_t size) { return tracemalloc_raw_alloc(0, ctx, 1, size); } + static void* tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize) { return tracemalloc_raw_alloc(1, ctx, nelem, elsize); } + static void* tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) { @@ -691,7 +900,7 @@ tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) if (ptr2 != NULL && ptr != NULL) { TABLES_LOCK(); - tracemalloc_remove_trace(ptr); + REMOVE_TRACE(ptr); TABLES_UNLOCK(); } return ptr2; @@ -715,22 +924,31 @@ tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) } #endif /* TRACE_RAW_MALLOC */ + static int -tracemalloc_clear_filename(_Py_hashtable_entry_t *entry, void *user_data) +tracemalloc_clear_filename(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry, + void *user_data) { - PyObject *filename = (PyObject *)entry->key; + PyObject *filename; + + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, filename); Py_DECREF(filename); return 0; } + static int -traceback_free_traceback(_Py_hashtable_entry_t *entry, void *user_data) +traceback_free_traceback(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry, + void *user_data) { - traceback_t *traceback = (traceback_t *)entry->key; + traceback_t *traceback; + + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, traceback); raw_free(traceback); return 0; } + /* reentrant flag must be set to call this function and GIL must be held */ static void tracemalloc_clear_traces(void) @@ -753,6 +971,7 @@ tracemalloc_clear_traces(void) _Py_hashtable_clear(tracemalloc_filenames); } + static int tracemalloc_init(void) { @@ -789,21 +1008,29 @@ tracemalloc_init(void) } #endif - tracemalloc_filenames = hashtable_new(0, - (_Py_hashtable_hash_func)PyObject_Hash, + tracemalloc_filenames = hashtable_new(sizeof(PyObject *), 0, + hashtable_hash_pyobject, hashtable_compare_unicode); - tracemalloc_tracebacks = hashtable_new(0, - (_Py_hashtable_hash_func)hashtable_hash_traceback, - (_Py_hashtable_compare_func)hashtable_compare_traceback); + tracemalloc_tracebacks = hashtable_new(sizeof(traceback_t *), 0, + hashtable_hash_traceback, + hashtable_compare_traceback); - tracemalloc_traces = hashtable_new(sizeof(trace_t), - _Py_hashtable_hash_ptr, - _Py_hashtable_compare_direct); + if (tracemalloc_config.use_domain) { + tracemalloc_traces = hashtable_new(sizeof(pointer_t), + sizeof(trace_t), + hashtable_hash_pointer_t, + hashtable_compare_pointer_t); + } + else { + tracemalloc_traces = hashtable_new(sizeof(uintptr_t), + sizeof(trace_t), + _Py_hashtable_hash_ptr, + _Py_hashtable_compare_direct); + } if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL - || tracemalloc_traces == NULL) - { + || tracemalloc_traces == NULL) { PyErr_NoMemory(); return -1; } @@ -823,6 +1050,7 @@ tracemalloc_init(void) return 0; } + static void tracemalloc_deinit(void) { @@ -833,9 +1061,9 @@ tracemalloc_deinit(void) tracemalloc_stop(); /* destroy hash tables */ - _Py_hashtable_destroy(tracemalloc_traces); _Py_hashtable_destroy(tracemalloc_tracebacks); _Py_hashtable_destroy(tracemalloc_filenames); + _Py_hashtable_destroy(tracemalloc_traces); #if defined(WITH_THREAD) && defined(TRACE_RAW_MALLOC) if (tables_lock != NULL) { @@ -846,11 +1074,13 @@ tracemalloc_deinit(void) #ifdef REENTRANT_THREADLOCAL PyThread_delete_key(tracemalloc_reentrant_key); + tracemalloc_reentrant_key = -1; #endif Py_XDECREF(unknown_filename); } + static int tracemalloc_start(int max_nframe) { @@ -907,6 +1137,7 @@ tracemalloc_start(int max_nframe) return 0; } + static void tracemalloc_stop(void) { @@ -923,8 +1154,9 @@ tracemalloc_stop(void) PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); - /* release memory */ tracemalloc_clear_traces(); + + /* release memory */ raw_free(tracemalloc_traceback); tracemalloc_traceback = NULL; } @@ -935,6 +1167,7 @@ PyDoc_STRVAR(tracemalloc_is_tracing_doc, "True if the tracemalloc module is tracing Python memory allocations,\n" "False otherwise."); + static PyObject* py_tracemalloc_is_tracing(PyObject *self) { @@ -946,6 +1179,7 @@ PyDoc_STRVAR(tracemalloc_clear_traces_doc, "\n" "Clear traces of memory blocks allocated by Python."); + static PyObject* py_tracemalloc_clear_traces(PyObject *self) { @@ -959,6 +1193,7 @@ py_tracemalloc_clear_traces(PyObject *self) Py_RETURN_NONE; } + static PyObject* frame_to_pyobject(frame_t *frame) { @@ -968,8 +1203,6 @@ frame_to_pyobject(frame_t *frame) if (frame_obj == NULL) return NULL; - if (frame->filename == NULL) - frame->filename = Py_None; Py_INCREF(frame->filename); PyTuple_SET_ITEM(frame_obj, 0, frame->filename); @@ -983,6 +1216,7 @@ frame_to_pyobject(frame_t *frame) return frame_obj; } + static PyObject* traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table) { @@ -1021,33 +1255,43 @@ traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table) return frames; } + static PyObject* -trace_to_pyobject(trace_t *trace, _Py_hashtable_t *intern_tracebacks) +trace_to_pyobject(_PyTraceMalloc_domain_t domain, trace_t *trace, + _Py_hashtable_t *intern_tracebacks) { PyObject *trace_obj = NULL; - PyObject *size, *traceback; + PyObject *obj; - trace_obj = PyTuple_New(2); + trace_obj = PyTuple_New(3); if (trace_obj == NULL) return NULL; - size = PyLong_FromSize_t(trace->size); - if (size == NULL) { + obj = PyLong_FromSize_t(domain); + if (obj == NULL) { Py_DECREF(trace_obj); return NULL; } - PyTuple_SET_ITEM(trace_obj, 0, size); + PyTuple_SET_ITEM(trace_obj, 0, obj); - traceback = traceback_to_pyobject(trace->traceback, intern_tracebacks); - if (traceback == NULL) { + obj = PyLong_FromSize_t(trace->size); + if (obj == NULL) { Py_DECREF(trace_obj); return NULL; } - PyTuple_SET_ITEM(trace_obj, 1, traceback); + PyTuple_SET_ITEM(trace_obj, 1, obj); + + obj = traceback_to_pyobject(trace->traceback, intern_tracebacks); + if (obj == NULL) { + Py_DECREF(trace_obj); + return NULL; + } + PyTuple_SET_ITEM(trace_obj, 2, obj); return trace_obj; } + typedef struct { _Py_hashtable_t *traces; _Py_hashtable_t *tracebacks; @@ -1055,16 +1299,26 @@ typedef struct { } get_traces_t; static int -tracemalloc_get_traces_fill(_Py_hashtable_entry_t *entry, void *user_data) +tracemalloc_get_traces_fill(_Py_hashtable_t *traces, _Py_hashtable_entry_t *entry, + void *user_data) { get_traces_t *get_traces = user_data; - trace_t *trace; + _PyTraceMalloc_domain_t domain; + trace_t trace; PyObject *tracemalloc_obj; int res; - trace = (trace_t *)_Py_HASHTABLE_ENTRY_DATA(entry); + if (tracemalloc_config.use_domain) { + pointer_t key; + _Py_HASHTABLE_ENTRY_READ_KEY(traces, entry, key); + domain = key.domain; + } + else { + domain = DEFAULT_DOMAIN; + } + _Py_HASHTABLE_ENTRY_READ_DATA(traces, entry, trace); - tracemalloc_obj = trace_to_pyobject(trace, get_traces->tracebacks); + tracemalloc_obj = trace_to_pyobject(domain, &trace, get_traces->tracebacks); if (tracemalloc_obj == NULL) return 1; @@ -1076,14 +1330,19 @@ tracemalloc_get_traces_fill(_Py_hashtable_entry_t *entry, void *user_data) return 0; } + static int -tracemalloc_pyobject_decref_cb(_Py_hashtable_entry_t *entry, void *user_data) +tracemalloc_pyobject_decref_cb(_Py_hashtable_t *tracebacks, + _Py_hashtable_entry_t *entry, + void *user_data) { - PyObject *obj = (PyObject *)_Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry); + PyObject *obj; + _Py_HASHTABLE_ENTRY_READ_DATA(tracebacks, entry, obj); Py_DECREF(obj); return 0; } + PyDoc_STRVAR(tracemalloc_get_traces_doc, "_get_traces() -> list\n" "\n" @@ -1110,7 +1369,8 @@ py_tracemalloc_get_traces(PyObject *self, PyObject *obj) /* the traceback hash table is used temporarily to intern traceback tuple of (filename, lineno) tuples */ - get_traces.tracebacks = hashtable_new(sizeof(PyObject *), + get_traces.tracebacks = hashtable_new(sizeof(traceback_t *), + sizeof(PyObject *), _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct); if (get_traces.tracebacks == NULL) { @@ -1142,15 +1402,43 @@ error: finally: if (get_traces.tracebacks != NULL) { _Py_hashtable_foreach(get_traces.tracebacks, - tracemalloc_pyobject_decref_cb, NULL); + tracemalloc_pyobject_decref_cb, NULL); _Py_hashtable_destroy(get_traces.tracebacks); } - if (get_traces.traces != NULL) + if (get_traces.traces != NULL) { _Py_hashtable_destroy(get_traces.traces); + } return get_traces.list; } + +static traceback_t* +tracemalloc_get_traceback(_PyTraceMalloc_domain_t domain, uintptr_t ptr) +{ + trace_t trace; + int found; + + if (!tracemalloc_config.tracing) + return NULL; + + TABLES_LOCK(); + if (tracemalloc_config.use_domain) { + pointer_t key = {ptr, domain}; + found = _Py_HASHTABLE_GET(tracemalloc_traces, key, trace); + } + else { + found = _Py_HASHTABLE_GET(tracemalloc_traces, ptr, trace); + } + TABLES_UNLOCK(); + + if (!found) + return NULL; + + return trace.traceback; +} + + PyDoc_STRVAR(tracemalloc_get_object_traceback_doc, "_get_object_traceback(obj)\n" "\n" @@ -1165,11 +1453,7 @@ py_tracemalloc_get_object_traceback(PyObject *self, PyObject *obj) { PyTypeObject *type; void *ptr; - trace_t trace; - int found; - - if (!tracemalloc_config.tracing) - Py_RETURN_NONE; + traceback_t *traceback; type = Py_TYPE(obj); if (PyType_IS_GC(type)) @@ -1177,16 +1461,48 @@ py_tracemalloc_get_object_traceback(PyObject *self, PyObject *obj) else ptr = (void *)obj; - TABLES_LOCK(); - found = _Py_HASHTABLE_GET(tracemalloc_traces, ptr, trace); - TABLES_UNLOCK(); - - if (!found) + traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); + if (traceback == NULL) Py_RETURN_NONE; - return traceback_to_pyobject(trace.traceback, NULL); + return traceback_to_pyobject(traceback, NULL); } + +#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) + +static void +_PyMem_DumpFrame(int fd, frame_t * frame) +{ + PUTS(fd, " File \""); + _Py_DumpASCII(fd, frame->filename); + PUTS(fd, "\", line "); + _Py_DumpDecimal(fd, frame->lineno); + PUTS(fd, "\n"); +} + +/* Dump the traceback where a memory block was allocated into file descriptor + fd. The function may block on TABLES_LOCK() but it is unlikely. */ +void +_PyMem_DumpTraceback(int fd, const void *ptr) +{ + traceback_t *traceback; + int i; + + traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); + if (traceback == NULL) + return; + + PUTS(fd, "Memory block allocated at (most recent call first):\n"); + for (i=0; i < traceback->nframe; i++) { + _PyMem_DumpFrame(fd, &traceback->frames[i]); + } + PUTS(fd, "\n"); +} + +#undef PUTS + + PyDoc_STRVAR(tracemalloc_start_doc, "start(nframe: int=1)\n" "\n" @@ -1222,6 +1538,7 @@ PyDoc_STRVAR(tracemalloc_stop_doc, "Stop tracing Python memory allocations and clear traces\n" "of memory blocks allocated by Python."); + static PyObject* py_tracemalloc_stop(PyObject *self) { @@ -1229,6 +1546,7 @@ py_tracemalloc_stop(PyObject *self) Py_RETURN_NONE; } + PyDoc_STRVAR(tracemalloc_get_traceback_limit_doc, "get_traceback_limit() -> int\n" "\n" @@ -1244,6 +1562,7 @@ py_tracemalloc_get_traceback_limit(PyObject *self) return PyLong_FromLong(tracemalloc_config.max_nframe); } + PyDoc_STRVAR(tracemalloc_get_tracemalloc_memory_doc, "get_tracemalloc_memory() -> int\n" "\n" @@ -1267,6 +1586,7 @@ tracemalloc_get_tracemalloc_memory(PyObject *self) return Py_BuildValue("N", size_obj); } + PyDoc_STRVAR(tracemalloc_get_traced_memory_doc, "get_traced_memory() -> (int, int)\n" "\n" @@ -1292,6 +1612,7 @@ tracemalloc_get_traced_memory(PyObject *self) return Py_BuildValue("NN", size_obj, peak_size_obj); } + static PyMethodDef module_methods[] = { {"is_tracing", (PyCFunction)py_tracemalloc_is_tracing, METH_NOARGS, tracemalloc_is_tracing_doc}, @@ -1342,6 +1663,7 @@ PyInit__tracemalloc(void) return m; } + static int parse_sys_xoptions(PyObject *value) { @@ -1370,6 +1692,7 @@ parse_sys_xoptions(PyObject *value) return Py_SAFE_DOWNCAST(nframe, long, int); } + int _PyTraceMalloc_Init(void) { @@ -1428,6 +1751,7 @@ _PyTraceMalloc_Init(void) return tracemalloc_start(nframe); } + void _PyTraceMalloc_Fini(void) { @@ -1437,3 +1761,59 @@ _PyTraceMalloc_Fini(void) tracemalloc_deinit(); } +int +_PyTraceMalloc_Track(_PyTraceMalloc_domain_t domain, uintptr_t ptr, + size_t size) +{ + int res; +#ifdef WITH_THREAD + PyGILState_STATE gil_state; +#endif + + if (!tracemalloc_config.tracing) { + /* tracemalloc is not tracing: do nothing */ + return -2; + } + +#ifdef WITH_THREAD + gil_state = PyGILState_Ensure(); +#endif + + TABLES_LOCK(); + res = tracemalloc_add_trace(domain, ptr, size); + TABLES_UNLOCK(); + +#ifdef WITH_THREAD + PyGILState_Release(gil_state); +#endif + return res; +} + + +int +_PyTraceMalloc_Untrack(_PyTraceMalloc_domain_t domain, uintptr_t ptr) +{ + if (!tracemalloc_config.tracing) { + /* tracemalloc is not tracing: do nothing */ + return -2; + } + + TABLES_LOCK(); + tracemalloc_remove_trace(domain, ptr); + TABLES_UNLOCK(); + + return 0; +} + + +PyObject* +_PyTraceMalloc_GetTraceback(_PyTraceMalloc_domain_t domain, uintptr_t ptr) +{ + traceback_t *traceback; + + traceback = tracemalloc_get_traceback(domain, ptr); + if (traceback == NULL) + Py_RETURN_NONE; + + return traceback_to_pyobject(traceback, NULL); +} diff --git a/Modules/_winapi.c b/Modules/_winapi.c index edc6cf4..91d4f01 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -175,7 +175,7 @@ class HANDLE_return_converter(CReturnConverter): self.declare(data) self.err_occurred_if("_return_value == INVALID_HANDLE_VALUE", data) data.return_conversion.append( - 'if (_return_value == NULL)\n Py_RETURN_NONE;\n') + 'if (_return_value == NULL) {\n Py_RETURN_NONE;\n}\n') data.return_conversion.append( 'return_value = HANDLE_TO_PYNUM(_return_value);\n') @@ -188,7 +188,7 @@ class DWORD_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = Py_BuildValue("k", _return_value);\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=374076979596ebba]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=94819e72d2c6d558]*/ #include "clinic/_winapi.c.h" @@ -486,7 +486,7 @@ _winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, const USHORT prefix_len = 4; USHORT print_len = 0; USHORT rdb_size = 0; - PREPARSE_DATA_BUFFER rdb = NULL; + _Py_PREPARSE_DATA_BUFFER rdb = NULL; /* Junction point creation */ HANDLE junction = NULL; @@ -542,18 +542,18 @@ _winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, - the size of the print name in bytes - the size of the substitute name in bytes - the size of two NUL terminators in bytes */ - rdb_size = REPARSE_DATA_BUFFER_HEADER_SIZE + + rdb_size = _Py_REPARSE_DATA_BUFFER_HEADER_SIZE + sizeof(rdb->MountPointReparseBuffer) - sizeof(rdb->MountPointReparseBuffer.PathBuffer) + /* Two +1's for NUL terminators. */ (prefix_len + print_len + 1 + print_len + 1) * sizeof(WCHAR); - rdb = (PREPARSE_DATA_BUFFER)PyMem_RawMalloc(rdb_size); + rdb = (_Py_PREPARSE_DATA_BUFFER)PyMem_RawMalloc(rdb_size); if (rdb == NULL) goto cleanup; memset(rdb, 0, rdb_size); rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - rdb->ReparseDataLength = rdb_size - REPARSE_DATA_BUFFER_HEADER_SIZE; + rdb->ReparseDataLength = rdb_size - _Py_REPARSE_DATA_BUFFER_HEADER_SIZE; rdb->MountPointReparseBuffer.SubstituteNameOffset = 0; rdb->MountPointReparseBuffer.SubstituteNameLength = (prefix_len + print_len) * sizeof(WCHAR); @@ -674,7 +674,7 @@ _winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size) /* helpers for createprocess */ static unsigned long -getulong(PyObject* obj, char* name) +getulong(PyObject* obj, const char* name) { PyObject* value; unsigned long ret; @@ -690,7 +690,7 @@ getulong(PyObject* obj, char* name) } static HANDLE -gethandle(PyObject* obj, char* name) +gethandle(PyObject* obj, const char* name) { PyObject* value; HANDLE ret; diff --git a/Modules/addrinfo.h b/Modules/addrinfo.h index 1cb6f0e..c3c8624 100644 --- a/Modules/addrinfo.h +++ b/Modules/addrinfo.h @@ -141,11 +141,7 @@ struct addrinfo { * RFC 2553: protocol-independent placeholder for socket addresses */ #define _SS_MAXSIZE 128 -#ifdef HAVE_LONG_LONG -#define _SS_ALIGNSIZE (sizeof(PY_LONG_LONG)) -#else -#define _SS_ALIGNSIZE (sizeof(double)) -#endif /* HAVE_LONG_LONG */ +#define _SS_ALIGNSIZE (sizeof(long long)) #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) #define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ _SS_PAD1SIZE - _SS_ALIGNSIZE) @@ -158,11 +154,7 @@ struct sockaddr_storage { unsigned short ss_family; /* address family */ #endif /* HAVE_SOCKADDR_SA_LEN */ char __ss_pad1[_SS_PAD1SIZE]; -#ifdef HAVE_LONG_LONG - PY_LONG_LONG __ss_align; /* force desired structure storage alignment */ -#else - double __ss_align; /* force desired structure storage alignment */ -#endif /* HAVE_LONG_LONG */ + long long __ss_align; /* force desired structure storage alignment */ char __ss_pad2[_SS_PAD2SIZE]; }; #endif /* !HAVE_SOCKADDR_STORAGE */ diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index a4966b4..5868c52 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -31,7 +31,7 @@ struct arraydescr { int itemsize; PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); - char *formats; + const char *formats; int is_integer_type; int is_signed; }; @@ -40,7 +40,7 @@ typedef struct arrayobject { PyObject_VAR_HEAD char *ob_item; Py_ssize_t allocated; - struct arraydescr *ob_descr; + const struct arraydescr *ob_descr; PyObject *weakreflist; /* List of weak references */ int ob_exports; /* Number of exported buffers */ } arrayobject; @@ -418,22 +418,20 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) return 0; } -#ifdef HAVE_LONG_LONG - static PyObject * q_getitem(arrayobject *ap, Py_ssize_t i) { - return PyLong_FromLongLong(((PY_LONG_LONG *)ap->ob_item)[i]); + return PyLong_FromLongLong(((long long *)ap->ob_item)[i]); } static int q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { - PY_LONG_LONG x; + long long x; if (!PyArg_Parse(v, "L;array item must be integer", &x)) return -1; if (i >= 0) - ((PY_LONG_LONG *)ap->ob_item)[i] = x; + ((long long *)ap->ob_item)[i] = x; return 0; } @@ -441,20 +439,20 @@ static PyObject * QQ_getitem(arrayobject *ap, Py_ssize_t i) { return PyLong_FromUnsignedLongLong( - ((unsigned PY_LONG_LONG *)ap->ob_item)[i]); + ((unsigned long long *)ap->ob_item)[i]); } static int QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { - unsigned PY_LONG_LONG x; + unsigned long long x; if (PyLong_Check(v)) { x = PyLong_AsUnsignedLongLong(v); - if (x == (unsigned PY_LONG_LONG) -1 && PyErr_Occurred()) + if (x == (unsigned long long) -1 && PyErr_Occurred()) return -1; } else { - PY_LONG_LONG y; + long long y; if (!PyArg_Parse(v, "L;array item must be integer", &y)) return -1; if (y < 0) { @@ -462,14 +460,13 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) "unsigned long long is less than minimum"); return -1; } - x = (unsigned PY_LONG_LONG)y; + x = (unsigned long long)y; } if (i >= 0) - ((unsigned PY_LONG_LONG *)ap->ob_item)[i] = x; + ((unsigned long long *)ap->ob_item)[i] = x; return 0; } -#endif static PyObject * f_getitem(arrayobject *ap, Py_ssize_t i) @@ -511,7 +508,7 @@ d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) * Don't forget to update typecode_to_mformat_code() if you add a new * typecode. */ -static struct arraydescr descriptors[] = { +static const struct arraydescr descriptors[] = { {'b', 1, b_getitem, b_setitem, "b", 1, 1}, {'B', 1, BB_getitem, BB_setitem, "B", 1, 0}, {'u', sizeof(Py_UNICODE), u_getitem, u_setitem, "u", 0, 0}, @@ -521,10 +518,8 @@ static struct arraydescr descriptors[] = { {'I', sizeof(int), II_getitem, II_setitem, "I", 1, 0}, {'l', sizeof(long), l_getitem, l_setitem, "l", 1, 1}, {'L', sizeof(long), LL_getitem, LL_setitem, "L", 1, 0}, -#ifdef HAVE_LONG_LONG - {'q', sizeof(PY_LONG_LONG), q_getitem, q_setitem, "q", 1, 1}, - {'Q', sizeof(PY_LONG_LONG), QQ_getitem, QQ_setitem, "Q", 1, 0}, -#endif + {'q', sizeof(long long), q_getitem, q_setitem, "q", 1, 1}, + {'Q', sizeof(long long), QQ_getitem, QQ_setitem, "Q", 1, 0}, {'f', sizeof(float), f_getitem, f_setitem, "f", 0, 0}, {'d', sizeof(double), d_getitem, d_setitem, "d", 0, 0}, {'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */ @@ -539,7 +534,7 @@ class array.array "arrayobject *" "&Arraytype" /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/ static PyObject * -newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr) +newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr) { arrayobject *op; size_t nbytes; @@ -852,37 +847,10 @@ array_repeat(arrayobject *a, Py_ssize_t n) } static int -array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) +array_del_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) { char *item; - Py_ssize_t n; /* Size of replacement array */ Py_ssize_t d; /* Change in size */ -#define b ((arrayobject *)v) - if (v == NULL) - n = 0; - else if (array_Check(v)) { - n = Py_SIZE(b); - if (a == b) { - /* Special case "a[i:j] = a" -- copy b first */ - int ret; - v = array_slice(b, 0, n); - if (!v) - return -1; - ret = array_ass_slice(a, ilow, ihigh, v); - Py_DECREF(v); - return ret; - } - if (b->ob_descr != a->ob_descr) { - PyErr_BadArgument(); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, - "can only assign array (not \"%.200s\") to array slice", - Py_TYPE(v)->tp_name); - return -1; - } if (ilow < 0) ilow = 0; else if (ilow > Py_SIZE(a)) @@ -894,7 +862,7 @@ array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) else if (ihigh > Py_SIZE(a)) ihigh = Py_SIZE(a); item = a->ob_item; - d = n - (ihigh-ilow); + d = ihigh-ilow; /* Issue #4509: If the array has exported buffers and the slice assignment would change the size of the array, fail early to make sure we don't modify it. */ @@ -903,25 +871,14 @@ array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) "cannot resize an array that is exporting buffers"); return -1; } - if (d < 0) { /* Delete -d items */ - memmove(item + (ihigh+d)*a->ob_descr->itemsize, + if (d > 0) { /* Delete d items */ + memmove(item + (ihigh-d)*a->ob_descr->itemsize, item + ihigh*a->ob_descr->itemsize, (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize); - if (array_resize(a, Py_SIZE(a) + d) == -1) - return -1; - } - else if (d > 0) { /* Insert d items */ - if (array_resize(a, Py_SIZE(a) + d)) + if (array_resize(a, Py_SIZE(a) - d) == -1) return -1; - memmove(item + (ihigh+d)*a->ob_descr->itemsize, - item + ihigh*a->ob_descr->itemsize, - (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize); } - if (n > 0) - memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item, - n*b->ob_descr->itemsize); return 0; -#undef b } static int @@ -933,7 +890,7 @@ array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v) return -1; } if (v == NULL) - return array_ass_slice(a, i, i+1, v); + return array_del_slice(a, i, i+1); return (*a->ob_descr->setitem)(a, i, v); } @@ -1163,8 +1120,7 @@ array_array_remove(arrayobject *self, PyObject *v) cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); Py_DECREF(selfi); if (cmp > 0) { - if (array_ass_slice(self, i, i+1, - (PyObject *)NULL) != 0) + if (array_del_slice(self, i, i+1) != 0) return NULL; Py_INCREF(Py_None); return Py_None; @@ -1207,7 +1163,7 @@ array_array_pop_impl(arrayobject *self, Py_ssize_t i) v = getarrayitem((PyObject *)self, i); if (v == NULL) return NULL; - if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) { + if (array_del_slice(self, i, i+1) != 0) { Py_DECREF(v); return NULL; } @@ -1861,16 +1817,14 @@ typecode_to_mformat_code(char typecode) intsize = sizeof(long); is_signed = 0; break; -#if HAVE_LONG_LONG case 'q': - intsize = sizeof(PY_LONG_LONG); + intsize = sizeof(long long); is_signed = 1; break; case 'Q': - intsize = sizeof(PY_LONG_LONG); + intsize = sizeof(long long); is_signed = 0; break; -#endif default: return UNKNOWN_FORMAT; } @@ -1954,7 +1908,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, { PyObject *converted_items; PyObject *result; - struct arraydescr *descr; + const struct arraydescr *descr; if (!PyType_Check(arraytype)) { PyErr_Format(PyExc_TypeError, @@ -2092,7 +2046,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size; const unsigned char *memstr = (unsigned char *)PyBytes_AS_STRING(items); - struct arraydescr *descr; + const struct arraydescr *descr; /* If possible, try to pack array's items using a data type * that fits better. This may result in an array with narrower @@ -2562,7 +2516,7 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) view->format = NULL; view->internal = NULL; if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) { - view->format = self->ob_descr->formats; + view->format = (char *)self->ob_descr->formats; #ifdef Py_UNICODE_WIDE if (self->ob_descr->typecode == 'u') { view->format = "w"; @@ -2603,7 +2557,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { int c; PyObject *initial = NULL, *it = NULL; - struct arraydescr *descr; + const struct arraydescr *descr; if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds)) return NULL; @@ -2732,11 +2686,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } PyErr_SetString(PyExc_ValueError, -#ifdef HAVE_LONG_LONG "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)"); -#else - "bad typecode (must be b, B, u, h, H, i, I, l, L, f or d)"); -#endif return NULL; } @@ -2883,9 +2833,20 @@ array_iter(arrayobject *ao) static PyObject * arrayiter_next(arrayiterobject *it) { + arrayobject *ao; + + assert(it != NULL); assert(PyArrayIter_Check(it)); - if (it->index < Py_SIZE(it->ao)) - return (*it->getitem)(it->ao, it->index++); + ao = it->ao; + if (ao == NULL) { + return NULL; + } + assert(array_Check(ao)); + if (it->index < Py_SIZE(ao)) { + return (*it->getitem)(ao, it->index++); + } + it->ao = NULL; + Py_DECREF(ao); return NULL; } @@ -2914,8 +2875,11 @@ static PyObject * array_arrayiterator___reduce___impl(arrayiterobject *self) /*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/ { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - self->ao, self->index); + PyObject *func = _PyObject_GetBuiltin("iter"); + if (self->ao == NULL) { + return Py_BuildValue("N(())", func); + } + return Py_BuildValue("N(O)n", func, self->ao, self->index); } /*[clinic input] @@ -2995,7 +2959,7 @@ array_modexec(PyObject *m) char buffer[Py_ARRAY_LENGTH(descriptors)], *p; PyObject *typecodes; Py_ssize_t size = 0; - struct arraydescr *descr; + const struct arraydescr *descr; if (PyType_Ready(&Arraytype) < 0) return -1; diff --git a/Modules/audioop.c b/Modules/audioop.c index 1e131d2..3f31a2b 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -5,8 +5,6 @@ #include "Python.h" -typedef short PyInt16; - #if defined(__CHAR_UNSIGNED__) #if defined(signed) /* This module currently does not work on systems where only unsigned @@ -51,13 +49,15 @@ fbound(double val, double minval, double maxval) #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */ -static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF, - 0x1FF, 0x3FF, 0x7FF, 0xFFF}; -static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF, - 0x3FF, 0x7FF, 0xFFF, 0x1FFF}; +static const int16_t seg_aend[8] = { + 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF +}; +static const int16_t seg_uend[8] = { + 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF +}; -static PyInt16 -search(PyInt16 val, PyInt16 *table, int size) +static int16_t +search(int16_t val, const int16_t *table, int size) { int i; @@ -70,7 +70,7 @@ search(PyInt16 val, PyInt16 *table, int size) #define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc]) #define st_alaw2linear16(uc) (_st_alaw2linear16[uc]) -static PyInt16 _st_ulaw2linear16[256] = { +static const int16_t _st_ulaw2linear16[256] = { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, -15996, -15484, -14972, -14460, -13948, @@ -143,10 +143,10 @@ static PyInt16 _st_ulaw2linear16[256] = { * John Wiley & Sons, pps 98-111 and 472-476. */ static unsigned char -st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */ +st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */ { - PyInt16 mask; - PyInt16 seg; + int16_t mask; + int16_t seg; unsigned char uval; /* u-law inverts all bits */ @@ -176,7 +176,7 @@ st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */ } -static PyInt16 _st_alaw2linear16[256] = { +static const int16_t _st_alaw2linear16[256] = { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, @@ -237,9 +237,9 @@ static PyInt16 _st_alaw2linear16[256] = { * John Wiley & Sons, pps 98-111 and 472-476. */ static unsigned char -st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */ +st_linear2alaw(int16_t pcm_val) /* 2's complement (13-bit range) */ { - PyInt16 mask; + int16_t mask; short seg; unsigned char aval; @@ -270,12 +270,12 @@ st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */ /* End of code taken from sox */ /* Intel ADPCM step variation table */ -static int indexTable[16] = { +static const int indexTable[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8, }; -static int stepsizeTable[89] = { +static const int stepsizeTable[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, @@ -295,7 +295,7 @@ static int stepsizeTable[89] = { #define GETINT8(cp, i) GETINTX(signed char, (cp), (i)) #define GETINT16(cp, i) GETINTX(short, (cp), (i)) -#define GETINT32(cp, i) GETINTX(PY_INT32_T, (cp), (i)) +#define GETINT32(cp, i) GETINTX(int32_t, (cp), (i)) #if WORDS_BIGENDIAN #define GETINT24(cp, i) ( \ @@ -312,7 +312,7 @@ static int stepsizeTable[89] = { #define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val)) #define SETINT16(cp, i, val) SETINTX(short, (cp), (i), (val)) -#define SETINT32(cp, i, val) SETINTX(PY_INT32_T, (cp), (i), (val)) +#define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val)) #if WORDS_BIGENDIAN #define SETINT24(cp, i, val) do { \ @@ -444,7 +444,9 @@ audioop_max_impl(PyObject *module, Py_buffer *fragment, int width) return NULL; for (i = 0; i < fragment->len; i += width) { int val = GETRAWSAMPLE(width, fragment->buf, i); - if (val < 0) absval = (-val); + /* Cast to unsigned before negating. Unsigned overflow is well- + defined, but signed overflow is not. */ + if (val < 0) absval = (unsigned int)-(int64_t)val; else absval = val; if (absval > max) max = absval; } @@ -1125,7 +1127,7 @@ audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias) val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu; else { assert(width == 4); - val = GETINTX(PY_UINT32_T, fragment->buf, i); + val = GETINTX(uint32_t, fragment->buf, i); } val += (unsigned int)bias; @@ -1140,7 +1142,7 @@ audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias) SETINT24(ncp, i, (int)val); else { assert(width == 4); - SETINTX(PY_UINT32_T, ncp, i, val); + SETINTX(uint32_t, ncp, i, val); } } return rv; @@ -1332,7 +1334,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, weightA /= d; weightB /= d; - if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) { + if ((size_t)nchannels > SIZE_MAX/sizeof(int)) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return NULL; diff --git a/Modules/binascii.c b/Modules/binascii.c index f0b47d8..c3320ce 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -74,7 +74,7 @@ static PyObject *Incomplete; #define SKIP 0x7E #define FAIL 0x7D -static unsigned char table_a2b_hqx[256] = { +static const unsigned char table_a2b_hqx[256] = { /* ^@ ^A ^B ^C ^D ^E ^F ^G */ /* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, /* \b \t \n ^K ^L \r ^N ^O */ @@ -125,10 +125,10 @@ static unsigned char table_a2b_hqx[256] = { FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, }; -static unsigned char table_b2a_hqx[] = +static const unsigned char table_b2a_hqx[] = "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; -static char table_a2b_base64[] = { +static const char table_a2b_base64[] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, @@ -144,12 +144,12 @@ static char table_a2b_base64[] = { /* Max binary chunk size; limited only by available memory */ #define BASE64_MAXBIN ((PY_SSIZE_T_MAX - 3) / 2) -static unsigned char table_b2a_base64[] = +static const unsigned char table_b2a_base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static unsigned short crctab_hqx[256] = { +static const unsigned short crctab_hqx[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, @@ -256,7 +256,8 @@ static PyObject * binascii_a2b_uu_impl(PyObject *module, Py_buffer *data) /*[clinic end generated code: output=e027f8e0b0598742 input=7cafeaf73df63d1c]*/ { - unsigned char *ascii_data, *bin_data; + const unsigned char *ascii_data; + unsigned char *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; @@ -342,13 +343,15 @@ static PyObject * binascii_b2a_uu_impl(PyObject *module, Py_buffer *data) /*[clinic end generated code: output=0070670e52e4aa6b input=00fdf458ce8b465b]*/ { - unsigned char *ascii_data, *bin_data; + unsigned char *ascii_data; + const unsigned char *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; - PyObject *rv; - Py_ssize_t bin_len; + Py_ssize_t bin_len, out_len; + _PyBytesWriter writer; + _PyBytesWriter_Init(&writer); bin_data = data->buf; bin_len = data->len; if ( bin_len > 45 ) { @@ -358,9 +361,10 @@ binascii_b2a_uu_impl(PyObject *module, Py_buffer *data) } /* We're lazy and allocate to much (fixed up later) */ - if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) + out_len = 2 + (bin_len + 2) / 3 * 4; + ascii_data = _PyBytesWriter_Alloc(&writer, out_len); + if (ascii_data == NULL) return NULL; - ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); /* Store the length */ *ascii_data++ = ' ' + (bin_len & 077); @@ -382,17 +386,12 @@ binascii_b2a_uu_impl(PyObject *module, Py_buffer *data) } *ascii_data++ = '\n'; /* Append a courtesy newline */ - if (_PyBytes_Resize(&rv, - (ascii_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - return rv; + return _PyBytesWriter_Finish(&writer, ascii_data); } static int -binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num) +binascii_find_valid(const unsigned char *s, Py_ssize_t slen, int num) { /* Finds & returns the (num+1)th ** valid character for base64, or -1 if none. @@ -429,13 +428,14 @@ static PyObject * binascii_a2b_base64_impl(PyObject *module, Py_buffer *data) /*[clinic end generated code: output=0628223f19fd3f9b input=5872acf6e1cac243]*/ { - unsigned char *ascii_data, *bin_data; + const unsigned char *ascii_data; + unsigned char *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; - PyObject *rv; Py_ssize_t ascii_len, bin_len; int quad_pos = 0; + _PyBytesWriter writer; ascii_data = data->buf; ascii_len = data->len; @@ -447,11 +447,12 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data) bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ + _PyBytesWriter_Init(&writer); + /* Allocate the buffer */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) + bin_data = _PyBytesWriter_Alloc(&writer, bin_len); + if (bin_data == NULL) return NULL; - bin_data = (unsigned char *)PyBytes_AS_STRING(rv); - bin_len = 0; for( ; ascii_len > 0; ascii_len--, ascii_data++) { this_ch = *ascii_data; @@ -496,31 +497,17 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data) if ( leftbits >= 8 ) { leftbits -= 8; *bin_data++ = (leftchar >> leftbits) & 0xff; - bin_len++; leftchar &= ((1 << leftbits) - 1); } } if (leftbits != 0) { PyErr_SetString(Error, "Incorrect padding"); - Py_DECREF(rv); + _PyBytesWriter_Dealloc(&writer); return NULL; } - /* And set string size correctly. If the result string is empty - ** (because the input was all invalid) return the shared empty - ** string instead; _PyBytes_Resize() won't do this for us. - */ - if (bin_len > 0) { - if (_PyBytes_Resize(&rv, bin_len) < 0) { - Py_CLEAR(rv); - } - } - else { - Py_DECREF(rv); - rv = PyBytes_FromStringAndSize("", 0); - } - return rv; + return _PyBytesWriter_Finish(&writer, bin_data); } @@ -528,24 +515,27 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data) binascii.b2a_base64 data: Py_buffer - / + * + newline: int(c_default="1") = True Base64-code line of data. [clinic start generated code]*/ static PyObject * -binascii_b2a_base64_impl(PyObject *module, Py_buffer *data) -/*[clinic end generated code: output=4d96663170778dc3 input=14ec4e47371174a9]*/ +binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline) +/*[clinic end generated code: output=4ad62c8e8485d3b3 input=7b2ea6fa38d8924c]*/ { - unsigned char *ascii_data, *bin_data; + unsigned char *ascii_data; + const unsigned char *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; - PyObject *rv; - Py_ssize_t bin_len; + Py_ssize_t bin_len, out_len; + _PyBytesWriter writer; bin_data = data->buf; bin_len = data->len; + _PyBytesWriter_Init(&writer); assert(bin_len >= 0); @@ -555,11 +545,14 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data) } /* We're lazy and allocate too much (fixed up later). - "+3" leaves room for up to two pad characters and a trailing - newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) + "+2" leaves room for up to two pad characters. + Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ + out_len = bin_len*2 + 2; + if (newline) + out_len++; + ascii_data = _PyBytesWriter_Alloc(&writer, out_len); + if (ascii_data == NULL) return NULL; - ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; bin_len > 0 ; bin_len--, bin_data++ ) { /* Shift the data into our buffer */ @@ -581,14 +574,10 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data) *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2]; *ascii_data++ = BASE64_PAD; } - *ascii_data++ = '\n'; /* Append a courtesy newline */ + if (newline) + *ascii_data++ = '\n'; /* Append a courtesy newline */ - if (_PyBytes_Resize(&rv, - (ascii_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - return rv; + return _PyBytesWriter_Finish(&writer, ascii_data); } /*[clinic input] @@ -604,16 +593,19 @@ static PyObject * binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data) /*[clinic end generated code: output=4d6d8c54d54ea1c1 input=0d914c680e0eed55]*/ { - unsigned char *ascii_data, *bin_data; + const unsigned char *ascii_data; + unsigned char *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; - PyObject *rv; + PyObject *res; Py_ssize_t len; int done = 0; + _PyBytesWriter writer; ascii_data = data->buf; len = data->len; + _PyBytesWriter_Init(&writer); assert(len >= 0); @@ -623,9 +615,9 @@ binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data) /* Allocate a string that is too big (fixed later) Add two to the initial length to prevent interning which would preclude subsequent resizing. */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) + bin_data = _PyBytesWriter_Alloc(&writer, len + 2); + if (bin_data == NULL) return NULL; - bin_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; len > 0 ; len--, ascii_data++ ) { /* Get the byte and look it up */ @@ -634,7 +626,7 @@ binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data) continue; if ( this_ch == FAIL ) { PyErr_SetString(Error, "Illegal char"); - Py_DECREF(rv); + _PyBytesWriter_Dealloc(&writer); return NULL; } if ( this_ch == DONE ) { @@ -656,21 +648,14 @@ binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data) if ( leftbits && !done ) { PyErr_SetString(Incomplete, "String has incomplete number of bytes"); - Py_DECREF(rv); + _PyBytesWriter_Dealloc(&writer); return NULL; } - if (_PyBytes_Resize(&rv, - (bin_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - if (rv) { - PyObject *rrv = Py_BuildValue("Oi", rv, done); - Py_DECREF(rv); - return rrv; - } - return NULL; + res = _PyBytesWriter_Finish(&writer, bin_data); + if (res == NULL) + return NULL; + return Py_BuildValue("Ni", res, done); } @@ -687,11 +672,13 @@ static PyObject * binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data) /*[clinic end generated code: output=393d79338f5f5629 input=e1f1712447a82b09]*/ { - unsigned char *in_data, *out_data; - PyObject *rv; + const unsigned char *in_data; + unsigned char *out_data; unsigned char ch; Py_ssize_t in, inend, len; + _PyBytesWriter writer; + _PyBytesWriter_Init(&writer); in_data = data->buf; len = data->len; @@ -701,9 +688,9 @@ binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data) return PyErr_NoMemory(); /* Worst case: output is twice as big as input (fixed later) */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) + out_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); + if (out_data == NULL) return NULL; - out_data = (unsigned char *)PyBytes_AS_STRING(rv); for( in=0; in<len; in++) { ch = in_data[in]; @@ -729,12 +716,8 @@ binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data) } } } - if (_PyBytes_Resize(&rv, - (out_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - return rv; + + return _PyBytesWriter_Finish(&writer, out_data); } @@ -751,15 +734,17 @@ static PyObject * binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data) /*[clinic end generated code: output=d0aa5a704bc9f7de input=9596ebe019fe12ba]*/ { - unsigned char *ascii_data, *bin_data; + unsigned char *ascii_data; + const unsigned char *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; - PyObject *rv; Py_ssize_t len; + _PyBytesWriter writer; bin_data = data->buf; len = data->len; + _PyBytesWriter_Init(&writer); assert(len >= 0); @@ -767,9 +752,9 @@ binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data) return PyErr_NoMemory(); /* Allocate a buffer that is at least large enough */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) + ascii_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); + if (ascii_data == NULL) return NULL; - ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; len > 0 ; len--, bin_data++ ) { /* Shift into our buffer, and output any 6bits ready */ @@ -786,12 +771,8 @@ binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data) leftchar <<= (6-leftbits); *ascii_data++ = table_b2a_hqx[leftchar & 0x3f]; } - if (_PyBytes_Resize(&rv, - (ascii_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - return rv; + + return _PyBytesWriter_Finish(&writer, ascii_data); } @@ -808,13 +789,15 @@ static PyObject * binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data) /*[clinic end generated code: output=9826619565de1c6c input=54cdd49fc014402c]*/ { - unsigned char *in_data, *out_data; + const unsigned char *in_data; + unsigned char *out_data; unsigned char in_byte, in_repeat; - PyObject *rv; - Py_ssize_t in_len, out_len, out_len_left; + Py_ssize_t in_len; + _PyBytesWriter writer; in_data = data->buf; in_len = data->len; + _PyBytesWriter_Init(&writer); assert(in_len >= 0); @@ -825,59 +808,48 @@ binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data) return PyErr_NoMemory(); /* Allocate a buffer of reasonable size. Resized when needed */ - out_len = in_len*2; - if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) + out_data = _PyBytesWriter_Alloc(&writer, in_len); + if (out_data == NULL) return NULL; - out_len_left = out_len; - out_data = (unsigned char *)PyBytes_AS_STRING(rv); + + /* Use overallocation */ + writer.overallocate = 1; /* ** We need two macros here to get/put bytes and handle ** end-of-buffer for input and output strings. */ -#define INBYTE(b) \ - do { \ - if ( --in_len < 0 ) { \ - PyErr_SetString(Incomplete, ""); \ - Py_DECREF(rv); \ - return NULL; \ - } \ - b = *in_data++; \ +#define INBYTE(b) \ + do { \ + if ( --in_len < 0 ) { \ + PyErr_SetString(Incomplete, ""); \ + goto error; \ + } \ + b = *in_data++; \ } while(0) -#define OUTBYTE(b) \ - do { \ - if ( --out_len_left < 0 ) { \ - if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \ - if (_PyBytes_Resize(&rv, 2*out_len) < 0) \ - { Py_XDECREF(rv); return NULL; } \ - out_data = (unsigned char *)PyBytes_AS_STRING(rv) \ - + out_len; \ - out_len_left = out_len-1; \ - out_len = out_len * 2; \ - } \ - *out_data++ = b; \ - } while(0) - - /* - ** Handle first byte separately (since we have to get angry - ** in case of an orphaned RLE code). - */ - INBYTE(in_byte); + /* + ** Handle first byte separately (since we have to get angry + ** in case of an orphaned RLE code). + */ + INBYTE(in_byte); if (in_byte == RUNCHAR) { INBYTE(in_repeat); + /* only 1 byte will be written, but 2 bytes were preallocated: + subtract 1 byte to prevent overallocation */ + writer.min_size--; + if (in_repeat != 0) { /* Note Error, not Incomplete (which is at the end ** of the string only). This is a programmer error. */ PyErr_SetString(Error, "Orphaned RLE code at start"); - Py_DECREF(rv); - return NULL; + goto error; } - OUTBYTE(RUNCHAR); + *out_data++ = RUNCHAR; } else { - OUTBYTE(in_byte); + *out_data++ = in_byte; } while( in_len > 0 ) { @@ -885,26 +857,39 @@ binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data) if (in_byte == RUNCHAR) { INBYTE(in_repeat); + /* only 1 byte will be written, but 2 bytes were preallocated: + subtract 1 byte to prevent overallocation */ + writer.min_size--; + if ( in_repeat == 0 ) { /* Just an escaped RUNCHAR value */ - OUTBYTE(RUNCHAR); + *out_data++ = RUNCHAR; } else { /* Pick up value and output a sequence of it */ in_byte = out_data[-1]; + + /* enlarge the buffer if needed */ + if (in_repeat > 1) { + /* -1 because we already preallocated 1 byte */ + out_data = _PyBytesWriter_Prepare(&writer, out_data, + in_repeat - 1); + if (out_data == NULL) + goto error; + } + while ( --in_repeat > 0 ) - OUTBYTE(in_byte); + *out_data++ = in_byte; } } else { /* Normal byte */ - OUTBYTE(in_byte); + *out_data++ = in_byte; } } - if (_PyBytes_Resize(&rv, - (out_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - return rv; + return _PyBytesWriter_Finish(&writer, out_data); + +error: + _PyBytesWriter_Dealloc(&writer); + return NULL; } @@ -922,7 +907,7 @@ static unsigned int binascii_crc_hqx_impl(PyObject *module, Py_buffer *data, unsigned int crc) /*[clinic end generated code: output=8ec2a78590d19170 input=add8c53712ccceda]*/ { - unsigned char *bin_data; + const unsigned char *bin_data; Py_ssize_t len; crc &= 0xffff; @@ -1000,7 +985,7 @@ binascii_crc_hqx_impl(PyObject *module, Py_buffer *data, unsigned int crc) using byte-swap instructions. ********************************************************************/ -static unsigned int crc_32_tab[256] = { +static const unsigned int crc_32_tab[256] = { 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, @@ -1073,7 +1058,7 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) #ifdef USE_ZLIB_CRC32 /* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ { - Byte *buf; + const Byte *buf; Py_ssize_t len; int signed_val; @@ -1084,7 +1069,7 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) } #else /* USE_ZLIB_CRC32 */ { /* By Jim Ahlstrom; All rights transferred to CNRI */ - unsigned char *bin_data; + const unsigned char *bin_data; Py_ssize_t len; unsigned int result; @@ -1167,7 +1152,7 @@ static PyObject * binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr) /*[clinic end generated code: output=0cc1a139af0eeecb input=9e1e7f2f94db24fd]*/ { - char* argbuf; + const char* argbuf; Py_ssize_t arglen; PyObject *retval; char* retbuf; @@ -1224,7 +1209,7 @@ binascii_unhexlify_impl(PyObject *module, Py_buffer *hexstr) return binascii_a2b_hex_impl(module, hexstr); } -static int table_hex[128] = { +static const int table_hex[128] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, @@ -1255,7 +1240,8 @@ binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header) { Py_ssize_t in, out; char ch; - unsigned char *ascii_data, *odata; + const unsigned char *ascii_data; + unsigned char *odata; Py_ssize_t datalen = 0; PyObject *rv; @@ -1361,13 +1347,14 @@ binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, /*[clinic end generated code: output=e9884472ebb1a94c input=7f2a9aaa008e92b2]*/ { Py_ssize_t in, out; - unsigned char *databuf, *odata; + const unsigned char *databuf; + unsigned char *odata; Py_ssize_t datalen = 0, odatalen = 0; PyObject *rv; unsigned int linelen = 0; unsigned char ch; int crlf = 0; - unsigned char *p; + const unsigned char *p; databuf = data->buf; datalen = data->len; @@ -1376,7 +1363,7 @@ binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, /* XXX: this function has the side effect of converting all of * the end of lines to be the same depending on this detection * here */ - p = (unsigned char *) memchr(databuf, '\n', datalen); + p = (const unsigned char *) memchr(databuf, '\n', datalen); if ((p != NULL) && (p > databuf) && (*(p-1) == '\r')) crlf = 1; diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index 8a47ff8..c9c58cd 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -25,13 +25,15 @@ static PyObject * _multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"input", "errors", NULL}; + static const char * const _keywords[] = {"input", "errors", NULL}; + static _PyArg_Parser _parser = {"O|z:encode", _keywords, 0}; PyObject *input; const char *errors = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|z:encode", _keywords, - &input, &errors)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &input, &errors)) { goto exit; + } return_value = _multibytecodec_MultibyteCodec_encode_impl(self, input, errors); exit: @@ -61,19 +63,22 @@ static PyObject * _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"input", "errors", NULL}; + static const char * const _keywords[] = {"input", "errors", NULL}; + static _PyArg_Parser _parser = {"y*|z:decode", _keywords, 0}; Py_buffer input = {NULL, NULL}; const char *errors = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|z:decode", _keywords, - &input, &errors)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &input, &errors)) { goto exit; + } return_value = _multibytecodec_MultibyteCodec_decode_impl(self, &input, errors); exit: /* Cleanup for input */ - if (input.obj) + if (input.obj) { PyBuffer_Release(&input); + } return return_value; } @@ -95,13 +100,15 @@ static PyObject * _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"input", "final", NULL}; + static const char * const _keywords[] = {"input", "final", NULL}; + static _PyArg_Parser _parser = {"O|i:encode", _keywords, 0}; PyObject *input; int final = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:encode", _keywords, - &input, &final)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &input, &final)) { goto exit; + } return_value = _multibytecodec_MultibyteIncrementalEncoder_encode_impl(self, input, final); exit: @@ -142,19 +149,22 @@ static PyObject * _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"input", "final", NULL}; + static const char * const _keywords[] = {"input", "final", NULL}; + static _PyArg_Parser _parser = {"y*|i:decode", _keywords, 0}; Py_buffer input = {NULL, NULL}; int final = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|i:decode", _keywords, - &input, &final)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &input, &final)) { goto exit; + } return_value = _multibytecodec_MultibyteIncrementalDecoder_decode_impl(self, &input, final); exit: /* Cleanup for input */ - if (input.obj) + if (input.obj) { PyBuffer_Release(&input); + } return return_value; } @@ -196,8 +206,9 @@ _multibytecodec_MultibyteStreamReader_read(MultibyteStreamReaderObject *self, Py if (!PyArg_UnpackTuple(args, "read", 0, 1, - &sizeobj)) + &sizeobj)) { goto exit; + } return_value = _multibytecodec_MultibyteStreamReader_read_impl(self, sizeobj); exit: @@ -224,8 +235,9 @@ _multibytecodec_MultibyteStreamReader_readline(MultibyteStreamReaderObject *self if (!PyArg_UnpackTuple(args, "readline", 0, 1, - &sizeobj)) + &sizeobj)) { goto exit; + } return_value = _multibytecodec_MultibyteStreamReader_readline_impl(self, sizeobj); exit: @@ -252,8 +264,9 @@ _multibytecodec_MultibyteStreamReader_readlines(MultibyteStreamReaderObject *sel if (!PyArg_UnpackTuple(args, "readlines", 0, 1, - &sizehintobj)) + &sizehintobj)) { goto exit; + } return_value = _multibytecodec_MultibyteStreamReader_readlines_impl(self, sizehintobj); exit: @@ -317,4 +330,4 @@ PyDoc_STRVAR(_multibytecodec___create_codec__doc__, #define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, -/*[clinic end generated code: output=eebb21e18c3043d1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8e86fa162c85230b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index 3ed8303e..c4032ea 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -25,14 +25,16 @@ _bz2_BZ2Compressor_compress(BZ2Compressor *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:compress", &data)) + if (!PyArg_Parse(arg, "y*:compress", &data)) { goto exit; + } return_value = _bz2_BZ2Compressor_compress_impl(self, &data); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -80,11 +82,13 @@ _bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) int compresslevel = 9; if ((Py_TYPE(self) == &BZ2Compressor_Type) && - !_PyArg_NoKeywords("BZ2Compressor", kwargs)) + !_PyArg_NoKeywords("BZ2Compressor", kwargs)) { goto exit; + } if (!PyArg_ParseTuple(args, "|i:BZ2Compressor", - &compresslevel)) + &compresslevel)) { goto exit; + } return_value = _bz2_BZ2Compressor___init___impl((BZ2Compressor *)self, compresslevel); exit: @@ -121,19 +125,22 @@ static PyObject * _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"data", "max_length", NULL}; + static const char * const _keywords[] = {"data", "max_length", NULL}; + static _PyArg_Parser _parser = {"y*|n:decompress", _keywords, 0}; Py_buffer data = {NULL, NULL}; Py_ssize_t max_length = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|n:decompress", _keywords, - &data, &max_length)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, &max_length)) { goto exit; + } return_value = _bz2_BZ2Decompressor_decompress_impl(self, &data, max_length); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -155,14 +162,16 @@ _bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) int return_value = -1; if ((Py_TYPE(self) == &BZ2Decompressor_Type) && - !_PyArg_NoPositional("BZ2Decompressor", args)) + !_PyArg_NoPositional("BZ2Decompressor", args)) { goto exit; + } if ((Py_TYPE(self) == &BZ2Decompressor_Type) && - !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) + !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) { goto exit; + } return_value = _bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self); exit: return return_value; } -/*[clinic end generated code: output=fef29b76b3314fc7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=40e5ef049f9e719b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index af06c6d..c7fd66f 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -33,8 +33,9 @@ _codecs_lookup(PyObject *module, PyObject *arg) PyObject *return_value = NULL; const char *encoding; - if (!PyArg_Parse(arg, "s:lookup", &encoding)) + if (!PyArg_Parse(arg, "s:lookup", &encoding)) { goto exit; + } return_value = _codecs_lookup_impl(module, encoding); exit: @@ -64,14 +65,16 @@ static PyObject * _codecs_encode(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"obj", "encoding", "errors", NULL}; + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; + static _PyArg_Parser _parser = {"O|ss:encode", _keywords, 0}; PyObject *obj; const char *encoding = NULL; const char *errors = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ss:encode", _keywords, - &obj, &encoding, &errors)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &obj, &encoding, &errors)) { goto exit; + } return_value = _codecs_encode_impl(module, obj, encoding, errors); exit: @@ -101,14 +104,16 @@ static PyObject * _codecs_decode(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"obj", "encoding", "errors", NULL}; + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; + static _PyArg_Parser _parser = {"O|ss:decode", _keywords, 0}; PyObject *obj; const char *encoding = NULL; const char *errors = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ss:decode", _keywords, - &obj, &encoding, &errors)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &obj, &encoding, &errors)) { goto exit; + } return_value = _codecs_decode_impl(module, obj, encoding, errors); exit: @@ -133,8 +138,9 @@ _codecs__forget_codec(PyObject *module, PyObject *arg) PyObject *return_value = NULL; const char *encoding; - if (!PyArg_Parse(arg, "s:_forget_codec", &encoding)) + if (!PyArg_Parse(arg, "s:_forget_codec", &encoding)) { goto exit; + } return_value = _codecs__forget_codec_impl(module, encoding); exit: @@ -161,14 +167,16 @@ _codecs_escape_decode(PyObject *module, PyObject *args) const char *errors = NULL; if (!PyArg_ParseTuple(args, "s*|z:escape_decode", - &data, &errors)) + &data, &errors)) { goto exit; + } return_value = _codecs_escape_decode_impl(module, &data, errors); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -193,8 +201,9 @@ _codecs_escape_encode(PyObject *module, PyObject *args) const char *errors = NULL; if (!PyArg_ParseTuple(args, "O!|z:escape_encode", - &PyBytes_Type, &data, &errors)) + &PyBytes_Type, &data, &errors)) { goto exit; + } return_value = _codecs_escape_encode_impl(module, data, errors); exit: @@ -221,8 +230,9 @@ _codecs_unicode_internal_decode(PyObject *module, PyObject *args) const char *errors = NULL; if (!PyArg_ParseTuple(args, "O|z:unicode_internal_decode", - &obj, &errors)) + &obj, &errors)) { goto exit; + } return_value = _codecs_unicode_internal_decode_impl(module, obj, errors); exit: @@ -250,14 +260,16 @@ _codecs_utf_7_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zi:utf_7_decode", - &data, &errors, &final)) + &data, &errors, &final)) { goto exit; + } return_value = _codecs_utf_7_decode_impl(module, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -283,14 +295,16 @@ _codecs_utf_8_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zi:utf_8_decode", - &data, &errors, &final)) + &data, &errors, &final)) { goto exit; + } return_value = _codecs_utf_8_decode_impl(module, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -316,14 +330,16 @@ _codecs_utf_16_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zi:utf_16_decode", - &data, &errors, &final)) + &data, &errors, &final)) { goto exit; + } return_value = _codecs_utf_16_decode_impl(module, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -349,14 +365,16 @@ _codecs_utf_16_le_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zi:utf_16_le_decode", - &data, &errors, &final)) + &data, &errors, &final)) { goto exit; + } return_value = _codecs_utf_16_le_decode_impl(module, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -382,14 +400,16 @@ _codecs_utf_16_be_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zi:utf_16_be_decode", - &data, &errors, &final)) + &data, &errors, &final)) { goto exit; + } return_value = _codecs_utf_16_be_decode_impl(module, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -417,14 +437,16 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zii:utf_16_ex_decode", - &data, &errors, &byteorder, &final)) + &data, &errors, &byteorder, &final)) { goto exit; + } return_value = _codecs_utf_16_ex_decode_impl(module, &data, errors, byteorder, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -450,14 +472,16 @@ _codecs_utf_32_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zi:utf_32_decode", - &data, &errors, &final)) + &data, &errors, &final)) { goto exit; + } return_value = _codecs_utf_32_decode_impl(module, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -483,14 +507,16 @@ _codecs_utf_32_le_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zi:utf_32_le_decode", - &data, &errors, &final)) + &data, &errors, &final)) { goto exit; + } return_value = _codecs_utf_32_le_decode_impl(module, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -516,14 +542,16 @@ _codecs_utf_32_be_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zi:utf_32_be_decode", - &data, &errors, &final)) + &data, &errors, &final)) { goto exit; + } return_value = _codecs_utf_32_be_decode_impl(module, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -551,14 +579,16 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zii:utf_32_ex_decode", - &data, &errors, &byteorder, &final)) + &data, &errors, &byteorder, &final)) { goto exit; + } return_value = _codecs_utf_32_ex_decode_impl(module, &data, errors, byteorder, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -583,14 +613,16 @@ _codecs_unicode_escape_decode(PyObject *module, PyObject *args) const char *errors = NULL; if (!PyArg_ParseTuple(args, "s*|z:unicode_escape_decode", - &data, &errors)) + &data, &errors)) { goto exit; + } return_value = _codecs_unicode_escape_decode_impl(module, &data, errors); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -615,14 +647,16 @@ _codecs_raw_unicode_escape_decode(PyObject *module, PyObject *args) const char *errors = NULL; if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode", - &data, &errors)) + &data, &errors)) { goto exit; + } return_value = _codecs_raw_unicode_escape_decode_impl(module, &data, errors); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -647,14 +681,16 @@ _codecs_latin_1_decode(PyObject *module, PyObject *args) const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:latin_1_decode", - &data, &errors)) + &data, &errors)) { goto exit; + } return_value = _codecs_latin_1_decode_impl(module, &data, errors); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -679,14 +715,16 @@ _codecs_ascii_decode(PyObject *module, PyObject *args) const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:ascii_decode", - &data, &errors)) + &data, &errors)) { goto exit; + } return_value = _codecs_ascii_decode_impl(module, &data, errors); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -712,19 +750,21 @@ _codecs_charmap_decode(PyObject *module, PyObject *args) PyObject *mapping = NULL; if (!PyArg_ParseTuple(args, "y*|zO:charmap_decode", - &data, &errors, &mapping)) + &data, &errors, &mapping)) { goto exit; + } return_value = _codecs_charmap_decode_impl(module, &data, errors, mapping); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } -#if defined(HAVE_MBCS) +#if defined(MS_WINDOWS) PyDoc_STRVAR(_codecs_mbcs_decode__doc__, "mbcs_decode($module, data, errors=None, final=False, /)\n" @@ -747,21 +787,62 @@ _codecs_mbcs_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "y*|zi:mbcs_decode", - &data, &errors, &final)) + &data, &errors, &final)) { goto exit; + } return_value = _codecs_mbcs_decode_impl(module, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } -#endif /* defined(HAVE_MBCS) */ +#endif /* defined(MS_WINDOWS) */ -#if defined(HAVE_MBCS) +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_codecs_oem_decode__doc__, +"oem_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_OEM_DECODE_METHODDEF \ + {"oem_decode", (PyCFunction)_codecs_oem_decode, METH_VARARGS, _codecs_oem_decode__doc__}, + +static PyObject * +_codecs_oem_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_oem_decode(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:oem_decode", + &data, &errors, &final)) { + goto exit; + } + return_value = _codecs_oem_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) PyDoc_STRVAR(_codecs_code_page_decode__doc__, "code_page_decode($module, codepage, data, errors=None, final=False, /)\n" @@ -785,19 +866,21 @@ _codecs_code_page_decode(PyObject *module, PyObject *args) int final = 0; if (!PyArg_ParseTuple(args, "iy*|zi:code_page_decode", - &codepage, &data, &errors, &final)) + &codepage, &data, &errors, &final)) { goto exit; + } return_value = _codecs_code_page_decode_impl(module, codepage, &data, errors, final); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } -#endif /* defined(HAVE_MBCS) */ +#endif /* defined(MS_WINDOWS) */ PyDoc_STRVAR(_codecs_readbuffer_encode__doc__, "readbuffer_encode($module, data, errors=None, /)\n" @@ -819,14 +902,16 @@ _codecs_readbuffer_encode(PyObject *module, PyObject *args) const char *errors = NULL; if (!PyArg_ParseTuple(args, "s*|z:readbuffer_encode", - &data, &errors)) + &data, &errors)) { goto exit; + } return_value = _codecs_readbuffer_encode_impl(module, &data, errors); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -851,8 +936,9 @@ _codecs_unicode_internal_encode(PyObject *module, PyObject *args) const char *errors = NULL; if (!PyArg_ParseTuple(args, "O|z:unicode_internal_encode", - &obj, &errors)) + &obj, &errors)) { goto exit; + } return_value = _codecs_unicode_internal_encode_impl(module, obj, errors); exit: @@ -878,9 +964,10 @@ _codecs_utf_7_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:utf_7_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:utf_7_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_utf_7_encode_impl(module, str, errors); exit: @@ -906,9 +993,10 @@ _codecs_utf_8_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:utf_8_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:utf_8_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_utf_8_encode_impl(module, str, errors); exit: @@ -935,9 +1023,10 @@ _codecs_utf_16_encode(PyObject *module, PyObject *args) const char *errors = NULL; int byteorder = 0; - if (!PyArg_ParseTuple(args, "O|zi:utf_16_encode", - &str, &errors, &byteorder)) + if (!PyArg_ParseTuple(args, "U|zi:utf_16_encode", + &str, &errors, &byteorder)) { goto exit; + } return_value = _codecs_utf_16_encode_impl(module, str, errors, byteorder); exit: @@ -963,9 +1052,10 @@ _codecs_utf_16_le_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:utf_16_le_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:utf_16_le_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_utf_16_le_encode_impl(module, str, errors); exit: @@ -991,9 +1081,10 @@ _codecs_utf_16_be_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:utf_16_be_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:utf_16_be_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_utf_16_be_encode_impl(module, str, errors); exit: @@ -1020,9 +1111,10 @@ _codecs_utf_32_encode(PyObject *module, PyObject *args) const char *errors = NULL; int byteorder = 0; - if (!PyArg_ParseTuple(args, "O|zi:utf_32_encode", - &str, &errors, &byteorder)) + if (!PyArg_ParseTuple(args, "U|zi:utf_32_encode", + &str, &errors, &byteorder)) { goto exit; + } return_value = _codecs_utf_32_encode_impl(module, str, errors, byteorder); exit: @@ -1048,9 +1140,10 @@ _codecs_utf_32_le_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:utf_32_le_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:utf_32_le_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_utf_32_le_encode_impl(module, str, errors); exit: @@ -1076,9 +1169,10 @@ _codecs_utf_32_be_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:utf_32_be_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:utf_32_be_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_utf_32_be_encode_impl(module, str, errors); exit: @@ -1104,9 +1198,10 @@ _codecs_unicode_escape_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:unicode_escape_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:unicode_escape_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_unicode_escape_encode_impl(module, str, errors); exit: @@ -1132,9 +1227,10 @@ _codecs_raw_unicode_escape_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:raw_unicode_escape_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:raw_unicode_escape_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_raw_unicode_escape_encode_impl(module, str, errors); exit: @@ -1160,9 +1256,10 @@ _codecs_latin_1_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:latin_1_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:latin_1_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_latin_1_encode_impl(module, str, errors); exit: @@ -1188,9 +1285,10 @@ _codecs_ascii_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:ascii_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:ascii_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_ascii_encode_impl(module, str, errors); exit: @@ -1217,9 +1315,10 @@ _codecs_charmap_encode(PyObject *module, PyObject *args) const char *errors = NULL; PyObject *mapping = NULL; - if (!PyArg_ParseTuple(args, "O|zO:charmap_encode", - &str, &errors, &mapping)) + if (!PyArg_ParseTuple(args, "U|zO:charmap_encode", + &str, &errors, &mapping)) { goto exit; + } return_value = _codecs_charmap_encode_impl(module, str, errors, mapping); exit: @@ -1243,15 +1342,16 @@ _codecs_charmap_build(PyObject *module, PyObject *arg) PyObject *return_value = NULL; PyObject *map; - if (!PyArg_Parse(arg, "U:charmap_build", &map)) + if (!PyArg_Parse(arg, "U:charmap_build", &map)) { goto exit; + } return_value = _codecs_charmap_build_impl(module, map); exit: return return_value; } -#if defined(HAVE_MBCS) +#if defined(MS_WINDOWS) PyDoc_STRVAR(_codecs_mbcs_encode__doc__, "mbcs_encode($module, str, errors=None, /)\n" @@ -1271,18 +1371,51 @@ _codecs_mbcs_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "O|z:mbcs_encode", - &str, &errors)) + if (!PyArg_ParseTuple(args, "U|z:mbcs_encode", + &str, &errors)) { goto exit; + } return_value = _codecs_mbcs_encode_impl(module, str, errors); exit: return return_value; } -#endif /* defined(HAVE_MBCS) */ +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_codecs_oem_encode__doc__, +"oem_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_OEM_ENCODE_METHODDEF \ + {"oem_encode", (PyCFunction)_codecs_oem_encode, METH_VARARGS, _codecs_oem_encode__doc__}, -#if defined(HAVE_MBCS) +static PyObject * +_codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors); + +static PyObject * +_codecs_oem_encode(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "U|z:oem_encode", + &str, &errors)) { + goto exit; + } + return_value = _codecs_oem_encode_impl(module, str, errors); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) PyDoc_STRVAR(_codecs_code_page_encode__doc__, "code_page_encode($module, code_page, str, errors=None, /)\n" @@ -1304,16 +1437,17 @@ _codecs_code_page_encode(PyObject *module, PyObject *args) PyObject *str; const char *errors = NULL; - if (!PyArg_ParseTuple(args, "iO|z:code_page_encode", - &code_page, &str, &errors)) + if (!PyArg_ParseTuple(args, "iU|z:code_page_encode", + &code_page, &str, &errors)) { goto exit; + } return_value = _codecs_code_page_encode_impl(module, code_page, str, errors); exit: return return_value; } -#endif /* defined(HAVE_MBCS) */ +#endif /* defined(MS_WINDOWS) */ PyDoc_STRVAR(_codecs_register_error__doc__, "register_error($module, errors, handler, /)\n" @@ -1340,8 +1474,9 @@ _codecs_register_error(PyObject *module, PyObject *args) PyObject *handler; if (!PyArg_ParseTuple(args, "sO:register_error", - &errors, &handler)) + &errors, &handler)) { goto exit; + } return_value = _codecs_register_error_impl(module, errors, handler); exit: @@ -1369,8 +1504,9 @@ _codecs_lookup_error(PyObject *module, PyObject *arg) PyObject *return_value = NULL; const char *name; - if (!PyArg_Parse(arg, "s:lookup_error", &name)) + if (!PyArg_Parse(arg, "s:lookup_error", &name)) { goto exit; + } return_value = _codecs_lookup_error_impl(module, name); exit: @@ -1381,6 +1517,10 @@ exit: #define _CODECS_MBCS_DECODE_METHODDEF #endif /* !defined(_CODECS_MBCS_DECODE_METHODDEF) */ +#ifndef _CODECS_OEM_DECODE_METHODDEF + #define _CODECS_OEM_DECODE_METHODDEF +#endif /* !defined(_CODECS_OEM_DECODE_METHODDEF) */ + #ifndef _CODECS_CODE_PAGE_DECODE_METHODDEF #define _CODECS_CODE_PAGE_DECODE_METHODDEF #endif /* !defined(_CODECS_CODE_PAGE_DECODE_METHODDEF) */ @@ -1389,7 +1529,11 @@ exit: #define _CODECS_MBCS_ENCODE_METHODDEF #endif /* !defined(_CODECS_MBCS_ENCODE_METHODDEF) */ +#ifndef _CODECS_OEM_ENCODE_METHODDEF + #define _CODECS_OEM_ENCODE_METHODDEF +#endif /* !defined(_CODECS_OEM_ENCODE_METHODDEF) */ + #ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF #define _CODECS_CODE_PAGE_ENCODE_METHODDEF #endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ -/*[clinic end generated code: output=42fed94e2ab765ba input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ebe313ab417b17bb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cryptmodule.c.h b/Modules/clinic/_cryptmodule.c.h index a3c371c..412c6fe 100644 --- a/Modules/clinic/_cryptmodule.c.h +++ b/Modules/clinic/_cryptmodule.c.h @@ -27,11 +27,12 @@ crypt_crypt(PyObject *module, PyObject *args) const char *salt; if (!PyArg_ParseTuple(args, "ss:crypt", - &word, &salt)) + &word, &salt)) { goto exit; + } return_value = crypt_crypt_impl(module, word, salt); exit: return return_value; } -/*[clinic end generated code: output=e0493a9691537690 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8dfc88264e662df4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index 5e11742..62ff1c8 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -40,22 +40,26 @@ curses_window_addch(PyCursesWindowObject *self, PyObject *args) switch (PyTuple_GET_SIZE(args)) { case 1: - if (!PyArg_ParseTuple(args, "O:addch", &ch)) + if (!PyArg_ParseTuple(args, "O:addch", &ch)) { goto exit; + } break; case 2: - if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) + if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) { goto exit; + } group_right_1 = 1; break; case 3: - if (!PyArg_ParseTuple(args, "iiO:addch", &y, &x, &ch)) + if (!PyArg_ParseTuple(args, "iiO:addch", &y, &x, &ch)) { goto exit; + } group_left_1 = 1; break; case 4: - if (!PyArg_ParseTuple(args, "iiOl:addch", &y, &x, &ch, &attr)) + if (!PyArg_ParseTuple(args, "iiOl:addch", &y, &x, &ch, &attr)) { goto exit; + } group_right_1 = 1; group_left_1 = 1; break; @@ -68,4 +72,4 @@ curses_window_addch(PyCursesWindowObject *self, PyObject *args) exit: return return_value; } -/*[clinic end generated code: output=982b1e709577f3ec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=13ffc5f8d79cbfbf input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_datetimemodule.c.h b/Modules/clinic/_datetimemodule.c.h index 688c903..cf09207 100644 --- a/Modules/clinic/_datetimemodule.c.h +++ b/Modules/clinic/_datetimemodule.c.h @@ -23,15 +23,17 @@ static PyObject * datetime_datetime_now(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"tz", NULL}; + static const char * const _keywords[] = {"tz", NULL}; + static _PyArg_Parser _parser = {"|O:now", _keywords, 0}; PyObject *tz = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:now", _keywords, - &tz)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &tz)) { goto exit; + } return_value = datetime_datetime_now_impl(type, tz); exit: return return_value; } -/*[clinic end generated code: output=7f45c670d6e4953a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=61f85af5637df8b5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index 49cbceb..06cf7e6 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -60,8 +60,9 @@ _dbm_dbm_get(dbmobject *self, PyObject *args) PyObject *default_value = NULL; if (!PyArg_ParseTuple(args, "s#|O:get", - &key, &key_length, &default_value)) + &key, &key_length, &default_value)) { goto exit; + } return_value = _dbm_dbm_get_impl(self, key, key_length, default_value); exit: @@ -93,8 +94,9 @@ _dbm_dbm_setdefault(dbmobject *self, PyObject *args) PyObject *default_value = NULL; if (!PyArg_ParseTuple(args, "s#|O:setdefault", - &key, &key_length, &default_value)) + &key, &key_length, &default_value)) { goto exit; + } return_value = _dbm_dbm_setdefault_impl(self, key, key_length, default_value); exit: @@ -131,11 +133,12 @@ dbmopen(PyObject *module, PyObject *args) int mode = 438; if (!PyArg_ParseTuple(args, "s|si:open", - &filename, &flags, &mode)) + &filename, &flags, &mode)) { goto exit; + } return_value = dbmopen_impl(module, filename, flags, mode); exit: return return_value; } -/*[clinic end generated code: output=fff12f168cdf8b43 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=99adf966ef0475ff input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 86b4c4c..c91dfbf 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -19,8 +19,9 @@ _elementtree_Element_append(ElementObject *self, PyObject *arg) PyObject *return_value = NULL; PyObject *subelement; - if (!PyArg_Parse(arg, "O!:append", &Element_Type, &subelement)) + if (!PyArg_Parse(arg, "O!:append", &Element_Type, &subelement)) { goto exit; + } return_value = _elementtree_Element_append_impl(self, subelement); exit: @@ -87,8 +88,9 @@ _elementtree_Element___sizeof__(ElementObject *self, PyObject *Py_UNUSED(ignored Py_ssize_t _return_value; _return_value = _elementtree_Element___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: @@ -144,13 +146,15 @@ static PyObject * _elementtree_Element_find(ElementObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "namespaces", NULL}; + static const char * const _keywords[] = {"path", "namespaces", NULL}; + static _PyArg_Parser _parser = {"O|O:find", _keywords, 0}; PyObject *path; PyObject *namespaces = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:find", _keywords, - &path, &namespaces)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &path, &namespaces)) { goto exit; + } return_value = _elementtree_Element_find_impl(self, path, namespaces); exit: @@ -174,14 +178,16 @@ static PyObject * _elementtree_Element_findtext(ElementObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "default", "namespaces", NULL}; + static const char * const _keywords[] = {"path", "default", "namespaces", NULL}; + static _PyArg_Parser _parser = {"O|OO:findtext", _keywords, 0}; PyObject *path; PyObject *default_value = Py_None; PyObject *namespaces = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO:findtext", _keywords, - &path, &default_value, &namespaces)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &path, &default_value, &namespaces)) { goto exit; + } return_value = _elementtree_Element_findtext_impl(self, path, default_value, namespaces); exit: @@ -204,13 +210,15 @@ static PyObject * _elementtree_Element_findall(ElementObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "namespaces", NULL}; + static const char * const _keywords[] = {"path", "namespaces", NULL}; + static _PyArg_Parser _parser = {"O|O:findall", _keywords, 0}; PyObject *path; PyObject *namespaces = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:findall", _keywords, - &path, &namespaces)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &path, &namespaces)) { goto exit; + } return_value = _elementtree_Element_findall_impl(self, path, namespaces); exit: @@ -233,13 +241,15 @@ static PyObject * _elementtree_Element_iterfind(ElementObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "namespaces", NULL}; + static const char * const _keywords[] = {"path", "namespaces", NULL}; + static _PyArg_Parser _parser = {"O|O:iterfind", _keywords, 0}; PyObject *path; PyObject *namespaces = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:iterfind", _keywords, - &path, &namespaces)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &path, &namespaces)) { goto exit; + } return_value = _elementtree_Element_iterfind_impl(self, path, namespaces); exit: @@ -262,13 +272,15 @@ static PyObject * _elementtree_Element_get(ElementObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"key", "default", NULL}; + static const char * const _keywords[] = {"key", "default", NULL}; + static _PyArg_Parser _parser = {"O|O:get", _keywords, 0}; PyObject *key; PyObject *default_value = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get", _keywords, - &key, &default_value)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &key, &default_value)) { goto exit; + } return_value = _elementtree_Element_get_impl(self, key, default_value); exit: @@ -307,12 +319,14 @@ static PyObject * _elementtree_Element_iter(ElementObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"tag", NULL}; + static const char * const _keywords[] = {"tag", NULL}; + static _PyArg_Parser _parser = {"|O:iter", _keywords, 0}; PyObject *tag = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:iter", _keywords, - &tag)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &tag)) { goto exit; + } return_value = _elementtree_Element_iter_impl(self, tag); exit: @@ -356,8 +370,9 @@ _elementtree_Element_insert(ElementObject *self, PyObject *args) PyObject *subelement; if (!PyArg_ParseTuple(args, "nO!:insert", - &index, &Element_Type, &subelement)) + &index, &Element_Type, &subelement)) { goto exit; + } return_value = _elementtree_Element_insert_impl(self, index, subelement); exit: @@ -419,8 +434,9 @@ _elementtree_Element_makeelement(ElementObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "makeelement", 2, 2, - &tag, &attrib)) + &tag, &attrib)) { goto exit; + } return_value = _elementtree_Element_makeelement_impl(self, tag, attrib); exit: @@ -444,8 +460,9 @@ _elementtree_Element_remove(ElementObject *self, PyObject *arg) PyObject *return_value = NULL; PyObject *subelement; - if (!PyArg_Parse(arg, "O!:remove", &Element_Type, &subelement)) + if (!PyArg_Parse(arg, "O!:remove", &Element_Type, &subelement)) { goto exit; + } return_value = _elementtree_Element_remove_impl(self, subelement); exit: @@ -473,8 +490,9 @@ _elementtree_Element_set(ElementObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "set", 2, 2, - &key, &value)) + &key, &value)) { goto exit; + } return_value = _elementtree_Element_set_impl(self, key, value); exit: @@ -489,12 +507,14 @@ static int _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"element_factory", NULL}; + static const char * const _keywords[] = {"element_factory", NULL}; + static _PyArg_Parser _parser = {"|O:TreeBuilder", _keywords, 0}; PyObject *element_factory = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:TreeBuilder", _keywords, - &element_factory)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &element_factory)) { goto exit; + } return_value = _elementtree_TreeBuilder___init___impl((TreeBuilderObject *)self, element_factory); exit: @@ -555,8 +575,9 @@ _elementtree_TreeBuilder_start(TreeBuilderObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "start", 1, 2, - &tag, &attrs)) + &tag, &attrs)) { goto exit; + } return_value = _elementtree_TreeBuilder_start_impl(self, tag, attrs); exit: @@ -571,14 +592,16 @@ static int _elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"html", "target", "encoding", NULL}; + static const char * const _keywords[] = {"html", "target", "encoding", NULL}; + static _PyArg_Parser _parser = {"|OOz:XMLParser", _keywords, 0}; PyObject *html = NULL; PyObject *target = NULL; const char *encoding = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOz:XMLParser", _keywords, - &html, &target, &encoding)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &html, &target, &encoding)) { goto exit; + } return_value = _elementtree_XMLParser___init___impl((XMLParserObject *)self, html, target, encoding); exit: @@ -640,8 +663,9 @@ _elementtree_XMLParser_doctype(XMLParserObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "doctype", 3, 3, - &name, &pubid, &system)) + &name, &pubid, &system)) { goto exit; + } return_value = _elementtree_XMLParser_doctype_impl(self, name, pubid, system); exit: @@ -668,12 +692,14 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *args) PyObject *events_queue; PyObject *events_to_report = Py_None; - if (!PyArg_ParseTuple(args, "O!|O:_setevents", - &PyList_Type, &events_queue, &events_to_report)) + if (!PyArg_UnpackTuple(args, "_setevents", + 1, 2, + &events_queue, &events_to_report)) { goto exit; + } return_value = _elementtree_XMLParser__setevents_impl(self, events_queue, events_to_report); exit: return return_value; } -/*[clinic end generated code: output=25b8bf7e7f2151ca input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4c5e94c28a009ce6 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index 2d87cfc..fdd589c 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -23,8 +23,9 @@ _gdbm_gdbm_get(dbmobject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "get", 1, 2, - &key, &default_value)) + &key, &default_value)) { goto exit; + } return_value = _gdbm_gdbm_get_impl(self, key, default_value); exit: @@ -53,8 +54,9 @@ _gdbm_gdbm_setdefault(dbmobject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, - &key, &default_value)) + &key, &default_value)) { goto exit; + } return_value = _gdbm_gdbm_setdefault_impl(self, key, default_value); exit: @@ -147,8 +149,9 @@ _gdbm_gdbm_nextkey(dbmobject *self, PyObject *arg) const char *key; Py_ssize_clean_t key_length; - if (!PyArg_Parse(arg, "s#:nextkey", &key, &key_length)) + if (!PyArg_Parse(arg, "s#:nextkey", &key, &key_length)) { goto exit; + } return_value = _gdbm_gdbm_nextkey_impl(self, key, key_length); exit: @@ -242,11 +245,12 @@ dbmopen(PyObject *module, PyObject *args) int mode = 438; if (!PyArg_ParseTuple(args, "s|si:open", - &name, &flags, &mode)) + &name, &flags, &mode)) { goto exit; + } return_value = dbmopen_impl(module, name, flags, mode); exit: return return_value; } -/*[clinic end generated code: output=9ac7a89858a9765f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ed0f5d4e3d79b80c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h new file mode 100644 index 0000000..96e6cfe --- /dev/null +++ b/Modules/clinic/_hashopenssl.c.h @@ -0,0 +1,60 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) + +PyDoc_STRVAR(_hashlib_scrypt__doc__, +"scrypt($module, /, password, *, salt=None, n=None, r=None, p=None,\n" +" maxmem=0, dklen=64)\n" +"--\n" +"\n" +"scrypt password-based key derivation function."); + +#define _HASHLIB_SCRYPT_METHODDEF \ + {"scrypt", (PyCFunction)_hashlib_scrypt, METH_VARARGS|METH_KEYWORDS, _hashlib_scrypt__doc__}, + +static PyObject * +_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, + PyObject *n_obj, PyObject *r_obj, PyObject *p_obj, + long maxmem, long dklen); + +static PyObject * +_hashlib_scrypt(PyObject *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"password", "salt", "n", "r", "p", "maxmem", "dklen", NULL}; + static _PyArg_Parser _parser = {"y*|$y*O!O!O!ll:scrypt", _keywords, 0}; + Py_buffer password = {NULL, NULL}; + Py_buffer salt = {NULL, NULL}; + PyObject *n_obj = Py_None; + PyObject *r_obj = Py_None; + PyObject *p_obj = Py_None; + long maxmem = 0; + long dklen = 64; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &password, &salt, &PyLong_Type, &n_obj, &PyLong_Type, &r_obj, &PyLong_Type, &p_obj, &maxmem, &dklen)) { + goto exit; + } + return_value = _hashlib_scrypt_impl(module, &password, &salt, n_obj, r_obj, p_obj, maxmem, dklen); + +exit: + /* Cleanup for password */ + if (password.obj) { + PyBuffer_Release(&password); + } + /* Cleanup for salt */ + if (salt.obj) { + PyBuffer_Release(&salt); + } + + return return_value; +} + +#endif /* (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) */ + +#ifndef _HASHLIB_SCRYPT_METHODDEF + #define _HASHLIB_SCRYPT_METHODDEF +#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ +/*[clinic end generated code: output=8c5386789f77430a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h index f8d38ea..c2ac89a 100644 --- a/Modules/clinic/_lzmamodule.c.h +++ b/Modules/clinic/_lzmamodule.c.h @@ -25,14 +25,16 @@ _lzma_LZMACompressor_compress(Compressor *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:compress", &data)) + if (!PyArg_Parse(arg, "y*:compress", &data)) { goto exit; + } return_value = _lzma_LZMACompressor_compress_impl(self, &data); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -89,19 +91,22 @@ static PyObject * _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"data", "max_length", NULL}; + static const char * const _keywords[] = {"data", "max_length", NULL}; + static _PyArg_Parser _parser = {"y*|n:decompress", _keywords, 0}; Py_buffer data = {NULL, NULL}; Py_ssize_t max_length = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|n:decompress", _keywords, - &data, &max_length)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, &max_length)) { goto exit; + } return_value = _lzma_LZMADecompressor_decompress_impl(self, &data, max_length); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -137,14 +142,16 @@ static int _lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"format", "memlimit", "filters", NULL}; + static const char * const _keywords[] = {"format", "memlimit", "filters", NULL}; + static _PyArg_Parser _parser = {"|iOO:LZMADecompressor", _keywords, 0}; int format = FORMAT_AUTO; PyObject *memlimit = Py_None; PyObject *filters = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOO:LZMADecompressor", _keywords, - &format, &memlimit, &filters)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &format, &memlimit, &filters)) { goto exit; + } return_value = _lzma_LZMADecompressor___init___impl((Decompressor *)self, format, memlimit, filters); exit: @@ -171,8 +178,9 @@ _lzma_is_check_supported(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int check_id; - if (!PyArg_Parse(arg, "i:is_check_supported", &check_id)) + if (!PyArg_Parse(arg, "i:is_check_supported", &check_id)) { goto exit; + } return_value = _lzma_is_check_supported_impl(module, check_id); exit: @@ -199,8 +207,9 @@ _lzma__encode_filter_properties(PyObject *module, PyObject *arg) PyObject *return_value = NULL; lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL}; - if (!PyArg_Parse(arg, "O&:_encode_filter_properties", lzma_filter_converter, &filter)) + if (!PyArg_Parse(arg, "O&:_encode_filter_properties", lzma_filter_converter, &filter)) { goto exit; + } return_value = _lzma__encode_filter_properties_impl(module, filter); exit: @@ -234,15 +243,17 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *args) Py_buffer encoded_props = {NULL, NULL}; if (!PyArg_ParseTuple(args, "O&y*:_decode_filter_properties", - lzma_vli_converter, &filter_id, &encoded_props)) + lzma_vli_converter, &filter_id, &encoded_props)) { goto exit; + } return_value = _lzma__decode_filter_properties_impl(module, filter_id, &encoded_props); exit: /* Cleanup for encoded_props */ - if (encoded_props.obj) + if (encoded_props.obj) { PyBuffer_Release(&encoded_props); + } return return_value; } -/*[clinic end generated code: output=fada06020fd318cc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9434583fe111c771 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h index a5f6442..513cbfd 100644 --- a/Modules/clinic/_opcode.c.h +++ b/Modules/clinic/_opcode.c.h @@ -23,14 +23,16 @@ _opcode_stack_effect(PyObject *module, PyObject *args) int _return_value; if (!PyArg_ParseTuple(args, "i|O:stack_effect", - &opcode, &oparg)) + &opcode, &oparg)) { goto exit; + } _return_value = _opcode_stack_effect_impl(module, opcode, oparg); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: return return_value; } -/*[clinic end generated code: output=984d6de140303d10 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4d91c6a765097853 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index bd12d2a..b8eec33 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -53,8 +53,9 @@ _pickle_Pickler___sizeof__(PicklerObject *self, PyObject *Py_UNUSED(ignored)) Py_ssize_t _return_value; _return_value = _pickle_Pickler___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: @@ -92,14 +93,16 @@ static int _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"file", "protocol", "fix_imports", NULL}; + static const char * const _keywords[] = {"file", "protocol", "fix_imports", NULL}; + static _PyArg_Parser _parser = {"O|Op:Pickler", _keywords, 0}; PyObject *file; PyObject *protocol = NULL; int fix_imports = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Op:Pickler", _keywords, - &file, &protocol, &fix_imports)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &file, &protocol, &fix_imports)) { goto exit; + } return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports); exit: @@ -212,8 +215,9 @@ _pickle_Unpickler_find_class(UnpicklerObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "find_class", 2, 2, - &module_name, &global_name)) + &module_name, &global_name)) { goto exit; + } return_value = _pickle_Unpickler_find_class_impl(self, module_name, global_name); exit: @@ -239,8 +243,9 @@ _pickle_Unpickler___sizeof__(UnpicklerObject *self, PyObject *Py_UNUSED(ignored) Py_ssize_t _return_value; _return_value = _pickle_Unpickler___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: @@ -281,15 +286,17 @@ static int _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + static _PyArg_Parser _parser = {"O|$pss:Unpickler", _keywords, 0}; PyObject *file; int fix_imports = 1; const char *encoding = "ASCII"; const char *errors = "strict"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$pss:Unpickler", _keywords, - &file, &fix_imports, &encoding, &errors)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &file, &fix_imports, &encoding, &errors)) { goto exit; + } return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors); exit: @@ -387,15 +394,17 @@ static PyObject * _pickle_dump(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"obj", "file", "protocol", "fix_imports", NULL}; + static const char * const _keywords[] = {"obj", "file", "protocol", "fix_imports", NULL}; + static _PyArg_Parser _parser = {"OO|O$p:dump", _keywords, 0}; PyObject *obj; PyObject *file; PyObject *protocol = NULL; int fix_imports = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O$p:dump", _keywords, - &obj, &file, &protocol, &fix_imports)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &obj, &file, &protocol, &fix_imports)) { goto exit; + } return_value = _pickle_dump_impl(module, obj, file, protocol, fix_imports); exit: @@ -431,14 +440,16 @@ static PyObject * _pickle_dumps(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"obj", "protocol", "fix_imports", NULL}; + static const char * const _keywords[] = {"obj", "protocol", "fix_imports", NULL}; + static _PyArg_Parser _parser = {"O|O$p:dumps", _keywords, 0}; PyObject *obj; PyObject *protocol = NULL; int fix_imports = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O$p:dumps", _keywords, - &obj, &protocol, &fix_imports)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &obj, &protocol, &fix_imports)) { goto exit; + } return_value = _pickle_dumps_impl(module, obj, protocol, fix_imports); exit: @@ -485,15 +496,17 @@ static PyObject * _pickle_load(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + static _PyArg_Parser _parser = {"O|$pss:load", _keywords, 0}; PyObject *file; int fix_imports = 1; const char *encoding = "ASCII"; const char *errors = "strict"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$pss:load", _keywords, - &file, &fix_imports, &encoding, &errors)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &file, &fix_imports, &encoding, &errors)) { goto exit; + } return_value = _pickle_load_impl(module, file, fix_imports, encoding, errors); exit: @@ -531,18 +544,20 @@ static PyObject * _pickle_loads(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"data", "fix_imports", "encoding", "errors", NULL}; + static const char * const _keywords[] = {"data", "fix_imports", "encoding", "errors", NULL}; + static _PyArg_Parser _parser = {"O|$pss:loads", _keywords, 0}; PyObject *data; int fix_imports = 1; const char *encoding = "ASCII"; const char *errors = "strict"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$pss:loads", _keywords, - &data, &fix_imports, &encoding, &errors)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, &fix_imports, &encoding, &errors)) { goto exit; + } return_value = _pickle_loads_impl(module, data, fix_imports, encoding, errors); exit: return return_value; } -/*[clinic end generated code: output=93657e55d6a748af input=a9049054013a1b77]*/ +/*[clinic end generated code: output=50f9127109673c98 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_sre.c.h b/Modules/clinic/_sre.c.h index 3281717..9aba13e 100644 --- a/Modules/clinic/_sre.c.h +++ b/Modules/clinic/_sre.c.h @@ -20,8 +20,9 @@ _sre_getcodesize(PyObject *module, PyObject *Py_UNUSED(ignored)) int _return_value; _return_value = _sre_getcodesize_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -48,11 +49,13 @@ _sre_getlower(PyObject *module, PyObject *args) int _return_value; if (!PyArg_ParseTuple(args, "ii:getlower", - &character, &flags)) + &character, &flags)) { goto exit; + } _return_value = _sre_getlower_impl(module, character, flags); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -77,15 +80,17 @@ static PyObject * _sre_SRE_Pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + static const char * const _keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + static _PyArg_Parser _parser = {"|Onn$O:match", _keywords, 0}; PyObject *string = NULL; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; PyObject *pattern = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Onn$O:match", _keywords, - &string, &pos, &endpos, &pattern)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string, &pos, &endpos, &pattern)) { goto exit; + } return_value = _sre_SRE_Pattern_match_impl(self, string, pos, endpos, pattern); exit: @@ -111,15 +116,17 @@ static PyObject * _sre_SRE_Pattern_fullmatch(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + static const char * const _keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + static _PyArg_Parser _parser = {"|Onn$O:fullmatch", _keywords, 0}; PyObject *string = NULL; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; PyObject *pattern = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Onn$O:fullmatch", _keywords, - &string, &pos, &endpos, &pattern)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string, &pos, &endpos, &pattern)) { goto exit; + } return_value = _sre_SRE_Pattern_fullmatch_impl(self, string, pos, endpos, pattern); exit: @@ -147,15 +154,17 @@ static PyObject * _sre_SRE_Pattern_search(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + static const char * const _keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + static _PyArg_Parser _parser = {"|Onn$O:search", _keywords, 0}; PyObject *string = NULL; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; PyObject *pattern = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Onn$O:search", _keywords, - &string, &pos, &endpos, &pattern)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string, &pos, &endpos, &pattern)) { goto exit; + } return_value = _sre_SRE_Pattern_search_impl(self, string, pos, endpos, pattern); exit: @@ -181,15 +190,17 @@ static PyObject * _sre_SRE_Pattern_findall(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", "pos", "endpos", "source", NULL}; + static const char * const _keywords[] = {"string", "pos", "endpos", "source", NULL}; + static _PyArg_Parser _parser = {"|Onn$O:findall", _keywords, 0}; PyObject *string = NULL; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; PyObject *source = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Onn$O:findall", _keywords, - &string, &pos, &endpos, &source)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string, &pos, &endpos, &source)) { goto exit; + } return_value = _sre_SRE_Pattern_findall_impl(self, string, pos, endpos, source); exit: @@ -215,14 +226,16 @@ static PyObject * _sre_SRE_Pattern_finditer(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", "pos", "endpos", NULL}; + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; + static _PyArg_Parser _parser = {"O|nn:finditer", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|nn:finditer", _keywords, - &string, &pos, &endpos)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string, &pos, &endpos)) { goto exit; + } return_value = _sre_SRE_Pattern_finditer_impl(self, string, pos, endpos); exit: @@ -245,14 +258,16 @@ static PyObject * _sre_SRE_Pattern_scanner(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", "pos", "endpos", NULL}; + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; + static _PyArg_Parser _parser = {"O|nn:scanner", _keywords, 0}; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|nn:scanner", _keywords, - &string, &pos, &endpos)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string, &pos, &endpos)) { goto exit; + } return_value = _sre_SRE_Pattern_scanner_impl(self, string, pos, endpos); exit: @@ -276,14 +291,16 @@ static PyObject * _sre_SRE_Pattern_split(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", "maxsplit", "source", NULL}; + static const char * const _keywords[] = {"string", "maxsplit", "source", NULL}; + static _PyArg_Parser _parser = {"|On$O:split", _keywords, 0}; PyObject *string = NULL; Py_ssize_t maxsplit = 0; PyObject *source = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|On$O:split", _keywords, - &string, &maxsplit, &source)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string, &maxsplit, &source)) { goto exit; + } return_value = _sre_SRE_Pattern_split_impl(self, string, maxsplit, source); exit: @@ -307,14 +324,16 @@ static PyObject * _sre_SRE_Pattern_sub(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"repl", "string", "count", NULL}; + static const char * const _keywords[] = {"repl", "string", "count", NULL}; + static _PyArg_Parser _parser = {"OO|n:sub", _keywords, 0}; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|n:sub", _keywords, - &repl, &string, &count)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &repl, &string, &count)) { goto exit; + } return_value = _sre_SRE_Pattern_sub_impl(self, repl, string, count); exit: @@ -338,14 +357,16 @@ static PyObject * _sre_SRE_Pattern_subn(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"repl", "string", "count", NULL}; + static const char * const _keywords[] = {"repl", "string", "count", NULL}; + static _PyArg_Parser _parser = {"OO|n:subn", _keywords, 0}; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|n:subn", _keywords, - &repl, &string, &count)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &repl, &string, &count)) { goto exit; + } return_value = _sre_SRE_Pattern_subn_impl(self, repl, string, count); exit: @@ -384,12 +405,14 @@ static PyObject * _sre_SRE_Pattern___deepcopy__(PatternObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"memo", NULL}; + static const char * const _keywords[] = {"memo", NULL}; + static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; PyObject *memo; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:__deepcopy__", _keywords, - &memo)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &memo)) { goto exit; + } return_value = _sre_SRE_Pattern___deepcopy___impl(self, memo); exit: @@ -414,7 +437,8 @@ static PyObject * _sre_compile(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"pattern", "flags", "code", "groups", "groupindex", "indexgroup", NULL}; + static const char * const _keywords[] = {"pattern", "flags", "code", "groups", "groupindex", "indexgroup", NULL}; + static _PyArg_Parser _parser = {"OiO!nOO:compile", _keywords, 0}; PyObject *pattern; int flags; PyObject *code; @@ -422,9 +446,10 @@ _sre_compile(PyObject *module, PyObject *args, PyObject *kwargs) PyObject *groupindex; PyObject *indexgroup; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiO!nOO:compile", _keywords, - &pattern, &flags, &PyList_Type, &code, &groups, &groupindex, &indexgroup)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &pattern, &flags, &PyList_Type, &code, &groups, &groupindex, &indexgroup)) { goto exit; + } return_value = _sre_compile_impl(module, pattern, flags, code, groups, groupindex, indexgroup); exit: @@ -447,12 +472,14 @@ static PyObject * _sre_SRE_Match_expand(MatchObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"template", NULL}; + static const char * const _keywords[] = {"template", NULL}; + static _PyArg_Parser _parser = {"O:expand", _keywords, 0}; PyObject *template; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:expand", _keywords, - &template)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &template)) { goto exit; + } return_value = _sre_SRE_Match_expand_impl(self, template); exit: @@ -478,12 +505,14 @@ static PyObject * _sre_SRE_Match_groups(MatchObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"default", NULL}; + static const char * const _keywords[] = {"default", NULL}; + static _PyArg_Parser _parser = {"|O:groups", _keywords, 0}; PyObject *default_value = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:groups", _keywords, - &default_value)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &default_value)) { goto exit; + } return_value = _sre_SRE_Match_groups_impl(self, default_value); exit: @@ -509,12 +538,14 @@ static PyObject * _sre_SRE_Match_groupdict(MatchObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"default", NULL}; + static const char * const _keywords[] = {"default", NULL}; + static _PyArg_Parser _parser = {"|O:groupdict", _keywords, 0}; PyObject *default_value = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:groupdict", _keywords, - &default_value)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &default_value)) { goto exit; + } return_value = _sre_SRE_Match_groupdict_impl(self, default_value); exit: @@ -542,11 +573,13 @@ _sre_SRE_Match_start(MatchObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "start", 0, 1, - &group)) + &group)) { goto exit; + } _return_value = _sre_SRE_Match_start_impl(self, group); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: @@ -574,11 +607,13 @@ _sre_SRE_Match_end(MatchObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "end", 0, 1, - &group)) + &group)) { goto exit; + } _return_value = _sre_SRE_Match_end_impl(self, group); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: @@ -605,8 +640,9 @@ _sre_SRE_Match_span(MatchObject *self, PyObject *args) if (!PyArg_UnpackTuple(args, "span", 0, 1, - &group)) + &group)) { goto exit; + } return_value = _sre_SRE_Match_span_impl(self, group); exit: @@ -645,12 +681,14 @@ static PyObject * _sre_SRE_Match___deepcopy__(MatchObject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"memo", NULL}; + static const char * const _keywords[] = {"memo", NULL}; + static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; PyObject *memo; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:__deepcopy__", _keywords, - &memo)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &memo)) { goto exit; + } return_value = _sre_SRE_Match___deepcopy___impl(self, memo); exit: @@ -690,4 +728,4 @@ _sre_SRE_Scanner_search(ScannerObject *self, PyObject *Py_UNUSED(ignored)) { return _sre_SRE_Scanner_search_impl(self); } -/*[clinic end generated code: output=a4ce9e5b748ce532 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2cbc2b1482738e54 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 852e365..ee8213a 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -36,8 +36,9 @@ _ssl__test_decode_cert(PyObject *module, PyObject *arg) PyObject *return_value = NULL; PyObject *path; - if (!PyArg_Parse(arg, "O&:_test_decode_cert", PyUnicode_FSConverter, &path)) + if (!PyArg_Parse(arg, "O&:_test_decode_cert", PyUnicode_FSConverter, &path)) { goto exit; + } return_value = _ssl__test_decode_cert_impl(module, path); exit: @@ -71,8 +72,9 @@ _ssl__SSLSocket_peer_certificate(PySSLSocket *self, PyObject *args) int binary_mode = 0; if (!PyArg_ParseTuple(args, "|p:peer_certificate", - &binary_mode)) + &binary_mode)) { goto exit; + } return_value = _ssl__SSLSocket_peer_certificate_impl(self, binary_mode); exit: @@ -209,14 +211,16 @@ _ssl__SSLSocket_write(PySSLSocket *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer b = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:write", &b)) + if (!PyArg_Parse(arg, "y*:write", &b)) { goto exit; + } return_value = _ssl__SSLSocket_write_impl(self, &b); exit: /* Cleanup for b */ - if (b.obj) + if (b.obj) { PyBuffer_Release(&b); + } return return_value; } @@ -260,12 +264,14 @@ _ssl__SSLSocket_read(PySSLSocket *self, PyObject *args) switch (PyTuple_GET_SIZE(args)) { case 1: - if (!PyArg_ParseTuple(args, "i:read", &len)) + if (!PyArg_ParseTuple(args, "i:read", &len)) { goto exit; + } break; case 2: - if (!PyArg_ParseTuple(args, "iw*:read", &len, &buffer)) + if (!PyArg_ParseTuple(args, "iw*:read", &len, &buffer)) { goto exit; + } group_right_1 = 1; break; default: @@ -276,8 +282,9 @@ _ssl__SSLSocket_read(PySSLSocket *self, PyObject *args) exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -332,11 +339,13 @@ _ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) int proto_version; if ((type == &PySSLContext_Type) && - !_PyArg_NoKeywords("_SSLContext", kwargs)) + !_PyArg_NoKeywords("_SSLContext", kwargs)) { goto exit; + } if (!PyArg_ParseTuple(args, "i:_SSLContext", - &proto_version)) + &proto_version)) { goto exit; + } return_value = _ssl__SSLContext_impl(type, proto_version); exit: @@ -360,14 +369,36 @@ _ssl__SSLContext_set_ciphers(PySSLContext *self, PyObject *arg) PyObject *return_value = NULL; const char *cipherlist; - if (!PyArg_Parse(arg, "s:set_ciphers", &cipherlist)) + if (!PyArg_Parse(arg, "s:set_ciphers", &cipherlist)) { goto exit; + } return_value = _ssl__SSLContext_set_ciphers_impl(self, cipherlist); exit: return return_value; } +#if (OPENSSL_VERSION_NUMBER >= 0x10002000UL) + +PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__, +"get_ciphers($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF \ + {"get_ciphers", (PyCFunction)_ssl__SSLContext_get_ciphers, METH_NOARGS, _ssl__SSLContext_get_ciphers__doc__}, + +static PyObject * +_ssl__SSLContext_get_ciphers_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_get_ciphers(PySSLContext *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLContext_get_ciphers_impl(self); +} + +#endif /* (OPENSSL_VERSION_NUMBER >= 0x10002000UL) */ + PyDoc_STRVAR(_ssl__SSLContext__set_npn_protocols__doc__, "_set_npn_protocols($self, protos, /)\n" "--\n" @@ -386,14 +417,16 @@ _ssl__SSLContext__set_npn_protocols(PySSLContext *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer protos = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:_set_npn_protocols", &protos)) + if (!PyArg_Parse(arg, "y*:_set_npn_protocols", &protos)) { goto exit; + } return_value = _ssl__SSLContext__set_npn_protocols_impl(self, &protos); exit: /* Cleanup for protos */ - if (protos.obj) + if (protos.obj) { PyBuffer_Release(&protos); + } return return_value; } @@ -416,14 +449,16 @@ _ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer protos = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:_set_alpn_protocols", &protos)) + if (!PyArg_Parse(arg, "y*:_set_alpn_protocols", &protos)) { goto exit; + } return_value = _ssl__SSLContext__set_alpn_protocols_impl(self, &protos); exit: /* Cleanup for protos */ - if (protos.obj) + if (protos.obj) { PyBuffer_Release(&protos); + } return return_value; } @@ -444,14 +479,16 @@ static PyObject * _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"certfile", "keyfile", "password", NULL}; + static const char * const _keywords[] = {"certfile", "keyfile", "password", NULL}; + static _PyArg_Parser _parser = {"O|OO:load_cert_chain", _keywords, 0}; PyObject *certfile; PyObject *keyfile = NULL; PyObject *password = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO:load_cert_chain", _keywords, - &certfile, &keyfile, &password)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &certfile, &keyfile, &password)) { goto exit; + } return_value = _ssl__SSLContext_load_cert_chain_impl(self, certfile, keyfile, password); exit: @@ -476,14 +513,16 @@ static PyObject * _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"cafile", "capath", "cadata", NULL}; + static const char * const _keywords[] = {"cafile", "capath", "cadata", NULL}; + static _PyArg_Parser _parser = {"|OOO:load_verify_locations", _keywords, 0}; PyObject *cafile = NULL; PyObject *capath = NULL; PyObject *cadata = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO:load_verify_locations", _keywords, - &cafile, &capath, &cadata)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &cafile, &capath, &cadata)) { goto exit; + } return_value = _ssl__SSLContext_load_verify_locations_impl(self, cafile, capath, cadata); exit: @@ -514,14 +553,16 @@ static PyObject * _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"sock", "server_side", "server_hostname", NULL}; + static const char * const _keywords[] = {"sock", "server_side", "server_hostname", NULL}; + static _PyArg_Parser _parser = {"O!i|O:_wrap_socket", _keywords, 0}; PyObject *sock; int server_side; PyObject *hostname_obj = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!i|O:_wrap_socket", _keywords, - PySocketModule.Sock_Type, &sock, &server_side, &hostname_obj)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + PySocketModule.Sock_Type, &sock, &server_side, &hostname_obj)) { goto exit; + } return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj); exit: @@ -546,15 +587,17 @@ static PyObject * _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", NULL}; + static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", NULL}; + static _PyArg_Parser _parser = {"O!O!i|O:_wrap_bio", _keywords, 0}; PySSLMemoryBIO *incoming; PySSLMemoryBIO *outgoing; int server_side; PyObject *hostname_obj = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!i|O:_wrap_bio", _keywords, - &PySSLMemoryBIO_Type, &incoming, &PySSLMemoryBIO_Type, &outgoing, &server_side, &hostname_obj)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &PySSLMemoryBIO_Type, &incoming, &PySSLMemoryBIO_Type, &outgoing, &server_side, &hostname_obj)) { goto exit; + } return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj); exit: @@ -666,12 +709,14 @@ static PyObject * _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"binary_form", NULL}; + static const char * const _keywords[] = {"binary_form", NULL}; + static _PyArg_Parser _parser = {"|p:get_ca_certs", _keywords, 0}; int binary_form = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p:get_ca_certs", _keywords, - &binary_form)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &binary_form)) { goto exit; + } return_value = _ssl__SSLContext_get_ca_certs_impl(self, binary_form); exit: @@ -687,11 +732,13 @@ _ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyObject *return_value = NULL; if ((type == &PySSLMemoryBIO_Type) && - !_PyArg_NoPositional("MemoryBIO", args)) + !_PyArg_NoPositional("MemoryBIO", args)) { goto exit; + } if ((type == &PySSLMemoryBIO_Type) && - !_PyArg_NoKeywords("MemoryBIO", kwargs)) + !_PyArg_NoKeywords("MemoryBIO", kwargs)) { goto exit; + } return_value = _ssl_MemoryBIO_impl(type); exit: @@ -722,8 +769,9 @@ _ssl_MemoryBIO_read(PySSLMemoryBIO *self, PyObject *args) int len = -1; if (!PyArg_ParseTuple(args, "|i:read", - &len)) + &len)) { goto exit; + } return_value = _ssl_MemoryBIO_read_impl(self, len); exit: @@ -750,14 +798,16 @@ _ssl_MemoryBIO_write(PySSLMemoryBIO *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer b = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:write", &b)) + if (!PyArg_Parse(arg, "y*:write", &b)) { goto exit; + } return_value = _ssl_MemoryBIO_write_impl(self, &b); exit: /* Cleanup for b */ - if (b.obj) + if (b.obj) { PyBuffer_Release(&b); + } return return_value; } @@ -805,14 +855,16 @@ _ssl_RAND_add(PyObject *module, PyObject *args) double entropy; if (!PyArg_ParseTuple(args, "s*d:RAND_add", - &view, &entropy)) + &view, &entropy)) { goto exit; + } return_value = _ssl_RAND_add_impl(module, &view, entropy); exit: /* Cleanup for view */ - if (view.obj) + if (view.obj) { PyBuffer_Release(&view); + } return return_value; } @@ -835,8 +887,9 @@ _ssl_RAND_bytes(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int n; - if (!PyArg_Parse(arg, "i:RAND_bytes", &n)) + if (!PyArg_Parse(arg, "i:RAND_bytes", &n)) { goto exit; + } return_value = _ssl_RAND_bytes_impl(module, n); exit: @@ -864,8 +917,9 @@ _ssl_RAND_pseudo_bytes(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int n; - if (!PyArg_Parse(arg, "i:RAND_pseudo_bytes", &n)) + if (!PyArg_Parse(arg, "i:RAND_pseudo_bytes", &n)) { goto exit; + } return_value = _ssl_RAND_pseudo_bytes_impl(module, n); exit: @@ -916,8 +970,9 @@ _ssl_RAND_egd(PyObject *module, PyObject *arg) PyObject *return_value = NULL; PyObject *path; - if (!PyArg_Parse(arg, "O&:RAND_egd", PyUnicode_FSConverter, &path)) + if (!PyArg_Parse(arg, "O&:RAND_egd", PyUnicode_FSConverter, &path)) { goto exit; + } return_value = _ssl_RAND_egd_impl(module, path); exit: @@ -965,13 +1020,15 @@ static PyObject * _ssl_txt2obj(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"txt", "name", NULL}; + static const char * const _keywords[] = {"txt", "name", NULL}; + static _PyArg_Parser _parser = {"s|p:txt2obj", _keywords, 0}; const char *txt; int name = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|p:txt2obj", _keywords, - &txt, &name)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &txt, &name)) { goto exit; + } return_value = _ssl_txt2obj_impl(module, txt, name); exit: @@ -996,8 +1053,9 @@ _ssl_nid2obj(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int nid; - if (!PyArg_Parse(arg, "i:nid2obj", &nid)) + if (!PyArg_Parse(arg, "i:nid2obj", &nid)) { goto exit; + } return_value = _ssl_nid2obj_impl(module, nid); exit: @@ -1028,12 +1086,14 @@ static PyObject * _ssl_enum_certificates(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"store_name", NULL}; + static const char * const _keywords[] = {"store_name", NULL}; + static _PyArg_Parser _parser = {"s:enum_certificates", _keywords, 0}; const char *store_name; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:enum_certificates", _keywords, - &store_name)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &store_name)) { goto exit; + } return_value = _ssl_enum_certificates_impl(module, store_name); exit: @@ -1065,12 +1125,14 @@ static PyObject * _ssl_enum_crls(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"store_name", NULL}; + static const char * const _keywords[] = {"store_name", NULL}; + static _PyArg_Parser _parser = {"s:enum_crls", _keywords, 0}; const char *store_name; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:enum_crls", _keywords, - &store_name)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &store_name)) { goto exit; + } return_value = _ssl_enum_crls_impl(module, store_name); exit: @@ -1087,6 +1149,10 @@ exit: #define _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF #endif /* !defined(_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF) */ +#ifndef _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF + #define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF +#endif /* !defined(_SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF) */ + #ifndef _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF #endif /* !defined(_SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF) */ @@ -1102,4 +1168,4 @@ exit: #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=6fb10594d8351dc5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2e7907a7d8f97ccf input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index 77af083..edd5380 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -19,8 +19,9 @@ _tkinter_tkapp_eval(TkappObject *self, PyObject *arg) PyObject *return_value = NULL; const char *script; - if (!PyArg_Parse(arg, "s:eval", &script)) + if (!PyArg_Parse(arg, "s:eval", &script)) { goto exit; + } return_value = _tkinter_tkapp_eval_impl(self, script); exit: @@ -44,8 +45,9 @@ _tkinter_tkapp_evalfile(TkappObject *self, PyObject *arg) PyObject *return_value = NULL; const char *fileName; - if (!PyArg_Parse(arg, "s:evalfile", &fileName)) + if (!PyArg_Parse(arg, "s:evalfile", &fileName)) { goto exit; + } return_value = _tkinter_tkapp_evalfile_impl(self, fileName); exit: @@ -69,8 +71,9 @@ _tkinter_tkapp_record(TkappObject *self, PyObject *arg) PyObject *return_value = NULL; const char *script; - if (!PyArg_Parse(arg, "s:record", &script)) + if (!PyArg_Parse(arg, "s:record", &script)) { goto exit; + } return_value = _tkinter_tkapp_record_impl(self, script); exit: @@ -94,8 +97,9 @@ _tkinter_tkapp_adderrinfo(TkappObject *self, PyObject *arg) PyObject *return_value = NULL; const char *msg; - if (!PyArg_Parse(arg, "s:adderrinfo", &msg)) + if (!PyArg_Parse(arg, "s:adderrinfo", &msg)) { goto exit; + } return_value = _tkinter_tkapp_adderrinfo_impl(self, msg); exit: @@ -143,8 +147,9 @@ _tkinter_tkapp_exprstring(TkappObject *self, PyObject *arg) PyObject *return_value = NULL; const char *s; - if (!PyArg_Parse(arg, "s:exprstring", &s)) + if (!PyArg_Parse(arg, "s:exprstring", &s)) { goto exit; + } return_value = _tkinter_tkapp_exprstring_impl(self, s); exit: @@ -168,8 +173,9 @@ _tkinter_tkapp_exprlong(TkappObject *self, PyObject *arg) PyObject *return_value = NULL; const char *s; - if (!PyArg_Parse(arg, "s:exprlong", &s)) + if (!PyArg_Parse(arg, "s:exprlong", &s)) { goto exit; + } return_value = _tkinter_tkapp_exprlong_impl(self, s); exit: @@ -193,8 +199,9 @@ _tkinter_tkapp_exprdouble(TkappObject *self, PyObject *arg) PyObject *return_value = NULL; const char *s; - if (!PyArg_Parse(arg, "s:exprdouble", &s)) + if (!PyArg_Parse(arg, "s:exprdouble", &s)) { goto exit; + } return_value = _tkinter_tkapp_exprdouble_impl(self, s); exit: @@ -218,8 +225,9 @@ _tkinter_tkapp_exprboolean(TkappObject *self, PyObject *arg) PyObject *return_value = NULL; const char *s; - if (!PyArg_Parse(arg, "s:exprboolean", &s)) + if (!PyArg_Parse(arg, "s:exprboolean", &s)) { goto exit; + } return_value = _tkinter_tkapp_exprboolean_impl(self, s); exit: @@ -262,8 +270,9 @@ _tkinter_tkapp_createcommand(TkappObject *self, PyObject *args) PyObject *func; if (!PyArg_ParseTuple(args, "sO:createcommand", - &name, &func)) + &name, &func)) { goto exit; + } return_value = _tkinter_tkapp_createcommand_impl(self, name, func); exit: @@ -287,8 +296,9 @@ _tkinter_tkapp_deletecommand(TkappObject *self, PyObject *arg) PyObject *return_value = NULL; const char *name; - if (!PyArg_Parse(arg, "s:deletecommand", &name)) + if (!PyArg_Parse(arg, "s:deletecommand", &name)) { goto exit; + } return_value = _tkinter_tkapp_deletecommand_impl(self, name); exit: @@ -318,8 +328,9 @@ _tkinter_tkapp_createfilehandler(TkappObject *self, PyObject *args) PyObject *func; if (!PyArg_ParseTuple(args, "OiO:createfilehandler", - &file, &mask, &func)) + &file, &mask, &func)) { goto exit; + } return_value = _tkinter_tkapp_createfilehandler_impl(self, file, mask, func); exit: @@ -377,8 +388,9 @@ _tkinter_tkapp_createtimerhandler(TkappObject *self, PyObject *args) PyObject *func; if (!PyArg_ParseTuple(args, "iO:createtimerhandler", - &milliseconds, &func)) + &milliseconds, &func)) { goto exit; + } return_value = _tkinter_tkapp_createtimerhandler_impl(self, milliseconds, func); exit: @@ -403,8 +415,9 @@ _tkinter_tkapp_mainloop(TkappObject *self, PyObject *args) int threshold = 0; if (!PyArg_ParseTuple(args, "|i:mainloop", - &threshold)) + &threshold)) { goto exit; + } return_value = _tkinter_tkapp_mainloop_impl(self, threshold); exit: @@ -429,8 +442,9 @@ _tkinter_tkapp_dooneevent(TkappObject *self, PyObject *args) int flags = 0; if (!PyArg_ParseTuple(args, "|i:dooneevent", - &flags)) + &flags)) { goto exit; + } return_value = _tkinter_tkapp_dooneevent_impl(self, flags); exit: @@ -551,8 +565,9 @@ _tkinter_create(PyObject *module, PyObject *args) const char *use = NULL; if (!PyArg_ParseTuple(args, "|zssiiiiz:create", - &screenName, &baseName, &className, &interactive, &wantobjects, &wantTk, &sync, &use)) + &screenName, &baseName, &className, &interactive, &wantobjects, &wantTk, &sync, &use)) { goto exit; + } return_value = _tkinter_create_impl(module, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use); exit: @@ -579,8 +594,9 @@ _tkinter_setbusywaitinterval(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int new_val; - if (!PyArg_Parse(arg, "i:setbusywaitinterval", &new_val)) + if (!PyArg_Parse(arg, "i:setbusywaitinterval", &new_val)) { goto exit; + } return_value = _tkinter_setbusywaitinterval_impl(module, new_val); exit: @@ -606,8 +622,9 @@ _tkinter_getbusywaitinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) int _return_value; _return_value = _tkinter_getbusywaitinterval_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -621,4 +638,4 @@ exit: #ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ -/*[clinic end generated code: output=f9057c8bf288633d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=836c578b71d69097 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h index b83b33e..c192e72 100644 --- a/Modules/clinic/_weakref.c.h +++ b/Modules/clinic/_weakref.c.h @@ -21,11 +21,12 @@ _weakref_getweakrefcount(PyObject *module, PyObject *object) Py_ssize_t _return_value; _return_value = _weakref_getweakrefcount_impl(module, object); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: return return_value; } -/*[clinic end generated code: output=d9086c8576d46933 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e1ad587147323e19 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index ac38d37..44d48a9 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -19,8 +19,9 @@ _winapi_Overlapped_GetOverlappedResult(OverlappedObject *self, PyObject *arg) PyObject *return_value = NULL; int wait; - if (!PyArg_Parse(arg, "p:GetOverlappedResult", &wait)) + if (!PyArg_Parse(arg, "p:GetOverlappedResult", &wait)) { goto exit; + } return_value = _winapi_Overlapped_GetOverlappedResult_impl(self, wait); exit: @@ -79,8 +80,9 @@ _winapi_CloseHandle(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HANDLE handle; - if (!PyArg_Parse(arg, "" F_HANDLE ":CloseHandle", &handle)) + if (!PyArg_Parse(arg, "" F_HANDLE ":CloseHandle", &handle)) { goto exit; + } return_value = _winapi_CloseHandle_impl(module, handle); exit: @@ -103,13 +105,15 @@ static PyObject * _winapi_ConnectNamedPipe(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"handle", "overlapped", NULL}; + static const char * const _keywords[] = {"handle", "overlapped", NULL}; + static _PyArg_Parser _parser = {"" F_HANDLE "|i:ConnectNamedPipe", _keywords, 0}; HANDLE handle; int use_overlapped = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" F_HANDLE "|i:ConnectNamedPipe", _keywords, - &handle, &use_overlapped)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &handle, &use_overlapped)) { goto exit; + } return_value = _winapi_ConnectNamedPipe_impl(module, handle, use_overlapped); exit: @@ -147,13 +151,16 @@ _winapi_CreateFile(PyObject *module, PyObject *args) HANDLE _return_value; if (!PyArg_ParseTuple(args, "skk" F_POINTER "kk" F_HANDLE ":CreateFile", - &file_name, &desired_access, &share_mode, &security_attributes, &creation_disposition, &flags_and_attributes, &template_file)) + &file_name, &desired_access, &share_mode, &security_attributes, &creation_disposition, &flags_and_attributes, &template_file)) { goto exit; + } _return_value = _winapi_CreateFile_impl(module, file_name, desired_access, share_mode, security_attributes, creation_disposition, flags_and_attributes, template_file); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { goto exit; - if (_return_value == NULL) + } + if (_return_value == NULL) { Py_RETURN_NONE; + } return_value = HANDLE_TO_PYNUM(_return_value); exit: @@ -180,8 +187,9 @@ _winapi_CreateJunction(PyObject *module, PyObject *args) LPWSTR dst_path; if (!PyArg_ParseTuple(args, "uu:CreateJunction", - &src_path, &dst_path)) + &src_path, &dst_path)) { goto exit; + } return_value = _winapi_CreateJunction_impl(module, src_path, dst_path); exit: @@ -220,13 +228,16 @@ _winapi_CreateNamedPipe(PyObject *module, PyObject *args) HANDLE _return_value; if (!PyArg_ParseTuple(args, "skkkkkk" F_POINTER ":CreateNamedPipe", - &name, &open_mode, &pipe_mode, &max_instances, &out_buffer_size, &in_buffer_size, &default_timeout, &security_attributes)) + &name, &open_mode, &pipe_mode, &max_instances, &out_buffer_size, &in_buffer_size, &default_timeout, &security_attributes)) { goto exit; + } _return_value = _winapi_CreateNamedPipe_impl(module, name, open_mode, pipe_mode, max_instances, out_buffer_size, in_buffer_size, default_timeout, security_attributes); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { goto exit; - if (_return_value == NULL) + } + if (_return_value == NULL) { Py_RETURN_NONE; + } return_value = HANDLE_TO_PYNUM(_return_value); exit: @@ -258,8 +269,9 @@ _winapi_CreatePipe(PyObject *module, PyObject *args) DWORD size; if (!PyArg_ParseTuple(args, "Ok:CreatePipe", - &pipe_attrs, &size)) + &pipe_attrs, &size)) { goto exit; + } return_value = _winapi_CreatePipe_impl(module, pipe_attrs, size); exit: @@ -308,8 +320,9 @@ _winapi_CreateProcess(PyObject *module, PyObject *args) PyObject *startup_info; if (!PyArg_ParseTuple(args, "ZZOOikOZO:CreateProcess", - &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, ¤t_directory, &startup_info)) + &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, ¤t_directory, &startup_info)) { goto exit; + } return_value = _winapi_CreateProcess_impl(module, application_name, command_line, proc_attrs, thread_attrs, inherit_handles, creation_flags, env_mapping, current_directory, startup_info); exit: @@ -351,13 +364,16 @@ _winapi_DuplicateHandle(PyObject *module, PyObject *args) HANDLE _return_value; if (!PyArg_ParseTuple(args, "" F_HANDLE "" F_HANDLE "" F_HANDLE "ki|k:DuplicateHandle", - &source_process_handle, &source_handle, &target_process_handle, &desired_access, &inherit_handle, &options)) + &source_process_handle, &source_handle, &target_process_handle, &desired_access, &inherit_handle, &options)) { goto exit; + } _return_value = _winapi_DuplicateHandle_impl(module, source_process_handle, source_handle, target_process_handle, desired_access, inherit_handle, options); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { goto exit; - if (_return_value == NULL) + } + if (_return_value == NULL) { Py_RETURN_NONE; + } return_value = HANDLE_TO_PYNUM(_return_value); exit: @@ -381,8 +397,9 @@ _winapi_ExitProcess(PyObject *module, PyObject *arg) PyObject *return_value = NULL; UINT ExitCode; - if (!PyArg_Parse(arg, "I:ExitProcess", &ExitCode)) + if (!PyArg_Parse(arg, "I:ExitProcess", &ExitCode)) { goto exit; + } return_value = _winapi_ExitProcess_impl(module, ExitCode); exit: @@ -408,10 +425,12 @@ _winapi_GetCurrentProcess(PyObject *module, PyObject *Py_UNUSED(ignored)) HANDLE _return_value; _return_value = _winapi_GetCurrentProcess_impl(module); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { goto exit; - if (_return_value == NULL) + } + if (_return_value == NULL) { Py_RETURN_NONE; + } return_value = HANDLE_TO_PYNUM(_return_value); exit: @@ -437,11 +456,13 @@ _winapi_GetExitCodeProcess(PyObject *module, PyObject *arg) HANDLE process; DWORD _return_value; - if (!PyArg_Parse(arg, "" F_HANDLE ":GetExitCodeProcess", &process)) + if (!PyArg_Parse(arg, "" F_HANDLE ":GetExitCodeProcess", &process)) { goto exit; + } _return_value = _winapi_GetExitCodeProcess_impl(module, process); - if ((_return_value == DWORD_MAX) && PyErr_Occurred()) + if ((_return_value == DWORD_MAX) && PyErr_Occurred()) { goto exit; + } return_value = Py_BuildValue("k", _return_value); exit: @@ -466,8 +487,9 @@ _winapi_GetLastError(PyObject *module, PyObject *Py_UNUSED(ignored)) DWORD _return_value; _return_value = _winapi_GetLastError_impl(module); - if ((_return_value == DWORD_MAX) && PyErr_Occurred()) + if ((_return_value == DWORD_MAX) && PyErr_Occurred()) { goto exit; + } return_value = Py_BuildValue("k", _return_value); exit: @@ -499,8 +521,9 @@ _winapi_GetModuleFileName(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HMODULE module_handle; - if (!PyArg_Parse(arg, "" F_HANDLE ":GetModuleFileName", &module_handle)) + if (!PyArg_Parse(arg, "" F_HANDLE ":GetModuleFileName", &module_handle)) { goto exit; + } return_value = _winapi_GetModuleFileName_impl(module, module_handle); exit: @@ -531,13 +554,16 @@ _winapi_GetStdHandle(PyObject *module, PyObject *arg) DWORD std_handle; HANDLE _return_value; - if (!PyArg_Parse(arg, "k:GetStdHandle", &std_handle)) + if (!PyArg_Parse(arg, "k:GetStdHandle", &std_handle)) { goto exit; + } _return_value = _winapi_GetStdHandle_impl(module, std_handle); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { goto exit; - if (_return_value == NULL) + } + if (_return_value == NULL) { Py_RETURN_NONE; + } return_value = HANDLE_TO_PYNUM(_return_value); exit: @@ -563,8 +589,9 @@ _winapi_GetVersion(PyObject *module, PyObject *Py_UNUSED(ignored)) long _return_value; _return_value = _winapi_GetVersion_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong(_return_value); exit: @@ -593,13 +620,16 @@ _winapi_OpenProcess(PyObject *module, PyObject *args) HANDLE _return_value; if (!PyArg_ParseTuple(args, "kik:OpenProcess", - &desired_access, &inherit_handle, &process_id)) + &desired_access, &inherit_handle, &process_id)) { goto exit; + } _return_value = _winapi_OpenProcess_impl(module, desired_access, inherit_handle, process_id); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { goto exit; - if (_return_value == NULL) + } + if (_return_value == NULL) { Py_RETURN_NONE; + } return_value = HANDLE_TO_PYNUM(_return_value); exit: @@ -625,8 +655,9 @@ _winapi_PeekNamedPipe(PyObject *module, PyObject *args) int size = 0; if (!PyArg_ParseTuple(args, "" F_HANDLE "|i:PeekNamedPipe", - &handle, &size)) + &handle, &size)) { goto exit; + } return_value = _winapi_PeekNamedPipe_impl(module, handle, size); exit: @@ -649,14 +680,16 @@ static PyObject * _winapi_ReadFile(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"handle", "size", "overlapped", NULL}; + static const char * const _keywords[] = {"handle", "size", "overlapped", NULL}; + static _PyArg_Parser _parser = {"" F_HANDLE "i|i:ReadFile", _keywords, 0}; HANDLE handle; int size; int use_overlapped = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" F_HANDLE "i|i:ReadFile", _keywords, - &handle, &size, &use_overlapped)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &handle, &size, &use_overlapped)) { goto exit; + } return_value = _winapi_ReadFile_impl(module, handle, size, use_overlapped); exit: @@ -688,8 +721,9 @@ _winapi_SetNamedPipeHandleState(PyObject *module, PyObject *args) PyObject *collect_data_timeout; if (!PyArg_ParseTuple(args, "" F_HANDLE "OOO:SetNamedPipeHandleState", - &named_pipe, &mode, &max_collection_count, &collect_data_timeout)) + &named_pipe, &mode, &max_collection_count, &collect_data_timeout)) { goto exit; + } return_value = _winapi_SetNamedPipeHandleState_impl(module, named_pipe, mode, max_collection_count, collect_data_timeout); exit: @@ -717,8 +751,9 @@ _winapi_TerminateProcess(PyObject *module, PyObject *args) UINT exit_code; if (!PyArg_ParseTuple(args, "" F_HANDLE "I:TerminateProcess", - &handle, &exit_code)) + &handle, &exit_code)) { goto exit; + } return_value = _winapi_TerminateProcess_impl(module, handle, exit_code); exit: @@ -744,8 +779,9 @@ _winapi_WaitNamedPipe(PyObject *module, PyObject *args) DWORD timeout; if (!PyArg_ParseTuple(args, "sk:WaitNamedPipe", - &name, &timeout)) + &name, &timeout)) { goto exit; + } return_value = _winapi_WaitNamedPipe_impl(module, name, timeout); exit: @@ -774,8 +810,9 @@ _winapi_WaitForMultipleObjects(PyObject *module, PyObject *args) DWORD milliseconds = INFINITE; if (!PyArg_ParseTuple(args, "Oi|k:WaitForMultipleObjects", - &handle_seq, &wait_flag, &milliseconds)) + &handle_seq, &wait_flag, &milliseconds)) { goto exit; + } return_value = _winapi_WaitForMultipleObjects_impl(module, handle_seq, wait_flag, milliseconds); exit: @@ -808,11 +845,13 @@ _winapi_WaitForSingleObject(PyObject *module, PyObject *args) long _return_value; if (!PyArg_ParseTuple(args, "" F_HANDLE "k:WaitForSingleObject", - &handle, &milliseconds)) + &handle, &milliseconds)) { goto exit; + } _return_value = _winapi_WaitForSingleObject_impl(module, handle, milliseconds); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong(_return_value); exit: @@ -835,17 +874,19 @@ static PyObject * _winapi_WriteFile(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"handle", "buffer", "overlapped", NULL}; + static const char * const _keywords[] = {"handle", "buffer", "overlapped", NULL}; + static _PyArg_Parser _parser = {"" F_HANDLE "O|i:WriteFile", _keywords, 0}; HANDLE handle; PyObject *buffer; int use_overlapped = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" F_HANDLE "O|i:WriteFile", _keywords, - &handle, &buffer, &use_overlapped)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &handle, &buffer, &use_overlapped)) { goto exit; + } return_value = _winapi_WriteFile_impl(module, handle, buffer, use_overlapped); exit: return return_value; } -/*[clinic end generated code: output=a4c4b2a9fcb0bea1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4bfccfb32ab726e8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index 0c7061a..3b9fcda 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -77,8 +77,9 @@ array_array_pop(arrayobject *self, PyObject *args) Py_ssize_t i = -1; if (!PyArg_ParseTuple(args, "|n:pop", - &i)) + &i)) { goto exit; + } return_value = array_array_pop_impl(self, i); exit: @@ -114,8 +115,9 @@ array_array_insert(arrayobject *self, PyObject *args) PyObject *v; if (!PyArg_ParseTuple(args, "nO:insert", - &i, &v)) + &i, &v)) { goto exit; + } return_value = array_array_insert_impl(self, i, v); exit: @@ -211,8 +213,9 @@ array_array_fromfile(arrayobject *self, PyObject *args) Py_ssize_t n; if (!PyArg_ParseTuple(args, "On:fromfile", - &f, &n)) + &f, &n)) { goto exit; + } return_value = array_array_fromfile_impl(self, f, n); exit: @@ -275,14 +278,16 @@ array_array_fromstring(arrayobject *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer buffer = {NULL, NULL}; - if (!PyArg_Parse(arg, "s*:fromstring", &buffer)) + if (!PyArg_Parse(arg, "s*:fromstring", &buffer)) { goto exit; + } return_value = array_array_fromstring_impl(self, &buffer); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -305,14 +310,16 @@ array_array_frombytes(arrayobject *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer buffer = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:frombytes", &buffer)) + if (!PyArg_Parse(arg, "y*:frombytes", &buffer)) { goto exit; + } return_value = array_array_frombytes_impl(self, &buffer); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -379,8 +386,9 @@ array_array_fromunicode(arrayobject *self, PyObject *arg) Py_UNICODE *ustr; Py_ssize_clean_t ustr_length; - if (!PyArg_Parse(arg, "u#:fromunicode", &ustr, &ustr_length)) + if (!PyArg_Parse(arg, "u#:fromunicode", &ustr, &ustr_length)) { goto exit; + } return_value = array_array_fromunicode_impl(self, ustr, ustr_length); exit: @@ -453,8 +461,9 @@ array__array_reconstructor(PyObject *module, PyObject *args) PyObject *items; if (!PyArg_ParseTuple(args, "OCiO:_array_reconstructor", - &arraytype, &typecode, &mformat_code, &items)) + &arraytype, &typecode, &mformat_code, &items)) { goto exit; + } return_value = array__array_reconstructor_impl(module, arraytype, typecode, mformat_code, items); exit: @@ -496,4 +505,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__, #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, -/*[clinic end generated code: output=305df3f5796039e4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b2054fb764c8cc64 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h index 62e313b5..be4b718 100644 --- a/Modules/clinic/audioop.c.h +++ b/Modules/clinic/audioop.c.h @@ -24,14 +24,16 @@ audioop_getsample(PyObject *module, PyObject *args) Py_ssize_t index; if (!PyArg_ParseTuple(args, "y*in:getsample", - &fragment, &width, &index)) + &fragment, &width, &index)) { goto exit; + } return_value = audioop_getsample_impl(module, &fragment, width, index); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -56,14 +58,16 @@ audioop_max(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:max", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_max_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -88,14 +92,16 @@ audioop_minmax(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:minmax", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_minmax_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -120,14 +126,16 @@ audioop_avg(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:avg", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_avg_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -152,14 +160,16 @@ audioop_rms(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:rms", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_rms_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -185,17 +195,20 @@ audioop_findfit(PyObject *module, PyObject *args) Py_buffer reference = {NULL, NULL}; if (!PyArg_ParseTuple(args, "y*y*:findfit", - &fragment, &reference)) + &fragment, &reference)) { goto exit; + } return_value = audioop_findfit_impl(module, &fragment, &reference); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } /* Cleanup for reference */ - if (reference.obj) + if (reference.obj) { PyBuffer_Release(&reference); + } return return_value; } @@ -221,17 +234,20 @@ audioop_findfactor(PyObject *module, PyObject *args) Py_buffer reference = {NULL, NULL}; if (!PyArg_ParseTuple(args, "y*y*:findfactor", - &fragment, &reference)) + &fragment, &reference)) { goto exit; + } return_value = audioop_findfactor_impl(module, &fragment, &reference); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } /* Cleanup for reference */ - if (reference.obj) + if (reference.obj) { PyBuffer_Release(&reference); + } return return_value; } @@ -257,14 +273,16 @@ audioop_findmax(PyObject *module, PyObject *args) Py_ssize_t length; if (!PyArg_ParseTuple(args, "y*n:findmax", - &fragment, &length)) + &fragment, &length)) { goto exit; + } return_value = audioop_findmax_impl(module, &fragment, length); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -289,14 +307,16 @@ audioop_avgpp(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:avgpp", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_avgpp_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -321,14 +341,16 @@ audioop_maxpp(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:maxpp", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_maxpp_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -353,14 +375,16 @@ audioop_cross(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:cross", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_cross_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -387,14 +411,16 @@ audioop_mul(PyObject *module, PyObject *args) double factor; if (!PyArg_ParseTuple(args, "y*id:mul", - &fragment, &width, &factor)) + &fragment, &width, &factor)) { goto exit; + } return_value = audioop_mul_impl(module, &fragment, width, factor); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -422,14 +448,16 @@ audioop_tomono(PyObject *module, PyObject *args) double rfactor; if (!PyArg_ParseTuple(args, "y*idd:tomono", - &fragment, &width, &lfactor, &rfactor)) + &fragment, &width, &lfactor, &rfactor)) { goto exit; + } return_value = audioop_tomono_impl(module, &fragment, width, lfactor, rfactor); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -457,14 +485,16 @@ audioop_tostereo(PyObject *module, PyObject *args) double rfactor; if (!PyArg_ParseTuple(args, "y*idd:tostereo", - &fragment, &width, &lfactor, &rfactor)) + &fragment, &width, &lfactor, &rfactor)) { goto exit; + } return_value = audioop_tostereo_impl(module, &fragment, width, lfactor, rfactor); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -491,17 +521,20 @@ audioop_add(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*y*i:add", - &fragment1, &fragment2, &width)) + &fragment1, &fragment2, &width)) { goto exit; + } return_value = audioop_add_impl(module, &fragment1, &fragment2, width); exit: /* Cleanup for fragment1 */ - if (fragment1.obj) + if (fragment1.obj) { PyBuffer_Release(&fragment1); + } /* Cleanup for fragment2 */ - if (fragment2.obj) + if (fragment2.obj) { PyBuffer_Release(&fragment2); + } return return_value; } @@ -527,14 +560,16 @@ audioop_bias(PyObject *module, PyObject *args) int bias; if (!PyArg_ParseTuple(args, "y*ii:bias", - &fragment, &width, &bias)) + &fragment, &width, &bias)) { goto exit; + } return_value = audioop_bias_impl(module, &fragment, width, bias); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -559,14 +594,16 @@ audioop_reverse(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:reverse", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_reverse_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -591,14 +628,16 @@ audioop_byteswap(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:byteswap", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_byteswap_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -625,14 +664,16 @@ audioop_lin2lin(PyObject *module, PyObject *args) int newwidth; if (!PyArg_ParseTuple(args, "y*ii:lin2lin", - &fragment, &width, &newwidth)) + &fragment, &width, &newwidth)) { goto exit; + } return_value = audioop_lin2lin_impl(module, &fragment, width, newwidth); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -666,14 +707,16 @@ audioop_ratecv(PyObject *module, PyObject *args) int weightB = 0; if (!PyArg_ParseTuple(args, "y*iiiiO|ii:ratecv", - &fragment, &width, &nchannels, &inrate, &outrate, &state, &weightA, &weightB)) + &fragment, &width, &nchannels, &inrate, &outrate, &state, &weightA, &weightB)) { goto exit; + } return_value = audioop_ratecv_impl(module, &fragment, width, nchannels, inrate, outrate, state, weightA, weightB); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -698,14 +741,16 @@ audioop_lin2ulaw(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:lin2ulaw", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_lin2ulaw_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -730,14 +775,16 @@ audioop_ulaw2lin(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:ulaw2lin", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_ulaw2lin_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -762,14 +809,16 @@ audioop_lin2alaw(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:lin2alaw", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_lin2alaw_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -794,14 +843,16 @@ audioop_alaw2lin(PyObject *module, PyObject *args) int width; if (!PyArg_ParseTuple(args, "y*i:alaw2lin", - &fragment, &width)) + &fragment, &width)) { goto exit; + } return_value = audioop_alaw2lin_impl(module, &fragment, width); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -828,14 +879,16 @@ audioop_lin2adpcm(PyObject *module, PyObject *args) PyObject *state; if (!PyArg_ParseTuple(args, "y*iO:lin2adpcm", - &fragment, &width, &state)) + &fragment, &width, &state)) { goto exit; + } return_value = audioop_lin2adpcm_impl(module, &fragment, width, state); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } @@ -862,15 +915,17 @@ audioop_adpcm2lin(PyObject *module, PyObject *args) PyObject *state; if (!PyArg_ParseTuple(args, "y*iO:adpcm2lin", - &fragment, &width, &state)) + &fragment, &width, &state)) { goto exit; + } return_value = audioop_adpcm2lin_impl(module, &fragment, width, state); exit: /* Cleanup for fragment */ - if (fragment.obj) + if (fragment.obj) { PyBuffer_Release(&fragment); + } return return_value; } -/*[clinic end generated code: output=385fb09fa21a62c0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e0ab74c3fa57c39c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index e20cac2..0ee7f57 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -20,8 +20,9 @@ binascii_a2b_uu(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "O&:a2b_uu", ascii_buffer_converter, &data)) + if (!PyArg_Parse(arg, "O&:a2b_uu", ascii_buffer_converter, &data)) { goto exit; + } return_value = binascii_a2b_uu_impl(module, &data); exit: @@ -50,14 +51,16 @@ binascii_b2a_uu(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:b2a_uu", &data)) + if (!PyArg_Parse(arg, "y*:b2a_uu", &data)) { goto exit; + } return_value = binascii_b2a_uu_impl(module, &data); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -80,8 +83,9 @@ binascii_a2b_base64(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "O&:a2b_base64", ascii_buffer_converter, &data)) + if (!PyArg_Parse(arg, "O&:a2b_base64", ascii_buffer_converter, &data)) { goto exit; + } return_value = binascii_a2b_base64_impl(module, &data); exit: @@ -93,31 +97,37 @@ exit: } PyDoc_STRVAR(binascii_b2a_base64__doc__, -"b2a_base64($module, data, /)\n" +"b2a_base64($module, /, data, *, newline=True)\n" "--\n" "\n" "Base64-code line of data."); #define BINASCII_B2A_BASE64_METHODDEF \ - {"b2a_base64", (PyCFunction)binascii_b2a_base64, METH_O, binascii_b2a_base64__doc__}, + {"b2a_base64", (PyCFunction)binascii_b2a_base64, METH_VARARGS|METH_KEYWORDS, binascii_b2a_base64__doc__}, static PyObject * -binascii_b2a_base64_impl(PyObject *module, Py_buffer *data); +binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline); static PyObject * -binascii_b2a_base64(PyObject *module, PyObject *arg) +binascii_b2a_base64(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"data", "newline", NULL}; + static _PyArg_Parser _parser = {"y*|$i:b2a_base64", _keywords, 0}; Py_buffer data = {NULL, NULL}; + int newline = 1; - if (!PyArg_Parse(arg, "y*:b2a_base64", &data)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, &newline)) { goto exit; - return_value = binascii_b2a_base64_impl(module, &data); + } + return_value = binascii_b2a_base64_impl(module, &data, newline); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -140,8 +150,9 @@ binascii_a2b_hqx(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "O&:a2b_hqx", ascii_buffer_converter, &data)) + if (!PyArg_Parse(arg, "O&:a2b_hqx", ascii_buffer_converter, &data)) { goto exit; + } return_value = binascii_a2b_hqx_impl(module, &data); exit: @@ -170,14 +181,16 @@ binascii_rlecode_hqx(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:rlecode_hqx", &data)) + if (!PyArg_Parse(arg, "y*:rlecode_hqx", &data)) { goto exit; + } return_value = binascii_rlecode_hqx_impl(module, &data); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -200,14 +213,16 @@ binascii_b2a_hqx(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:b2a_hqx", &data)) + if (!PyArg_Parse(arg, "y*:b2a_hqx", &data)) { goto exit; + } return_value = binascii_b2a_hqx_impl(module, &data); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -230,14 +245,16 @@ binascii_rledecode_hqx(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:rledecode_hqx", &data)) + if (!PyArg_Parse(arg, "y*:rledecode_hqx", &data)) { goto exit; + } return_value = binascii_rledecode_hqx_impl(module, &data); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -263,17 +280,20 @@ binascii_crc_hqx(PyObject *module, PyObject *args) unsigned int _return_value; if (!PyArg_ParseTuple(args, "y*I:crc_hqx", - &data, &crc)) + &data, &crc)) { goto exit; + } _return_value = binascii_crc_hqx_impl(module, &data, crc); - if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -299,17 +319,20 @@ binascii_crc32(PyObject *module, PyObject *args) unsigned int _return_value; if (!PyArg_ParseTuple(args, "y*|I:crc32", - &data, &crc)) + &data, &crc)) { goto exit; + } _return_value = binascii_crc32_impl(module, &data, crc); - if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -335,14 +358,16 @@ binascii_b2a_hex(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:b2a_hex", &data)) + if (!PyArg_Parse(arg, "y*:b2a_hex", &data)) { goto exit; + } return_value = binascii_b2a_hex_impl(module, &data); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -367,14 +392,16 @@ binascii_hexlify(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:hexlify", &data)) + if (!PyArg_Parse(arg, "y*:hexlify", &data)) { goto exit; + } return_value = binascii_hexlify_impl(module, &data); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -400,8 +427,9 @@ binascii_a2b_hex(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer hexstr = {NULL, NULL}; - if (!PyArg_Parse(arg, "O&:a2b_hex", ascii_buffer_converter, &hexstr)) + if (!PyArg_Parse(arg, "O&:a2b_hex", ascii_buffer_converter, &hexstr)) { goto exit; + } return_value = binascii_a2b_hex_impl(module, &hexstr); exit: @@ -432,8 +460,9 @@ binascii_unhexlify(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_buffer hexstr = {NULL, NULL}; - if (!PyArg_Parse(arg, "O&:unhexlify", ascii_buffer_converter, &hexstr)) + if (!PyArg_Parse(arg, "O&:unhexlify", ascii_buffer_converter, &hexstr)) { goto exit; + } return_value = binascii_unhexlify_impl(module, &hexstr); exit: @@ -460,13 +489,15 @@ static PyObject * binascii_a2b_qp(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"data", "header", NULL}; + static const char * const _keywords[] = {"data", "header", NULL}; + static _PyArg_Parser _parser = {"O&|i:a2b_qp", _keywords, 0}; Py_buffer data = {NULL, NULL}; int header = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i:a2b_qp", _keywords, - ascii_buffer_converter, &data, &header)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + ascii_buffer_converter, &data, &header)) { goto exit; + } return_value = binascii_a2b_qp_impl(module, &data, header); exit: @@ -498,22 +529,25 @@ static PyObject * binascii_b2a_qp(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"data", "quotetabs", "istext", "header", NULL}; + static const char * const _keywords[] = {"data", "quotetabs", "istext", "header", NULL}; + static _PyArg_Parser _parser = {"y*|iii:b2a_qp", _keywords, 0}; Py_buffer data = {NULL, NULL}; int quotetabs = 0; int istext = 1; int header = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|iii:b2a_qp", _keywords, - &data, "etabs, &istext, &header)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, "etabs, &istext, &header)) { goto exit; + } return_value = binascii_b2a_qp_impl(module, &data, quotetabs, istext, header); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } -/*[clinic end generated code: output=51173fc9718a5edc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=12611b05d8bf4a9c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h index a255353..e46c314 100644 --- a/Modules/clinic/cmathmodule.c.h +++ b/Modules/clinic/cmathmodule.c.h @@ -21,8 +21,9 @@ cmath_acos(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:acos", &z)) + if (!PyArg_Parse(arg, "D:acos", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_acos_impl(module, z); @@ -62,8 +63,9 @@ cmath_acosh(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:acosh", &z)) + if (!PyArg_Parse(arg, "D:acosh", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_acosh_impl(module, z); @@ -103,8 +105,9 @@ cmath_asin(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:asin", &z)) + if (!PyArg_Parse(arg, "D:asin", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_asin_impl(module, z); @@ -144,8 +147,9 @@ cmath_asinh(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:asinh", &z)) + if (!PyArg_Parse(arg, "D:asinh", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_asinh_impl(module, z); @@ -185,8 +189,9 @@ cmath_atan(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:atan", &z)) + if (!PyArg_Parse(arg, "D:atan", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_atan_impl(module, z); @@ -226,8 +231,9 @@ cmath_atanh(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:atanh", &z)) + if (!PyArg_Parse(arg, "D:atanh", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_atanh_impl(module, z); @@ -267,8 +273,9 @@ cmath_cos(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:cos", &z)) + if (!PyArg_Parse(arg, "D:cos", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_cos_impl(module, z); @@ -308,8 +315,9 @@ cmath_cosh(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:cosh", &z)) + if (!PyArg_Parse(arg, "D:cosh", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_cosh_impl(module, z); @@ -349,8 +357,9 @@ cmath_exp(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:exp", &z)) + if (!PyArg_Parse(arg, "D:exp", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_exp_impl(module, z); @@ -390,8 +399,9 @@ cmath_log10(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:log10", &z)) + if (!PyArg_Parse(arg, "D:log10", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_log10_impl(module, z); @@ -431,8 +441,9 @@ cmath_sin(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:sin", &z)) + if (!PyArg_Parse(arg, "D:sin", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_sin_impl(module, z); @@ -472,8 +483,9 @@ cmath_sinh(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:sinh", &z)) + if (!PyArg_Parse(arg, "D:sinh", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_sinh_impl(module, z); @@ -513,8 +525,9 @@ cmath_sqrt(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:sqrt", &z)) + if (!PyArg_Parse(arg, "D:sqrt", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_sqrt_impl(module, z); @@ -554,8 +567,9 @@ cmath_tan(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:tan", &z)) + if (!PyArg_Parse(arg, "D:tan", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_tan_impl(module, z); @@ -595,8 +609,9 @@ cmath_tanh(PyObject *module, PyObject *arg) Py_complex z; Py_complex _return_value; - if (!PyArg_Parse(arg, "D:tanh", &z)) + if (!PyArg_Parse(arg, "D:tanh", &z)) { goto exit; + } /* modifications for z */ errno = 0; PyFPE_START_PROTECT("complex function", goto exit); _return_value = cmath_tanh_impl(module, z); @@ -639,8 +654,9 @@ cmath_log(PyObject *module, PyObject *args) PyObject *y_obj = NULL; if (!PyArg_ParseTuple(args, "D|O:log", - &x, &y_obj)) + &x, &y_obj)) { goto exit; + } return_value = cmath_log_impl(module, x, y_obj); exit: @@ -665,8 +681,9 @@ cmath_phase(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_complex z; - if (!PyArg_Parse(arg, "D:phase", &z)) + if (!PyArg_Parse(arg, "D:phase", &z)) { goto exit; + } return_value = cmath_phase_impl(module, z); exit: @@ -693,8 +710,9 @@ cmath_polar(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_complex z; - if (!PyArg_Parse(arg, "D:polar", &z)) + if (!PyArg_Parse(arg, "D:polar", &z)) { goto exit; + } return_value = cmath_polar_impl(module, z); exit: @@ -721,8 +739,9 @@ cmath_rect(PyObject *module, PyObject *args) double phi; if (!PyArg_ParseTuple(args, "dd:rect", - &r, &phi)) + &r, &phi)) { goto exit; + } return_value = cmath_rect_impl(module, r, phi); exit: @@ -747,8 +766,9 @@ cmath_isfinite(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_complex z; - if (!PyArg_Parse(arg, "D:isfinite", &z)) + if (!PyArg_Parse(arg, "D:isfinite", &z)) { goto exit; + } return_value = cmath_isfinite_impl(module, z); exit: @@ -773,8 +793,9 @@ cmath_isnan(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_complex z; - if (!PyArg_Parse(arg, "D:isnan", &z)) + if (!PyArg_Parse(arg, "D:isnan", &z)) { goto exit; + } return_value = cmath_isnan_impl(module, z); exit: @@ -799,8 +820,9 @@ cmath_isinf(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_complex z; - if (!PyArg_Parse(arg, "D:isinf", &z)) + if (!PyArg_Parse(arg, "D:isinf", &z)) { goto exit; + } return_value = cmath_isinf_impl(module, z); exit: @@ -839,22 +861,25 @@ static PyObject * cmath_isclose(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; + static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; + static _PyArg_Parser _parser = {"DD|$dd:isclose", _keywords, 0}; Py_complex a; Py_complex b; double rel_tol = 1e-09; double abs_tol = 0.0; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "DD|$dd:isclose", _keywords, - &a, &b, &rel_tol, &abs_tol)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &a, &b, &rel_tol, &abs_tol)) { goto exit; + } _return_value = cmath_isclose_impl(module, a, b, rel_tol, abs_tol); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: return return_value; } -/*[clinic end generated code: output=732194029b7fb1e7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aa2e77ca9fc26928 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h index 67660eb..84a004b 100644 --- a/Modules/clinic/fcntlmodule.c.h +++ b/Modules/clinic/fcntlmodule.c.h @@ -33,8 +33,9 @@ fcntl_fcntl(PyObject *module, PyObject *args) PyObject *arg = NULL; if (!PyArg_ParseTuple(args, "O&i|O:fcntl", - conv_descriptor, &fd, &code, &arg)) + conv_descriptor, &fd, &code, &arg)) { goto exit; + } return_value = fcntl_fcntl_impl(module, fd, code, arg); exit: @@ -91,8 +92,9 @@ fcntl_ioctl(PyObject *module, PyObject *args) int mutate_arg = 1; if (!PyArg_ParseTuple(args, "O&I|Op:ioctl", - conv_descriptor, &fd, &code, &ob_arg, &mutate_arg)) + conv_descriptor, &fd, &code, &ob_arg, &mutate_arg)) { goto exit; + } return_value = fcntl_ioctl_impl(module, fd, code, ob_arg, mutate_arg); exit: @@ -122,8 +124,9 @@ fcntl_flock(PyObject *module, PyObject *args) int code; if (!PyArg_ParseTuple(args, "O&i:flock", - conv_descriptor, &fd, &code)) + conv_descriptor, &fd, &code)) { goto exit; + } return_value = fcntl_flock_impl(module, fd, code); exit: @@ -175,11 +178,12 @@ fcntl_lockf(PyObject *module, PyObject *args) int whence = 0; if (!PyArg_ParseTuple(args, "O&i|OOi:lockf", - conv_descriptor, &fd, &code, &lenobj, &startobj, &whence)) + conv_descriptor, &fd, &code, &lenobj, &startobj, &whence)) { goto exit; + } return_value = fcntl_lockf_impl(module, fd, code, lenobj, startobj, whence); exit: return return_value; } -/*[clinic end generated code: output=97b1306b864c01c8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=36cff76a8fb2c9a6 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h index 2c47a42..9c9d595 100644 --- a/Modules/clinic/grpmodule.c.h +++ b/Modules/clinic/grpmodule.c.h @@ -20,12 +20,14 @@ static PyObject * grp_getgrgid(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"id", NULL}; + static const char * const _keywords[] = {"id", NULL}; + static _PyArg_Parser _parser = {"O:getgrgid", _keywords, 0}; PyObject *id; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:getgrgid", _keywords, - &id)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &id)) { goto exit; + } return_value = grp_getgrgid_impl(module, id); exit: @@ -50,12 +52,14 @@ static PyObject * grp_getgrnam(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"name", NULL}; + static const char * const _keywords[] = {"name", NULL}; + static _PyArg_Parser _parser = {"U:getgrnam", _keywords, 0}; PyObject *name; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U:getgrnam", _keywords, - &name)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &name)) { goto exit; + } return_value = grp_getgrnam_impl(module, name); exit: @@ -82,4 +86,4 @@ grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) { return grp_getgrall_impl(module); } -/*[clinic end generated code: output=bee09feefc54a2cb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c06081097b7fffe7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index 0bd958a..aeb1c41 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -81,15 +81,17 @@ static PyObject * _md5_md5(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", NULL}; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {"|O:md5", _keywords, 0}; PyObject *string = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:md5", _keywords, - &string)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string)) { goto exit; + } return_value = _md5_md5_impl(module, string); exit: return return_value; } -/*[clinic end generated code: output=4cd3cc96e35563d2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f86fc2f3f21831e2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 1bbfc06..6088eec 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -36,14 +36,16 @@ static PyObject * os_stat(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&|$O&p:stat", _keywords, 0}; path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", _keywords, - path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) { goto exit; + } return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks); exit: @@ -72,13 +74,15 @@ static PyObject * os_lstat(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "dir_fd", NULL}; + static const char * const _keywords[] = {"path", "dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&|$O&:lstat", _keywords, 0}; path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); int dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", _keywords, - path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd)) { goto exit; + } return_value = os_lstat_impl(module, &path, dir_fd); exit: @@ -131,7 +135,8 @@ static PyObject * os_access(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&i|$O&pp:access", _keywords, 0}; path_t path = PATH_T_INITIALIZE("access", "path", 0, 0); int mode; int dir_fd = DEFAULT_DIR_FD; @@ -139,12 +144,14 @@ os_access(PyObject *module, PyObject *args, PyObject *kwargs) int follow_symlinks = 1; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", _keywords, - path_converter, &path, &mode, FACCESSAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &mode, FACCESSAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) { goto exit; + } _return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: @@ -178,11 +185,13 @@ os_ttyname(PyObject *module, PyObject *arg) int fd; char *_return_value; - if (!PyArg_Parse(arg, "i:ttyname", &fd)) + if (!PyArg_Parse(arg, "i:ttyname", &fd)) { goto exit; + } _return_value = os_ttyname_impl(module, fd); - if (_return_value == NULL) + if (_return_value == NULL) { goto exit; + } return_value = PyUnicode_DecodeFSDefault(_return_value); exit: @@ -233,12 +242,14 @@ static PyObject * os_chdir(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", NULL}; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {"O&:chdir", _keywords, 0}; path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", _keywords, - path_converter, &path)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path)) { goto exit; + } return_value = os_chdir_impl(module, &path); exit: @@ -269,12 +280,14 @@ static PyObject * os_fchdir(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", NULL}; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {"O&:fchdir", _keywords, 0}; int fd; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:fchdir", _keywords, - fildes_converter, &fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + fildes_converter, &fd)) { goto exit; + } return_value = os_fchdir_impl(module, fd); exit: @@ -320,15 +333,17 @@ static PyObject * os_chmod(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&i|$O&p:chmod", _keywords, 0}; path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); int mode; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", _keywords, - path_converter, &path, &mode, FCHMODAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &mode, FCHMODAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) { goto exit; + } return_value = os_chmod_impl(module, &path, mode, dir_fd, follow_symlinks); exit: @@ -358,13 +373,15 @@ static PyObject * os_fchmod(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", "mode", NULL}; + static const char * const _keywords[] = {"fd", "mode", NULL}; + static _PyArg_Parser _parser = {"ii:fchmod", _keywords, 0}; int fd; int mode; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:fchmod", _keywords, - &fd, &mode)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &fd, &mode)) { goto exit; + } return_value = os_fchmod_impl(module, fd, mode); exit: @@ -394,13 +411,15 @@ static PyObject * os_lchmod(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "mode", NULL}; + static const char * const _keywords[] = {"path", "mode", NULL}; + static _PyArg_Parser _parser = {"O&i:lchmod", _keywords, 0}; path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); int mode; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i:lchmod", _keywords, - path_converter, &path, &mode)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &mode)) { goto exit; + } return_value = os_lchmod_impl(module, &path, mode); exit: @@ -437,14 +456,16 @@ static PyObject * os_chflags(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "flags", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "flags", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&k|p:chflags", _keywords, 0}; path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); unsigned long flags; int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|p:chflags", _keywords, - path_converter, &path, &flags, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &flags, &follow_symlinks)) { goto exit; + } return_value = os_chflags_impl(module, &path, flags, follow_symlinks); exit: @@ -477,13 +498,15 @@ static PyObject * os_lchflags(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "flags", NULL}; + static const char * const _keywords[] = {"path", "flags", NULL}; + static _PyArg_Parser _parser = {"O&k:lchflags", _keywords, 0}; path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); unsigned long flags; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k:lchflags", _keywords, - path_converter, &path, &flags)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &flags)) { goto exit; + } return_value = os_lchflags_impl(module, &path, flags); exit: @@ -513,12 +536,14 @@ static PyObject * os_chroot(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", NULL}; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {"O&:chroot", _keywords, 0}; path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chroot", _keywords, - path_converter, &path)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path)) { goto exit; + } return_value = os_chroot_impl(module, &path); exit: @@ -548,12 +573,14 @@ static PyObject * os_fsync(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", NULL}; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {"O&:fsync", _keywords, 0}; int fd; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:fsync", _keywords, - fildes_converter, &fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + fildes_converter, &fd)) { goto exit; + } return_value = os_fsync_impl(module, fd); exit: @@ -602,12 +629,14 @@ static PyObject * os_fdatasync(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", NULL}; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {"O&:fdatasync", _keywords, 0}; int fd; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:fdatasync", _keywords, - fildes_converter, &fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + fildes_converter, &fd)) { goto exit; + } return_value = os_fdatasync_impl(module, fd); exit: @@ -659,16 +688,18 @@ static PyObject * os_chown(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&O&O&|$O&p:chown", _keywords, 0}; path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN); uid_t uid; gid_t gid; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", _keywords, - path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid, FCHOWNAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid, FCHOWNAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) { goto exit; + } return_value = os_chown_impl(module, &path, uid, gid, dir_fd, follow_symlinks); exit: @@ -700,14 +731,16 @@ static PyObject * os_fchown(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", "uid", "gid", NULL}; + static const char * const _keywords[] = {"fd", "uid", "gid", NULL}; + static _PyArg_Parser _parser = {"iO&O&:fchown", _keywords, 0}; int fd; uid_t uid; gid_t gid; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&O&:fchown", _keywords, - &fd, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &fd, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid)) { goto exit; + } return_value = os_fchown_impl(module, fd, uid, gid); exit: @@ -737,14 +770,16 @@ static PyObject * os_lchown(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "uid", "gid", NULL}; + static const char * const _keywords[] = {"path", "uid", "gid", NULL}; + static _PyArg_Parser _parser = {"O&O&O&:lchown", _keywords, 0}; path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); uid_t uid; gid_t gid; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&:lchown", _keywords, - path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid)) { goto exit; + } return_value = os_lchown_impl(module, &path, uid, gid); exit: @@ -822,16 +857,18 @@ static PyObject * os_link(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&O&|$O&O&p:link", _keywords, 0}; path_t src = PATH_T_INITIALIZE("link", "src", 0, 0); path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$O&O&p:link", _keywords, - path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd, &follow_symlinks)) { goto exit; + } return_value = os_link_impl(module, &src, &dst, src_dir_fd, dst_dir_fd, follow_symlinks); exit: @@ -872,12 +909,14 @@ static PyObject * os_listdir(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", NULL}; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {"|O&:listdir", _keywords, 0}; path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", _keywords, - path_converter, &path)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path)) { goto exit; + } return_value = os_listdir_impl(module, &path); exit: @@ -906,8 +945,9 @@ os__getfullpathname(PyObject *module, PyObject *arg) PyObject *return_value = NULL; path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0); - if (!PyArg_Parse(arg, "O&:_getfullpathname", path_converter, &path)) + if (!PyArg_Parse(arg, "O&:_getfullpathname", path_converter, &path)) { goto exit; + } return_value = os__getfullpathname_impl(module, &path); exit: @@ -939,8 +979,9 @@ os__getfinalpathname(PyObject *module, PyObject *arg) PyObject *return_value = NULL; PyObject *path; - if (!PyArg_Parse(arg, "U:_getfinalpathname", &path)) + if (!PyArg_Parse(arg, "U:_getfinalpathname", &path)) { goto exit; + } return_value = os__getfinalpathname_impl(module, path); exit: @@ -968,8 +1009,9 @@ os__isdir(PyObject *module, PyObject *arg) PyObject *return_value = NULL; path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0); - if (!PyArg_Parse(arg, "O&:_isdir", path_converter, &path)) + if (!PyArg_Parse(arg, "O&:_isdir", path_converter, &path)) { goto exit; + } return_value = os__isdir_impl(module, &path); exit: @@ -999,12 +1041,14 @@ static PyObject * os__getvolumepathname(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", NULL}; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {"U:_getvolumepathname", _keywords, 0}; PyObject *path; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U:_getvolumepathname", _keywords, - &path)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &path)) { goto exit; + } return_value = os__getvolumepathname_impl(module, path); exit: @@ -1036,14 +1080,16 @@ static PyObject * os_mkdir(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "mode", "dir_fd", NULL}; + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&|i$O&:mkdir", _keywords, 0}; path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); int mode = 511; int dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", _keywords, - path_converter, &path, &mode, MKDIRAT_DIR_FD_CONVERTER, &dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &mode, MKDIRAT_DIR_FD_CONVERTER, &dir_fd)) { goto exit; + } return_value = os_mkdir_impl(module, &path, mode, dir_fd); exit: @@ -1073,8 +1119,9 @@ os_nice(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int increment; - if (!PyArg_Parse(arg, "i:nice", &increment)) + if (!PyArg_Parse(arg, "i:nice", &increment)) { goto exit; + } return_value = os_nice_impl(module, increment); exit: @@ -1101,13 +1148,15 @@ static PyObject * os_getpriority(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"which", "who", NULL}; + static const char * const _keywords[] = {"which", "who", NULL}; + static _PyArg_Parser _parser = {"ii:getpriority", _keywords, 0}; int which; int who; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:getpriority", _keywords, - &which, &who)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &which, &who)) { goto exit; + } return_value = os_getpriority_impl(module, which, who); exit: @@ -1134,14 +1183,16 @@ static PyObject * os_setpriority(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"which", "who", "priority", NULL}; + static const char * const _keywords[] = {"which", "who", "priority", NULL}; + static _PyArg_Parser _parser = {"iii:setpriority", _keywords, 0}; int which; int who; int priority; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iii:setpriority", _keywords, - &which, &who, &priority)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &which, &who, &priority)) { goto exit; + } return_value = os_setpriority_impl(module, which, who, priority); exit: @@ -1173,15 +1224,17 @@ static PyObject * os_rename(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&O&|$O&O&:rename", _keywords, 0}; path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$O&O&:rename", _keywords, - path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) { goto exit; + } return_value = os_rename_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); exit: @@ -1216,15 +1269,17 @@ static PyObject * os_replace(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&O&|$O&O&:replace", _keywords, 0}; path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0); path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$O&O&:replace", _keywords, - path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) { goto exit; + } return_value = os_replace_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); exit: @@ -1257,13 +1312,15 @@ static PyObject * os_rmdir(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "dir_fd", NULL}; + static const char * const _keywords[] = {"path", "dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&|$O&:rmdir", _keywords, 0}; path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); int dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", _keywords, - path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) { goto exit; + } return_value = os_rmdir_impl(module, &path, dir_fd); exit: @@ -1291,16 +1348,19 @@ static PyObject * os_system(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"command", NULL}; + static const char * const _keywords[] = {"command", NULL}; + static _PyArg_Parser _parser = {"u:system", _keywords, 0}; Py_UNICODE *command; long _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "u:system", _keywords, - &command)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &command)) { goto exit; + } _return_value = os_system_impl(module, command); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong(_return_value); exit: @@ -1327,16 +1387,19 @@ static PyObject * os_system(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"command", NULL}; + static const char * const _keywords[] = {"command", NULL}; + static _PyArg_Parser _parser = {"O&:system", _keywords, 0}; PyObject *command = NULL; long _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:system", _keywords, - PyUnicode_FSConverter, &command)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + PyUnicode_FSConverter, &command)) { goto exit; + } _return_value = os_system_impl(module, command); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong(_return_value); exit: @@ -1366,8 +1429,9 @@ os_umask(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int mask; - if (!PyArg_Parse(arg, "i:umask", &mask)) + if (!PyArg_Parse(arg, "i:umask", &mask)) { goto exit; + } return_value = os_umask_impl(module, mask); exit: @@ -1395,13 +1459,15 @@ static PyObject * os_unlink(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "dir_fd", NULL}; + static const char * const _keywords[] = {"path", "dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&|$O&:unlink", _keywords, 0}; path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); int dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", _keywords, - path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) { goto exit; + } return_value = os_unlink_impl(module, &path, dir_fd); exit: @@ -1432,13 +1498,15 @@ static PyObject * os_remove(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "dir_fd", NULL}; + static const char * const _keywords[] = {"path", "dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&|$O&:remove", _keywords, 0}; path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0); int dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:remove", _keywords, - path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) { goto exit; + } return_value = os_remove_impl(module, &path, dir_fd); exit: @@ -1513,16 +1581,18 @@ static PyObject * os_utime(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&|O$OO&p:utime", _keywords, 0}; path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); PyObject *times = NULL; PyObject *ns = NULL; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|O$OO&p:utime", _keywords, - path_converter, &path, ×, &ns, FUTIMENSAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, ×, &ns, FUTIMENSAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) { goto exit; + } return_value = os_utime_impl(module, &path, times, ns, dir_fd, follow_symlinks); exit: @@ -1548,12 +1618,14 @@ static PyObject * os__exit(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"status", NULL}; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {"i:_exit", _keywords, 0}; int status; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:_exit", _keywords, - &status)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &status)) { goto exit; + } return_value = os__exit_impl(module, status); exit: @@ -1577,23 +1649,24 @@ PyDoc_STRVAR(os_execv__doc__, {"execv", (PyCFunction)os_execv, METH_VARARGS, os_execv__doc__}, static PyObject * -os_execv_impl(PyObject *module, PyObject *path, PyObject *argv); +os_execv_impl(PyObject *module, path_t *path, PyObject *argv); static PyObject * os_execv(PyObject *module, PyObject *args) { PyObject *return_value = NULL; - PyObject *path = NULL; + path_t path = PATH_T_INITIALIZE("execv", "path", 0, 0); PyObject *argv; if (!PyArg_ParseTuple(args, "O&O:execv", - PyUnicode_FSConverter, &path, &argv)) + path_converter, &path, &argv)) { goto exit; - return_value = os_execv_impl(module, path, argv); + } + return_value = os_execv_impl(module, &path, argv); exit: /* Cleanup for path */ - Py_XDECREF(path); + path_cleanup(&path); return return_value; } @@ -1625,14 +1698,16 @@ static PyObject * os_execve(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "argv", "env", NULL}; + static const char * const _keywords[] = {"path", "argv", "env", NULL}; + static _PyArg_Parser _parser = {"O&OO:execve", _keywords, 0}; path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); PyObject *argv; PyObject *env; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", _keywords, - path_converter, &path, &argv, &env)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &argv, &env)) { goto exit; + } return_value = os_execve_impl(module, &path, argv, env); exit: @@ -1644,7 +1719,7 @@ exit: #endif /* defined(HAVE_EXECV) */ -#if defined(HAVE_SPAWNV) +#if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) PyDoc_STRVAR(os_spawnv__doc__, "spawnv($module, mode, path, argv, /)\n" @@ -1663,31 +1738,32 @@ PyDoc_STRVAR(os_spawnv__doc__, {"spawnv", (PyCFunction)os_spawnv, METH_VARARGS, os_spawnv__doc__}, static PyObject * -os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv); +os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv); static PyObject * os_spawnv(PyObject *module, PyObject *args) { PyObject *return_value = NULL; int mode; - PyObject *path = NULL; + path_t path = PATH_T_INITIALIZE("spawnv", "path", 0, 0); PyObject *argv; if (!PyArg_ParseTuple(args, "iO&O:spawnv", - &mode, PyUnicode_FSConverter, &path, &argv)) + &mode, path_converter, &path, &argv)) { goto exit; - return_value = os_spawnv_impl(module, mode, path, argv); + } + return_value = os_spawnv_impl(module, mode, &path, argv); exit: /* Cleanup for path */ - Py_XDECREF(path); + path_cleanup(&path); return return_value; } -#endif /* defined(HAVE_SPAWNV) */ +#endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) */ -#if defined(HAVE_SPAWNV) +#if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) PyDoc_STRVAR(os_spawnve__doc__, "spawnve($module, mode, path, argv, env, /)\n" @@ -1708,7 +1784,7 @@ PyDoc_STRVAR(os_spawnve__doc__, {"spawnve", (PyCFunction)os_spawnve, METH_VARARGS, os_spawnve__doc__}, static PyObject * -os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv, +os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, PyObject *env); static PyObject * @@ -1716,23 +1792,24 @@ os_spawnve(PyObject *module, PyObject *args) { PyObject *return_value = NULL; int mode; - PyObject *path = NULL; + path_t path = PATH_T_INITIALIZE("spawnve", "path", 0, 0); PyObject *argv; PyObject *env; if (!PyArg_ParseTuple(args, "iO&OO:spawnve", - &mode, PyUnicode_FSConverter, &path, &argv, &env)) + &mode, path_converter, &path, &argv, &env)) { goto exit; - return_value = os_spawnve_impl(module, mode, path, argv, env); + } + return_value = os_spawnve_impl(module, mode, &path, argv, env); exit: /* Cleanup for path */ - Py_XDECREF(path); + path_cleanup(&path); return return_value; } -#endif /* defined(HAVE_SPAWNV) */ +#endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) */ #if defined(HAVE_FORK1) @@ -1800,12 +1877,14 @@ static PyObject * os_sched_get_priority_max(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"policy", NULL}; + static const char * const _keywords[] = {"policy", NULL}; + static _PyArg_Parser _parser = {"i:sched_get_priority_max", _keywords, 0}; int policy; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:sched_get_priority_max", _keywords, - &policy)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &policy)) { goto exit; + } return_value = os_sched_get_priority_max_impl(module, policy); exit: @@ -1832,12 +1911,14 @@ static PyObject * os_sched_get_priority_min(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"policy", NULL}; + static const char * const _keywords[] = {"policy", NULL}; + static _PyArg_Parser _parser = {"i:sched_get_priority_min", _keywords, 0}; int policy; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:sched_get_priority_min", _keywords, - &policy)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &policy)) { goto exit; + } return_value = os_sched_get_priority_min_impl(module, policy); exit: @@ -1868,8 +1949,9 @@ os_sched_getscheduler(PyObject *module, PyObject *arg) PyObject *return_value = NULL; pid_t pid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getscheduler", &pid)) + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getscheduler", &pid)) { goto exit; + } return_value = os_sched_getscheduler_impl(module, pid); exit: @@ -1896,12 +1978,14 @@ static PyObject * os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"sched_priority", NULL}; + static const char * const _keywords[] = {"sched_priority", NULL}; + static _PyArg_Parser _parser = {"O:sched_param", _keywords, 0}; PyObject *sched_priority; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", _keywords, - &sched_priority)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &sched_priority)) { goto exit; + } return_value = os_sched_param_impl(type, sched_priority); exit: @@ -1937,8 +2021,9 @@ os_sched_setscheduler(PyObject *module, PyObject *args) struct sched_param param; if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "iO&:sched_setscheduler", - &pid, &policy, convert_sched_param, ¶m)) + &pid, &policy, convert_sched_param, ¶m)) { goto exit; + } return_value = os_sched_setscheduler_impl(module, pid, policy, ¶m); exit: @@ -1970,8 +2055,9 @@ os_sched_getparam(PyObject *module, PyObject *arg) PyObject *return_value = NULL; pid_t pid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getparam", &pid)) + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getparam", &pid)) { goto exit; + } return_value = os_sched_getparam_impl(module, pid); exit: @@ -2006,8 +2092,9 @@ os_sched_setparam(PyObject *module, PyObject *args) struct sched_param param; if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "O&:sched_setparam", - &pid, convert_sched_param, ¶m)) + &pid, convert_sched_param, ¶m)) { goto exit; + } return_value = os_sched_setparam_impl(module, pid, ¶m); exit: @@ -2039,11 +2126,13 @@ os_sched_rr_get_interval(PyObject *module, PyObject *arg) pid_t pid; double _return_value; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_rr_get_interval", &pid)) + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_rr_get_interval", &pid)) { goto exit; + } _return_value = os_sched_rr_get_interval_impl(module, pid); - if ((_return_value == -1.0) && PyErr_Occurred()) + if ((_return_value == -1.0) && PyErr_Occurred()) { goto exit; + } return_value = PyFloat_FromDouble(_return_value); exit: @@ -2098,8 +2187,9 @@ os_sched_setaffinity(PyObject *module, PyObject *args) PyObject *mask; if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "O:sched_setaffinity", - &pid, &mask)) + &pid, &mask)) { goto exit; + } return_value = os_sched_setaffinity_impl(module, pid, mask); exit: @@ -2114,7 +2204,7 @@ PyDoc_STRVAR(os_sched_getaffinity__doc__, "sched_getaffinity($module, pid, /)\n" "--\n" "\n" -"Return the affinity of the process identified by pid.\n" +"Return the affinity of the process identified by pid (or the current process if zero).\n" "\n" "The affinity is returned as a set of CPU identifiers."); @@ -2130,8 +2220,9 @@ os_sched_getaffinity(PyObject *module, PyObject *arg) PyObject *return_value = NULL; pid_t pid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getaffinity", &pid)) + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getaffinity", &pid)) { goto exit; + } return_value = os_sched_getaffinity_impl(module, pid); exit: @@ -2316,12 +2407,14 @@ static PyObject * os_getpgid(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"pid", NULL}; + static const char * const _keywords[] = {"pid", NULL}; + static _PyArg_Parser _parser = {"" _Py_PARSE_PID ":getpgid", _keywords, 0}; pid_t pid; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" _Py_PARSE_PID ":getpgid", _keywords, - &pid)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &pid)) { goto exit; + } return_value = os_getpgid_impl(module, pid); exit: @@ -2465,8 +2558,9 @@ os_kill(PyObject *module, PyObject *args) Py_ssize_t signal; if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "n:kill", - &pid, &signal)) + &pid, &signal)) { goto exit; + } return_value = os_kill_impl(module, pid, signal); exit: @@ -2497,8 +2591,9 @@ os_killpg(PyObject *module, PyObject *args) int signal; if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "i:killpg", - &pgid, &signal)) + &pgid, &signal)) { goto exit; + } return_value = os_killpg_impl(module, pgid, signal); exit: @@ -2527,8 +2622,9 @@ os_plock(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int op; - if (!PyArg_Parse(arg, "i:plock", &op)) + if (!PyArg_Parse(arg, "i:plock", &op)) { goto exit; + } return_value = os_plock_impl(module, op); exit: @@ -2557,8 +2653,9 @@ os_setuid(PyObject *module, PyObject *arg) PyObject *return_value = NULL; uid_t uid; - if (!PyArg_Parse(arg, "O&:setuid", _Py_Uid_Converter, &uid)) + if (!PyArg_Parse(arg, "O&:setuid", _Py_Uid_Converter, &uid)) { goto exit; + } return_value = os_setuid_impl(module, uid); exit: @@ -2587,8 +2684,9 @@ os_seteuid(PyObject *module, PyObject *arg) PyObject *return_value = NULL; uid_t euid; - if (!PyArg_Parse(arg, "O&:seteuid", _Py_Uid_Converter, &euid)) + if (!PyArg_Parse(arg, "O&:seteuid", _Py_Uid_Converter, &euid)) { goto exit; + } return_value = os_seteuid_impl(module, euid); exit: @@ -2617,8 +2715,9 @@ os_setegid(PyObject *module, PyObject *arg) PyObject *return_value = NULL; gid_t egid; - if (!PyArg_Parse(arg, "O&:setegid", _Py_Gid_Converter, &egid)) + if (!PyArg_Parse(arg, "O&:setegid", _Py_Gid_Converter, &egid)) { goto exit; + } return_value = os_setegid_impl(module, egid); exit: @@ -2649,8 +2748,9 @@ os_setreuid(PyObject *module, PyObject *args) uid_t euid; if (!PyArg_ParseTuple(args, "O&O&:setreuid", - _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid)) + _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid)) { goto exit; + } return_value = os_setreuid_impl(module, ruid, euid); exit: @@ -2681,8 +2781,9 @@ os_setregid(PyObject *module, PyObject *args) gid_t egid; if (!PyArg_ParseTuple(args, "O&O&:setregid", - _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid)) + _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid)) { goto exit; + } return_value = os_setregid_impl(module, rgid, egid); exit: @@ -2711,8 +2812,9 @@ os_setgid(PyObject *module, PyObject *arg) PyObject *return_value = NULL; gid_t gid; - if (!PyArg_Parse(arg, "O&:setgid", _Py_Gid_Converter, &gid)) + if (!PyArg_Parse(arg, "O&:setgid", _Py_Gid_Converter, &gid)) { goto exit; + } return_value = os_setgid_impl(module, gid); exit: @@ -2755,12 +2857,14 @@ static PyObject * os_wait3(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"options", NULL}; + static const char * const _keywords[] = {"options", NULL}; + static _PyArg_Parser _parser = {"i:wait3", _keywords, 0}; int options; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:wait3", _keywords, - &options)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &options)) { goto exit; + } return_value = os_wait3_impl(module, options); exit: @@ -2790,13 +2894,15 @@ static PyObject * os_wait4(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"pid", "options", NULL}; + static const char * const _keywords[] = {"pid", "options", NULL}; + static _PyArg_Parser _parser = {"" _Py_PARSE_PID "i:wait4", _keywords, 0}; pid_t pid; int options; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" _Py_PARSE_PID "i:wait4", _keywords, - &pid, &options)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &pid, &options)) { goto exit; + } return_value = os_wait4_impl(module, pid, options); exit: @@ -2839,8 +2945,9 @@ os_waitid(PyObject *module, PyObject *args) int options; if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", - &idtype, &id, &options)) + &idtype, &id, &options)) { goto exit; + } return_value = os_waitid_impl(module, idtype, id, options); exit: @@ -2876,8 +2983,9 @@ os_waitpid(PyObject *module, PyObject *args) int options; if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "i:waitpid", - &pid, &options)) + &pid, &options)) { goto exit; + } return_value = os_waitpid_impl(module, pid, options); exit: @@ -2903,18 +3011,19 @@ PyDoc_STRVAR(os_waitpid__doc__, {"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__}, static PyObject * -os_waitpid_impl(PyObject *module, Py_intptr_t pid, int options); +os_waitpid_impl(PyObject *module, intptr_t pid, int options); static PyObject * os_waitpid(PyObject *module, PyObject *args) { PyObject *return_value = NULL; - Py_intptr_t pid; + intptr_t pid; int options; if (!PyArg_ParseTuple(args, "" _Py_PARSE_INTPTR "i:waitpid", - &pid, &options)) + &pid, &options)) { goto exit; + } return_value = os_waitpid_impl(module, pid, options); exit: @@ -2977,15 +3086,17 @@ static PyObject * os_symlink(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; + static const char * const _keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&O&|p$O&:symlink", _keywords, 0}; path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0); path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0); int target_is_directory = 0; int dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|p$O&:symlink", _keywords, - path_converter, &src, path_converter, &dst, &target_is_directory, SYMLINKAT_DIR_FD_CONVERTER, &dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &src, path_converter, &dst, &target_is_directory, SYMLINKAT_DIR_FD_CONVERTER, &dir_fd)) { goto exit; + } return_value = os_symlink_impl(module, &src, &dst, target_is_directory, dir_fd); exit: @@ -3045,8 +3156,9 @@ os_getsid(PyObject *module, PyObject *arg) PyObject *return_value = NULL; pid_t pid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":getsid", &pid)) + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":getsid", &pid)) { goto exit; + } return_value = os_getsid_impl(module, pid); exit: @@ -3099,8 +3211,9 @@ os_setpgid(PyObject *module, PyObject *args) pid_t pgrp; if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "" _Py_PARSE_PID ":setpgid", - &pid, &pgrp)) + &pid, &pgrp)) { goto exit; + } return_value = os_setpgid_impl(module, pid, pgrp); exit: @@ -3129,8 +3242,9 @@ os_tcgetpgrp(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - if (!PyArg_Parse(arg, "i:tcgetpgrp", &fd)) + if (!PyArg_Parse(arg, "i:tcgetpgrp", &fd)) { goto exit; + } return_value = os_tcgetpgrp_impl(module, fd); exit: @@ -3161,8 +3275,9 @@ os_tcsetpgrp(PyObject *module, PyObject *args) pid_t pgid; if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", - &fd, &pgid)) + &fd, &pgid)) { goto exit; + } return_value = os_tcsetpgrp_impl(module, fd, pgid); exit: @@ -3192,19 +3307,22 @@ static PyObject * os_open(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; + static const char * const _keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&i|i$O&:open", _keywords, 0}; path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); int flags; int mode = 511; int dir_fd = DEFAULT_DIR_FD; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", _keywords, - path_converter, &path, &flags, &mode, OPENAT_DIR_FD_CONVERTER, &dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &flags, &mode, OPENAT_DIR_FD_CONVERTER, &dir_fd)) { goto exit; + } _return_value = os_open_impl(module, &path, flags, mode, dir_fd); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -3230,12 +3348,14 @@ static PyObject * os_close(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", NULL}; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {"i:close", _keywords, 0}; int fd; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:close", _keywords, - &fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &fd)) { goto exit; + } return_value = os_close_impl(module, fd); exit: @@ -3262,8 +3382,9 @@ os_closerange(PyObject *module, PyObject *args) int fd_high; if (!PyArg_ParseTuple(args, "ii:closerange", - &fd_low, &fd_high)) + &fd_low, &fd_high)) { goto exit; + } return_value = os_closerange_impl(module, fd_low, fd_high); exit: @@ -3289,11 +3410,13 @@ os_dup(PyObject *module, PyObject *arg) int fd; int _return_value; - if (!PyArg_Parse(arg, "i:dup", &fd)) + if (!PyArg_Parse(arg, "i:dup", &fd)) { goto exit; + } _return_value = os_dup_impl(module, fd); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -3316,14 +3439,16 @@ static PyObject * os_dup2(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", "fd2", "inheritable", NULL}; + static const char * const _keywords[] = {"fd", "fd2", "inheritable", NULL}; + static _PyArg_Parser _parser = {"ii|p:dup2", _keywords, 0}; int fd; int fd2; int inheritable = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|p:dup2", _keywords, - &fd, &fd2, &inheritable)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &fd, &fd2, &inheritable)) { goto exit; + } return_value = os_dup2_impl(module, fd, fd2, inheritable); exit: @@ -3360,8 +3485,9 @@ os_lockf(PyObject *module, PyObject *args) Py_off_t length; if (!PyArg_ParseTuple(args, "iiO&:lockf", - &fd, &command, Py_off_t_converter, &length)) + &fd, &command, Py_off_t_converter, &length)) { goto exit; + } return_value = os_lockf_impl(module, fd, command, length); exit: @@ -3395,11 +3521,13 @@ os_lseek(PyObject *module, PyObject *args) Py_off_t _return_value; if (!PyArg_ParseTuple(args, "iO&i:lseek", - &fd, Py_off_t_converter, &position, &how)) + &fd, Py_off_t_converter, &position, &how)) { goto exit; + } _return_value = os_lseek_impl(module, fd, position, how); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromPy_off_t(_return_value); exit: @@ -3426,8 +3554,9 @@ os_read(PyObject *module, PyObject *args) Py_ssize_t length; if (!PyArg_ParseTuple(args, "in:read", - &fd, &length)) + &fd, &length)) { goto exit; + } return_value = os_read_impl(module, fd, length); exit: @@ -3465,11 +3594,13 @@ os_readv(PyObject *module, PyObject *args) Py_ssize_t _return_value; if (!PyArg_ParseTuple(args, "iO:readv", - &fd, &buffers)) + &fd, &buffers)) { goto exit; + } _return_value = os_readv_impl(module, fd, buffers); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: @@ -3504,8 +3635,9 @@ os_pread(PyObject *module, PyObject *args) Py_off_t offset; if (!PyArg_ParseTuple(args, "iiO&:pread", - &fd, &length, Py_off_t_converter, &offset)) + &fd, &length, Py_off_t_converter, &offset)) { goto exit; + } return_value = os_pread_impl(module, fd, length, offset); exit: @@ -3535,17 +3667,20 @@ os_write(PyObject *module, PyObject *args) Py_ssize_t _return_value; if (!PyArg_ParseTuple(args, "iy*:write", - &fd, &data)) + &fd, &data)) { goto exit; + } _return_value = os_write_impl(module, fd, &data); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -3569,12 +3704,14 @@ static PyObject * os_fstat(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", NULL}; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {"i:fstat", _keywords, 0}; int fd; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:fstat", _keywords, - &fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &fd)) { goto exit; + } return_value = os_fstat_impl(module, fd); exit: @@ -3603,11 +3740,13 @@ os_isatty(PyObject *module, PyObject *arg) int fd; int _return_value; - if (!PyArg_Parse(arg, "i:isatty", &fd)) + if (!PyArg_Parse(arg, "i:isatty", &fd)) { goto exit; + } _return_value = os_isatty_impl(module, fd); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: @@ -3665,8 +3804,9 @@ os_pipe2(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flags; - if (!PyArg_Parse(arg, "i:pipe2", &flags)) + if (!PyArg_Parse(arg, "i:pipe2", &flags)) { goto exit; + } return_value = os_pipe2_impl(module, flags); exit: @@ -3701,11 +3841,13 @@ os_writev(PyObject *module, PyObject *args) Py_ssize_t _return_value; if (!PyArg_ParseTuple(args, "iO:writev", - &fd, &buffers)) + &fd, &buffers)) { goto exit; + } _return_value = os_writev_impl(module, fd, buffers); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: @@ -3742,17 +3884,20 @@ os_pwrite(PyObject *module, PyObject *args) Py_ssize_t _return_value; if (!PyArg_ParseTuple(args, "iy*O&:pwrite", - &fd, &buffer, Py_off_t_converter, &offset)) + &fd, &buffer, Py_off_t_converter, &offset)) { goto exit; + } _return_value = os_pwrite_impl(module, fd, &buffer, offset); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromSsize_t(_return_value); exit: /* Cleanup for buffer */ - if (buffer.obj) + if (buffer.obj) { PyBuffer_Release(&buffer); + } return return_value; } @@ -3782,14 +3927,16 @@ static PyObject * os_mkfifo(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "mode", "dir_fd", NULL}; + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&|i$O&:mkfifo", _keywords, 0}; path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); int mode = 438; int dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", _keywords, - path_converter, &path, &mode, MKFIFOAT_DIR_FD_CONVERTER, &dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &mode, MKFIFOAT_DIR_FD_CONVERTER, &dir_fd)) { goto exit; + } return_value = os_mkfifo_impl(module, &path, mode, dir_fd); exit: @@ -3832,15 +3979,17 @@ static PyObject * os_mknod(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "mode", "device", "dir_fd", NULL}; + static const char * const _keywords[] = {"path", "mode", "device", "dir_fd", NULL}; + static _PyArg_Parser _parser = {"O&|iO&$O&:mknod", _keywords, 0}; path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); int mode = 384; dev_t device = 0; int dir_fd = DEFAULT_DIR_FD; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", _keywords, - path_converter, &path, &mode, _Py_Dev_Converter, &device, MKNODAT_DIR_FD_CONVERTER, &dir_fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &mode, _Py_Dev_Converter, &device, MKNODAT_DIR_FD_CONVERTER, &dir_fd)) { goto exit; + } return_value = os_mknod_impl(module, &path, mode, device, dir_fd); exit: @@ -3873,11 +4022,13 @@ os_major(PyObject *module, PyObject *arg) dev_t device; unsigned int _return_value; - if (!PyArg_Parse(arg, "O&:major", _Py_Dev_Converter, &device)) + if (!PyArg_Parse(arg, "O&:major", _Py_Dev_Converter, &device)) { goto exit; + } _return_value = os_major_impl(module, device); - if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); exit: @@ -3907,11 +4058,13 @@ os_minor(PyObject *module, PyObject *arg) dev_t device; unsigned int _return_value; - if (!PyArg_Parse(arg, "O&:minor", _Py_Dev_Converter, &device)) + if (!PyArg_Parse(arg, "O&:minor", _Py_Dev_Converter, &device)) { goto exit; + } _return_value = os_minor_impl(module, device); - if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); exit: @@ -3943,11 +4096,13 @@ os_makedev(PyObject *module, PyObject *args) dev_t _return_value; if (!PyArg_ParseTuple(args, "ii:makedev", - &major, &minor)) + &major, &minor)) { goto exit; + } _return_value = os_makedev_impl(module, major, minor); - if ((_return_value == (dev_t)-1) && PyErr_Occurred()) + if ((_return_value == (dev_t)-1) && PyErr_Occurred()) { goto exit; + } return_value = _PyLong_FromDev(_return_value); exit: @@ -3978,8 +4133,9 @@ os_ftruncate(PyObject *module, PyObject *args) Py_off_t length; if (!PyArg_ParseTuple(args, "iO&:ftruncate", - &fd, Py_off_t_converter, &length)) + &fd, Py_off_t_converter, &length)) { goto exit; + } return_value = os_ftruncate_impl(module, fd, length); exit: @@ -4009,13 +4165,15 @@ static PyObject * os_truncate(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "length", NULL}; + static const char * const _keywords[] = {"path", "length", NULL}; + static _PyArg_Parser _parser = {"O&O&:truncate", _keywords, 0}; path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); Py_off_t length; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", _keywords, - path_converter, &path, Py_off_t_converter, &length)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, Py_off_t_converter, &length)) { goto exit; + } return_value = os_truncate_impl(module, &path, length); exit: @@ -4054,8 +4212,9 @@ os_posix_fallocate(PyObject *module, PyObject *args) Py_off_t length; if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate", - &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length)) + &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length)) { goto exit; + } return_value = os_posix_fallocate_impl(module, fd, offset, length); exit: @@ -4097,8 +4256,9 @@ os_posix_fadvise(PyObject *module, PyObject *args) int advice; if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise", - &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length, &advice)) + &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length, &advice)) { goto exit; + } return_value = os_posix_fadvise_impl(module, fd, offset, length, advice); exit: @@ -4129,8 +4289,9 @@ os_putenv(PyObject *module, PyObject *args) PyObject *value; if (!PyArg_ParseTuple(args, "UU:putenv", - &name, &value)) + &name, &value)) { goto exit; + } return_value = os_putenv_impl(module, name, value); exit: @@ -4161,8 +4322,9 @@ os_putenv(PyObject *module, PyObject *args) PyObject *value = NULL; if (!PyArg_ParseTuple(args, "O&O&:putenv", - PyUnicode_FSConverter, &name, PyUnicode_FSConverter, &value)) + PyUnicode_FSConverter, &name, PyUnicode_FSConverter, &value)) { goto exit; + } return_value = os_putenv_impl(module, name, value); exit: @@ -4196,8 +4358,9 @@ os_unsetenv(PyObject *module, PyObject *arg) PyObject *return_value = NULL; PyObject *name = NULL; - if (!PyArg_Parse(arg, "O&:unsetenv", PyUnicode_FSConverter, &name)) + if (!PyArg_Parse(arg, "O&:unsetenv", PyUnicode_FSConverter, &name)) { goto exit; + } return_value = os_unsetenv_impl(module, name); exit: @@ -4227,8 +4390,9 @@ os_strerror(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int code; - if (!PyArg_Parse(arg, "i:strerror", &code)) + if (!PyArg_Parse(arg, "i:strerror", &code)) { goto exit; + } return_value = os_strerror_impl(module, code); exit: @@ -4256,11 +4420,13 @@ os_WCOREDUMP(PyObject *module, PyObject *arg) int status; int _return_value; - if (!PyArg_Parse(arg, "i:WCOREDUMP", &status)) + if (!PyArg_Parse(arg, "i:WCOREDUMP", &status)) { goto exit; + } _return_value = os_WCOREDUMP_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: @@ -4290,16 +4456,19 @@ static PyObject * os_WIFCONTINUED(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"status", NULL}; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {"i:WIFCONTINUED", _keywords, 0}; int status; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WIFCONTINUED", _keywords, - &status)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &status)) { goto exit; + } _return_value = os_WIFCONTINUED_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: @@ -4326,16 +4495,19 @@ static PyObject * os_WIFSTOPPED(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"status", NULL}; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {"i:WIFSTOPPED", _keywords, 0}; int status; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WIFSTOPPED", _keywords, - &status)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &status)) { goto exit; + } _return_value = os_WIFSTOPPED_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: @@ -4362,16 +4534,19 @@ static PyObject * os_WIFSIGNALED(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"status", NULL}; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {"i:WIFSIGNALED", _keywords, 0}; int status; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WIFSIGNALED", _keywords, - &status)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &status)) { goto exit; + } _return_value = os_WIFSIGNALED_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: @@ -4398,16 +4573,19 @@ static PyObject * os_WIFEXITED(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"status", NULL}; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {"i:WIFEXITED", _keywords, 0}; int status; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WIFEXITED", _keywords, - &status)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &status)) { goto exit; + } _return_value = os_WIFEXITED_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: @@ -4434,16 +4612,19 @@ static PyObject * os_WEXITSTATUS(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"status", NULL}; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {"i:WEXITSTATUS", _keywords, 0}; int status; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WEXITSTATUS", _keywords, - &status)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &status)) { goto exit; + } _return_value = os_WEXITSTATUS_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -4470,16 +4651,19 @@ static PyObject * os_WTERMSIG(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"status", NULL}; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {"i:WTERMSIG", _keywords, 0}; int status; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WTERMSIG", _keywords, - &status)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &status)) { goto exit; + } _return_value = os_WTERMSIG_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -4506,16 +4690,19 @@ static PyObject * os_WSTOPSIG(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"status", NULL}; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {"i:WSTOPSIG", _keywords, 0}; int status; int _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WSTOPSIG", _keywords, - &status)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &status)) { goto exit; + } _return_value = os_WSTOPSIG_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -4546,8 +4733,9 @@ os_fstatvfs(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int fd; - if (!PyArg_Parse(arg, "i:fstatvfs", &fd)) + if (!PyArg_Parse(arg, "i:fstatvfs", &fd)) { goto exit; + } return_value = os_fstatvfs_impl(module, fd); exit: @@ -4578,12 +4766,14 @@ static PyObject * os_statvfs(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", NULL}; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {"O&:statvfs", _keywords, 0}; path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", _keywords, - path_converter, &path)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path)) { goto exit; + } return_value = os_statvfs_impl(module, &path); exit: @@ -4613,12 +4803,14 @@ static PyObject * os__getdiskusage(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", NULL}; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {"u:_getdiskusage", _keywords, 0}; Py_UNICODE *path; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "u:_getdiskusage", _keywords, - &path)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &path)) { goto exit; + } return_value = os__getdiskusage_impl(module, path); exit: @@ -4652,11 +4844,13 @@ os_fpathconf(PyObject *module, PyObject *args) long _return_value; if (!PyArg_ParseTuple(args, "iO&:fpathconf", - &fd, conv_path_confname, &name)) + &fd, conv_path_confname, &name)) { goto exit; + } _return_value = os_fpathconf_impl(module, fd, name); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong(_return_value); exit: @@ -4687,17 +4881,20 @@ static PyObject * os_pathconf(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "name", NULL}; + static const char * const _keywords[] = {"path", "name", NULL}; + static _PyArg_Parser _parser = {"O&O&:pathconf", _keywords, 0}; path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); int name; long _return_value; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", _keywords, - path_converter, &path, conv_path_confname, &name)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, conv_path_confname, &name)) { goto exit; + } _return_value = os_pathconf_impl(module, &path, name); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong(_return_value); exit: @@ -4729,8 +4926,9 @@ os_confstr(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int name; - if (!PyArg_Parse(arg, "O&:confstr", conv_confstr_confname, &name)) + if (!PyArg_Parse(arg, "O&:confstr", conv_confstr_confname, &name)) { goto exit; + } return_value = os_confstr_impl(module, name); exit: @@ -4760,11 +4958,13 @@ os_sysconf(PyObject *module, PyObject *arg) int name; long _return_value; - if (!PyArg_Parse(arg, "O&:sysconf", conv_sysconf_confname, &name)) + if (!PyArg_Parse(arg, "O&:sysconf", conv_sysconf_confname, &name)) { goto exit; + } _return_value = os_sysconf_impl(module, name); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong(_return_value); exit: @@ -4794,6 +4994,60 @@ os_abort(PyObject *module, PyObject *Py_UNUSED(ignored)) return os_abort_impl(module); } +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os_startfile__doc__, +"startfile($module, /, filepath, operation=None)\n" +"--\n" +"\n" +"startfile(filepath [, operation])\n" +"\n" +"Start a file with its associated application.\n" +"\n" +"When \"operation\" is not specified or \"open\", this acts like\n" +"double-clicking the file in Explorer, or giving the file name as an\n" +"argument to the DOS \"start\" command: the file is opened with whatever\n" +"application (if any) its extension is associated.\n" +"When another \"operation\" is given, it specifies what should be done with\n" +"the file. A typical operation is \"print\".\n" +"\n" +"startfile returns as soon as the associated application is launched.\n" +"There is no option to wait for the application to close, and no way\n" +"to retrieve the application\'s exit status.\n" +"\n" +"The filepath is relative to the current directory. If you want to use\n" +"an absolute path, make sure the first character is not a slash (\"/\");\n" +"the underlying Win32 ShellExecute function doesn\'t work if it is."); + +#define OS_STARTFILE_METHODDEF \ + {"startfile", (PyCFunction)os_startfile, METH_VARARGS|METH_KEYWORDS, os_startfile__doc__}, + +static PyObject * +os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation); + +static PyObject * +os_startfile(PyObject *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"filepath", "operation", NULL}; + path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0); + Py_UNICODE *operation = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|u:startfile", _keywords, + path_converter, &filepath, &operation)) { + goto exit; + } + return_value = os_startfile_impl(module, &filepath, operation); + +exit: + /* Cleanup for filepath */ + path_cleanup(&filepath); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + #if defined(HAVE_GETLOADAVG) PyDoc_STRVAR(os_getloadavg__doc__, @@ -4839,12 +5093,14 @@ static PyObject * os_device_encoding(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"fd", NULL}; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {"i:device_encoding", _keywords, 0}; int fd; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:device_encoding", _keywords, - &fd)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &fd)) { goto exit; + } return_value = os_device_encoding_impl(module, fd); exit: @@ -4874,8 +5130,9 @@ os_setresuid(PyObject *module, PyObject *args) uid_t suid; if (!PyArg_ParseTuple(args, "O&O&O&:setresuid", - _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid, _Py_Uid_Converter, &suid)) + _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid, _Py_Uid_Converter, &suid)) { goto exit; + } return_value = os_setresuid_impl(module, ruid, euid, suid); exit: @@ -4907,8 +5164,9 @@ os_setresgid(PyObject *module, PyObject *args) gid_t sgid; if (!PyArg_ParseTuple(args, "O&O&O&:setresgid", - _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid, _Py_Gid_Converter, &sgid)) + _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid, _Py_Gid_Converter, &sgid)) { goto exit; + } return_value = os_setresgid_impl(module, rgid, egid, sgid); exit: @@ -4985,14 +5243,16 @@ static PyObject * os_getxattr(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&O&|$p:getxattr", _keywords, 0}; path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0); int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", _keywords, - path_converter, &path, path_converter, &attribute, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, path_converter, &attribute, &follow_symlinks)) { goto exit; + } return_value = os_getxattr_impl(module, &path, &attribute, follow_symlinks); exit: @@ -5031,16 +5291,18 @@ static PyObject * os_setxattr(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&O&y*|i$p:setxattr", _keywords, 0}; path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1); path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0); Py_buffer value = {NULL, NULL}; int flags = 0; int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr", _keywords, - path_converter, &path, path_converter, &attribute, &value, &flags, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, path_converter, &attribute, &value, &flags, &follow_symlinks)) { goto exit; + } return_value = os_setxattr_impl(module, &path, &attribute, &value, flags, follow_symlinks); exit: @@ -5049,8 +5311,9 @@ exit: /* Cleanup for attribute */ path_cleanup(&attribute); /* Cleanup for value */ - if (value.obj) + if (value.obj) { PyBuffer_Release(&value); + } return return_value; } @@ -5081,14 +5344,16 @@ static PyObject * os_removexattr(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"O&O&|$p:removexattr", _keywords, 0}; path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0); int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr", _keywords, - path_converter, &path, path_converter, &attribute, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, path_converter, &attribute, &follow_symlinks)) { goto exit; + } return_value = os_removexattr_impl(module, &path, &attribute, follow_symlinks); exit: @@ -5126,13 +5391,15 @@ static PyObject * os_listxattr(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"path", "follow_symlinks", NULL}; + static const char * const _keywords[] = {"path", "follow_symlinks", NULL}; + static _PyArg_Parser _parser = {"|O&$p:listxattr", _keywords, 0}; path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); int follow_symlinks = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", _keywords, - path_converter, &path, &follow_symlinks)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + path_converter, &path, &follow_symlinks)) { goto exit; + } return_value = os_listxattr_impl(module, &path, follow_symlinks); exit: @@ -5162,8 +5429,9 @@ os_urandom(PyObject *module, PyObject *arg) PyObject *return_value = NULL; Py_ssize_t size; - if (!PyArg_Parse(arg, "n:urandom", &size)) + if (!PyArg_Parse(arg, "n:urandom", &size)) { goto exit; + } return_value = os_urandom_impl(module, size); exit: @@ -5174,7 +5442,11 @@ PyDoc_STRVAR(os_cpu_count__doc__, "cpu_count($module, /)\n" "--\n" "\n" -"Return the number of CPUs in the system; return None if indeterminable."); +"Return the number of CPUs in the system; return None if indeterminable.\n" +"\n" +"This number is not equivalent to the number of CPUs the current process can\n" +"use. The number of usable CPUs can be obtained with\n" +"``len(os.sched_getaffinity(0))``"); #define OS_CPU_COUNT_METHODDEF \ {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__}, @@ -5207,11 +5479,13 @@ os_get_inheritable(PyObject *module, PyObject *arg) int fd; int _return_value; - if (!PyArg_Parse(arg, "i:get_inheritable", &fd)) + if (!PyArg_Parse(arg, "i:get_inheritable", &fd)) { goto exit; + } _return_value = os_get_inheritable_impl(module, fd); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: @@ -5238,8 +5512,9 @@ os_set_inheritable(PyObject *module, PyObject *args) int inheritable; if (!PyArg_ParseTuple(args, "ii:set_inheritable", - &fd, &inheritable)) + &fd, &inheritable)) { goto exit; + } return_value = os_set_inheritable_impl(module, fd, inheritable); exit: @@ -5258,20 +5533,22 @@ PyDoc_STRVAR(os_get_handle_inheritable__doc__, {"get_handle_inheritable", (PyCFunction)os_get_handle_inheritable, METH_O, os_get_handle_inheritable__doc__}, static int -os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle); +os_get_handle_inheritable_impl(PyObject *module, intptr_t handle); static PyObject * os_get_handle_inheritable(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - Py_intptr_t handle; + intptr_t handle; int _return_value; - if (!PyArg_Parse(arg, "" _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) + if (!PyArg_Parse(arg, "" _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) { goto exit; + } _return_value = os_get_handle_inheritable_impl(module, handle); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyBool_FromLong((long)_return_value); exit: @@ -5292,19 +5569,20 @@ PyDoc_STRVAR(os_set_handle_inheritable__doc__, {"set_handle_inheritable", (PyCFunction)os_set_handle_inheritable, METH_VARARGS, os_set_handle_inheritable__doc__}, static PyObject * -os_set_handle_inheritable_impl(PyObject *module, Py_intptr_t handle, +os_set_handle_inheritable_impl(PyObject *module, intptr_t handle, int inheritable); static PyObject * os_set_handle_inheritable(PyObject *module, PyObject *args) { PyObject *return_value = NULL; - Py_intptr_t handle; + intptr_t handle; int inheritable; if (!PyArg_ParseTuple(args, "" _Py_PARSE_INTPTR "p:set_handle_inheritable", - &handle, &inheritable)) + &handle, &inheritable)) { goto exit; + } return_value = os_set_handle_inheritable_impl(module, handle, inheritable); exit: @@ -5313,6 +5591,75 @@ exit: #endif /* defined(MS_WINDOWS) */ +PyDoc_STRVAR(os_fspath__doc__, +"fspath($module, /, path)\n" +"--\n" +"\n" +"Return the file system path representation of the object.\n" +"\n" +"If the object is str or bytes, then allow it to pass through as-is. If the\n" +"object defines __fspath__(), then return the result of that method. All other\n" +"types raise a TypeError."); + +#define OS_FSPATH_METHODDEF \ + {"fspath", (PyCFunction)os_fspath, METH_VARARGS|METH_KEYWORDS, os_fspath__doc__}, + +static PyObject * +os_fspath_impl(PyObject *module, PyObject *path); + +static PyObject * +os_fspath(PyObject *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {"O:fspath", _keywords, 0}; + PyObject *path; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &path)) { + goto exit; + } + return_value = os_fspath_impl(module, path); + +exit: + return return_value; +} + +#if defined(HAVE_GETRANDOM_SYSCALL) + +PyDoc_STRVAR(os_getrandom__doc__, +"getrandom($module, /, size, flags=0)\n" +"--\n" +"\n" +"Obtain a series of random bytes."); + +#define OS_GETRANDOM_METHODDEF \ + {"getrandom", (PyCFunction)os_getrandom, METH_VARARGS|METH_KEYWORDS, os_getrandom__doc__}, + +static PyObject * +os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags); + +static PyObject * +os_getrandom(PyObject *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"size", "flags", NULL}; + static _PyArg_Parser _parser = {"n|i:getrandom", _keywords, 0}; + Py_ssize_t size; + int flags = 0; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &size, &flags)) { + goto exit; + } + return_value = os_getrandom_impl(module, size, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETRANDOM_SYSCALL) */ + #ifndef OS_TTYNAME_METHODDEF #define OS_TTYNAME_METHODDEF #endif /* !defined(OS_TTYNAME_METHODDEF) */ @@ -5741,6 +6088,10 @@ exit: #define OS_SYSCONF_METHODDEF #endif /* !defined(OS_SYSCONF_METHODDEF) */ +#ifndef OS_STARTFILE_METHODDEF + #define OS_STARTFILE_METHODDEF +#endif /* !defined(OS_STARTFILE_METHODDEF) */ + #ifndef OS_GETLOADAVG_METHODDEF #define OS_GETLOADAVG_METHODDEF #endif /* !defined(OS_GETLOADAVG_METHODDEF) */ @@ -5784,4 +6135,8 @@ exit: #ifndef OS_SET_HANDLE_INHERITABLE_METHODDEF #define OS_SET_HANDLE_INHERITABLE_METHODDEF #endif /* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */ -/*[clinic end generated code: output=9d5f831b23145d1e input=a9049054013a1b77]*/ + +#ifndef OS_GETRANDOM_METHODDEF + #define OS_GETRANDOM_METHODDEF +#endif /* !defined(OS_GETRANDOM_METHODDEF) */ +/*[clinic end generated code: output=fce51c7d432662c2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pwdmodule.c.h b/Modules/clinic/pwdmodule.c.h index cb191a0..f9e0644 100644 --- a/Modules/clinic/pwdmodule.c.h +++ b/Modules/clinic/pwdmodule.c.h @@ -33,8 +33,9 @@ pwd_getpwnam(PyObject *module, PyObject *arg_) PyObject *return_value = NULL; PyObject *arg; - if (!PyArg_Parse(arg_, "U:getpwnam", &arg)) + if (!PyArg_Parse(arg_, "U:getpwnam", &arg)) { goto exit; + } return_value = pwd_getpwnam_impl(module, arg); exit: @@ -68,4 +69,4 @@ pwd_getpwall(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef PWD_GETPWALL_METHODDEF #define PWD_GETPWALL_METHODDEF #endif /* !defined(PWD_GETPWALL_METHODDEF) */ -/*[clinic end generated code: output=d0ea1c5c832f0c1a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fc41d8d88ec206d8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h index c5b5c71..8a03f67 100644 --- a/Modules/clinic/pyexpat.c.h +++ b/Modules/clinic/pyexpat.c.h @@ -25,8 +25,9 @@ pyexpat_xmlparser_Parse(xmlparseobject *self, PyObject *args) int isfinal = 0; if (!PyArg_ParseTuple(args, "O|i:Parse", - &data, &isfinal)) + &data, &isfinal)) { goto exit; + } return_value = pyexpat_xmlparser_Parse_impl(self, data, isfinal); exit: @@ -60,8 +61,9 @@ pyexpat_xmlparser_SetBase(xmlparseobject *self, PyObject *arg) PyObject *return_value = NULL; const char *base; - if (!PyArg_Parse(arg, "s:SetBase", &base)) + if (!PyArg_Parse(arg, "s:SetBase", &base)) { goto exit; + } return_value = pyexpat_xmlparser_SetBase_impl(self, base); exit: @@ -129,8 +131,9 @@ pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyObject *arg const char *encoding = NULL; if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate", - &context, &encoding)) + &context, &encoding)) { goto exit; + } return_value = pyexpat_xmlparser_ExternalEntityParserCreate_impl(self, context, encoding); exit: @@ -160,8 +163,9 @@ pyexpat_xmlparser_SetParamEntityParsing(xmlparseobject *self, PyObject *arg) PyObject *return_value = NULL; int flag; - if (!PyArg_Parse(arg, "i:SetParamEntityParsing", &flag)) + if (!PyArg_Parse(arg, "i:SetParamEntityParsing", &flag)) { goto exit; + } return_value = pyexpat_xmlparser_SetParamEntityParsing_impl(self, flag); exit: @@ -193,8 +197,9 @@ pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyObject *args) int flag = 1; if (!PyArg_ParseTuple(args, "|p:UseForeignDTD", - &flag)) + &flag)) { goto exit; + } return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, flag); exit: @@ -238,14 +243,16 @@ static PyObject * pyexpat_ParserCreate(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"encoding", "namespace_separator", "intern", NULL}; + static const char * const _keywords[] = {"encoding", "namespace_separator", "intern", NULL}; + static _PyArg_Parser _parser = {"|zzO:ParserCreate", _keywords, 0}; const char *encoding = NULL; const char *namespace_separator = NULL; PyObject *intern = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zzO:ParserCreate", _keywords, - &encoding, &namespace_separator, &intern)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &encoding, &namespace_separator, &intern)) { goto exit; + } return_value = pyexpat_ParserCreate_impl(module, encoding, namespace_separator, intern); exit: @@ -270,8 +277,9 @@ pyexpat_ErrorString(PyObject *module, PyObject *arg) PyObject *return_value = NULL; long code; - if (!PyArg_Parse(arg, "l:ErrorString", &code)) + if (!PyArg_Parse(arg, "l:ErrorString", &code)) { goto exit; + } return_value = pyexpat_ErrorString_impl(module, code); exit: @@ -281,4 +289,4 @@ exit: #ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ -/*[clinic end generated code: output=d479cfab607e9dc8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=93cfe662f2bc48e5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index 5b8db80..1972762 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -81,15 +81,17 @@ static PyObject * _sha1_sha1(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", NULL}; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {"|O:sha1", _keywords, 0}; PyObject *string = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha1", _keywords, - &string)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string)) { goto exit; + } return_value = _sha1_sha1_impl(module, string); exit: return return_value; } -/*[clinic end generated code: output=0b6a194fbb0b94f2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=549a5d08c248337d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha256module.c.h b/Modules/clinic/sha256module.c.h index 661569c..4239ab8 100644 --- a/Modules/clinic/sha256module.c.h +++ b/Modules/clinic/sha256module.c.h @@ -81,12 +81,14 @@ static PyObject * _sha256_sha256(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", NULL}; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {"|O:sha256", _keywords, 0}; PyObject *string = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha256", _keywords, - &string)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string)) { goto exit; + } return_value = _sha256_sha256_impl(module, string); exit: @@ -109,15 +111,17 @@ static PyObject * _sha256_sha224(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", NULL}; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {"|O:sha224", _keywords, 0}; PyObject *string = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha224", _keywords, - &string)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string)) { goto exit; + } return_value = _sha256_sha224_impl(module, string); exit: return return_value; } -/*[clinic end generated code: output=5a1fc5480e399f95 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a1296ba6d0780051 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha512module.c.h b/Modules/clinic/sha512module.c.h index d64c2a4..9680ea2 100644 --- a/Modules/clinic/sha512module.c.h +++ b/Modules/clinic/sha512module.c.h @@ -2,8 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(PY_LONG_LONG) - PyDoc_STRVAR(SHA512Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -22,10 +20,6 @@ SHA512Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) return SHA512Type_copy_impl(self); } -#endif /* defined(PY_LONG_LONG) */ - -#if defined(PY_LONG_LONG) - PyDoc_STRVAR(SHA512Type_digest__doc__, "digest($self, /)\n" "--\n" @@ -44,10 +38,6 @@ SHA512Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored)) return SHA512Type_digest_impl(self); } -#endif /* defined(PY_LONG_LONG) */ - -#if defined(PY_LONG_LONG) - PyDoc_STRVAR(SHA512Type_hexdigest__doc__, "hexdigest($self, /)\n" "--\n" @@ -66,10 +56,6 @@ SHA512Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored)) return SHA512Type_hexdigest_impl(self); } -#endif /* defined(PY_LONG_LONG) */ - -#if defined(PY_LONG_LONG) - PyDoc_STRVAR(SHA512Type_update__doc__, "update($self, obj, /)\n" "--\n" @@ -79,10 +65,6 @@ PyDoc_STRVAR(SHA512Type_update__doc__, #define SHA512TYPE_UPDATE_METHODDEF \ {"update", (PyCFunction)SHA512Type_update, METH_O, SHA512Type_update__doc__}, -#endif /* defined(PY_LONG_LONG) */ - -#if defined(PY_LONG_LONG) - PyDoc_STRVAR(_sha512_sha512__doc__, "sha512($module, /, string=b\'\')\n" "--\n" @@ -99,22 +81,20 @@ static PyObject * _sha512_sha512(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", NULL}; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {"|O:sha512", _keywords, 0}; PyObject *string = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha512", _keywords, - &string)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string)) { goto exit; + } return_value = _sha512_sha512_impl(module, string); exit: return return_value; } -#endif /* defined(PY_LONG_LONG) */ - -#if defined(PY_LONG_LONG) - PyDoc_STRVAR(_sha512_sha384__doc__, "sha384($module, /, string=b\'\')\n" "--\n" @@ -131,41 +111,17 @@ static PyObject * _sha512_sha384(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"string", NULL}; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {"|O:sha384", _keywords, 0}; PyObject *string = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha384", _keywords, - &string)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &string)) { goto exit; + } return_value = _sha512_sha384_impl(module, string); exit: return return_value; } - -#endif /* defined(PY_LONG_LONG) */ - -#ifndef SHA512TYPE_COPY_METHODDEF - #define SHA512TYPE_COPY_METHODDEF -#endif /* !defined(SHA512TYPE_COPY_METHODDEF) */ - -#ifndef SHA512TYPE_DIGEST_METHODDEF - #define SHA512TYPE_DIGEST_METHODDEF -#endif /* !defined(SHA512TYPE_DIGEST_METHODDEF) */ - -#ifndef SHA512TYPE_HEXDIGEST_METHODDEF - #define SHA512TYPE_HEXDIGEST_METHODDEF -#endif /* !defined(SHA512TYPE_HEXDIGEST_METHODDEF) */ - -#ifndef SHA512TYPE_UPDATE_METHODDEF - #define SHA512TYPE_UPDATE_METHODDEF -#endif /* !defined(SHA512TYPE_UPDATE_METHODDEF) */ - -#ifndef _SHA512_SHA512_METHODDEF - #define _SHA512_SHA512_METHODDEF -#endif /* !defined(_SHA512_SHA512_METHODDEF) */ - -#ifndef _SHA512_SHA384_METHODDEF - #define _SHA512_SHA384_METHODDEF -#endif /* !defined(_SHA512_SHA384_METHODDEF) */ -/*[clinic end generated code: output=bb87f494df50ffc0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8f7f6603a9c4e910 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index c8f4cd5..f8d5bd9 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -23,11 +23,13 @@ signal_alarm(PyObject *module, PyObject *arg) int seconds; long _return_value; - if (!PyArg_Parse(arg, "i:alarm", &seconds)) + if (!PyArg_Parse(arg, "i:alarm", &seconds)) { goto exit; + } _return_value = signal_alarm_impl(module, seconds); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong(_return_value); exit: @@ -85,8 +87,9 @@ signal_signal(PyObject *module, PyObject *args) PyObject *handler; if (!PyArg_ParseTuple(args, "iO:signal", - &signalnum, &handler)) + &signalnum, &handler)) { goto exit; + } return_value = signal_signal_impl(module, signalnum, handler); exit: @@ -117,8 +120,9 @@ signal_getsignal(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int signalnum; - if (!PyArg_Parse(arg, "i:getsignal", &signalnum)) + if (!PyArg_Parse(arg, "i:getsignal", &signalnum)) { goto exit; + } return_value = signal_getsignal_impl(module, signalnum); exit: @@ -150,8 +154,9 @@ signal_siginterrupt(PyObject *module, PyObject *args) int flag; if (!PyArg_ParseTuple(args, "ii:siginterrupt", - &signalnum, &flag)) + &signalnum, &flag)) { goto exit; + } return_value = signal_siginterrupt_impl(module, signalnum, flag); exit: @@ -189,8 +194,9 @@ signal_setitimer(PyObject *module, PyObject *args) double interval = 0.0; if (!PyArg_ParseTuple(args, "id|d:setitimer", - &which, &seconds, &interval)) + &which, &seconds, &interval)) { goto exit; + } return_value = signal_setitimer_impl(module, which, seconds, interval); exit: @@ -219,8 +225,9 @@ signal_getitimer(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int which; - if (!PyArg_Parse(arg, "i:getitimer", &which)) + if (!PyArg_Parse(arg, "i:getitimer", &which)) { goto exit; + } return_value = signal_getitimer_impl(module, which); exit: @@ -251,8 +258,9 @@ signal_pthread_sigmask(PyObject *module, PyObject *args) PyObject *mask; if (!PyArg_ParseTuple(args, "iO:pthread_sigmask", - &how, &mask)) + &how, &mask)) { goto exit; + } return_value = signal_pthread_sigmask_impl(module, how, mask); exit: @@ -344,8 +352,9 @@ signal_sigtimedwait(PyObject *module, PyObject *args) if (!PyArg_UnpackTuple(args, "sigtimedwait", 2, 2, - &sigset, &timeout_obj)) + &sigset, &timeout_obj)) { goto exit; + } return_value = signal_sigtimedwait_impl(module, sigset, timeout_obj); exit: @@ -376,8 +385,9 @@ signal_pthread_kill(PyObject *module, PyObject *args) int signalnum; if (!PyArg_ParseTuple(args, "li:pthread_kill", - &thread_id, &signalnum)) + &thread_id, &signalnum)) { goto exit; + } return_value = signal_pthread_kill_impl(module, thread_id, signalnum); exit: @@ -429,4 +439,4 @@ exit: #ifndef SIGNAL_PTHREAD_KILL_METHODDEF #define SIGNAL_PTHREAD_KILL_METHODDEF #endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */ -/*[clinic end generated code: output=dafa598412bfb8d2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c6990ef0d0ba72b6 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/spwdmodule.c.h b/Modules/clinic/spwdmodule.c.h index e26acf1..b2479ff 100644 --- a/Modules/clinic/spwdmodule.c.h +++ b/Modules/clinic/spwdmodule.c.h @@ -24,8 +24,9 @@ spwd_getspnam(PyObject *module, PyObject *arg_) PyObject *return_value = NULL; PyObject *arg; - if (!PyArg_Parse(arg_, "U:getspnam", &arg)) + if (!PyArg_Parse(arg_, "U:getspnam", &arg)) { goto exit; + } return_value = spwd_getspnam_impl(module, arg); exit: @@ -65,4 +66,4 @@ spwd_getspall(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SPWD_GETSPALL_METHODDEF #define SPWD_GETSPALL_METHODDEF #endif /* !defined(SPWD_GETSPALL_METHODDEF) */ -/*[clinic end generated code: output=510f681b36f54c30 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=07cd8af0afd77fe7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h index d520c1e..d481ccb 100644 --- a/Modules/clinic/unicodedata.c.h +++ b/Modules/clinic/unicodedata.c.h @@ -27,8 +27,9 @@ unicodedata_UCD_decimal(PyObject *self, PyObject *args) PyObject *default_value = NULL; if (!PyArg_ParseTuple(args, "C|O:decimal", - &chr, &default_value)) + &chr, &default_value)) { goto exit; + } return_value = unicodedata_UCD_decimal_impl(self, chr, default_value); exit: @@ -59,8 +60,9 @@ unicodedata_UCD_digit(PyObject *self, PyObject *args) PyObject *default_value = NULL; if (!PyArg_ParseTuple(args, "C|O:digit", - &chr, &default_value)) + &chr, &default_value)) { goto exit; + } return_value = unicodedata_UCD_digit_impl(self, chr, default_value); exit: @@ -92,8 +94,9 @@ unicodedata_UCD_numeric(PyObject *self, PyObject *args) PyObject *default_value = NULL; if (!PyArg_ParseTuple(args, "C|O:numeric", - &chr, &default_value)) + &chr, &default_value)) { goto exit; + } return_value = unicodedata_UCD_numeric_impl(self, chr, default_value); exit: @@ -118,8 +121,9 @@ unicodedata_UCD_category(PyObject *self, PyObject *arg) PyObject *return_value = NULL; int chr; - if (!PyArg_Parse(arg, "C:category", &chr)) + if (!PyArg_Parse(arg, "C:category", &chr)) { goto exit; + } return_value = unicodedata_UCD_category_impl(self, chr); exit: @@ -146,8 +150,9 @@ unicodedata_UCD_bidirectional(PyObject *self, PyObject *arg) PyObject *return_value = NULL; int chr; - if (!PyArg_Parse(arg, "C:bidirectional", &chr)) + if (!PyArg_Parse(arg, "C:bidirectional", &chr)) { goto exit; + } return_value = unicodedata_UCD_bidirectional_impl(self, chr); exit: @@ -175,11 +180,13 @@ unicodedata_UCD_combining(PyObject *self, PyObject *arg) int chr; int _return_value; - if (!PyArg_Parse(arg, "C:combining", &chr)) + if (!PyArg_Parse(arg, "C:combining", &chr)) { goto exit; + } _return_value = unicodedata_UCD_combining_impl(self, chr); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -208,11 +215,13 @@ unicodedata_UCD_mirrored(PyObject *self, PyObject *arg) int chr; int _return_value; - if (!PyArg_Parse(arg, "C:mirrored", &chr)) + if (!PyArg_Parse(arg, "C:mirrored", &chr)) { goto exit; + } _return_value = unicodedata_UCD_mirrored_impl(self, chr); - if ((_return_value == -1) && PyErr_Occurred()) + if ((_return_value == -1) && PyErr_Occurred()) { goto exit; + } return_value = PyLong_FromLong((long)_return_value); exit: @@ -237,8 +246,9 @@ unicodedata_UCD_east_asian_width(PyObject *self, PyObject *arg) PyObject *return_value = NULL; int chr; - if (!PyArg_Parse(arg, "C:east_asian_width", &chr)) + if (!PyArg_Parse(arg, "C:east_asian_width", &chr)) { goto exit; + } return_value = unicodedata_UCD_east_asian_width_impl(self, chr); exit: @@ -265,8 +275,9 @@ unicodedata_UCD_decomposition(PyObject *self, PyObject *arg) PyObject *return_value = NULL; int chr; - if (!PyArg_Parse(arg, "C:decomposition", &chr)) + if (!PyArg_Parse(arg, "C:decomposition", &chr)) { goto exit; + } return_value = unicodedata_UCD_decomposition_impl(self, chr); exit: @@ -296,8 +307,9 @@ unicodedata_UCD_normalize(PyObject *self, PyObject *args) PyObject *input; if (!PyArg_ParseTuple(args, "sO!:normalize", - &form, &PyUnicode_Type, &input)) + &form, &PyUnicode_Type, &input)) { goto exit; + } return_value = unicodedata_UCD_normalize_impl(self, form, input); exit: @@ -327,8 +339,9 @@ unicodedata_UCD_name(PyObject *self, PyObject *args) PyObject *default_value = NULL; if (!PyArg_ParseTuple(args, "C|O:name", - &chr, &default_value)) + &chr, &default_value)) { goto exit; + } return_value = unicodedata_UCD_name_impl(self, chr, default_value); exit: @@ -358,11 +371,12 @@ unicodedata_UCD_lookup(PyObject *self, PyObject *arg) const char *name; Py_ssize_clean_t name_length; - if (!PyArg_Parse(arg, "s#:lookup", &name, &name_length)) + if (!PyArg_Parse(arg, "s#:lookup", &name, &name_length)) { goto exit; + } return_value = unicodedata_UCD_lookup_impl(self, name, name_length); exit: return return_value; } -/*[clinic end generated code: output=4f8da33c6bc6efc9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5313ce129da87b2f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index b1af7ce..172308a 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -3,44 +3,48 @@ preserve [clinic start generated code]*/ PyDoc_STRVAR(zlib_compress__doc__, -"compress($module, bytes, level=Z_DEFAULT_COMPRESSION, /)\n" +"compress($module, data, /, level=Z_DEFAULT_COMPRESSION)\n" "--\n" "\n" "Returns a bytes object containing compressed data.\n" "\n" -" bytes\n" +" data\n" " Binary data to be compressed.\n" " level\n" -" Compression level, in 0-9."); +" Compression level, in 0-9 or -1."); #define ZLIB_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)zlib_compress, METH_VARARGS, zlib_compress__doc__}, + {"compress", (PyCFunction)zlib_compress, METH_VARARGS|METH_KEYWORDS, zlib_compress__doc__}, static PyObject * -zlib_compress_impl(PyObject *module, Py_buffer *bytes, int level); +zlib_compress_impl(PyObject *module, Py_buffer *data, int level); static PyObject * -zlib_compress(PyObject *module, PyObject *args) +zlib_compress(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - Py_buffer bytes = {NULL, NULL}; + static const char * const _keywords[] = {"", "level", NULL}; + static _PyArg_Parser _parser = {"y*|i:compress", _keywords, 0}; + Py_buffer data = {NULL, NULL}; int level = Z_DEFAULT_COMPRESSION; - if (!PyArg_ParseTuple(args, "y*|i:compress", - &bytes, &level)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, &level)) { goto exit; - return_value = zlib_compress_impl(module, &bytes, level); + } + return_value = zlib_compress_impl(module, &data, level); exit: - /* Cleanup for bytes */ - if (bytes.obj) - PyBuffer_Release(&bytes); + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } return return_value; } PyDoc_STRVAR(zlib_decompress__doc__, -"decompress($module, data, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE, /)\n" +"decompress($module, data, /, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE)\n" "--\n" "\n" "Returns a bytes object containing the uncompressed data.\n" @@ -53,29 +57,33 @@ PyDoc_STRVAR(zlib_decompress__doc__, " The initial output buffer size."); #define ZLIB_DECOMPRESS_METHODDEF \ - {"decompress", (PyCFunction)zlib_decompress, METH_VARARGS, zlib_decompress__doc__}, + {"decompress", (PyCFunction)zlib_decompress, METH_VARARGS|METH_KEYWORDS, zlib_decompress__doc__}, static PyObject * zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, Py_ssize_t bufsize); static PyObject * -zlib_decompress(PyObject *module, PyObject *args) +zlib_decompress(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "wbits", "bufsize", NULL}; + static _PyArg_Parser _parser = {"y*|iO&:decompress", _keywords, 0}; Py_buffer data = {NULL, NULL}; int wbits = MAX_WBITS; Py_ssize_t bufsize = DEF_BUF_SIZE; - if (!PyArg_ParseTuple(args, "y*|iO&:decompress", - &data, &wbits, ssize_t_converter, &bufsize)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, &wbits, ssize_t_converter, &bufsize)) { goto exit; + } return_value = zlib_decompress_impl(module, &data, wbits, bufsize); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -121,7 +129,8 @@ static PyObject * zlib_compressobj(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; + static const char * const _keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; + static _PyArg_Parser _parser = {"|iiiiiy*:compressobj", _keywords, 0}; int level = Z_DEFAULT_COMPRESSION; int method = DEFLATED; int wbits = MAX_WBITS; @@ -129,15 +138,17 @@ zlib_compressobj(PyObject *module, PyObject *args, PyObject *kwargs) int strategy = Z_DEFAULT_STRATEGY; Py_buffer zdict = {NULL, NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiiiiy*:compressobj", _keywords, - &level, &method, &wbits, &memLevel, &strategy, &zdict)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &level, &method, &wbits, &memLevel, &strategy, &zdict)) { goto exit; + } return_value = zlib_compressobj_impl(module, level, method, wbits, memLevel, strategy, &zdict); exit: /* Cleanup for zdict */ - if (zdict.obj) + if (zdict.obj) { PyBuffer_Release(&zdict); + } return return_value; } @@ -164,13 +175,15 @@ static PyObject * zlib_decompressobj(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static char *_keywords[] = {"wbits", "zdict", NULL}; + static const char * const _keywords[] = {"wbits", "zdict", NULL}; + static _PyArg_Parser _parser = {"|iO:decompressobj", _keywords, 0}; int wbits = MAX_WBITS; PyObject *zdict = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:decompressobj", _keywords, - &wbits, &zdict)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &wbits, &zdict)) { goto exit; + } return_value = zlib_decompressobj_impl(module, wbits, zdict); exit: @@ -202,20 +215,22 @@ zlib_Compress_compress(compobject *self, PyObject *arg) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; - if (!PyArg_Parse(arg, "y*:compress", &data)) + if (!PyArg_Parse(arg, "y*:compress", &data)) { goto exit; + } return_value = zlib_Compress_compress_impl(self, &data); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } PyDoc_STRVAR(zlib_Decompress_decompress__doc__, -"decompress($self, data, max_length=0, /)\n" +"decompress($self, data, /, max_length=0)\n" "--\n" "\n" "Return a bytes object containing the decompressed version of the data.\n" @@ -232,28 +247,32 @@ PyDoc_STRVAR(zlib_Decompress_decompress__doc__, "Call the flush() method to clear these buffers."); #define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \ - {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__}, + {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS|METH_KEYWORDS, zlib_Decompress_decompress__doc__}, static PyObject * zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, Py_ssize_t max_length); static PyObject * -zlib_Decompress_decompress(compobject *self, PyObject *args) +zlib_Decompress_decompress(compobject *self, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "max_length", NULL}; + static _PyArg_Parser _parser = {"y*|O&:decompress", _keywords, 0}; Py_buffer data = {NULL, NULL}; Py_ssize_t max_length = 0; - if (!PyArg_ParseTuple(args, "y*|O&:decompress", - &data, ssize_t_converter, &max_length)) + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &data, ssize_t_converter, &max_length)) { goto exit; + } return_value = zlib_Decompress_decompress_impl(self, &data, max_length); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -283,8 +302,9 @@ zlib_Compress_flush(compobject *self, PyObject *args) int mode = Z_FINISH; if (!PyArg_ParseTuple(args, "|i:flush", - &mode)) + &mode)) { goto exit; + } return_value = zlib_Compress_flush_impl(self, mode); exit: @@ -357,8 +377,9 @@ zlib_Decompress_flush(compobject *self, PyObject *args) Py_ssize_t length = DEF_BUF_SIZE; if (!PyArg_ParseTuple(args, "|O&:flush", - ssize_t_converter, &length)) + ssize_t_converter, &length)) { goto exit; + } return_value = zlib_Decompress_flush_impl(self, length); exit: @@ -390,14 +411,16 @@ zlib_adler32(PyObject *module, PyObject *args) unsigned int value = 1; if (!PyArg_ParseTuple(args, "y*|I:adler32", - &data, &value)) + &data, &value)) { goto exit; + } return_value = zlib_adler32_impl(module, &data, value); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -427,14 +450,16 @@ zlib_crc32(PyObject *module, PyObject *args) unsigned int value = 0; if (!PyArg_ParseTuple(args, "y*|I:crc32", - &data, &value)) + &data, &value)) { goto exit; + } return_value = zlib_crc32_impl(module, &data, value); exit: /* Cleanup for data */ - if (data.obj) + if (data.obj) { PyBuffer_Release(&data); + } return return_value; } @@ -442,4 +467,4 @@ exit: #ifndef ZLIB_COMPRESS_COPY_METHODDEF #define ZLIB_COMPRESS_COPY_METHODDEF #endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */ -/*[clinic end generated code: output=7711ef02d1d5776c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=48911ef429b65903 input=a9049054013a1b77]*/ diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index cba42a7..8319767 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -81,6 +81,54 @@ else { #endif #define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2) +/* Constants cmath.inf, cmath.infj, cmath.nan, cmath.nanj. + cmath.nan and cmath.nanj are defined only when either + PY_NO_SHORT_FLOAT_REPR is *not* defined (which should be + the most common situation on machines using an IEEE 754 + representation), or Py_NAN is defined. */ + +static double +m_inf(void) +{ +#ifndef PY_NO_SHORT_FLOAT_REPR + return _Py_dg_infinity(0); +#else + return Py_HUGE_VAL; +#endif +} + +static Py_complex +c_infj(void) +{ + Py_complex r; + r.real = 0.0; + r.imag = m_inf(); + return r; +} + +#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) + +static double +m_nan(void) +{ +#ifndef PY_NO_SHORT_FLOAT_REPR + return _Py_dg_stdnan(0); +#else + return Py_NAN; +#endif +} + +static Py_complex +c_nanj(void) +{ + Py_complex r; + r.real = 0.0; + r.imag = m_nan(); + return r; +} + +#endif + /* forward declarations */ static Py_complex cmath_asinh_impl(PyObject *, Py_complex); static Py_complex cmath_atanh_impl(PyObject *, Py_complex); @@ -1239,6 +1287,13 @@ PyInit_cmath(void) PyModule_AddObject(m, "pi", PyFloat_FromDouble(Py_MATH_PI)); PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); + PyModule_AddObject(m, "tau", PyFloat_FromDouble(Py_MATH_TAU)); /* 2pi */ + PyModule_AddObject(m, "inf", PyFloat_FromDouble(m_inf())); + PyModule_AddObject(m, "infj", PyComplex_FromCComplex(c_infj())); +#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) + PyModule_AddObject(m, "nan", PyFloat_FromDouble(m_nan())); + PyModule_AddObject(m, "nanj", PyComplex_FromCComplex(c_nanj())); +#endif /* initialize special value tables */ diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index f1fda48..1c1e4fb 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -119,7 +119,7 @@ static fault_handler_t faulthandler_handlers[] = { handler fails in faulthandler_fatal_error() */ {SIGSEGV, 0, "Segmentation fault", } }; -static const unsigned char faulthandler_nsignals = \ +static const size_t faulthandler_nsignals = \ Py_ARRAY_LENGTH(faulthandler_handlers); #ifdef HAVE_SIGALTSTACK @@ -159,7 +159,7 @@ faulthandler_get_fileno(PyObject **file_ptr) fd = _PyLong_AsInt(file); if (fd == -1 && PyErr_Occurred()) return -1; - if (fd < 0 || !_PyVerify_fd(fd)) { + if (fd < 0) { PyErr_SetString(PyExc_ValueError, "file is not a valid file descripter"); return -1; @@ -168,7 +168,7 @@ faulthandler_get_fileno(PyObject **file_ptr) return fd; } - result = _PyObject_CallMethodId(file, &PyId_fileno, ""); + result = _PyObject_CallMethodId(file, &PyId_fileno, NULL); if (result == NULL) return -1; @@ -186,7 +186,7 @@ faulthandler_get_fileno(PyObject **file_ptr) return -1; } - result = _PyObject_CallMethodId(file, &PyId_flush, ""); + result = _PyObject_CallMethodId(file, &PyId_flush, NULL); if (result != NULL) Py_DECREF(result); else { @@ -202,8 +202,9 @@ faulthandler_get_fileno(PyObject **file_ptr) static PyThreadState* get_thread_state(void) { - PyThreadState *tstate = PyThreadState_Get(); + PyThreadState *tstate = _PyThreadState_UncheckedGet(); if (tstate == NULL) { + /* just in case but very unlikely... */ PyErr_SetString(PyExc_RuntimeError, "unable to get the current thread state"); return NULL; @@ -234,11 +235,12 @@ faulthandler_dump_traceback(int fd, int all_threads, PyGILState_GetThisThreadState(). */ tstate = PyGILState_GetThisThreadState(); #else - tstate = PyThreadState_Get(); + tstate = _PyThreadState_UncheckedGet(); #endif - if (all_threads) - _Py_DumpTracebackThreads(fd, interp, tstate); + if (all_threads) { + (void)_Py_DumpTracebackThreads(fd, NULL, tstate); + } else { if (tstate != NULL) _Py_DumpTraceback(fd, tstate); @@ -272,7 +274,7 @@ faulthandler_dump_traceback_py(PyObject *self, return NULL; if (all_threads) { - errmsg = _Py_DumpTracebackThreads(fd, tstate->interp, tstate); + errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate); if (errmsg != NULL) { PyErr_SetString(PyExc_RuntimeError, errmsg); return NULL; @@ -288,6 +290,19 @@ faulthandler_dump_traceback_py(PyObject *self, Py_RETURN_NONE; } +static void +faulthandler_disable_fatal_handler(fault_handler_t *handler) +{ + if (!handler->enabled) + return; + handler->enabled = 0; +#ifdef HAVE_SIGACTION + (void)sigaction(handler->signum, &handler->previous, NULL); +#else + (void)signal(handler->signum, handler->previous); +#endif +} + /* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals. @@ -306,7 +321,7 @@ static void faulthandler_fatal_error(int signum) { const int fd = fatal_error.fd; - unsigned int i; + size_t i; fault_handler_t *handler = NULL; int save_errno = errno; @@ -324,12 +339,7 @@ faulthandler_fatal_error(int signum) } /* restore the previous handler */ -#ifdef HAVE_SIGACTION - (void)sigaction(signum, &handler->previous, NULL); -#else - (void)signal(signum, handler->previous); -#endif - handler->enabled = 0; + faulthandler_disable_fatal_handler(handler); PUTS(fd, "Fatal Python error: "); PUTS(fd, handler->name); @@ -351,20 +361,117 @@ faulthandler_fatal_error(int signum) raise(signum); } +#ifdef MS_WINDOWS +static LONG WINAPI +faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info) +{ + const int fd = fatal_error.fd; + DWORD code = exc_info->ExceptionRecord->ExceptionCode; + DWORD flags = exc_info->ExceptionRecord->ExceptionFlags; + + /* only log fatal exceptions */ + if (flags & EXCEPTION_NONCONTINUABLE) { + /* call the next exception handler */ + return EXCEPTION_CONTINUE_SEARCH; + } + + PUTS(fd, "Windows fatal exception: "); + switch (code) + { + /* only format most common errors */ + case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break; + case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break; + case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break; + case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break; + case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break; + default: + PUTS(fd, "code "); + _Py_DumpDecimal(fd, code); + } + PUTS(fd, "\n\n"); + + if (code == EXCEPTION_ACCESS_VIOLATION) { + /* disable signal handler for SIGSEGV */ + size_t i; + for (i=0; i < faulthandler_nsignals; i++) { + fault_handler_t *handler = &faulthandler_handlers[i]; + if (handler->signum == SIGSEGV) { + faulthandler_disable_fatal_handler(handler); + break; + } + } + } + + faulthandler_dump_traceback(fd, fatal_error.all_threads, + fatal_error.interp); + + /* call the next exception handler */ + return EXCEPTION_CONTINUE_SEARCH; +} +#endif + /* Install the handler for fatal signals, faulthandler_fatal_error(). */ +static int +faulthandler_enable(void) +{ + size_t i; + + if (fatal_error.enabled) { + return 0; + } + fatal_error.enabled = 1; + + for (i=0; i < faulthandler_nsignals; i++) { + fault_handler_t *handler; +#ifdef HAVE_SIGACTION + struct sigaction action; +#endif + int err; + + handler = &faulthandler_handlers[i]; + assert(!handler->enabled); +#ifdef HAVE_SIGACTION + action.sa_handler = faulthandler_fatal_error; + sigemptyset(&action.sa_mask); + /* Do not prevent the signal from being received from within + its own signal handler */ + action.sa_flags = SA_NODEFER; +#ifdef HAVE_SIGALTSTACK + if (stack.ss_sp != NULL) { + /* Call the signal handler on an alternate signal stack + provided by sigaltstack() */ + action.sa_flags |= SA_ONSTACK; + } +#endif + err = sigaction(handler->signum, &action, &handler->previous); +#else + handler->previous = signal(handler->signum, + faulthandler_fatal_error); + err = (handler->previous == SIG_ERR); +#endif + if (err) { + PyErr_SetFromErrno(PyExc_RuntimeError); + return -1; + } + + handler->enabled = 1; + } + +#ifdef MS_WINDOWS + AddVectoredExceptionHandler(1, faulthandler_exc_handler); +#endif + return 0; +} + static PyObject* -faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs) +faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = {"file", "all_threads", NULL}; PyObject *file = NULL; int all_threads = 1; - unsigned int i; - fault_handler_t *handler; -#ifdef HAVE_SIGACTION - struct sigaction action; -#endif - int err; int fd; PyThreadState *tstate; @@ -386,37 +493,10 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs) fatal_error.all_threads = all_threads; fatal_error.interp = tstate->interp; - if (!fatal_error.enabled) { - fatal_error.enabled = 1; - - for (i=0; i < faulthandler_nsignals; i++) { - handler = &faulthandler_handlers[i]; -#ifdef HAVE_SIGACTION - action.sa_handler = faulthandler_fatal_error; - sigemptyset(&action.sa_mask); - /* Do not prevent the signal from being received from within - its own signal handler */ - action.sa_flags = SA_NODEFER; -#ifdef HAVE_SIGALTSTACK - if (stack.ss_sp != NULL) { - /* Call the signal handler on an alternate signal stack - provided by sigaltstack() */ - action.sa_flags |= SA_ONSTACK; - } -#endif - err = sigaction(handler->signum, &action, &handler->previous); -#else - handler->previous = signal(handler->signum, - faulthandler_fatal_error); - err = (handler->previous == SIG_ERR); -#endif - if (err) { - PyErr_SetFromErrno(PyExc_RuntimeError); - return NULL; - } - handler->enabled = 1; - } + if (faulthandler_enable() < 0) { + return NULL; } + Py_RETURN_NONE; } @@ -430,14 +510,7 @@ faulthandler_disable(void) fatal_error.enabled = 0; for (i=0; i < faulthandler_nsignals; i++) { handler = &faulthandler_handlers[i]; - if (!handler->enabled) - continue; -#ifdef HAVE_SIGACTION - (void)sigaction(handler->signum, &handler->previous, NULL); -#else - (void)signal(handler->signum, handler->previous); -#endif - handler->enabled = 0; + faulthandler_disable_fatal_handler(handler); } } @@ -469,7 +542,6 @@ faulthandler_thread(void *unused) { PyLockStatus st; const char* errmsg; - PyThreadState *current; int ok; #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) sigset_t set; @@ -489,12 +561,9 @@ faulthandler_thread(void *unused) /* Timeout => dump traceback */ assert(st == PY_LOCK_FAILURE); - /* get the thread holding the GIL, NULL if no thread hold the GIL */ - current = _PyThreadState_UncheckedGet(); - _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len); - errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current); + errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL); ok = (errmsg == NULL); if (thread.exit) @@ -894,7 +963,7 @@ static PyObject * faulthandler_sigsegv(PyObject *self, PyObject *args) { int release_gil = 0; - if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil)) + if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil)) return NULL; if (release_gil) { @@ -907,6 +976,49 @@ faulthandler_sigsegv(PyObject *self, PyObject *args) Py_RETURN_NONE; } +#ifdef WITH_THREAD +static void +faulthandler_fatal_error_thread(void *plock) +{ + PyThread_type_lock *lock = (PyThread_type_lock *)plock; + + Py_FatalError("in new thread"); + + /* notify the caller that we are done */ + PyThread_release_lock(lock); +} + +static PyObject * +faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) +{ + long thread; + PyThread_type_lock lock; + + faulthandler_suppress_crash_report(); + + lock = PyThread_allocate_lock(); + if (lock == NULL) + return PyErr_NoMemory(); + + PyThread_acquire_lock(lock, WAIT_LOCK); + + thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock); + if (thread == -1) { + PyThread_free_lock(lock); + PyErr_SetString(PyExc_RuntimeError, "unable to start the thread"); + return NULL; + } + + /* wait until the thread completes: it will never occur, since Py_FatalError() + exits the process immedialty. */ + PyThread_acquire_lock(lock, WAIT_LOCK); + PyThread_release_lock(lock); + PyThread_free_lock(lock); + + Py_RETURN_NONE; +} +#endif + static PyObject * faulthandler_sigfpe(PyObject *self, PyObject *args) { @@ -951,6 +1063,8 @@ faulthandler_fatal_error_py(PyObject *self, PyObject *args) } #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) +#define FAULTHANDLER_STACK_OVERFLOW + #ifdef __INTEL_COMPILER /* Issue #23654: Turn off ICC's tail call optimization for the * stack_overflow generator. ICC turns the recursive tail call into @@ -958,12 +1072,12 @@ faulthandler_fatal_error_py(PyObject *self, PyObject *args) # pragma intel optimization_level 0 #endif static -Py_uintptr_t -stack_overflow(Py_uintptr_t min_sp, Py_uintptr_t max_sp, size_t *depth) +uintptr_t +stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth) { /* allocate 4096 bytes on the stack at each call */ unsigned char buffer[4096]; - Py_uintptr_t sp = (Py_uintptr_t)&buffer; + uintptr_t sp = (uintptr_t)&buffer; *depth += 1; if (sp < min_sp || max_sp < sp) return sp; @@ -976,8 +1090,8 @@ static PyObject * faulthandler_stack_overflow(PyObject *self) { size_t depth, size; - Py_uintptr_t sp = (Py_uintptr_t)&depth; - Py_uintptr_t stop; + uintptr_t sp = (uintptr_t)&depth; + uintptr_t stop; faulthandler_suppress_crash_report(); depth = 0; @@ -994,7 +1108,7 @@ faulthandler_stack_overflow(PyObject *self) size, depth); return NULL; } -#endif +#endif /* defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) */ static int @@ -1017,12 +1131,25 @@ faulthandler_traverse(PyObject *module, visitproc visit, void *arg) return 0; } +#ifdef MS_WINDOWS +static PyObject * +faulthandler_raise_exception(PyObject *self, PyObject *args) +{ + unsigned int code, flags = 0; + if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags)) + return NULL; + faulthandler_suppress_crash_report(); + RaiseException(code, flags, 0, NULL); + Py_RETURN_NONE; +} +#endif + PyDoc_STRVAR(module_doc, "faulthandler module."); static PyMethodDef module_methods[] = { {"enable", - (PyCFunction)faulthandler_enable, METH_VARARGS|METH_KEYWORDS, + (PyCFunction)faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("enable(file=sys.stderr, all_threads=True): " "enable the fault handler")}, {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS, @@ -1065,16 +1192,25 @@ static PyMethodDef module_methods[] = { "a SIGSEGV or SIGBUS signal depending on the platform")}, {"_sigsegv", faulthandler_sigsegv, METH_VARARGS, PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")}, +#ifdef WITH_THREAD + {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS, + PyDoc_STR("fatal_error_c_thread(): " + "call Py_FatalError() in a new C thread.")}, +#endif {"_sigabrt", faulthandler_sigabrt, METH_NOARGS, PyDoc_STR("_sigabrt(): raise a SIGABRT signal")}, {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS, PyDoc_STR("_sigfpe(): raise a SIGFPE signal")}, {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS, PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")}, -#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) +#ifdef FAULTHANDLER_STACK_OVERFLOW {"_stack_overflow", (PyCFunction)faulthandler_stack_overflow, METH_NOARGS, PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")}, #endif +#ifdef MS_WINDOWS + {"_raise_exception", faulthandler_raise_exception, METH_VARARGS, + PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")}, +#endif {NULL, NULL} /* sentinel */ }; @@ -1093,7 +1229,33 @@ static struct PyModuleDef module_def = { PyMODINIT_FUNC PyInit_faulthandler(void) { - return PyModule_Create(&module_def); + PyObject *m = PyModule_Create(&module_def); + if (m == NULL) + return NULL; + + /* Add constants for unit tests */ +#ifdef MS_WINDOWS + /* RaiseException() codes (prefixed by an underscore) */ + if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION", + EXCEPTION_ACCESS_VIOLATION)) + return NULL; + if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO", + EXCEPTION_INT_DIVIDE_BY_ZERO)) + return NULL; + if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW", + EXCEPTION_STACK_OVERFLOW)) + return NULL; + + /* RaiseException() flags (prefixed by an underscore) */ + if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE", + EXCEPTION_NONCONTINUABLE)) + return NULL; + if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", + EXCEPTION_NONCONTINUABLE_EXCEPTION)) + return NULL; +#endif + + return m; } /* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable @@ -1128,7 +1290,7 @@ faulthandler_env_options(void) if (module == NULL) { return -1; } - res = _PyObject_CallMethodId(module, &PyId_enable, ""); + res = _PyObject_CallMethodId(module, &PyId_enable, NULL); Py_DECREF(module); if (res == NULL) return -1; diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index cb7222d..07950a6 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -738,7 +738,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) } static void -debug_cycle(char *msg, PyObject *op) +debug_cycle(const char *msg, PyObject *op) { PySys_FormatStderr("gc: %s <%s %p>\n", msg, Py_TYPE(op)->tp_name, op); @@ -892,6 +892,7 @@ clear_freelists(void) (void)PyList_ClearFreeList(); (void)PyDict_ClearFreeList(); (void)PySet_ClearFreeList(); + (void)PyAsyncGen_ClearFreeLists(); } /* This is the main function. Read this to understand how the diff --git a/Modules/getaddrinfo.c b/Modules/getaddrinfo.c index d8167ea..b6fb53c 100644 --- a/Modules/getaddrinfo.c +++ b/Modules/getaddrinfo.c @@ -136,7 +136,7 @@ static int get_addr(const char *, int, struct addrinfo **, struct addrinfo *, int); static int str_isnumber(const char *); -static char *ai_errlist[] = { +static const char * const ai_errlist[] = { "success.", "address family for hostname not supported.", /* EAI_ADDRFAMILY */ "temporary failure in name resolution.", /* EAI_AGAIN */ @@ -198,7 +198,7 @@ if (pai->ai_flags & AI_CANONNAME) {\ #define ERR(err) { error = (err); goto bad; } -char * +const char * gai_strerror(int ecode) { if (ecode < 0 || ecode > EAI_MAX) diff --git a/Modules/getpath.c b/Modules/getpath.c index 18deb60..65b47a3 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -460,8 +460,8 @@ calculate_path(void) { extern wchar_t *Py_GetProgramName(void); - static wchar_t delimiter[2] = {DELIM, '\0'}; - static wchar_t separator[2] = {SEP, '\0'}; + static const wchar_t delimiter[2] = {DELIM, '\0'}; + static const wchar_t separator[2] = {SEP, '\0'}; char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */ wchar_t *rtpypath = NULL; wchar_t *home = Py_GetPythonHome(); diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index 3a134a0..9437ae7 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -100,14 +100,25 @@ grp_getgrgid_impl(PyObject *module, PyObject *id) gid_t gid; struct group *p; - py_int_id = PyNumber_Long(id); - if (!py_int_id) + if (!_Py_Gid_Converter(id, &gid)) { + if (!PyErr_ExceptionMatches(PyExc_TypeError)) { return NULL; - if (!_Py_Gid_Converter(py_int_id, &gid)) { + } + PyErr_Clear(); + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "group id must be int, not %.200", + id->ob_type->tp_name) < 0) { + return NULL; + } + py_int_id = PyNumber_Long(id); + if (!py_int_id) + return NULL; + if (!_Py_Gid_Converter(py_int_id, &gid)) { + Py_DECREF(py_int_id); + return NULL; + } Py_DECREF(py_int_id); - return NULL; } - Py_DECREF(py_int_id); if ((p = getgrgid(gid)) == NULL) { PyObject *gid_obj = _PyLong_FromGid(gid); diff --git a/Modules/hashlib.h b/Modules/hashlib.h index 3580453..530b6b1 100644 --- a/Modules/hashlib.h +++ b/Modules/hashlib.h @@ -2,30 +2,33 @@ /* * Given a PyObject* obj, fill in the Py_buffer* viewp with the result - * of PyObject_GetBuffer. Sets an exception and issues a return NULL - * on any errors. + * of PyObject_GetBuffer. Sets an exception and issues the erraction + * on any errors, e.g. 'return NULL' or 'goto error'. */ -#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) do { \ +#define GET_BUFFER_VIEW_OR_ERROR(obj, viewp, erraction) do { \ if (PyUnicode_Check((obj))) { \ PyErr_SetString(PyExc_TypeError, \ "Unicode-objects must be encoded before hashing");\ - return NULL; \ + erraction; \ } \ if (!PyObject_CheckBuffer((obj))) { \ PyErr_SetString(PyExc_TypeError, \ "object supporting the buffer API required"); \ - return NULL; \ + erraction; \ } \ if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \ - return NULL; \ + erraction; \ } \ if ((viewp)->ndim > 1) { \ PyErr_SetString(PyExc_BufferError, \ "Buffer must be single dimension"); \ PyBuffer_Release((viewp)); \ - return NULL; \ + erraction; \ } \ - } while(0); + } while(0) + +#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \ + GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL) /* * Helper code to synchronize access to the hash object when the GIL is diff --git a/Modules/hashtable.c b/Modules/hashtable.c index fdddc19..3462fef 100644 --- a/Modules/hashtable.c +++ b/Modules/hashtable.c @@ -1,5 +1,5 @@ -/* The implementation of the hash table (_Py_hashtable_t) is based on the cfuhash - project: +/* The implementation of the hash table (_Py_hashtable_t) is based on the + cfuhash project: http://sourceforge.net/projects/libcfu/ Copyright of cfuhash: @@ -59,7 +59,21 @@ #define ENTRY_NEXT(ENTRY) \ ((_Py_hashtable_entry_t *)_Py_SLIST_ITEM_NEXT(ENTRY)) #define HASHTABLE_ITEM_SIZE(HT) \ - (sizeof(_Py_hashtable_entry_t) + (HT)->data_size) + (sizeof(_Py_hashtable_entry_t) + (HT)->key_size + (HT)->data_size) + +#define ENTRY_READ_PDATA(TABLE, ENTRY, DATA_SIZE, PDATA) \ + do { \ + assert((DATA_SIZE) == (TABLE)->data_size); \ + Py_MEMCPY((PDATA), _Py_HASHTABLE_ENTRY_PDATA(TABLE, (ENTRY)), \ + (DATA_SIZE)); \ + } while (0) + +#define ENTRY_WRITE_PDATA(TABLE, ENTRY, DATA_SIZE, PDATA) \ + do { \ + assert((DATA_SIZE) == (TABLE)->data_size); \ + Py_MEMCPY((void *)_Py_HASHTABLE_ENTRY_PDATA((TABLE), (ENTRY)), \ + (PDATA), (DATA_SIZE)); \ + } while (0) /* Forward declaration */ static void hashtable_rehash(_Py_hashtable_t *ht); @@ -70,6 +84,7 @@ _Py_slist_init(_Py_slist_t *list) list->head = NULL; } + static void _Py_slist_prepend(_Py_slist_t *list, _Py_slist_item_t *item) { @@ -77,6 +92,7 @@ _Py_slist_prepend(_Py_slist_t *list, _Py_slist_item_t *item) list->head = item; } + static void _Py_slist_remove(_Py_slist_t *list, _Py_slist_item_t *previous, _Py_slist_item_t *item) @@ -87,24 +103,26 @@ _Py_slist_remove(_Py_slist_t *list, _Py_slist_item_t *previous, list->head = item->next; } -Py_uhash_t -_Py_hashtable_hash_int(const void *key) -{ - return (Py_uhash_t)key; -} Py_uhash_t -_Py_hashtable_hash_ptr(const void *key) +_Py_hashtable_hash_ptr(struct _Py_hashtable_t *ht, const void *pkey) { - return (Py_uhash_t)_Py_HashPointer((void *)key); + void *key; + + _Py_HASHTABLE_READ_KEY(ht, pkey, key); + return (Py_uhash_t)_Py_HashPointer(key); } + int -_Py_hashtable_compare_direct(const void *key, const _Py_hashtable_entry_t *entry) +_Py_hashtable_compare_direct(_Py_hashtable_t *ht, const void *pkey, + const _Py_hashtable_entry_t *entry) { - return entry->key == key; + const void *pkey2 = _Py_HASHTABLE_ENTRY_PKEY(entry); + return (memcmp(pkey, pkey2, ht->key_size) == 0); } + /* makes sure the real size of the buckets array is a power of 2 */ static size_t round_size(size_t s) @@ -118,13 +136,12 @@ round_size(size_t s) return i; } + _Py_hashtable_t * -_Py_hashtable_new_full(size_t data_size, size_t init_size, +_Py_hashtable_new_full(size_t key_size, size_t data_size, + size_t init_size, _Py_hashtable_hash_func hash_func, _Py_hashtable_compare_func compare_func, - _Py_hashtable_copy_data_func copy_data_func, - _Py_hashtable_free_data_func free_data_func, - _Py_hashtable_get_data_size_func get_data_size_func, _Py_hashtable_allocator_t *allocator) { _Py_hashtable_t *ht; @@ -144,6 +161,7 @@ _Py_hashtable_new_full(size_t data_size, size_t init_size, ht->num_buckets = round_size(init_size); ht->entries = 0; + ht->key_size = key_size; ht->data_size = data_size; buckets_size = ht->num_buckets * sizeof(ht->buckets[0]); @@ -156,28 +174,27 @@ _Py_hashtable_new_full(size_t data_size, size_t init_size, ht->hash_func = hash_func; ht->compare_func = compare_func; - ht->copy_data_func = copy_data_func; - ht->free_data_func = free_data_func; - ht->get_data_size_func = get_data_size_func; ht->alloc = alloc; return ht; } + _Py_hashtable_t * -_Py_hashtable_new(size_t data_size, +_Py_hashtable_new(size_t key_size, size_t data_size, _Py_hashtable_hash_func hash_func, _Py_hashtable_compare_func compare_func) { - return _Py_hashtable_new_full(data_size, HASHTABLE_MIN_SIZE, + return _Py_hashtable_new_full(key_size, data_size, + HASHTABLE_MIN_SIZE, hash_func, compare_func, - NULL, NULL, NULL, NULL); + NULL); } + size_t _Py_hashtable_size(_Py_hashtable_t *ht) { size_t size; - size_t hv; size = sizeof(_Py_hashtable_t); @@ -187,22 +204,10 @@ _Py_hashtable_size(_Py_hashtable_t *ht) /* entries */ size += ht->entries * HASHTABLE_ITEM_SIZE(ht); - /* data linked from entries */ - if (ht->get_data_size_func) { - for (hv = 0; hv < ht->num_buckets; hv++) { - _Py_hashtable_entry_t *entry; - - for (entry = TABLE_HEAD(ht, hv); entry; entry = ENTRY_NEXT(entry)) { - void *data; - - data = _Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry); - size += ht->get_data_size_func(data); - } - } - } return size; } + #ifdef Py_DEBUG void _Py_hashtable_print_stats(_Py_hashtable_t *ht) @@ -243,38 +248,45 @@ _Py_hashtable_print_stats(_Py_hashtable_t *ht) } #endif -/* Get an entry. Return NULL if the key does not exist. */ + _Py_hashtable_entry_t * -_Py_hashtable_get_entry(_Py_hashtable_t *ht, const void *key) +_Py_hashtable_get_entry(_Py_hashtable_t *ht, + size_t key_size, const void *pkey) { Py_uhash_t key_hash; size_t index; _Py_hashtable_entry_t *entry; - key_hash = ht->hash_func(key); + assert(key_size == ht->key_size); + + key_hash = ht->hash_func(ht, pkey); index = key_hash & (ht->num_buckets - 1); for (entry = TABLE_HEAD(ht, index); entry != NULL; entry = ENTRY_NEXT(entry)) { - if (entry->key_hash == key_hash && ht->compare_func(key, entry)) + if (entry->key_hash == key_hash && ht->compare_func(ht, pkey, entry)) break; } return entry; } + static int -_hashtable_pop_entry(_Py_hashtable_t *ht, const void *key, void *data, size_t data_size) +_Py_hashtable_pop_entry(_Py_hashtable_t *ht, size_t key_size, const void *pkey, + void *data, size_t data_size) { Py_uhash_t key_hash; size_t index; _Py_hashtable_entry_t *entry, *previous; - key_hash = ht->hash_func(key); + assert(key_size == ht->key_size); + + key_hash = ht->hash_func(ht, pkey); index = key_hash & (ht->num_buckets - 1); previous = NULL; for (entry = TABLE_HEAD(ht, index); entry != NULL; entry = ENTRY_NEXT(entry)) { - if (entry->key_hash == key_hash && ht->compare_func(key, entry)) + if (entry->key_hash == key_hash && ht->compare_func(ht, pkey, entry)) break; previous = entry; } @@ -287,7 +299,7 @@ _hashtable_pop_entry(_Py_hashtable_t *ht, const void *key, void *data, size_t da ht->entries--; if (data != NULL) - _Py_HASHTABLE_ENTRY_READ_DATA(ht, data, data_size, entry); + ENTRY_READ_PDATA(ht, entry, data_size, data); ht->alloc.free(entry); if ((float)ht->entries / (float)ht->num_buckets < HASHTABLE_LOW) @@ -295,26 +307,27 @@ _hashtable_pop_entry(_Py_hashtable_t *ht, const void *key, void *data, size_t da return 1; } -/* Add a new entry to the hash. The key must not be present in the hash table. - Return 0 on success, -1 on memory error. */ + int -_Py_hashtable_set(_Py_hashtable_t *ht, const void *key, - void *data, size_t data_size) +_Py_hashtable_set(_Py_hashtable_t *ht, size_t key_size, const void *pkey, + size_t data_size, const void *data) { Py_uhash_t key_hash; size_t index; _Py_hashtable_entry_t *entry; + assert(key_size == ht->key_size); + assert(data != NULL || data_size == 0); #ifndef NDEBUG /* Don't write the assertion on a single line because it is interesting to know the duplicated entry if the assertion failed. The entry can be read using a debugger. */ - entry = _Py_hashtable_get_entry(ht, key); + entry = _Py_hashtable_get_entry(ht, key_size, pkey); assert(entry == NULL); #endif - key_hash = ht->hash_func(key); + key_hash = ht->hash_func(ht, pkey); index = key_hash & (ht->num_buckets - 1); entry = ht->alloc.malloc(HASHTABLE_ITEM_SIZE(ht)); @@ -323,12 +336,10 @@ _Py_hashtable_set(_Py_hashtable_t *ht, const void *key, return -1; } - entry->key = (void *)key; entry->key_hash = key_hash; - - assert(data_size == ht->data_size); + Py_MEMCPY((void *)_Py_HASHTABLE_ENTRY_PKEY(entry), pkey, ht->key_size); if (data) - memcpy(_Py_HASHTABLE_ENTRY_DATA(entry), data, data_size); + ENTRY_WRITE_PDATA(ht, entry, data_size, data); _Py_slist_prepend(&ht->buckets[index], (_Py_slist_item_t*)entry); ht->entries++; @@ -338,48 +349,50 @@ _Py_hashtable_set(_Py_hashtable_t *ht, const void *key, return 0; } -/* Get data from an entry. Copy entry data into data and return 1 if the entry - exists, return 0 if the entry does not exist. */ + int -_Py_hashtable_get(_Py_hashtable_t *ht, const void *key, void *data, size_t data_size) +_Py_hashtable_get(_Py_hashtable_t *ht, size_t key_size,const void *pkey, + size_t data_size, void *data) { _Py_hashtable_entry_t *entry; assert(data != NULL); - entry = _Py_hashtable_get_entry(ht, key); + entry = _Py_hashtable_get_entry(ht, key_size, pkey); if (entry == NULL) return 0; - _Py_HASHTABLE_ENTRY_READ_DATA(ht, data, data_size, entry); + ENTRY_READ_PDATA(ht, entry, data_size, data); return 1; } + int -_Py_hashtable_pop(_Py_hashtable_t *ht, const void *key, void *data, size_t data_size) +_Py_hashtable_pop(_Py_hashtable_t *ht, size_t key_size, const void *pkey, + size_t data_size, void *data) { assert(data != NULL); - assert(ht->free_data_func == NULL); - return _hashtable_pop_entry(ht, key, data, data_size); + return _Py_hashtable_pop_entry(ht, key_size, pkey, data, data_size); } -/* Delete an entry. The entry must exist. */ + +/* Code commented since the function is not needed in Python */ +#if 0 void -_Py_hashtable_delete(_Py_hashtable_t *ht, const void *key) +_Py_hashtable_delete(_Py_hashtable_t *ht, size_t key_size, const void *pkey) { #ifndef NDEBUG - int found = _hashtable_pop_entry(ht, key, NULL, 0); + int found = _Py_hashtable_pop_entry(ht, key_size, pkey, NULL, 0); assert(found); #else - (void)_hashtable_pop_entry(ht, key, NULL, 0); + (void)_Py_hashtable_pop_entry(ht, key_size, pkey, NULL, 0); #endif } +#endif + -/* Prototype for a pointer to a function to be called foreach - key/value pair in the hash by hashtable_foreach(). Iteration - stops if a non-zero value is returned. */ int _Py_hashtable_foreach(_Py_hashtable_t *ht, - int (*func) (_Py_hashtable_entry_t *entry, void *arg), + _Py_hashtable_foreach_func func, void *arg) { _Py_hashtable_entry_t *entry; @@ -387,7 +400,7 @@ _Py_hashtable_foreach(_Py_hashtable_t *ht, for (hv = 0; hv < ht->num_buckets; hv++) { for (entry = TABLE_HEAD(ht, hv); entry; entry = ENTRY_NEXT(entry)) { - int res = func(entry, arg); + int res = func(ht, entry, arg); if (res) return res; } @@ -395,6 +408,7 @@ _Py_hashtable_foreach(_Py_hashtable_t *ht, return 0; } + static void hashtable_rehash(_Py_hashtable_t *ht) { @@ -426,7 +440,8 @@ hashtable_rehash(_Py_hashtable_t *ht) for (entry = BUCKETS_HEAD(old_buckets[bucket]); entry != NULL; entry = next) { size_t entry_index; - assert(ht->hash_func(entry->key) == entry->key_hash); + + assert(ht->hash_func(ht, _Py_HASHTABLE_ENTRY_PKEY(entry)) == entry->key_hash); next = ENTRY_NEXT(entry); entry_index = entry->key_hash & (new_size - 1); @@ -437,6 +452,7 @@ hashtable_rehash(_Py_hashtable_t *ht) ht->alloc.free(old_buckets); } + void _Py_hashtable_clear(_Py_hashtable_t *ht) { @@ -446,8 +462,6 @@ _Py_hashtable_clear(_Py_hashtable_t *ht) for (i=0; i < ht->num_buckets; i++) { for (entry = TABLE_HEAD(ht, i); entry != NULL; entry = next) { next = ENTRY_NEXT(entry); - if (ht->free_data_func) - ht->free_data_func(_Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry)); ht->alloc.free(entry); } _Py_slist_init(&ht->buckets[i]); @@ -456,6 +470,7 @@ _Py_hashtable_clear(_Py_hashtable_t *ht) hashtable_rehash(ht); } + void _Py_hashtable_destroy(_Py_hashtable_t *ht) { @@ -465,8 +480,6 @@ _Py_hashtable_destroy(_Py_hashtable_t *ht) _Py_slist_item_t *entry = ht->buckets[i].head; while (entry) { _Py_slist_item_t *entry_next = entry->next; - if (ht->free_data_func) - ht->free_data_func(_Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry)); ht->alloc.free(entry); entry = entry_next; } @@ -476,39 +489,31 @@ _Py_hashtable_destroy(_Py_hashtable_t *ht) ht->alloc.free(ht); } -/* Return a copy of the hash table */ + _Py_hashtable_t * _Py_hashtable_copy(_Py_hashtable_t *src) { + const size_t key_size = src->key_size; + const size_t data_size = src->data_size; _Py_hashtable_t *dst; _Py_hashtable_entry_t *entry; size_t bucket; int err; - void *data, *new_data; - dst = _Py_hashtable_new_full(src->data_size, src->num_buckets, - src->hash_func, src->compare_func, - src->copy_data_func, src->free_data_func, - src->get_data_size_func, &src->alloc); + dst = _Py_hashtable_new_full(key_size, data_size, + src->num_buckets, + src->hash_func, + src->compare_func, + &src->alloc); if (dst == NULL) return NULL; for (bucket=0; bucket < src->num_buckets; bucket++) { entry = TABLE_HEAD(src, bucket); for (; entry; entry = ENTRY_NEXT(entry)) { - if (src->copy_data_func) { - data = _Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry); - new_data = src->copy_data_func(data); - if (new_data != NULL) - err = _Py_hashtable_set(dst, entry->key, - &new_data, src->data_size); - else - err = 1; - } - else { - data = _Py_HASHTABLE_ENTRY_DATA(entry); - err = _Py_hashtable_set(dst, entry->key, data, src->data_size); - } + const void *pkey = _Py_HASHTABLE_ENTRY_PKEY(entry); + const void *pdata = _Py_HASHTABLE_ENTRY_PDATA(src, entry); + err = _Py_hashtable_set(dst, key_size, pkey, data_size, pdata); if (err) { _Py_hashtable_destroy(dst); return NULL; @@ -517,4 +522,3 @@ _Py_hashtable_copy(_Py_hashtable_t *src) } return dst; } - diff --git a/Modules/hashtable.h b/Modules/hashtable.h index a9f9993..18fed09 100644 --- a/Modules/hashtable.h +++ b/Modules/hashtable.h @@ -1,9 +1,10 @@ #ifndef Py_HASHTABLE_H #define Py_HASHTABLE_H - /* The whole API is private */ #ifndef Py_LIMITED_API +/* Single linked list */ + typedef struct _Py_slist_item_s { struct _Py_slist_item_s *next; } _Py_slist_item_t; @@ -16,33 +17,66 @@ typedef struct { #define _Py_SLIST_HEAD(SLIST) (((_Py_slist_t *)SLIST)->head) + +/* _Py_hashtable: table entry */ + typedef struct { /* used by _Py_hashtable_t.buckets to link entries */ _Py_slist_item_t _Py_slist_item; - const void *key; Py_uhash_t key_hash; - /* data follows */ + /* key (key_size bytes) and then data (data_size bytes) follows */ } _Py_hashtable_entry_t; -#define _Py_HASHTABLE_ENTRY_DATA(ENTRY) \ - ((char *)(ENTRY) + sizeof(_Py_hashtable_entry_t)) +#define _Py_HASHTABLE_ENTRY_PKEY(ENTRY) \ + ((const void *)((char *)(ENTRY) \ + + sizeof(_Py_hashtable_entry_t))) + +#define _Py_HASHTABLE_ENTRY_PDATA(TABLE, ENTRY) \ + ((const void *)((char *)(ENTRY) \ + + sizeof(_Py_hashtable_entry_t) \ + + (TABLE)->key_size)) + +/* Get a key value from pkey: use memcpy() rather than a pointer dereference + to avoid memory alignment issues. */ +#define _Py_HASHTABLE_READ_KEY(TABLE, PKEY, DST_KEY) \ + do { \ + assert(sizeof(DST_KEY) == (TABLE)->key_size); \ + Py_MEMCPY(&(DST_KEY), (PKEY), sizeof(DST_KEY)); \ + } while (0) + +#define _Py_HASHTABLE_ENTRY_READ_KEY(TABLE, ENTRY, KEY) \ + do { \ + assert(sizeof(KEY) == (TABLE)->key_size); \ + Py_MEMCPY(&(KEY), _Py_HASHTABLE_ENTRY_PKEY(ENTRY), sizeof(KEY)); \ + } while (0) -#define _Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(ENTRY) \ - (*(void **)_Py_HASHTABLE_ENTRY_DATA(ENTRY)) +#define _Py_HASHTABLE_ENTRY_READ_DATA(TABLE, ENTRY, DATA) \ + do { \ + assert(sizeof(DATA) == (TABLE)->data_size); \ + Py_MEMCPY(&(DATA), _Py_HASHTABLE_ENTRY_PDATA(TABLE, (ENTRY)), \ + sizeof(DATA)); \ + } while (0) -#define _Py_HASHTABLE_ENTRY_READ_DATA(TABLE, DATA, DATA_SIZE, ENTRY) \ +#define _Py_HASHTABLE_ENTRY_WRITE_DATA(TABLE, ENTRY, DATA) \ do { \ - assert((DATA_SIZE) == (TABLE)->data_size); \ - memcpy(DATA, _Py_HASHTABLE_ENTRY_DATA(ENTRY), DATA_SIZE); \ + assert(sizeof(DATA) == (TABLE)->data_size); \ + Py_MEMCPY((void *)_Py_HASHTABLE_ENTRY_PDATA((TABLE), (ENTRY)), \ + &(DATA), sizeof(DATA)); \ } while (0) -typedef Py_uhash_t (*_Py_hashtable_hash_func) (const void *key); -typedef int (*_Py_hashtable_compare_func) (const void *key, const _Py_hashtable_entry_t *he); -typedef void* (*_Py_hashtable_copy_data_func)(void *data); -typedef void (*_Py_hashtable_free_data_func)(void *data); -typedef size_t (*_Py_hashtable_get_data_size_func)(void *data); + +/* _Py_hashtable: prototypes */ + +/* Forward declaration */ +struct _Py_hashtable_t; + +typedef Py_uhash_t (*_Py_hashtable_hash_func) (struct _Py_hashtable_t *ht, + const void *pkey); +typedef int (*_Py_hashtable_compare_func) (struct _Py_hashtable_t *ht, + const void *pkey, + const _Py_hashtable_entry_t *he); typedef struct { /* allocate a memory block */ @@ -52,77 +86,126 @@ typedef struct { void (*free) (void *ptr); } _Py_hashtable_allocator_t; -typedef struct { + +/* _Py_hashtable: table */ + +typedef struct _Py_hashtable_t { size_t num_buckets; size_t entries; /* Total number of entries in the table. */ _Py_slist_t *buckets; + size_t key_size; size_t data_size; _Py_hashtable_hash_func hash_func; _Py_hashtable_compare_func compare_func; - _Py_hashtable_copy_data_func copy_data_func; - _Py_hashtable_free_data_func free_data_func; - _Py_hashtable_get_data_size_func get_data_size_func; _Py_hashtable_allocator_t alloc; } _Py_hashtable_t; -/* hash and compare functions for integers and pointers */ -PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(const void *key); -PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_int(const void *key); -PyAPI_FUNC(int) _Py_hashtable_compare_direct(const void *key, const _Py_hashtable_entry_t *entry); +/* hash a pointer (void*) */ +PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr( + struct _Py_hashtable_t *ht, + const void *pkey); + +/* comparison using memcmp() */ +PyAPI_FUNC(int) _Py_hashtable_compare_direct( + _Py_hashtable_t *ht, + const void *pkey, + const _Py_hashtable_entry_t *entry); PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new( + size_t key_size, size_t data_size, _Py_hashtable_hash_func hash_func, _Py_hashtable_compare_func compare_func); + PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full( + size_t key_size, size_t data_size, size_t init_size, _Py_hashtable_hash_func hash_func, _Py_hashtable_compare_func compare_func, - _Py_hashtable_copy_data_func copy_data_func, - _Py_hashtable_free_data_func free_data_func, - _Py_hashtable_get_data_size_func get_data_size_func, _Py_hashtable_allocator_t *allocator); + +PyAPI_FUNC(void) _Py_hashtable_destroy(_Py_hashtable_t *ht); + +/* Return a copy of the hash table */ PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_copy(_Py_hashtable_t *src); + PyAPI_FUNC(void) _Py_hashtable_clear(_Py_hashtable_t *ht); -PyAPI_FUNC(void) _Py_hashtable_destroy(_Py_hashtable_t *ht); -typedef int (*_Py_hashtable_foreach_func) (_Py_hashtable_entry_t *entry, void *arg); +typedef int (*_Py_hashtable_foreach_func) (_Py_hashtable_t *ht, + _Py_hashtable_entry_t *entry, + void *arg); +/* Call func() on each entry of the hashtable. + Iteration stops if func() result is non-zero, in this case it's the result + of the call. Otherwise, the function returns 0. */ PyAPI_FUNC(int) _Py_hashtable_foreach( _Py_hashtable_t *ht, - _Py_hashtable_foreach_func func, void *arg); + _Py_hashtable_foreach_func func, + void *arg); + PyAPI_FUNC(size_t) _Py_hashtable_size(_Py_hashtable_t *ht); -PyAPI_FUNC(_Py_hashtable_entry_t*) _Py_hashtable_get_entry( - _Py_hashtable_t *ht, - const void *key); +/* Add a new entry to the hash. The key must not be present in the hash table. + Return 0 on success, -1 on memory error. + + Don't call directly this function, + but use _Py_HASHTABLE_SET() and _Py_HASHTABLE_SET_NODATA() macros */ PyAPI_FUNC(int) _Py_hashtable_set( _Py_hashtable_t *ht, - const void *key, - void *data, - size_t data_size); + size_t key_size, + const void *pkey, + size_t data_size, + const void *data); + +#define _Py_HASHTABLE_SET(TABLE, KEY, DATA) \ + _Py_hashtable_set(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA)) + +#define _Py_HASHTABLE_SET_NODATA(TABLE, KEY) \ + _Py_hashtable_set(TABLE, sizeof(KEY), &(KEY), 0, NULL) + + +/* Get an entry. + Return NULL if the key does not exist. + + Don't call directly this function, but use _Py_HASHTABLE_GET_ENTRY() + macro */ +PyAPI_FUNC(_Py_hashtable_entry_t*) _Py_hashtable_get_entry( + _Py_hashtable_t *ht, + size_t key_size, + const void *pkey); + +#define _Py_HASHTABLE_GET_ENTRY(TABLE, KEY) \ + _Py_hashtable_get_entry(TABLE, sizeof(KEY), &(KEY)) + + +/* Get data from an entry. Copy entry data into data and return 1 if the entry + exists, return 0 if the entry does not exist. + + Don't call directly this function, but use _Py_HASHTABLE_GET() macro */ PyAPI_FUNC(int) _Py_hashtable_get( _Py_hashtable_t *ht, - const void *key, - void *data, - size_t data_size); + size_t key_size, + const void *pkey, + size_t data_size, + void *data); + +#define _Py_HASHTABLE_GET(TABLE, KEY, DATA) \ + _Py_hashtable_get(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA)) + + +/* Don't call directly this function, but use _Py_HASHTABLE_POP() macro */ PyAPI_FUNC(int) _Py_hashtable_pop( _Py_hashtable_t *ht, - const void *key, - void *data, - size_t data_size); -PyAPI_FUNC(void) _Py_hashtable_delete( - _Py_hashtable_t *ht, - const void *key); + size_t key_size, + const void *pkey, + size_t data_size, + void *data); -#define _Py_HASHTABLE_SET(TABLE, KEY, DATA) \ - _Py_hashtable_set(TABLE, KEY, &(DATA), sizeof(DATA)) +#define _Py_HASHTABLE_POP(TABLE, KEY, DATA) \ + _Py_hashtable_pop(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA)) -#define _Py_HASHTABLE_GET(TABLE, KEY, DATA) \ - _Py_hashtable_get(TABLE, KEY, &(DATA), sizeof(DATA)) #endif /* Py_LIMITED_API */ - #endif diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 6ff241e..c966376 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1,4 +1,5 @@ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" @@ -7,7 +8,7 @@ */ -/* groupby object ***********************************************************/ +/* groupby object ************************************************************/ typedef struct { PyObject_HEAD @@ -74,7 +75,7 @@ groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg) static PyObject * groupby_next(groupbyobject *gbo) { - PyObject *newvalue, *newkey, *r, *grouper, *tmp; + PyObject *newvalue, *newkey, *r, *grouper; /* skip to next iteration group */ for (;;) { @@ -85,8 +86,7 @@ groupby_next(groupbyobject *gbo) else { int rcmp; - rcmp = PyObject_RichCompareBool(gbo->tgtkey, - gbo->currkey, Py_EQ); + rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ); if (rcmp == -1) return NULL; else if (rcmp == 0) @@ -101,27 +101,19 @@ groupby_next(groupbyobject *gbo) newkey = newvalue; Py_INCREF(newvalue); } else { - newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, - newvalue, NULL); + newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL); if (newkey == NULL) { Py_DECREF(newvalue); return NULL; } } - tmp = gbo->currkey; - gbo->currkey = newkey; - Py_XDECREF(tmp); - - tmp = gbo->currvalue; - gbo->currvalue = newvalue; - Py_XDECREF(tmp); + Py_XSETREF(gbo->currkey, newkey); + Py_XSETREF(gbo->currvalue, newvalue); } Py_INCREF(gbo->currkey); - tmp = gbo->tgtkey; - gbo->tgtkey = gbo->currkey; - Py_XDECREF(tmp); + Py_XSETREF(gbo->tgtkey, gbo->currkey); grouper = _grouper_create(gbo, gbo->tgtkey); if (grouper == NULL) @@ -173,7 +165,7 @@ static PyMethodDef groupby_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)groupby_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; PyDoc_STRVAR(groupby_doc, @@ -296,8 +288,7 @@ _grouper_next(_grouperobject *igo) newkey = newvalue; Py_INCREF(newvalue); } else { - newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, - newvalue, NULL); + newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL); if (newkey == NULL) { Py_DECREF(newvalue); return NULL; @@ -325,8 +316,7 @@ _grouper_next(_grouperobject *igo) static PyObject * _grouper_reduce(_grouperobject *lz) { - return Py_BuildValue("O(OO)", Py_TYPE(lz), - lz->parent, lz->tgtkey); + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey); } static PyMethodDef _grouper_methods[] = { @@ -359,7 +349,7 @@ static PyTypeObject _grouper_type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ - (traverseproc)_grouper_traverse,/* tp_traverse */ + (traverseproc)_grouper_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -380,8 +370,7 @@ static PyTypeObject _grouper_type = { }; - -/* tee object and with supporting function and objects ***************/ +/* tee object and with supporting function and objects ***********************/ /* The teedataobject pre-allocates space for LINKCELLS number of objects. To help the object fit neatly inside cache lines (space for 16 to 32 @@ -396,7 +385,7 @@ static PyTypeObject _grouper_type = { typedef struct { PyObject_HEAD PyObject *it; - int numread; /* 0 <= numread <= LINKCELLS */ + int numread; /* 0 <= numread <= LINKCELLS */ PyObject *nextlink; PyObject *(values[LINKCELLS]); } teedataobject; @@ -404,7 +393,7 @@ typedef struct { typedef struct { PyObject_HEAD teedataobject *dataobj; - int index; /* 0 <= index <= LINKCELLS */ + int index; /* 0 <= index <= LINKCELLS */ PyObject *weakreflist; } teeobject; @@ -461,6 +450,7 @@ static int teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg) { int i; + Py_VISIT(tdo->it); for (i = 0; i < tdo->numread; i++) Py_VISIT(tdo->values[i]); @@ -510,6 +500,7 @@ teedataobject_reduce(teedataobject *tdo) int i; /* create a temporary list of already iterated values */ PyObject *values = PyList_New(tdo->numread); + if (!values) return NULL; for (i=0 ; i<tdo->numread ; i++) { @@ -577,7 +568,7 @@ static PyMethodDef teedataobject_methods[] = { PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects."); static PyTypeObject teedataobject_type = { - PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ + PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ "itertools._tee_dataobject", /* tp_name */ sizeof(teedataobject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -597,7 +588,7 @@ static PyTypeObject teedataobject_type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ teedataobject_doc, /* tp_doc */ (traverseproc)teedataobject_traverse, /* tp_traverse */ (inquiry)teedataobject_clear, /* tp_clear */ @@ -752,9 +743,9 @@ PyDoc_STRVAR(teeobject_doc, "Iterator wrapped to make it copyable"); static PyMethodDef tee_methods[] = { - {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc}, - {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc}, - {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc}, + {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc}, + {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc}, + {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc}, {NULL, NULL} /* sentinel */ }; @@ -784,7 +775,7 @@ static PyTypeObject tee_type = { (traverseproc)tee_traverse, /* tp_traverse */ (inquiry)tee_clear, /* tp_clear */ 0, /* tp_richcompare */ - offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ + offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)tee_next, /* tp_iternext */ tee_methods, /* tp_methods */ @@ -850,12 +841,13 @@ PyDoc_STRVAR(tee_doc, "tee(iterable, n=2) --> tuple of n independent iterators."); -/* cycle object **********************************************************/ +/* cycle object **************************************************************/ typedef struct { PyObject_HEAD PyObject *it; PyObject *saved; + Py_ssize_t index; int firstpass; } cycleobject; @@ -895,6 +887,7 @@ cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } lz->it = it; lz->saved = saved; + lz->index = 0; lz->firstpass = 0; return (PyObject *)lz; @@ -904,15 +897,16 @@ static void cycle_dealloc(cycleobject *lz) { PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->saved); Py_XDECREF(lz->it); + Py_XDECREF(lz->saved); Py_TYPE(lz)->tp_free(lz); } static int cycle_traverse(cycleobject *lz, visitproc visit, void *arg) { - Py_VISIT(lz->it); + if (lz->it) + Py_VISIT(lz->it); Py_VISIT(lz->saved); return 0; } @@ -921,56 +915,69 @@ static PyObject * cycle_next(cycleobject *lz) { PyObject *item; - PyObject *it; - PyObject *tmp; - while (1) { + if (lz->it != NULL) { item = PyIter_Next(lz->it); if (item != NULL) { - if (!lz->firstpass && PyList_Append(lz->saved, item)) { + if (lz->firstpass) + return item; + if (PyList_Append(lz->saved, item)) { Py_DECREF(item); return NULL; } return item; } - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) - PyErr_Clear(); - else - return NULL; - } - if (PyList_Size(lz->saved) == 0) + /* Note: StopIteration is already cleared by PyIter_Next() */ + if (PyErr_Occurred()) return NULL; - it = PyObject_GetIter(lz->saved); - if (it == NULL) - return NULL; - tmp = lz->it; - lz->it = it; - lz->firstpass = 1; - Py_DECREF(tmp); + Py_CLEAR(lz->it); } + if (Py_SIZE(lz->saved) == 0) + return NULL; + item = PyList_GET_ITEM(lz->saved, lz->index); + lz->index++; + if (lz->index >= Py_SIZE(lz->saved)) + lz->index = 0; + Py_INCREF(item); + return item; } static PyObject * cycle_reduce(cycleobject *lz) { - /* Create a new cycle with the iterator tuple, then set - * the saved state on it. - */ - return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz), - lz->it, lz->saved, lz->firstpass); + /* Create a new cycle with the iterator tuple, then set the saved state */ + if (lz->it == NULL) { + PyObject *it = PyObject_GetIter(lz->saved); + if (it == NULL) + return NULL; + if (lz->index != 0) { + _Py_IDENTIFIER(__setstate__); + PyObject *res = _PyObject_CallMethodId(it, &PyId___setstate__, + "n", lz->index); + if (res == NULL) { + Py_DECREF(it); + return NULL; + } + Py_DECREF(res); + } + return Py_BuildValue("O(N)(Oi)", Py_TYPE(lz), it, lz->saved, 1); } + return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz), lz->it, lz->saved, + lz->firstpass); +} static PyObject * cycle_setstate(cycleobject *lz, PyObject *state) { PyObject *saved=NULL; int firstpass; - if (!PyArg_ParseTuple(state, "Oi", &saved, &firstpass)) + + if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) return NULL; - Py_XINCREF(saved); + Py_INCREF(saved); Py_XSETREF(lz->saved, saved); lz->firstpass = firstpass != 0; + lz->index = 0; Py_RETURN_NONE; } @@ -1039,7 +1046,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long start; + long start; } dropwhileobject; static PyTypeObject dropwhile_type; @@ -1129,8 +1136,7 @@ dropwhile_next(dropwhileobject *lz) static PyObject * dropwhile_reduce(dropwhileobject *lz) { - return Py_BuildValue("O(OO)l", Py_TYPE(lz), - lz->func, lz->it, lz->start); + return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start); } static PyObject * @@ -1181,13 +1187,13 @@ static PyTypeObject dropwhile_type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ dropwhile_doc, /* tp_doc */ - (traverseproc)dropwhile_traverse, /* tp_traverse */ + (traverseproc)dropwhile_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)dropwhile_next, /* tp_iternext */ - dropwhile_methods, /* tp_methods */ + dropwhile_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -1208,7 +1214,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long stop; + long stop; } takewhileobject; static PyTypeObject takewhile_type; @@ -1283,7 +1289,7 @@ takewhile_next(takewhileobject *lz) } ok = PyObject_IsTrue(good); Py_DECREF(good); - if (ok == 1) + if (ok > 0) return item; Py_DECREF(item); if (ok == 0) @@ -1294,14 +1300,14 @@ takewhile_next(takewhileobject *lz) static PyObject * takewhile_reduce(takewhileobject *lz) { - return Py_BuildValue("O(OO)l", Py_TYPE(lz), - lz->func, lz->it, lz->stop); + return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop); } static PyObject * takewhile_reduce_setstate(takewhileobject *lz, PyObject *state) { int stop = PyObject_IsTrue(state); + if (stop < 0) return NULL; lz->stop = stop; @@ -1345,7 +1351,7 @@ static PyTypeObject takewhile_type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ takewhile_doc, /* tp_doc */ - (traverseproc)takewhile_traverse, /* tp_traverse */ + (traverseproc)takewhile_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -1366,7 +1372,7 @@ static PyTypeObject takewhile_type = { }; -/* islice object ************************************************************/ +/* islice object *************************************************************/ typedef struct { PyObject_HEAD @@ -1402,7 +1408,8 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (PyErr_Occurred()) PyErr_Clear(); PyErr_SetString(PyExc_ValueError, - "Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize."); + "Stop argument for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); return NULL; } } @@ -1417,14 +1424,16 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (PyErr_Occurred()) PyErr_Clear(); PyErr_SetString(PyExc_ValueError, - "Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize."); + "Stop argument for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); return NULL; } } } if (start<0 || stop<-1) { PyErr_SetString(PyExc_ValueError, - "Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize."); + "Indices for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); return NULL; } @@ -1521,6 +1530,7 @@ islice_reduce(isliceobject *lz) * then 'setstate' with the next and count */ PyObject *stop; + if (lz->it == NULL) { PyObject *empty_list; PyObject *empty_it; @@ -1550,6 +1560,7 @@ static PyObject * islice_setstate(isliceobject *lz, PyObject *state) { Py_ssize_t cnt = PyLong_AsSsize_t(state); + if (cnt == -1 && PyErr_Occurred()) return NULL; lz->cnt = cnt; @@ -1764,7 +1775,7 @@ static PyTypeObject starmap_type = { }; -/* chain object ************************************************************/ +/* chain object **************************************************************/ typedef struct { PyObject_HEAD @@ -1840,32 +1851,32 @@ chain_next(chainobject *lz) PyObject *item; if (lz->source == NULL) - return NULL; /* already stopped */ + return NULL; /* already stopped */ if (lz->active == NULL) { PyObject *iterable = PyIter_Next(lz->source); if (iterable == NULL) { Py_CLEAR(lz->source); - return NULL; /* no more input sources */ + return NULL; /* no more input sources */ } lz->active = PyObject_GetIter(iterable); Py_DECREF(iterable); if (lz->active == NULL) { Py_CLEAR(lz->source); - return NULL; /* input not iterable */ + return NULL; /* input not iterable */ } } - item = PyIter_Next(lz->active); + item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active); if (item != NULL) return item; if (PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_StopIteration)) PyErr_Clear(); else - return NULL; /* input raised an exception */ + return NULL; /* input raised an exception */ } Py_CLEAR(lz->active); - return chain_next(lz); /* recurse and use next active */ + return chain_next(lz); /* recurse and use next active */ } static PyObject * @@ -1891,6 +1902,7 @@ static PyObject * chain_setstate(chainobject *lz, PyObject *state) { PyObject *source, *active=NULL; + if (! PyArg_ParseTuple(state, "O|O", &source, &active)) return NULL; @@ -1915,13 +1927,13 @@ Alternate chain() constructor taking a single iterable argument\n\ that evaluates lazily."); static PyMethodDef chain_methods[] = { - {"from_iterable", (PyCFunction) chain_new_from_iterable, METH_O | METH_CLASS, - chain_from_iterable_doc}, + {"from_iterable", (PyCFunction) chain_new_from_iterable, METH_O | METH_CLASS, + chain_from_iterable_doc}, {"__reduce__", (PyCFunction)chain_reduce, METH_NOARGS, reduce_doc}, {"__setstate__", (PyCFunction)chain_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; static PyTypeObject chain_type = { @@ -1973,10 +1985,10 @@ static PyTypeObject chain_type = { typedef struct { PyObject_HEAD - PyObject *pools; /* tuple of pool tuples */ - Py_ssize_t *indices; /* one index per pool */ - PyObject *result; /* most recently returned result tuple */ - int stopped; /* set to 1 when the product iterator is exhausted */ + PyObject *pools; /* tuple of pool tuples */ + Py_ssize_t *indices; /* one index per pool */ + PyObject *result; /* most recently returned result tuple */ + int stopped; /* set to 1 when the iterator is exhausted */ } productobject; static PyTypeObject product_type; @@ -1995,7 +2007,8 @@ product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *tmpargs = PyTuple_New(0); if (tmpargs == NULL) return NULL; - if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", kwlist, &repeat)) { + if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", + kwlist, &repeat)) { Py_DECREF(tmpargs); return NULL; } @@ -2284,7 +2297,7 @@ product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ..."); static PyTypeObject product_type = { PyVarObject_HEAD_INIT(NULL, 0) "itertools.product", /* tp_name */ - sizeof(productobject), /* tp_basicsize */ + sizeof(productobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)product_dealloc, /* tp_dealloc */ @@ -2326,15 +2339,15 @@ static PyTypeObject product_type = { }; -/* combinations object ************************************************************/ +/* combinations object *******************************************************/ typedef struct { PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ - Py_ssize_t *indices; /* one index per result element */ - PyObject *result; /* most recently returned result tuple */ - Py_ssize_t r; /* size of result tuple */ - int stopped; /* set to 1 when the combinations iterator is exhausted */ + PyObject *pool; /* input converted to a tuple */ + Py_ssize_t *indices; /* one index per result element */ + PyObject *result; /* most recently returned result tuple */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the iterator is exhausted */ } combinationsobject; static PyTypeObject combinations_type; @@ -2544,17 +2557,16 @@ combinations_setstate(combinationsobject *lz, PyObject *state) Py_ssize_t i; Py_ssize_t n = PyTuple_GET_SIZE(lz->pool); - if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) - { + if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) { PyErr_SetString(PyExc_ValueError, "invalid arguments"); return NULL; } - for (i=0; i<lz->r; i++) - { + for (i=0; i<lz->r; i++) { Py_ssize_t max; PyObject* indexObject = PyTuple_GET_ITEM(state, i); Py_ssize_t index = PyLong_AsSsize_t(indexObject); + if (index == -1 && PyErr_Occurred()) return NULL; /* not an integer */ max = i + n - lz->r; @@ -2640,7 +2652,7 @@ static PyTypeObject combinations_type = { }; -/* combinations with replacement object *******************************************/ +/* combinations with replacement object **************************************/ /* Equivalent to: @@ -2670,11 +2682,11 @@ static PyTypeObject combinations_type = { */ typedef struct { PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ + PyObject *pool; /* input converted to a tuple */ Py_ssize_t *indices; /* one index per result element */ PyObject *result; /* most recently returned result tuple */ - Py_ssize_t r; /* size of result tuple */ - int stopped; /* set to 1 when the cwr iterator is exhausted */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the cwr iterator is exhausted */ } cwrobject; static PyTypeObject cwr_type; @@ -2691,8 +2703,9 @@ cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_ssize_t i; static char *kwargs[] = {"iterable", "r", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations_with_replacement", kwargs, - &iterable, &r)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "On:combinations_with_replacement", + kwargs, &iterable, &r)) return NULL; pool = PySequence_Tuple(iterable); @@ -2857,8 +2870,7 @@ cwr_reduce(cwrobject *lz) indices = PyTuple_New(lz->r); if (!indices) return NULL; - for (i=0; i<lz->r; i++) - { + for (i=0; i<lz->r; i++) { PyObject* index = PyLong_FromSsize_t(lz->indices[i]); if (!index) { Py_DECREF(indices); @@ -2884,10 +2896,10 @@ cwr_setstate(cwrobject *lz, PyObject *state) } n = PyTuple_GET_SIZE(lz->pool); - for (i=0; i<lz->r; i++) - { + for (i=0; i<lz->r; i++) { PyObject* indexObject = PyTuple_GET_ITEM(state, i); Py_ssize_t index = PyLong_AsSsize_t(indexObject); + if (index < 0 && PyErr_Occurred()) return NULL; /* not an integer */ /* clamp the index */ @@ -2971,7 +2983,7 @@ static PyTypeObject cwr_type = { }; -/* permutations object ************************************************************ +/* permutations object ******************************************************** def permutations(iterable, r=None): 'permutations(range(3), 2) --> (0,1) (0,2) (1,0) (1,2) (2,0) (2,1)' @@ -2998,12 +3010,12 @@ def permutations(iterable, r=None): typedef struct { PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ - Py_ssize_t *indices; /* one index per element in the pool */ - Py_ssize_t *cycles; /* one rollover counter per element in the result */ - PyObject *result; /* most recently returned result tuple */ - Py_ssize_t r; /* size of result tuple */ - int stopped; /* set to 1 when the permutations iterator is exhausted */ + PyObject *pool; /* input converted to a tuple */ + Py_ssize_t *indices; /* one index per element in the pool */ + Py_ssize_t *cycles; /* one rollover counter per element in the result */ + PyObject *result; /* most recently returned result tuple */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the iterator is exhausted */ } permutationsobject; static PyTypeObject permutations_type; @@ -3218,7 +3230,7 @@ permutations_reduce(permutationsobject *po) indices = PyTuple_New(n); if (indices == NULL) goto err; - for (i=0; i<n; i++){ + for (i=0; i<n; i++) { PyObject* index = PyLong_FromSsize_t(po->indices[i]); if (!index) goto err; @@ -3228,8 +3240,7 @@ permutations_reduce(permutationsobject *po) cycles = PyTuple_New(po->r); if (cycles == NULL) goto err; - for (i=0; i<po->r; i++) - { + for (i=0 ; i<po->r ; i++) { PyObject* index = PyLong_FromSsize_t(po->cycles[i]); if (!index) goto err; @@ -3257,15 +3268,12 @@ permutations_setstate(permutationsobject *po, PyObject *state) return NULL; n = PyTuple_GET_SIZE(po->pool); - if (PyTuple_GET_SIZE(indices) != n || - PyTuple_GET_SIZE(cycles) != po->r) - { + if (PyTuple_GET_SIZE(indices) != n || PyTuple_GET_SIZE(cycles) != po->r) { PyErr_SetString(PyExc_ValueError, "invalid arguments"); return NULL; } - for (i=0; i<n; i++) - { + for (i=0; i<n; i++) { PyObject* indexObject = PyTuple_GET_ITEM(indices, i); Py_ssize_t index = PyLong_AsSsize_t(indexObject); if (index < 0 && PyErr_Occurred()) @@ -3278,8 +3286,7 @@ permutations_setstate(permutationsobject *po, PyObject *state) po->indices[i] = index; } - for (i=0; i<po->r; i++) - { + for (i=0; i<po->r; i++) { PyObject* indexObject = PyTuple_GET_ITEM(cycles, i); Py_ssize_t index = PyLong_AsSsize_t(indexObject); if (index < 0 && PyErr_Occurred()) @@ -3320,11 +3327,11 @@ permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)"); static PyTypeObject permutations_type = { PyVarObject_HEAD_INIT(NULL, 0) - "itertools.permutations", /* tp_name */ + "itertools.permutations", /* tp_name */ sizeof(permutationsobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)permutations_dealloc, /* tp_dealloc */ + (destructor)permutations_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3341,13 +3348,13 @@ static PyTypeObject permutations_type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ - permutations_doc, /* tp_doc */ - (traverseproc)permutations_traverse, /* tp_traverse */ + permutations_doc, /* tp_doc */ + (traverseproc)permutations_traverse,/* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ - (iternextfunc)permutations_next, /* tp_iternext */ + (iternextfunc)permutations_next, /* tp_iternext */ permuations_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ @@ -3358,11 +3365,11 @@ static PyTypeObject permutations_type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - permutations_new, /* tp_new */ + permutations_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; -/* accumulate object ************************************************************/ +/* accumulate object ********************************************************/ typedef struct { PyObject_HEAD @@ -3429,9 +3436,9 @@ accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg) static PyObject * accumulate_next(accumulateobject *lz) { - PyObject *val, *oldtotal, *newtotal; + PyObject *val, *newtotal; - val = PyIter_Next(lz->it); + val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it); if (val == NULL) return NULL; @@ -3449,11 +3456,8 @@ accumulate_next(accumulateobject *lz) if (newtotal == NULL) return NULL; - oldtotal = lz->total; - lz->total = newtotal; - Py_DECREF(oldtotal); - Py_INCREF(newtotal); + Py_SETREF(lz->total, newtotal); return newtotal; } @@ -3480,7 +3484,7 @@ accumulate_reduce(accumulateobject *lz) return Py_BuildValue("O(OO)O", Py_TYPE(lz), lz->it, lz->binop?lz->binop:Py_None, lz->total?lz->total:Py_None); - } +} static PyObject * accumulate_setstate(accumulateobject *lz, PyObject *state) @@ -3642,7 +3646,7 @@ compress_next(compressobject *lz) ok = PyObject_IsTrue(selector); Py_DECREF(selector); - if (ok == 1) + if (ok > 0) return datum; Py_DECREF(datum); if (ok < 0) @@ -3655,7 +3659,7 @@ compress_reduce(compressobject *lz) { return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->data, lz->selectors); - } +} static PyMethodDef compress_methods[] = { {"__reduce__", (PyCFunction)compress_reduce, METH_NOARGS, @@ -3674,44 +3678,44 @@ static PyTypeObject compress_type = { PyVarObject_HEAD_INIT(NULL, 0) "itertools.compress", /* tp_name */ sizeof(compressobject), /* tp_basicsize */ - 0, /* tp_itemsize */ + 0, /* tp_itemsize */ /* methods */ (destructor)compress_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - compress_doc, /* tp_doc */ - (traverseproc)compress_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ + Py_TPFLAGS_BASETYPE, /* tp_flags */ + compress_doc, /* tp_doc */ + (traverseproc)compress_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ (iternextfunc)compress_next, /* tp_iternext */ - compress_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - compress_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + compress_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + compress_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ }; @@ -3792,8 +3796,7 @@ filterfalse_next(filterfalseobject *lz) ok = PyObject_IsTrue(item); } else { PyObject *good; - good = PyObject_CallFunctionObjArgs(lz->func, - item, NULL); + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; @@ -3812,9 +3815,8 @@ filterfalse_next(filterfalseobject *lz) static PyObject * filterfalse_reduce(filterfalseobject *lz) { - return Py_BuildValue("O(OO)", Py_TYPE(lz), - lz->func, lz->it); - } + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); +} static PyMethodDef filterfalse_methods[] = { {"__reduce__", (PyCFunction)filterfalse_reduce, METH_NOARGS, @@ -3834,7 +3836,7 @@ static PyTypeObject filterfalse_type = { sizeof(filterfalseobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)filterfalse_dealloc, /* tp_dealloc */ + (destructor)filterfalse_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3852,7 +3854,7 @@ static PyTypeObject filterfalse_type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ filterfalse_doc, /* tp_doc */ - (traverseproc)filterfalse_traverse, /* tp_traverse */ + (traverseproc)filterfalse_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -4091,15 +4093,15 @@ static PyTypeObject count_type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE, /* tp_flags */ count_doc, /* tp_doc */ - (traverseproc)count_traverse, /* tp_traverse */ + (traverseproc)count_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ - count_methods, /* tp_methods */ + count_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -4265,9 +4267,7 @@ static PyTypeObject repeat_type = { PyObject_GC_Del, /* tp_free */ }; -/* ziplongest object ************************************************************/ - -#include "Python.h" +/* ziplongest object *********************************************************/ typedef struct { PyObject_HEAD @@ -4306,7 +4306,7 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ittuple = PyTuple_New(tuplesize); if (ittuple == NULL) return NULL; - for (i=0; i < tuplesize; ++i) { + for (i=0; i < tuplesize; i++) { PyObject *item = PyTuple_GET_ITEM(args, i); PyObject *it = PyObject_GetIter(item); if (it == NULL) { @@ -4447,6 +4447,7 @@ zip_longest_reduce(ziplongestobject *lz) */ int i; PyObject *args = PyTuple_New(PyTuple_GET_SIZE(lz->ittuple)); + if (args == NULL) return NULL; for (i=0; i<PyTuple_GET_SIZE(lz->ittuple); i++) { @@ -4497,7 +4498,7 @@ static PyTypeObject ziplongest_type = { sizeof(ziplongestobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)zip_longest_dealloc, /* tp_dealloc */ + (destructor)zip_longest_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -4514,8 +4515,8 @@ static PyTypeObject ziplongest_type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ - zip_longest_doc, /* tp_doc */ - (traverseproc)zip_longest_traverse, /* tp_traverse */ + zip_longest_doc, /* tp_doc */ + (traverseproc)zip_longest_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -4531,7 +4532,7 @@ static PyTypeObject ziplongest_type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - zip_longest_new, /* tp_new */ + zip_longest_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; diff --git a/Modules/main.c b/Modules/main.c index e4c955e..0b82f48 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -42,11 +42,11 @@ static int orig_argc; #define PROGRAM_OPTS BASE_OPTS /* Short usage message (with %s for argv0) */ -static char *usage_line = +static const char usage_line[] = "usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n"; /* Long usage message, split into parts < 512 bytes */ -static char *usage_1 = "\ +static const char usage_1[] = "\ Options and arguments (and corresponding environment variables):\n\ -b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\ and comparing bytes/bytearray with str. (-bb: issue errors)\n\ @@ -56,7 +56,7 @@ Options and arguments (and corresponding environment variables):\n\ -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\ -h : print this help message and exit (also --help)\n\ "; -static char *usage_2 = "\ +static const char usage_2[] = "\ -i : inspect interactively after running script; forces a prompt even\n\ if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ -I : isolate Python from the user's environment (implies -E and -s)\n\ @@ -67,7 +67,7 @@ static char *usage_2 = "\ -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\ -S : don't imply 'import site' on initialization\n\ "; -static char *usage_3 = "\ +static const char usage_3[] = "\ -u : unbuffered binary stdout and stderr, stdin always buffered;\n\ also PYTHONUNBUFFERED=x\n\ see man page for details on internal buffering relating to '-u'\n\ @@ -79,7 +79,7 @@ static char *usage_3 = "\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ -X opt : set implementation-specific option\n\ "; -static char *usage_4 = "\ +static const char usage_4[] = "\ file : program read from script file\n\ - : program read from stdin (default; interactive mode if a tty)\n\ arg ...: arguments passed to program in sys.argv[1:]\n\n\ @@ -88,22 +88,23 @@ PYTHONSTARTUP: file executed on interactive startup (no default)\n\ PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\ default module search path. The result is sys.path.\n\ "; -static char *usage_5 = +static const char usage_5[] = "PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n" " The default module search path uses %s.\n" "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n" "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n" -"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n\ -"; -static char *usage_6 = "\ -PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n\ - to seed the hashes of str, bytes and datetime objects. It can also be\n\ - set to an integer in the range [0,4294967295] to get hash values with a\n\ - predictable seed.\n\ -"; +"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n"; +static const char usage_6[] = +"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n" +" to seed the hashes of str, bytes and datetime objects. It can also be\n" +" set to an integer in the range [0,4294967295] to get hash values with a\n" +" predictable seed.\n" +"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n" +" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n" +" hooks.\n"; static int -usage(int exitcode, wchar_t* program) +usage(int exitcode, const wchar_t* program) { FILE *f = exitcode ? stderr : stdout; @@ -341,6 +342,7 @@ Py_Main(int argc, wchar_t **argv) int help = 0; int version = 0; int saw_unbuffered_flag = 0; + char *opt; PyCompilerFlags cf; PyObject *warning_option = NULL; PyObject *warning_options = NULL; @@ -365,6 +367,13 @@ Py_Main(int argc, wchar_t **argv) } } + opt = Py_GETENV("PYTHONMALLOC"); + if (_PyMem_SetupAllocators(opt) < 0) { + fprintf(stderr, + "Error in PYTHONMALLOC: unknown allocator \"%s\"!\n", opt); + exit(1); + } + Py_HashRandomizationFlag = 1; _PyRandom_Init(); @@ -473,7 +482,8 @@ Py_Main(int argc, wchar_t **argv) warning_option = PyUnicode_FromWideChar(_PyOS_optarg, -1); if (warning_option == NULL) Py_FatalError("failure in handling of -W argument"); - PyList_Append(warning_options, warning_option); + if (PyList_Append(warning_options, warning_option) == -1) + Py_FatalError("failure in handling of -W argument"); Py_DECREF(warning_option); break; @@ -654,7 +664,7 @@ Py_Main(int argc, wchar_t **argv) Py_SetProgramName(wbuf); /* Don't free wbuf, the argument to Py_SetProgramName - * must remain valid until the Py_Finalize is called. + * must remain valid until Py_FinalizeEx is called. */ } else { Py_SetProgramName(argv[0]); @@ -785,7 +795,11 @@ Py_Main(int argc, wchar_t **argv) sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0; } - Py_Finalize(); + if (Py_FinalizeEx() < 0) { + /* Value unlikely to be confused with a non-error exit status or + other special meaning */ + sts = 120; + } #ifdef __INSURE__ /* Insure++ is a memory analysis tool that aids in discovering diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index b945bd6..95ea4f7 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -875,7 +875,7 @@ math_1_to_int(PyObject *arg, double (*func) (double), int can_overflow) } static PyObject * -math_2(PyObject *args, double (*func) (double, double), char *funcname) +math_2(PyObject *args, double (*func) (double, double), const char *funcname) { PyObject *ox, *oy; double x, y, r; @@ -1672,7 +1672,7 @@ PyDoc_STRVAR(math_modf_doc, in that int is larger than PY_SSIZE_T_MAX. */ static PyObject* -loghelper(PyObject* arg, double (*func)(double), char *funcname) +loghelper(PyObject* arg, double (*func)(double), const char *funcname) { /* If it is int, do it ourselves. */ if (PyLong_Check(arg)) { @@ -2144,6 +2144,7 @@ PyInit_math(void) PyModule_AddObject(m, "pi", PyFloat_FromDouble(Py_MATH_PI)); PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); + PyModule_AddObject(m, "tau", PyFloat_FromDouble(Py_MATH_TAU)); /* 2pi */ PyModule_AddObject(m, "inf", PyFloat_FromDouble(m_inf())); #if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) PyModule_AddObject(m, "nan", PyFloat_FromDouble(m_nan())); diff --git a/Modules/md5module.c b/Modules/md5module.c index f94acc7..04bc06e 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -30,7 +30,7 @@ class MD5Type "MD5object *" "&PyType_Type" #if SIZEOF_INT == 4 typedef unsigned int MD5_INT32; /* 32-bit integer */ -typedef PY_LONG_LONG MD5_INT64; /* 64-bit integer */ +typedef long long MD5_INT64; /* 64-bit integer */ #else /* not defined. compilation will die. */ #endif diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index bb98a99..73c37d0 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -93,7 +93,7 @@ typedef struct { size_t size; size_t pos; /* relative to offset */ #ifdef MS_WINDOWS - PY_LONG_LONG offset; + long long offset; #else off_t offset; #endif @@ -389,6 +389,7 @@ mmap_write_method(mmap_object *self, PyObject *args) { Py_buffer data; + PyObject *result; CHECK_VALID(NULL); if (!PyArg_ParseTuple(args, "y*:write", &data)) @@ -406,9 +407,9 @@ mmap_write_method(mmap_object *self, } memcpy(self->data + self->pos, data.buf, data.len); self->pos = self->pos + data.len; + result = PyLong_FromSsize_t(data.len); PyBuffer_Release(&data); - Py_INCREF(Py_None); - return Py_None; + return result; } static PyObject * @@ -445,7 +446,7 @@ mmap_size_method(mmap_object *self, #ifdef MS_WINDOWS if (self->file_handle != INVALID_HANDLE_VALUE) { DWORD low,high; - PY_LONG_LONG size; + long long size; low = GetFileSize(self->file_handle, &high); if (low == INVALID_FILE_SIZE) { /* It might be that the function appears to have failed, @@ -456,7 +457,7 @@ mmap_size_method(mmap_object *self, } if (!high && low < LONG_MAX) return PyLong_FromLong((long)low); - size = (((PY_LONG_LONG)high)<<32) + low; + size = (((long long)high)<<32) + low; return PyLong_FromLongLong(size); } else { return PyLong_FromSsize_t(self->size); @@ -1257,7 +1258,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) /* A note on sizes and offsets: while the actual map size must hold in a Py_ssize_t, both the total file size and the start offset can be longer - than a Py_ssize_t, so we use PY_LONG_LONG which is always 64-bit. + than a Py_ssize_t, so we use long long which is always 64-bit. */ static PyObject * @@ -1266,7 +1267,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) mmap_object *m_obj; PyObject *map_size_obj = NULL; Py_ssize_t map_size; - PY_LONG_LONG offset = 0, size; + long long offset = 0, size; DWORD off_hi; /* upper 32 bits of offset */ DWORD off_lo; /* lower 32 bits of offset */ DWORD size_hi; /* upper 32 bits of size */ @@ -1325,10 +1326,6 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) */ if (fileno != -1 && fileno != 0) { /* Ensure that fileno is within the CRT's valid range */ - if (!_PyVerify_fd(fileno)) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } _Py_BEGIN_SUPPRESS_IPH fh = (HANDLE)_get_osfhandle(fileno); _Py_END_SUPPRESS_IPH @@ -1378,7 +1375,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) return PyErr_SetFromWindowsErr(dwErr); } - size = (((PY_LONG_LONG) high) << 32) + low; + size = (((long long) high) << 32) + low; if (size == 0) { PyErr_SetString(PyExc_ValueError, "cannot mmap an empty file"); diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 64eb5db..b6a855c 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -76,11 +76,7 @@ nis_mapname (char *map, int *pfix) *pfix = 0; for (i=0; aliases[i].alias != 0L; i++) { - if (!strcmp (aliases[i].alias, map)) { - *pfix = aliases[i].fix; - return aliases[i].map; - } - if (!strcmp (aliases[i].map, map)) { + if (!strcmp (aliases[i].alias, map) || !strcmp (aliases[i].map, map)) { *pfix = aliases[i].fix; return aliases[i].map; } diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index d2fd5c8..4796203 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -31,9 +31,13 @@ #endif #include <sys/ioctl.h> +#ifdef __ANDROID__ +#include <linux/soundcard.h> +#else #include <sys/soundcard.h> +#endif -#if defined(linux) +#ifdef __linux__ #ifndef HAVE_STDINT_H typedef unsigned long uint32_t; diff --git a/Modules/overlapped.c b/Modules/overlapped.c index f85e5bc..0aa8657 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -973,28 +973,28 @@ Overlapped_AcceptEx(OverlappedObject *self, PyObject *args) static int parse_address(PyObject *obj, SOCKADDR *Address, int Length) { - char *Host; + Py_UNICODE *Host; unsigned short Port; unsigned long FlowInfo; unsigned long ScopeId; memset(Address, 0, Length); - if (PyArg_ParseTuple(obj, "sH", &Host, &Port)) + if (PyArg_ParseTuple(obj, "uH", &Host, &Port)) { Address->sa_family = AF_INET; - if (WSAStringToAddressA(Host, AF_INET, NULL, Address, &Length) < 0) { + if (WSAStringToAddressW(Host, AF_INET, NULL, Address, &Length) < 0) { SetFromWindowsErr(WSAGetLastError()); return -1; } ((SOCKADDR_IN*)Address)->sin_port = htons(Port); return Length; } - else if (PyArg_ParseTuple(obj, "sHkk", &Host, &Port, &FlowInfo, &ScopeId)) + else if (PyArg_ParseTuple(obj, "uHkk", &Host, &Port, &FlowInfo, &ScopeId)) { PyErr_Clear(); Address->sa_family = AF_INET6; - if (WSAStringToAddressA(Host, AF_INET6, NULL, Address, &Length) < 0) { + if (WSAStringToAddressW(Host, AF_INET6, NULL, Address, &Length) < 0) { SetFromWindowsErr(WSAGetLastError()); return -1; } diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 6471b8e..82770a5 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -53,7 +53,7 @@ extern grammar _PyParser_Grammar; /* From graminit.c */ /* String constants used to initialize module attributes. * */ -static char parser_copyright_string[] = +static const char parser_copyright_string[] = "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\ University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\ Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\ @@ -63,7 +63,7 @@ Centrum, Amsterdam, The Netherlands."; PyDoc_STRVAR(parser_doc_string, "This is an interface to Python's internal parser."); -static char parser_version_string[] = "0.5"; +static const char parser_version_string[] = "0.5"; typedef PyObject* (*SeqMaker) (Py_ssize_t length); @@ -578,13 +578,13 @@ parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw) } -/* err_string(char* message) +/* err_string(const char* message) * * Sets the error string for an exception of type ParserError. * */ static void -err_string(char *message) +err_string(const char *message) { PyErr_SetString(parser_error, message); } @@ -597,7 +597,7 @@ err_string(char *message) * */ static PyObject* -parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type) +parser_do_parse(PyObject *args, PyObject *kw, const char *argspec, int type) { char* string = 0; PyObject* res = 0; @@ -670,9 +670,75 @@ parser_suite(PyST_Object *self, PyObject *args, PyObject *kw) static node* build_node_tree(PyObject *tuple); -static int validate_expr_tree(node *tree); -static int validate_file_input(node *tree); -static int validate_encoding_decl(node *tree); + +static int +validate_node(node *tree) +{ + int type = TYPE(tree); + int nch = NCH(tree); + dfa *nt_dfa; + state *dfa_state; + int pos, arc; + + assert(ISNONTERMINAL(type)); + type -= NT_OFFSET; + if (type >= _PyParser_Grammar.g_ndfas) { + PyErr_Format(parser_error, "Unrecognized node type %d.", TYPE(tree)); + return 0; + } + nt_dfa = &_PyParser_Grammar.g_dfa[type]; + REQ(tree, nt_dfa->d_type); + + /* Run the DFA for this nonterminal. */ + dfa_state = &nt_dfa->d_state[nt_dfa->d_initial]; + for (pos = 0; pos < nch; ++pos) { + node *ch = CHILD(tree, pos); + int ch_type = TYPE(ch); + for (arc = 0; arc < dfa_state->s_narcs; ++arc) { + short a_label = dfa_state->s_arc[arc].a_lbl; + assert(a_label < _PyParser_Grammar.g_ll.ll_nlabels); + if (_PyParser_Grammar.g_ll.ll_label[a_label].lb_type == ch_type) { + /* The child is acceptable; if non-terminal, validate it recursively. */ + if (ISNONTERMINAL(ch_type) && !validate_node(ch)) + return 0; + + /* Update the state, and move on to the next child. */ + dfa_state = &nt_dfa->d_state[dfa_state->s_arc[arc].a_arrow]; + goto arc_found; + } + } + /* What would this state have accepted? */ + { + short a_label = dfa_state->s_arc->a_lbl; + int next_type; + if (!a_label) /* Wouldn't accept any more children */ + goto illegal_num_children; + + next_type = _PyParser_Grammar.g_ll.ll_label[a_label].lb_type; + if (ISNONTERMINAL(next_type)) + PyErr_Format(parser_error, "Expected node type %d, got %d.", + next_type, ch_type); + else + PyErr_Format(parser_error, "Illegal terminal: expected %s.", + _PyParser_TokenNames[next_type]); + return 0; + } + +arc_found: + continue; + } + /* Are we in a final state? If so, return 1 for successful validation. */ + for (arc = 0; arc < dfa_state->s_narcs; ++arc) { + if (!dfa_state->s_arc[arc].a_lbl) { + return 1; + } + } + +illegal_num_children: + PyErr_Format(parser_error, + "Illegal number of children for %s node.", nt_dfa->d_name); + return 0; +} /* PyObject* parser_tuple2st(PyObject* self, PyObject* args) * @@ -681,7 +747,7 @@ static int validate_encoding_decl(node *tree); * tuple can be validated. It does this by checking the first code of the * tuple, and, if acceptable, builds the internal representation. If this * step succeeds, the internal representation is validated as fully as - * possible with the various validate_*() routines defined below. + * possible with the recursive validate_node() routine defined above. * * This function must be changed if support is to be added for PyST_FRAGMENT * ST objects. @@ -710,33 +776,35 @@ parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw) */ tree = build_node_tree(tuple); if (tree != 0) { - int start_sym = TYPE(tree); - if (start_sym == eval_input) { + node *validation_root = tree; + int tree_type = 0; + switch (TYPE(tree)) { + case eval_input: /* Might be an eval form. */ - if (validate_expr_tree(tree)) - st = parser_newstobject(tree, PyST_EXPR); - else - PyNode_Free(tree); - } - else if (start_sym == file_input) { - /* This looks like an exec form so far. */ - if (validate_file_input(tree)) - st = parser_newstobject(tree, PyST_SUITE); - else - PyNode_Free(tree); - } - else if (start_sym == encoding_decl) { + tree_type = PyST_EXPR; + break; + case encoding_decl: /* This looks like an encoding_decl so far. */ - if (validate_encoding_decl(tree)) - st = parser_newstobject(tree, PyST_SUITE); - else - PyNode_Free(tree); - } - else { + if (NCH(tree) != 1) + err_string("Error Parsing encoding_decl"); + validation_root = CHILD(tree, 0); + /* Fall through */ + case file_input: + /* This looks like an exec form so far. */ + + tree_type = PyST_SUITE; + break; + default: /* This is a fragment, at best. */ PyNode_Free(tree); err_string("parse tree does not use a valid start symbol"); + return (0); } + + if (validate_node(validation_root)) + st = parser_newstobject(tree, tree_type); + else + PyNode_Free(tree); } /* Make sure we raise an exception on all errors. We should never * get this, but we'd do well to be sure something is done. @@ -981,2433 +1049,6 @@ build_node_tree(PyObject *tuple) } -/* - * Validation routines used within the validation section: - */ -static int validate_terminal(node *terminal, int type, char *string); - -#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&") -#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^") -#define validate_colon(ch) validate_terminal(ch, COLON, ":") -#define validate_comma(ch) validate_terminal(ch, COMMA, ",") -#define validate_dedent(ch) validate_terminal(ch, DEDENT, "") -#define validate_equal(ch) validate_terminal(ch, EQUAL, "=") -#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL) -#define validate_lparen(ch) validate_terminal(ch, LPAR, "(") -#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL) -#define validate_rparen(ch) validate_terminal(ch, RPAR, ")") -#define validate_semi(ch) validate_terminal(ch, SEMI, ";") -#define validate_star(ch) validate_terminal(ch, STAR, "*") -#define validate_vbar(ch) validate_terminal(ch, VBAR, "|") -#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**") -#define validate_dot(ch) validate_terminal(ch, DOT, ".") -#define validate_at(ch) validate_terminal(ch, AT, "@") -#define validate_rarrow(ch) validate_terminal(ch, RARROW, "->") -#define validate_name(ch, str) validate_terminal(ch, NAME, str) - -#define VALIDATER(n) static int validate_##n(node *tree) - -VALIDATER(node); VALIDATER(small_stmt); -VALIDATER(class); VALIDATER(node); -VALIDATER(parameters); VALIDATER(suite); -VALIDATER(testlist); VALIDATER(varargslist); -VALIDATER(vfpdef); -VALIDATER(stmt); VALIDATER(simple_stmt); -VALIDATER(expr_stmt); VALIDATER(power); -VALIDATER(del_stmt); -VALIDATER(return_stmt); VALIDATER(raise_stmt); -VALIDATER(import_stmt); VALIDATER(import_stmt); -VALIDATER(import_name); VALIDATER(yield_stmt); -VALIDATER(global_stmt); VALIDATER(nonlocal_stmt); -VALIDATER(assert_stmt); -VALIDATER(compound_stmt); VALIDATER(test_or_star_expr); -VALIDATER(while); VALIDATER(for); -VALIDATER(try); VALIDATER(except_clause); -VALIDATER(test); VALIDATER(and_test); -VALIDATER(not_test); VALIDATER(comparison); -VALIDATER(comp_op); -VALIDATER(star_expr); VALIDATER(expr); -VALIDATER(xor_expr); VALIDATER(and_expr); -VALIDATER(shift_expr); VALIDATER(arith_expr); -VALIDATER(term); VALIDATER(factor); -VALIDATER(atom); VALIDATER(lambdef); -VALIDATER(trailer); VALIDATER(subscript); -VALIDATER(subscriptlist); VALIDATER(sliceop); -VALIDATER(exprlist); VALIDATER(dictorsetmaker); -VALIDATER(arglist); VALIDATER(argument); -VALIDATER(comp_for); -VALIDATER(comp_iter); VALIDATER(comp_if); -VALIDATER(testlist_comp); VALIDATER(yield_expr); -VALIDATER(or_test); -VALIDATER(test_nocond); VALIDATER(lambdef_nocond); -VALIDATER(yield_arg); -VALIDATER(async_funcdef); VALIDATER(async_stmt); -VALIDATER(atom_expr); - -#undef VALIDATER - -#define is_even(n) (((n) & 1) == 0) -#define is_odd(n) (((n) & 1) == 1) - - -static int -validate_ntype(node *n, int t) -{ - if (TYPE(n) != t) { - PyErr_Format(parser_error, "Expected node type %d, got %d.", - t, TYPE(n)); - return 0; - } - return 1; -} - - -/* Verifies that the number of child nodes is exactly 'num', raising - * an exception if it isn't. The exception message does not indicate - * the exact number of nodes, allowing this to be used to raise the - * "right" exception when the wrong number of nodes is present in a - * specific variant of a statement's syntax. This is commonly used - * in that fashion. - */ -static int -validate_numnodes(node *n, int num, const char *const name) -{ - if (NCH(n) != num) { - PyErr_Format(parser_error, - "Illegal number of children for %s node.", name); - return 0; - } - return 1; -} - - -static int -validate_terminal(node *terminal, int type, char *string) -{ - int res = (validate_ntype(terminal, type) - && ((string == 0) || (strcmp(string, STR(terminal)) == 0))); - - if (!res && !PyErr_Occurred()) { - PyErr_Format(parser_error, - "Illegal terminal: expected \"%s\"", string); - } - return (res); -} - -/* X (',' X) [','] */ -static int -validate_repeating_list_variable(node *tree, - int list_node_type, - int (*validate_child_func_inc)(node *, int *), - int *pos, - const char *const list_node_type_name) -{ - int nch = NCH(tree); - int res = (nch && validate_ntype(tree, list_node_type)); - - if (!res && !PyErr_Occurred()) { - /* Unconditionally raise. */ - (void) validate_numnodes(tree, 1, list_node_type_name); - } - else { - for ( ; res && *pos < nch; ) { - res = validate_child_func_inc(tree, pos); - if (!res || *pos >= nch) - break; - res = validate_comma(CHILD(tree, (*pos)++)); - } - } - return res; -} - -/* X (',' X) [','] */ -static int -validate_repeating_list(node *tree, - int list_node_type, - int (*validate_child_func)(node *), - const char *const list_node_type_name) -{ - int nch = NCH(tree); - int res = (nch && validate_ntype(tree, list_node_type)); - int pos = 0; - - if (!res && !PyErr_Occurred()) { - /* Unconditionally raise. */ - (void) validate_numnodes(tree, 1, list_node_type_name); - } - else { - for ( ; res && pos < nch; ) { - res = validate_child_func(CHILD(tree, pos++)); - if (!res || pos >= nch) - break; - res = validate_comma(CHILD(tree, pos++)); - } - } - return res; -} - - -/* validate_class() - * - * classdef: - * 'class' NAME ['(' testlist ')'] ':' suite - */ -static int -validate_class(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, classdef) && - ((nch == 4) || (nch == 6) || (nch == 7))); - - if (res) { - res = (validate_name(CHILD(tree, 0), "class") - && validate_ntype(CHILD(tree, 1), NAME) - && validate_colon(CHILD(tree, nch - 2)) - && validate_suite(CHILD(tree, nch - 1))); - } - else { - (void) validate_numnodes(tree, 4, "class"); - } - - if (res) { - if (nch == 7) { - res = ((validate_lparen(CHILD(tree, 2)) && - validate_arglist(CHILD(tree, 3)) && - validate_rparen(CHILD(tree, 4)))); - } - else if (nch == 6) { - res = (validate_lparen(CHILD(tree,2)) && - validate_rparen(CHILD(tree,3))); - } - } - return (res); -} - - -/* if_stmt: - * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] - */ -static int -validate_if(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, if_stmt) - && (nch >= 4) - && validate_name(CHILD(tree, 0), "if") - && validate_test(CHILD(tree, 1)) - && validate_colon(CHILD(tree, 2)) - && validate_suite(CHILD(tree, 3))); - - if (res && ((nch % 4) == 3)) { - /* ... 'else' ':' suite */ - res = (validate_name(CHILD(tree, nch - 3), "else") - && validate_colon(CHILD(tree, nch - 2)) - && validate_suite(CHILD(tree, nch - 1))); - nch -= 3; - } - else if (!res && !PyErr_Occurred()) - (void) validate_numnodes(tree, 4, "if"); - if ((nch % 4) != 0) - /* Will catch the case for nch < 4 */ - res = validate_numnodes(tree, 0, "if"); - else if (res && (nch > 4)) { - /* ... ('elif' test ':' suite)+ ... */ - int j = 4; - while ((j < nch) && res) { - res = (validate_name(CHILD(tree, j), "elif") - && validate_colon(CHILD(tree, j + 2)) - && validate_test(CHILD(tree, j + 1)) - && validate_suite(CHILD(tree, j + 3))); - j += 4; - } - } - return (res); -} - - -/* parameters: - * '(' [varargslist] ')' - * - */ -static int -validate_parameters(node *tree) -{ - int nch = NCH(tree); - int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3)); - - if (res) { - res = (validate_lparen(CHILD(tree, 0)) - && validate_rparen(CHILD(tree, nch - 1))); - if (res && (nch == 3)) - res = validate_varargslist(CHILD(tree, 1)); - } - else { - (void) validate_numnodes(tree, 2, "parameters"); - } - return (res); -} - - -/* validate_suite() - * - * suite: - * simple_stmt - * | NEWLINE INDENT stmt+ DEDENT - */ -static int -validate_suite(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4))); - - if (res && (nch == 1)) - res = validate_simple_stmt(CHILD(tree, 0)); - else if (res) { - /* NEWLINE INDENT stmt+ DEDENT */ - res = (validate_newline(CHILD(tree, 0)) - && validate_indent(CHILD(tree, 1)) - && validate_stmt(CHILD(tree, 2)) - && validate_dedent(CHILD(tree, nch - 1))); - - if (res && (nch > 4)) { - int i = 3; - --nch; /* forget the DEDENT */ - for ( ; res && (i < nch); ++i) - res = validate_stmt(CHILD(tree, i)); - } - else if (nch < 4) - res = validate_numnodes(tree, 4, "suite"); - } - return (res); -} - - -static int -validate_testlist(node *tree) -{ - return (validate_repeating_list(tree, testlist, - validate_test, "testlist")); -} - -static int -validate_testlist_star_expr(node *tl) -{ - return (validate_repeating_list(tl, testlist_star_expr, validate_test_or_star_expr, - "testlist")); -} - - -/* validate either vfpdef or tfpdef. - * vfpdef: NAME - * tfpdef: NAME [':' test] - */ -static int -validate_vfpdef(node *tree) -{ - int nch = NCH(tree); - if (TYPE(tree) == vfpdef) { - return nch == 1 && validate_name(CHILD(tree, 0), NULL); - } - else if (TYPE(tree) == tfpdef) { - if (nch == 1) { - return validate_name(CHILD(tree, 0), NULL); - } - else if (nch == 3) { - return validate_name(CHILD(tree, 0), NULL) && - validate_colon(CHILD(tree, 1)) && - validate_test(CHILD(tree, 2)); - } - } - return 0; -} - -/* '*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef - * ..or tfpdef in place of vfpdef. vfpdef: NAME; tfpdef: NAME [':' test] - */ -static int -validate_varargslist_trailer(node *tree, int start) -{ - int nch = NCH(tree); - int res = 0; - - if (nch <= start) { - err_string("expected variable argument trailer for varargslist"); - return 0; - } - if (TYPE(CHILD(tree, start)) == STAR) { - /* - * '*' [vfpdef] - */ - res = validate_star(CHILD(tree, start++)); - if (res && start < nch && (TYPE(CHILD(tree, start)) == vfpdef || - TYPE(CHILD(tree, start)) == tfpdef)) - res = validate_vfpdef(CHILD(tree, start++)); - /* - * (',' vfpdef ['=' test])* - */ - while (res && start + 1 < nch && ( - TYPE(CHILD(tree, start + 1)) == vfpdef || - TYPE(CHILD(tree, start + 1)) == tfpdef)) { - res = (validate_comma(CHILD(tree, start++)) - && validate_vfpdef(CHILD(tree, start++))); - if (res && start + 1 < nch && TYPE(CHILD(tree, start)) == EQUAL) - res = (validate_equal(CHILD(tree, start++)) - && validate_test(CHILD(tree, start++))); - } - /* - * [',' '**' vfpdef] - */ - if (res && start + 2 < nch && TYPE(CHILD(tree, start+1)) == DOUBLESTAR) - res = (validate_comma(CHILD(tree, start++)) - && validate_doublestar(CHILD(tree, start++)) - && validate_vfpdef(CHILD(tree, start++))); - } - else if (TYPE(CHILD(tree, start)) == DOUBLESTAR) { - /* - * '**' vfpdef - */ - if (start + 1 < nch) - res = (validate_doublestar(CHILD(tree, start++)) - && validate_vfpdef(CHILD(tree, start++))); - else { - res = 0; - err_string("expected vfpdef after ** in varargslist trailer"); - } - } - else { - res = 0; - err_string("expected * or ** in varargslist trailer"); - } - - if (res && start != nch) { - res = 0; - err_string("unexpected extra children in varargslist trailer"); - } - return res; -} - - -/* validate_varargslist() - * - * Validate typedargslist or varargslist. - * - * typedargslist: ((tfpdef ['=' test] ',')* - * ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | - * '**' tfpdef) - * | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) - * tfpdef: NAME [':' test] - * varargslist: ((vfpdef ['=' test] ',')* - * ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | - * '**' vfpdef) - * | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) - * vfpdef: NAME - * - */ -static int -validate_varargslist(node *tree) -{ - int nch = NCH(tree); - int res = (TYPE(tree) == varargslist || - TYPE(tree) == typedargslist) && - (nch != 0); - int sym; - node *ch; - int i = 0; - - if (!res) - return 0; - if (nch < 1) { - err_string("varargslist missing child nodes"); - return 0; - } - while (i < nch) { - ch = CHILD(tree, i); - sym = TYPE(ch); - if (sym == vfpdef || sym == tfpdef) { - /* validate (vfpdef ['=' test] ',')+ */ - res = validate_vfpdef(ch); - ++i; - if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) { - res = (validate_equal(CHILD(tree, i)) - && validate_test(CHILD(tree, i+1))); - if (res) - i += 2; - } - if (res && i < nch) { - res = validate_comma(CHILD(tree, i)); - ++i; - } - } else if (sym == DOUBLESTAR || sym == STAR) { - res = validate_varargslist_trailer(tree, i); - break; - } else { - res = 0; - err_string("illegal formation for varargslist"); - } - } - return res; -} - - -/* comp_iter: comp_for | comp_if - */ -static int -validate_comp_iter(node *tree) -{ - int res = (validate_ntype(tree, comp_iter) - && validate_numnodes(tree, 1, "comp_iter")); - if (res && TYPE(CHILD(tree, 0)) == comp_for) - res = validate_comp_for(CHILD(tree, 0)); - else - res = validate_comp_if(CHILD(tree, 0)); - - return res; -} - -/* comp_for: 'for' exprlist 'in' test [comp_iter] - */ -static int -validate_comp_for(node *tree) -{ - int nch = NCH(tree); - int res; - - if (nch == 5) - res = validate_comp_iter(CHILD(tree, 4)); - else - res = validate_numnodes(tree, 4, "comp_for"); - - if (res) - res = (validate_name(CHILD(tree, 0), "for") - && validate_exprlist(CHILD(tree, 1)) - && validate_name(CHILD(tree, 2), "in") - && validate_or_test(CHILD(tree, 3))); - - return res; -} - -/* comp_if: 'if' test_nocond [comp_iter] - */ -static int -validate_comp_if(node *tree) -{ - int nch = NCH(tree); - int res; - - if (nch == 3) - res = validate_comp_iter(CHILD(tree, 2)); - else - res = validate_numnodes(tree, 2, "comp_if"); - - if (res) - res = (validate_name(CHILD(tree, 0), "if") - && validate_test_nocond(CHILD(tree, 1))); - - return res; -} - - -/* simple_stmt | compound_stmt - * - */ -static int -validate_stmt(node *tree) -{ - int res = (validate_ntype(tree, stmt) - && validate_numnodes(tree, 1, "stmt")); - - if (res) { - tree = CHILD(tree, 0); - - if (TYPE(tree) == simple_stmt) - res = validate_simple_stmt(tree); - else - res = validate_compound_stmt(tree); - } - return (res); -} - - -/* small_stmt (';' small_stmt)* [';'] NEWLINE - * - */ -static int -validate_simple_stmt(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, simple_stmt) - && (nch >= 2) - && validate_small_stmt(CHILD(tree, 0)) - && validate_newline(CHILD(tree, nch - 1))); - - if (nch < 2) - res = validate_numnodes(tree, 2, "simple_stmt"); - --nch; /* forget the NEWLINE */ - if (res && is_even(nch)) - res = validate_semi(CHILD(tree, --nch)); - if (res && (nch > 2)) { - int i; - - for (i = 1; res && (i < nch); i += 2) - res = (validate_semi(CHILD(tree, i)) - && validate_small_stmt(CHILD(tree, i + 1))); - } - return (res); -} - - -static int -validate_small_stmt(node *tree) -{ - int nch = NCH(tree); - int res = validate_numnodes(tree, 1, "small_stmt"); - - if (res) { - int ntype = TYPE(CHILD(tree, 0)); - - if ( (ntype == expr_stmt) - || (ntype == del_stmt) - || (ntype == pass_stmt) - || (ntype == flow_stmt) - || (ntype == import_stmt) - || (ntype == global_stmt) - || (ntype == nonlocal_stmt) - || (ntype == assert_stmt)) - res = validate_node(CHILD(tree, 0)); - else { - res = 0; - err_string("illegal small_stmt child type"); - } - } - else if (nch == 1) { - res = 0; - PyErr_Format(parser_error, - "Unrecognized child node of small_stmt: %d.", - TYPE(CHILD(tree, 0))); - } - return (res); -} - - -/* compound_stmt: - * if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated - */ -static int -validate_compound_stmt(node *tree) -{ - int res = (validate_ntype(tree, compound_stmt) - && validate_numnodes(tree, 1, "compound_stmt")); - int ntype; - - if (!res) - return (0); - - tree = CHILD(tree, 0); - ntype = TYPE(tree); - if ( (ntype == if_stmt) - || (ntype == while_stmt) - || (ntype == for_stmt) - || (ntype == try_stmt) - || (ntype == with_stmt) - || (ntype == funcdef) - || (ntype == async_stmt) - || (ntype == classdef) - || (ntype == decorated)) - res = validate_node(tree); - else { - res = 0; - PyErr_Format(parser_error, - "Illegal compound statement type: %d.", TYPE(tree)); - } - return (res); -} - -static int -validate_yield_or_testlist(node *tree, int tse) -{ - if (TYPE(tree) == yield_expr) { - return validate_yield_expr(tree); - } - else { - if (tse) - return validate_testlist_star_expr(tree); - else - return validate_testlist(tree); - } -} - -static int -validate_expr_stmt(node *tree) -{ - int j; - int nch = NCH(tree); - int res = (validate_ntype(tree, expr_stmt) - && is_odd(nch) - && validate_testlist_star_expr(CHILD(tree, 0))); - - if (res && nch == 3 - && TYPE(CHILD(tree, 1)) == augassign) { - res = validate_numnodes(CHILD(tree, 1), 1, "augassign") - && validate_yield_or_testlist(CHILD(tree, 2), 0); - - if (res) { - char *s = STR(CHILD(CHILD(tree, 1), 0)); - - res = (strcmp(s, "+=") == 0 - || strcmp(s, "-=") == 0 - || strcmp(s, "*=") == 0 - || strcmp(s, "/=") == 0 - || strcmp(s, "//=") == 0 - || strcmp(s, "%=") == 0 - || strcmp(s, "&=") == 0 - || strcmp(s, "|=") == 0 - || strcmp(s, "^=") == 0 - || strcmp(s, "<<=") == 0 - || strcmp(s, ">>=") == 0 - || strcmp(s, "**=") == 0); - if (!res) - err_string("illegal augmented assignment operator"); - } - } - else { - for (j = 1; res && (j < nch); j += 2) - res = validate_equal(CHILD(tree, j)) - && validate_yield_or_testlist(CHILD(tree, j + 1), 1); - } - return (res); -} - - -static int -validate_del_stmt(node *tree) -{ - return (validate_numnodes(tree, 2, "del_stmt") - && validate_name(CHILD(tree, 0), "del") - && validate_exprlist(CHILD(tree, 1))); -} - - -static int -validate_return_stmt(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, return_stmt) - && ((nch == 1) || (nch == 2)) - && validate_name(CHILD(tree, 0), "return")); - - if (res && (nch == 2)) - res = validate_testlist(CHILD(tree, 1)); - - return (res); -} - - -/* - * raise_stmt: - * - * 'raise' [test ['from' test]] - */ -static int -validate_raise_stmt(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, raise_stmt) - && ((nch == 1) || (nch == 2) || (nch == 4))); - - if (!res && !PyErr_Occurred()) - (void) validate_numnodes(tree, 2, "raise"); - - if (res) { - res = validate_name(CHILD(tree, 0), "raise"); - if (res && (nch >= 2)) - res = validate_test(CHILD(tree, 1)); - if (res && (nch == 4)) { - res = (validate_name(CHILD(tree, 2), "from") - && validate_test(CHILD(tree, 3))); - } - } - return (res); -} - - -/* yield_expr: 'yield' [yield_arg] - */ -static int -validate_yield_expr(node *tree) -{ - int nch = NCH(tree); - if (nch < 1 || nch > 2) - return 0; - if (!validate_ntype(tree, yield_expr)) - return 0; - if (!validate_name(CHILD(tree, 0), "yield")) - return 0; - if (nch == 2) { - if (!validate_yield_arg(CHILD(tree, 1))) - return 0; - } - return 1; -} - -/* yield_arg: 'from' test | testlist - */ -static int -validate_yield_arg(node *tree) -{ - int nch = NCH(tree); - if (!validate_ntype(tree, yield_arg)) - return 0; - switch (nch) { - case 1: - if (!validate_testlist(CHILD(tree, nch - 1))) - return 0; - break; - case 2: - if (!validate_name(CHILD(tree, 0), "from")) - return 0; - if (!validate_test(CHILD(tree, 1))) - return 0; - break; - default: - return 0; - } - return 1; -} - -/* yield_stmt: yield_expr - */ -static int -validate_yield_stmt(node *tree) -{ - return (validate_ntype(tree, yield_stmt) - && validate_numnodes(tree, 1, "yield_stmt") - && validate_yield_expr(CHILD(tree, 0))); -} - - -static int -validate_import_as_name(node *tree) -{ - int nch = NCH(tree); - int ok = validate_ntype(tree, import_as_name); - - if (ok) { - if (nch == 1) - ok = validate_name(CHILD(tree, 0), NULL); - else if (nch == 3) - ok = (validate_name(CHILD(tree, 0), NULL) - && validate_name(CHILD(tree, 1), "as") - && validate_name(CHILD(tree, 2), NULL)); - else - ok = validate_numnodes(tree, 3, "import_as_name"); - } - return ok; -} - - -/* dotted_name: NAME ("." NAME)* - */ -static int -validate_dotted_name(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, dotted_name) - && is_odd(nch) - && validate_name(CHILD(tree, 0), NULL)); - int i; - - for (i = 1; res && (i < nch); i += 2) { - res = (validate_dot(CHILD(tree, i)) - && validate_name(CHILD(tree, i+1), NULL)); - } - return res; -} - - -/* dotted_as_name: dotted_name [NAME NAME] - */ -static int -validate_dotted_as_name(node *tree) -{ - int nch = NCH(tree); - int res = validate_ntype(tree, dotted_as_name); - - if (res) { - if (nch == 1) - res = validate_dotted_name(CHILD(tree, 0)); - else if (nch == 3) - res = (validate_dotted_name(CHILD(tree, 0)) - && validate_name(CHILD(tree, 1), "as") - && validate_name(CHILD(tree, 2), NULL)); - else { - res = 0; - err_string("illegal number of children for dotted_as_name"); - } - } - return res; -} - - -/* dotted_as_name (',' dotted_as_name)* */ -static int -validate_dotted_as_names(node *tree) -{ - int nch = NCH(tree); - int res = is_odd(nch) && validate_dotted_as_name(CHILD(tree, 0)); - int i; - - for (i = 1; res && (i < nch); i += 2) - res = (validate_comma(CHILD(tree, i)) - && validate_dotted_as_name(CHILD(tree, i + 1))); - return (res); -} - - -/* import_as_name (',' import_as_name)* [','] */ -static int -validate_import_as_names(node *tree) -{ - int nch = NCH(tree); - int res = validate_import_as_name(CHILD(tree, 0)); - int i; - - for (i = 1; res && (i + 1 < nch); i += 2) - res = (validate_comma(CHILD(tree, i)) - && validate_import_as_name(CHILD(tree, i + 1))); - return (res); -} - - -/* 'import' dotted_as_names */ -static int -validate_import_name(node *tree) -{ - return (validate_ntype(tree, import_name) - && validate_numnodes(tree, 2, "import_name") - && validate_name(CHILD(tree, 0), "import") - && validate_dotted_as_names(CHILD(tree, 1))); -} - -/* Helper function to count the number of leading dots (or ellipsis tokens) in - * 'from ...module import name' - */ -static int -count_from_dots(node *tree) -{ - int i; - for (i = 1; i < NCH(tree); i++) - if (TYPE(CHILD(tree, i)) != DOT && TYPE(CHILD(tree, i)) != ELLIPSIS) - break; - return i - 1; -} - -/* import_from: ('from' ('.'* dotted_name | '.'+) - * 'import' ('*' | '(' import_as_names ')' | import_as_names)) - */ -static int -validate_import_from(node *tree) -{ - int nch = NCH(tree); - int ndots = count_from_dots(tree); - int havename = (TYPE(CHILD(tree, ndots + 1)) == dotted_name); - int offset = ndots + havename; - int res = validate_ntype(tree, import_from) - && (offset >= 1) - && (nch >= 3 + offset) - && validate_name(CHILD(tree, 0), "from") - && (!havename || validate_dotted_name(CHILD(tree, ndots + 1))) - && validate_name(CHILD(tree, offset + 1), "import"); - - if (res && TYPE(CHILD(tree, offset + 2)) == LPAR) - res = ((nch == offset + 5) - && validate_lparen(CHILD(tree, offset + 2)) - && validate_import_as_names(CHILD(tree, offset + 3)) - && validate_rparen(CHILD(tree, offset + 4))); - else if (res && TYPE(CHILD(tree, offset + 2)) != STAR) - res = validate_import_as_names(CHILD(tree, offset + 2)); - return (res); -} - - -/* import_stmt: import_name | import_from */ -static int -validate_import_stmt(node *tree) -{ - int nch = NCH(tree); - int res = validate_numnodes(tree, 1, "import_stmt"); - - if (res) { - int ntype = TYPE(CHILD(tree, 0)); - - if (ntype == import_name || ntype == import_from) - res = validate_node(CHILD(tree, 0)); - else { - res = 0; - err_string("illegal import_stmt child type"); - } - } - else if (nch == 1) { - res = 0; - PyErr_Format(parser_error, - "Unrecognized child node of import_stmt: %d.", - TYPE(CHILD(tree, 0))); - } - return (res); -} - - -/* global_stmt: - * - * 'global' NAME (',' NAME)* - */ -static int -validate_global_stmt(node *tree) -{ - int j; - int nch = NCH(tree); - int res = (validate_ntype(tree, global_stmt) - && is_even(nch) && (nch >= 2)); - - if (!res && !PyErr_Occurred()) - err_string("illegal global statement"); - - if (res) - res = (validate_name(CHILD(tree, 0), "global") - && validate_ntype(CHILD(tree, 1), NAME)); - for (j = 2; res && (j < nch); j += 2) - res = (validate_comma(CHILD(tree, j)) - && validate_ntype(CHILD(tree, j + 1), NAME)); - - return (res); -} - -/* nonlocal_stmt: - * - * 'nonlocal' NAME (',' NAME)* - */ -static int -validate_nonlocal_stmt(node *tree) -{ - int j; - int nch = NCH(tree); - int res = (validate_ntype(tree, nonlocal_stmt) - && is_even(nch) && (nch >= 2)); - - if (!res && !PyErr_Occurred()) - err_string("illegal nonlocal statement"); - - if (res) - res = (validate_name(CHILD(tree, 0), "nonlocal") - && validate_ntype(CHILD(tree, 1), NAME)); - for (j = 2; res && (j < nch); j += 2) - res = (validate_comma(CHILD(tree, j)) - && validate_ntype(CHILD(tree, j + 1), NAME)); - - return res; -} - -/* assert_stmt: - * - * 'assert' test [',' test] - */ -static int -validate_assert_stmt(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, assert_stmt) - && ((nch == 2) || (nch == 4)) - && (validate_name(CHILD(tree, 0), "assert")) - && validate_test(CHILD(tree, 1))); - - if (!res && !PyErr_Occurred()) - err_string("illegal assert statement"); - if (res && (nch > 2)) - res = (validate_comma(CHILD(tree, 2)) - && validate_test(CHILD(tree, 3))); - - return (res); -} - - -static int -validate_while(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, while_stmt) - && ((nch == 4) || (nch == 7)) - && validate_name(CHILD(tree, 0), "while") - && validate_test(CHILD(tree, 1)) - && validate_colon(CHILD(tree, 2)) - && validate_suite(CHILD(tree, 3))); - - if (res && (nch == 7)) - res = (validate_name(CHILD(tree, 4), "else") - && validate_colon(CHILD(tree, 5)) - && validate_suite(CHILD(tree, 6))); - - return (res); -} - - -static int -validate_for(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, for_stmt) - && ((nch == 6) || (nch == 9)) - && validate_name(CHILD(tree, 0), "for") - && validate_exprlist(CHILD(tree, 1)) - && validate_name(CHILD(tree, 2), "in") - && validate_testlist(CHILD(tree, 3)) - && validate_colon(CHILD(tree, 4)) - && validate_suite(CHILD(tree, 5))); - - if (res && (nch == 9)) - res = (validate_name(CHILD(tree, 6), "else") - && validate_colon(CHILD(tree, 7)) - && validate_suite(CHILD(tree, 8))); - - return (res); -} - - -/* try_stmt: - * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] - ['finally' ':' suite] - * | 'try' ':' suite 'finally' ':' suite - * - */ -static int -validate_try(node *tree) -{ - int nch = NCH(tree); - int pos = 3; - int res = (validate_ntype(tree, try_stmt) - && (nch >= 6) && ((nch % 3) == 0)); - - if (res) - res = (validate_name(CHILD(tree, 0), "try") - && validate_colon(CHILD(tree, 1)) - && validate_suite(CHILD(tree, 2)) - && validate_colon(CHILD(tree, nch - 2)) - && validate_suite(CHILD(tree, nch - 1))); - else if (!PyErr_Occurred()) { - const char* name = "except"; - if (TYPE(CHILD(tree, nch - 3)) != except_clause) - name = STR(CHILD(tree, nch - 3)); - - PyErr_Format(parser_error, - "Illegal number of children for try/%s node.", name); - } - /* Handle try/finally statement */ - if (res && (TYPE(CHILD(tree, pos)) == NAME) && - (strcmp(STR(CHILD(tree, pos)), "finally") == 0)) { - res = (validate_numnodes(tree, 6, "try/finally") - && validate_colon(CHILD(tree, 4)) - && validate_suite(CHILD(tree, 5))); - return (res); - } - /* try/except statement: skip past except_clause sections */ - while (res && pos < nch && (TYPE(CHILD(tree, pos)) == except_clause)) { - res = (validate_except_clause(CHILD(tree, pos)) - && validate_colon(CHILD(tree, pos + 1)) - && validate_suite(CHILD(tree, pos + 2))); - pos += 3; - } - /* skip else clause */ - if (res && pos < nch && (TYPE(CHILD(tree, pos)) == NAME) && - (strcmp(STR(CHILD(tree, pos)), "else") == 0)) { - res = (validate_colon(CHILD(tree, pos + 1)) - && validate_suite(CHILD(tree, pos + 2))); - pos += 3; - } - if (res && pos < nch) { - /* last clause must be a finally */ - res = (validate_name(CHILD(tree, pos), "finally") - && validate_numnodes(tree, pos + 3, "try/except/finally") - && validate_colon(CHILD(tree, pos + 1)) - && validate_suite(CHILD(tree, pos + 2))); - } - return (res); -} - - -static int -validate_except_clause(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, except_clause) - && ((nch == 1) || (nch == 2) || (nch == 4)) - && validate_name(CHILD(tree, 0), "except")); - - if (res && (nch > 1)) - res = validate_test(CHILD(tree, 1)); - if (res && (nch == 4)) - res = (validate_name(CHILD(tree, 2), "as") - && validate_ntype(CHILD(tree, 3), NAME)); - - return (res); -} - - -static int -validate_test(node *tree) -{ - int nch = NCH(tree); - int res = validate_ntype(tree, test) && is_odd(nch); - - if (res && (TYPE(CHILD(tree, 0)) == lambdef)) - res = ((nch == 1) - && validate_lambdef(CHILD(tree, 0))); - else if (res) { - res = validate_or_test(CHILD(tree, 0)); - res = (res && (nch == 1 || (nch == 5 && - validate_name(CHILD(tree, 1), "if") && - validate_or_test(CHILD(tree, 2)) && - validate_name(CHILD(tree, 3), "else") && - validate_test(CHILD(tree, 4))))); - } - return (res); -} - -static int -validate_test_nocond(node *tree) -{ - int nch = NCH(tree); - int res = validate_ntype(tree, test_nocond) && (nch == 1); - - if (res && (TYPE(CHILD(tree, 0)) == lambdef_nocond)) - res = (validate_lambdef_nocond(CHILD(tree, 0))); - else if (res) { - res = (validate_or_test(CHILD(tree, 0))); - } - return (res); -} - -static int -validate_or_test(node *tree) -{ - int nch = NCH(tree); - int res = validate_ntype(tree, or_test) && is_odd(nch); - - if (res) { - int pos; - res = validate_and_test(CHILD(tree, 0)); - for (pos = 1; res && (pos < nch); pos += 2) - res = (validate_name(CHILD(tree, pos), "or") - && validate_and_test(CHILD(tree, pos + 1))); - } - return (res); -} - - -static int -validate_and_test(node *tree) -{ - int pos; - int nch = NCH(tree); - int res = (validate_ntype(tree, and_test) - && is_odd(nch) - && validate_not_test(CHILD(tree, 0))); - - for (pos = 1; res && (pos < nch); pos += 2) - res = (validate_name(CHILD(tree, pos), "and") - && validate_not_test(CHILD(tree, 0))); - - return (res); -} - - -static int -validate_not_test(node *tree) -{ - int nch = NCH(tree); - int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2)); - - if (res) { - if (nch == 2) - res = (validate_name(CHILD(tree, 0), "not") - && validate_not_test(CHILD(tree, 1))); - else if (nch == 1) - res = validate_comparison(CHILD(tree, 0)); - } - return (res); -} - - -static int -validate_comparison(node *tree) -{ - int pos; - int nch = NCH(tree); - int res = (validate_ntype(tree, comparison) - && is_odd(nch) - && validate_expr(CHILD(tree, 0))); - - for (pos = 1; res && (pos < nch); pos += 2) - res = (validate_comp_op(CHILD(tree, pos)) - && validate_expr(CHILD(tree, pos + 1))); - - return (res); -} - - -static int -validate_comp_op(node *tree) -{ - int res = 0; - int nch = NCH(tree); - - if (!validate_ntype(tree, comp_op)) - return (0); - if (nch == 1) { - /* - * Only child will be a terminal with a well-defined symbolic name - * or a NAME with a string of either 'is' or 'in' - */ - tree = CHILD(tree, 0); - switch (TYPE(tree)) { - case LESS: - case GREATER: - case EQEQUAL: - case EQUAL: - case LESSEQUAL: - case GREATEREQUAL: - case NOTEQUAL: - res = 1; - break; - case NAME: - res = ((strcmp(STR(tree), "in") == 0) - || (strcmp(STR(tree), "is") == 0)); - if (!res) { - PyErr_Format(parser_error, - "illegal operator '%s'", STR(tree)); - } - break; - default: - err_string("illegal comparison operator type"); - break; - } - } - else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) { - res = (validate_ntype(CHILD(tree, 0), NAME) - && validate_ntype(CHILD(tree, 1), NAME) - && (((strcmp(STR(CHILD(tree, 0)), "is") == 0) - && (strcmp(STR(CHILD(tree, 1)), "not") == 0)) - || ((strcmp(STR(CHILD(tree, 0)), "not") == 0) - && (strcmp(STR(CHILD(tree, 1)), "in") == 0)))); - if (!res && !PyErr_Occurred()) - err_string("unknown comparison operator"); - } - return (res); -} - - -static int -validate_star_expr(node *tree) -{ - int res = validate_ntype(tree, star_expr); - if (!res) return res; - if (!validate_numnodes(tree, 2, "star_expr")) - return 0; - return validate_ntype(CHILD(tree, 0), STAR) && \ - validate_expr(CHILD(tree, 1)); -} - - -static int -validate_expr(node *tree) -{ - int j; - int nch = NCH(tree); - int res = (validate_ntype(tree, expr) - && is_odd(nch) - && validate_xor_expr(CHILD(tree, 0))); - - for (j = 2; res && (j < nch); j += 2) - res = (validate_xor_expr(CHILD(tree, j)) - && validate_vbar(CHILD(tree, j - 1))); - - return (res); -} - - -static int -validate_xor_expr(node *tree) -{ - int j; - int nch = NCH(tree); - int res = (validate_ntype(tree, xor_expr) - && is_odd(nch) - && validate_and_expr(CHILD(tree, 0))); - - for (j = 2; res && (j < nch); j += 2) - res = (validate_circumflex(CHILD(tree, j - 1)) - && validate_and_expr(CHILD(tree, j))); - - return (res); -} - - -static int -validate_and_expr(node *tree) -{ - int pos; - int nch = NCH(tree); - int res = (validate_ntype(tree, and_expr) - && is_odd(nch) - && validate_shift_expr(CHILD(tree, 0))); - - for (pos = 1; res && (pos < nch); pos += 2) - res = (validate_ampersand(CHILD(tree, pos)) - && validate_shift_expr(CHILD(tree, pos + 1))); - - return (res); -} - - -static int -validate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2) - { - int pos = 1; - int nch = NCH(tree); - int res = (is_odd(nch) - && (*termvalid)(CHILD(tree, 0))); - - for ( ; res && (pos < nch); pos += 2) { - if (TYPE(CHILD(tree, pos)) != op1) - res = validate_ntype(CHILD(tree, pos), op2); - if (res) - res = (*termvalid)(CHILD(tree, pos + 1)); - } - return (res); -} - - -static int -validate_shift_expr(node *tree) -{ - return (validate_ntype(tree, shift_expr) - && validate_chain_two_ops(tree, validate_arith_expr, - LEFTSHIFT, RIGHTSHIFT)); -} - - -static int -validate_arith_expr(node *tree) -{ - return (validate_ntype(tree, arith_expr) - && validate_chain_two_ops(tree, validate_term, PLUS, MINUS)); -} - - -static int -validate_term(node *tree) -{ - int pos = 1; - int nch = NCH(tree); - int res = (validate_ntype(tree, term) - && is_odd(nch) - && validate_factor(CHILD(tree, 0))); - - for ( ; res && (pos < nch); pos += 2) - res = (((TYPE(CHILD(tree, pos)) == STAR) - || (TYPE(CHILD(tree, pos)) == SLASH) - || (TYPE(CHILD(tree, pos)) == DOUBLESLASH) - || (TYPE(CHILD(tree, pos)) == PERCENT)) - && validate_factor(CHILD(tree, pos + 1))); - - return (res); -} - - -/* factor: - * - * factor: ('+'|'-'|'~') factor | power - */ -static int -validate_factor(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, factor) - && (((nch == 2) - && ((TYPE(CHILD(tree, 0)) == PLUS) - || (TYPE(CHILD(tree, 0)) == MINUS) - || (TYPE(CHILD(tree, 0)) == TILDE)) - && validate_factor(CHILD(tree, 1))) - || ((nch == 1) - && validate_power(CHILD(tree, 0))))); - return (res); -} - - -/* power: - * - * power: atom_expr trailer* ['**' factor] - */ -static int -validate_power(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, power) && (nch >= 1) - && validate_atom_expr(CHILD(tree, 0))); - - if (nch > 1) { - if (nch != 3) { - err_string("illegal number of nodes for 'power'"); - return (0); - } - res = (validate_doublestar(CHILD(tree, 1)) - && validate_factor(CHILD(tree, 2))); - } - - return (res); -} - - -/* atom_expr: - * - * atom_expr: [AWAIT] atom trailer* - */ -static int -validate_atom_expr(node *tree) -{ - int start = 0; - int nch = NCH(tree); - int res; - int pos; - - res = validate_ntype(tree, atom_expr) && (nch >= 1); - if (!res) { - return (res); - } - - if (TYPE(CHILD(tree, 0)) == AWAIT) { - start = 1; - if (nch < 2) { - err_string("illegal number of nodes for 'atom_expr'"); - return (0); - } - } - - res = validate_atom(CHILD(tree, start)); - if (res) { - pos = start + 1; - while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer)) - res = validate_trailer(CHILD(tree, pos++)); - } - - return (res); -} - - -static int -validate_atom(node *tree) -{ - int pos; - int nch = NCH(tree); - int res = validate_ntype(tree, atom); - - if (res && nch < 1) - res = validate_numnodes(tree, nch+1, "atom"); - if (res) { - switch (TYPE(CHILD(tree, 0))) { - case LPAR: - res = ((nch <= 3) - && (validate_rparen(CHILD(tree, nch - 1)))); - - if (res && (nch == 3)) { - if (TYPE(CHILD(tree, 1))==yield_expr) - res = validate_yield_expr(CHILD(tree, 1)); - else - res = validate_testlist_comp(CHILD(tree, 1)); - } - break; - case LSQB: - if (nch == 2) - res = validate_ntype(CHILD(tree, 1), RSQB); - else if (nch == 3) - res = (validate_testlist_comp(CHILD(tree, 1)) - && validate_ntype(CHILD(tree, 2), RSQB)); - else { - res = 0; - err_string("illegal list display atom"); - } - break; - case LBRACE: - res = ((nch <= 3) - && validate_ntype(CHILD(tree, nch - 1), RBRACE)); - - if (res && (nch == 3)) - res = validate_dictorsetmaker(CHILD(tree, 1)); - break; - case NAME: - case NUMBER: - case ELLIPSIS: - res = (nch == 1); - break; - case STRING: - for (pos = 1; res && (pos < nch); ++pos) - res = validate_ntype(CHILD(tree, pos), STRING); - break; - default: - res = 0; - break; - } - } - return (res); -} - - -/* testlist_comp: - * (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) - */ -static int -validate_testlist_comp(node *tree) -{ - int nch = NCH(tree); - int ok; - - if (nch == 0) { - err_string("missing child nodes of testlist_comp"); - return 0; - } - - if (nch == 2 && TYPE(CHILD(tree, 1)) == comp_for) { - ok = (validate_test(CHILD(tree, 0)) - && validate_comp_for(CHILD(tree, 1))); - } - else { - ok = validate_repeating_list(tree, - testlist_comp, - validate_test_or_star_expr, - "testlist_comp"); - } - return ok; -} - -/* decorator: - * '@' dotted_name [ '(' [arglist] ')' ] NEWLINE - */ -static int -validate_decorator(node *tree) -{ - int ok; - int nch = NCH(tree); - ok = (validate_ntype(tree, decorator) && - (nch == 3 || nch == 5 || nch == 6) && - validate_at(CHILD(tree, 0)) && - validate_dotted_name(CHILD(tree, 1)) && - validate_newline(RCHILD(tree, -1))); - - if (ok && nch != 3) { - ok = (validate_lparen(CHILD(tree, 2)) && - validate_rparen(RCHILD(tree, -2))); - - if (ok && nch == 6) - ok = validate_arglist(CHILD(tree, 3)); - } - - return ok; -} - -/* decorators: - * decorator+ - */ -static int -validate_decorators(node *tree) -{ - int i, nch, ok; - nch = NCH(tree); - ok = validate_ntype(tree, decorators) && nch >= 1; - - for (i = 0; ok && i < nch; ++i) - ok = validate_decorator(CHILD(tree, i)); - - return ok; -} - -/* with_item: - * test ['as' expr] - */ -static int -validate_with_item(node *tree) -{ - int nch = NCH(tree); - int ok = (validate_ntype(tree, with_item) - && (nch == 1 || nch == 3) - && validate_test(CHILD(tree, 0))); - if (ok && nch == 3) - ok = (validate_name(CHILD(tree, 1), "as") - && validate_expr(CHILD(tree, 2))); - return ok; -} - -/* with_stmt: - * 0 1 ... -2 -1 - * 'with' with_item (',' with_item)* ':' suite - */ -static int -validate_with_stmt(node *tree) -{ - int i; - int nch = NCH(tree); - int ok = (validate_ntype(tree, with_stmt) - && (nch % 2 == 0) - && validate_name(CHILD(tree, 0), "with") - && validate_colon(RCHILD(tree, -2)) - && validate_suite(RCHILD(tree, -1))); - for (i = 1; ok && i < nch - 2; i += 2) - ok = validate_with_item(CHILD(tree, i)); - return ok; -} - -/* funcdef: 'def' NAME parameters ['->' test] ':' suite */ - -static int -validate_funcdef(node *tree) -{ - int nch = NCH(tree); - int res = validate_ntype(tree, funcdef); - if (res) { - if (nch == 5) { - res = (validate_name(CHILD(tree, 0), "def") - && validate_ntype(CHILD(tree, 1), NAME) - && validate_parameters(CHILD(tree, 2)) - && validate_colon(CHILD(tree, 3)) - && validate_suite(CHILD(tree, 4))); - } - else if (nch == 7) { - res = (validate_name(CHILD(tree, 0), "def") - && validate_ntype(CHILD(tree, 1), NAME) - && validate_parameters(CHILD(tree, 2)) - && validate_rarrow(CHILD(tree, 3)) - && validate_test(CHILD(tree, 4)) - && validate_colon(CHILD(tree, 5)) - && validate_suite(CHILD(tree, 6))); - } - else { - res = 0; - err_string("illegal number of children for funcdef"); - } - } - return res; -} - -/* async_funcdef: ASYNC funcdef */ - -static int -validate_async_funcdef(node *tree) -{ - int nch = NCH(tree); - int res = validate_ntype(tree, async_funcdef); - if (res) { - if (nch == 2) { - res = (validate_ntype(CHILD(tree, 0), ASYNC) - && validate_funcdef(CHILD(tree, 1))); - } - else { - res = 0; - err_string("illegal number of children for async_funcdef"); - } - } - return res; -} - - -/* async_stmt: ASYNC (funcdef | with_stmt | for_stmt) */ - -static int -validate_async_stmt(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, async_stmt) - && validate_ntype(CHILD(tree, 0), ASYNC)); - - if (nch != 2) { - res = 0; - err_string("illegal number of children for async_stmt"); - } else { - if (TYPE(CHILD(tree, 1)) == funcdef) { - res = validate_funcdef(CHILD(tree, 1)); - } - else if (TYPE(CHILD(tree, 1)) == with_stmt) { - res = validate_with_stmt(CHILD(tree, 1)); - } - else if (TYPE(CHILD(tree, 1)) == for_stmt) { - res = validate_for(CHILD(tree, 1)); - } - } - - return res; -} - - - -/* decorated - * decorators (classdef | funcdef) - */ -static int -validate_decorated(node *tree) -{ - int nch = NCH(tree); - int ok = (validate_ntype(tree, decorated) - && (nch == 2) - && validate_decorators(RCHILD(tree, -2))); - if (TYPE(RCHILD(tree, -1)) == funcdef) - ok = ok && validate_funcdef(RCHILD(tree, -1)); - else - ok = ok && validate_class(RCHILD(tree, -1)); - return ok; -} - -static int -validate_lambdef(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, lambdef) - && ((nch == 3) || (nch == 4)) - && validate_name(CHILD(tree, 0), "lambda") - && validate_colon(CHILD(tree, nch - 2)) - && validate_test(CHILD(tree, nch - 1))); - - if (res && (nch == 4)) - res = validate_varargslist(CHILD(tree, 1)); - else if (!res && !PyErr_Occurred()) - (void) validate_numnodes(tree, 3, "lambdef"); - - return (res); -} - - -static int -validate_lambdef_nocond(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, lambdef_nocond) - && ((nch == 3) || (nch == 4)) - && validate_name(CHILD(tree, 0), "lambda") - && validate_colon(CHILD(tree, nch - 2)) - && validate_test(CHILD(tree, nch - 1))); - - if (res && (nch == 4)) - res = validate_varargslist(CHILD(tree, 1)); - else if (!res && !PyErr_Occurred()) - (void) validate_numnodes(tree, 3, "lambdef_nocond"); - - return (res); -} - - -/* arglist: - * - * (argument ',')* (argument [','] | '*' test [',' '**' test] | '**' test) - */ -static int -validate_arglist(node *tree) -{ - int nch = NCH(tree); - int i = 0; - int ok = 1; - - if (nch <= 0) - /* raise the right error from having an invalid number of children */ - return validate_numnodes(tree, nch + 1, "arglist"); - - if (nch > 1) { - for (i=0; i<nch; i++) { - if (TYPE(CHILD(tree, i)) == argument) { - node *ch = CHILD(tree, i); - if (NCH(ch) == 2 && TYPE(CHILD(ch, 1)) == comp_for) { - err_string("need '(', ')' for generator expression"); - return 0; - } - } - } - } - - while (ok && nch-i >= 2) { - /* skip leading (argument ',') */ - ok = (validate_argument(CHILD(tree, i)) - && validate_comma(CHILD(tree, i+1))); - if (ok) - i += 2; - else - PyErr_Clear(); - } - ok = 1; - if (nch-i > 0) { - int sym = TYPE(CHILD(tree, i)); - - if (sym == argument) { - ok = validate_argument(CHILD(tree, i)); - if (ok && i+1 != nch) { - err_string("illegal arglist specification" - " (extra stuff on end)"); - ok = 0; - } - } - else { - err_string("illegal arglist specification"); - ok = 0; - } - } - return (ok); -} - - - -/* argument: ( test [comp_for] | - * test '=' test | - * '**' test | - * '*' test ) - */ -static int -validate_argument(node *tree) -{ - int nch = NCH(tree); - int res = (validate_ntype(tree, argument) - && ((nch == 1) || (nch == 2) || (nch == 3))); - - if (res) { - if (TYPE(CHILD(tree, 0)) == DOUBLESTAR) { - res = validate_test(CHILD(tree, 1)); - } - else if (TYPE(CHILD(tree, 0)) == STAR) { - res = validate_test(CHILD(tree, 1)); - } - else if (nch == 1) { - res = validate_test(CHILD(tree, 0)); - } - else if (nch == 2) { - res = (validate_test(CHILD(tree, 0)) - && validate_comp_for(CHILD(tree, 1))); - } - else if (res && (nch == 3)) { - res = (validate_test(CHILD(tree, 0)) - && validate_equal(CHILD(tree, 1)) - && validate_test(CHILD(tree, 2))); - } - } - return (res); -} - - - -/* trailer: - * - * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME - */ -static int -validate_trailer(node *tree) -{ - int nch = NCH(tree); - int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3)); - - if (res) { - switch (TYPE(CHILD(tree, 0))) { - case LPAR: - res = validate_rparen(CHILD(tree, nch - 1)); - if (res && (nch == 3)) - res = validate_arglist(CHILD(tree, 1)); - break; - case LSQB: - res = (validate_numnodes(tree, 3, "trailer") - && validate_subscriptlist(CHILD(tree, 1)) - && validate_ntype(CHILD(tree, 2), RSQB)); - break; - case DOT: - res = (validate_numnodes(tree, 2, "trailer") - && validate_ntype(CHILD(tree, 1), NAME)); - break; - default: - res = 0; - break; - } - } - else { - (void) validate_numnodes(tree, 2, "trailer"); - } - return (res); -} - - -/* subscriptlist: - * - * subscript (',' subscript)* [','] - */ -static int -validate_subscriptlist(node *tree) -{ - return (validate_repeating_list(tree, subscriptlist, - validate_subscript, "subscriptlist")); -} - - -/* subscript: - * - * '.' '.' '.' | test | [test] ':' [test] [sliceop] - */ -static int -validate_subscript(node *tree) -{ - int offset = 0; - int nch = NCH(tree); - int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4); - - if (!res) { - if (!PyErr_Occurred()) - err_string("invalid number of arguments for subscript node"); - return (0); - } - if (TYPE(CHILD(tree, 0)) == DOT) - /* take care of ('.' '.' '.') possibility */ - return (validate_numnodes(tree, 3, "subscript") - && validate_dot(CHILD(tree, 0)) - && validate_dot(CHILD(tree, 1)) - && validate_dot(CHILD(tree, 2))); - if (nch == 1) { - if (TYPE(CHILD(tree, 0)) == test) - res = validate_test(CHILD(tree, 0)); - else - res = validate_colon(CHILD(tree, 0)); - return (res); - } - /* Must be [test] ':' [test] [sliceop], - * but at least one of the optional components will - * be present, but we don't know which yet. - */ - if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) { - res = validate_test(CHILD(tree, 0)); - offset = 1; - } - if (res) - res = validate_colon(CHILD(tree, offset)); - if (res) { - int rem = nch - ++offset; - if (rem) { - if (TYPE(CHILD(tree, offset)) == test) { - res = validate_test(CHILD(tree, offset)); - ++offset; - --rem; - } - if (res && rem) - res = validate_sliceop(CHILD(tree, offset)); - } - } - return (res); -} - - -static int -validate_sliceop(node *tree) -{ - int nch = NCH(tree); - int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop")) - && validate_ntype(tree, sliceop); - if (!res && !PyErr_Occurred()) { - res = validate_numnodes(tree, 1, "sliceop"); - } - if (res) - res = validate_colon(CHILD(tree, 0)); - if (res && (nch == 2)) - res = validate_test(CHILD(tree, 1)); - - return (res); -} - - -static int -validate_test_or_star_expr(node *n) -{ - if (TYPE(n) == test) - return validate_test(n); - return validate_star_expr(n); -} - -static int -validate_expr_or_star_expr(node *n) -{ - if (TYPE(n) == expr) - return validate_expr(n); - return validate_star_expr(n); -} - - -static int -validate_exprlist(node *tree) -{ - return (validate_repeating_list(tree, exprlist, - validate_expr_or_star_expr, "exprlist")); -} - -/* Incrementing validate functions returns nonzero iff success (like other - * validate functions, and advance *i by the length of the matched pattern. */ - -/* test ':' test */ -static int -validate_test_colon_test_inc(node *tree, int *i) -{ - return (validate_test(CHILD(tree, (*i)++)) - && validate_colon(CHILD(tree, (*i)++)) - && validate_test(CHILD(tree, (*i)++))); -} - -/* test ':' test | '**' expr */ -static int -validate_dict_element_inc(node *tree, int *i) -{ - int nch = NCH(tree); - int res = 0; - if (nch - *i >= 2) { - if (TYPE(CHILD(tree, *i+1)) == COLON) { - /* test ':' test */ - res = validate_test_colon_test_inc(tree, i); - } else { - /* '**' expr */ - res = (validate_doublestar(CHILD(tree, (*i)++)) - && validate_expr(CHILD(tree, (*i)++))); - } - } - return res; -} - -/* - * dictorsetmaker: - * - * ( ((test ':' test | '**' expr) - * (comp_for | (',' (test ':' test | '**' expr))* [','])) | - * ((test | '*' test) - * (comp_for | (',' (test | '*' test))* [','])) ) - */ -static int -validate_dictorsetmaker(node *tree) -{ - int nch = NCH(tree); - int res; - int i = 0; - - res = validate_ntype(tree, dictorsetmaker); - if (!res) - return 0; - - if (nch - i < 1) { - /* Unconditionally raise. */ - (void) validate_numnodes(tree, 1, "dictorsetmaker"); - return 0; - } - - if (nch - i >= 2 - && ((TYPE(CHILD(tree, i+1)) == COLON) || - (TYPE(CHILD(tree, i)) == DOUBLESTAR))) { - /* Dictionary display or dictionary comprehension. */ - if (nch - i >= 4 && TYPE(CHILD(tree, i+3)) == comp_for) { - /* Dictionary comprehension. */ - res = (validate_test_colon_test_inc(tree, &i) - && validate_comp_for(CHILD(tree, i++))); - if (!res) - return 0; - } else { - /* Dictionary display. */ - return validate_repeating_list_variable( - tree, - dictorsetmaker, - validate_dict_element_inc, - &i, - "dictorsetmaker"); - } - } else { - /* Set display or set comprehension. */ - if (nch - i >= 2 && TYPE(CHILD(tree, i + 1)) == comp_for) { - /* Set comprehension. */ - res = (validate_test(CHILD(tree, i++)) - && validate_comp_for(CHILD(tree, i++))); - if (!res) - return 0; - } else { - /* Set display. */ - return validate_repeating_list(tree, - dictorsetmaker, - validate_test_or_star_expr, - "dictorsetmaker"); - } - } - - if (nch - i > 0) { - err_string("Illegal trailing nodes for dictorsetmaker."); - return 0; - } - - return 1; -} - - -static int -validate_eval_input(node *tree) -{ - int pos; - int nch = NCH(tree); - int res = (validate_ntype(tree, eval_input) - && (nch >= 2) - && validate_testlist(CHILD(tree, 0)) - && validate_ntype(CHILD(tree, nch - 1), ENDMARKER)); - - for (pos = 1; res && (pos < (nch - 1)); ++pos) - res = validate_ntype(CHILD(tree, pos), NEWLINE); - - return (res); -} - - -static int -validate_node(node *tree) -{ - int nch = 0; /* num. children on current node */ - int res = 1; /* result value */ - node* next = 0; /* node to process after this one */ - - while (res && (tree != 0)) { - nch = NCH(tree); - next = 0; - switch (TYPE(tree)) { - /* - * Definition nodes. - */ - case async_funcdef: - res = validate_async_funcdef(tree); - break; - case async_stmt: - res = validate_async_stmt(tree); - break; - case funcdef: - res = validate_funcdef(tree); - break; - case with_stmt: - res = validate_with_stmt(tree); - break; - case classdef: - res = validate_class(tree); - break; - case decorated: - res = validate_decorated(tree); - break; - /* - * "Trivial" parse tree nodes. - * (Why did I call these trivial?) - */ - case stmt: - res = validate_stmt(tree); - break; - case small_stmt: - /* - * expr_stmt | del_stmt | pass_stmt | flow_stmt | - * import_stmt | global_stmt | nonlocal_stmt | assert_stmt - */ - res = validate_small_stmt(tree); - break; - case flow_stmt: - res = (validate_numnodes(tree, 1, "flow_stmt") - && ((TYPE(CHILD(tree, 0)) == break_stmt) - || (TYPE(CHILD(tree, 0)) == continue_stmt) - || (TYPE(CHILD(tree, 0)) == yield_stmt) - || (TYPE(CHILD(tree, 0)) == return_stmt) - || (TYPE(CHILD(tree, 0)) == raise_stmt))); - if (res) - next = CHILD(tree, 0); - else if (nch == 1) - err_string("illegal flow_stmt type"); - break; - case yield_stmt: - res = validate_yield_stmt(tree); - break; - /* - * Compound statements. - */ - case simple_stmt: - res = validate_simple_stmt(tree); - break; - case compound_stmt: - res = validate_compound_stmt(tree); - break; - /* - * Fundamental statements. - */ - case expr_stmt: - res = validate_expr_stmt(tree); - break; - case del_stmt: - res = validate_del_stmt(tree); - break; - case pass_stmt: - res = (validate_numnodes(tree, 1, "pass") - && validate_name(CHILD(tree, 0), "pass")); - break; - case break_stmt: - res = (validate_numnodes(tree, 1, "break") - && validate_name(CHILD(tree, 0), "break")); - break; - case continue_stmt: - res = (validate_numnodes(tree, 1, "continue") - && validate_name(CHILD(tree, 0), "continue")); - break; - case return_stmt: - res = validate_return_stmt(tree); - break; - case raise_stmt: - res = validate_raise_stmt(tree); - break; - case import_stmt: - res = validate_import_stmt(tree); - break; - case import_name: - res = validate_import_name(tree); - break; - case import_from: - res = validate_import_from(tree); - break; - case global_stmt: - res = validate_global_stmt(tree); - break; - case nonlocal_stmt: - res = validate_nonlocal_stmt(tree); - break; - case assert_stmt: - res = validate_assert_stmt(tree); - break; - case if_stmt: - res = validate_if(tree); - break; - case while_stmt: - res = validate_while(tree); - break; - case for_stmt: - res = validate_for(tree); - break; - case try_stmt: - res = validate_try(tree); - break; - case suite: - res = validate_suite(tree); - break; - /* - * Expression nodes. - */ - case testlist: - res = validate_testlist(tree); - break; - case yield_expr: - res = validate_yield_expr(tree); - break; - case test: - res = validate_test(tree); - break; - case and_test: - res = validate_and_test(tree); - break; - case not_test: - res = validate_not_test(tree); - break; - case comparison: - res = validate_comparison(tree); - break; - case exprlist: - res = validate_exprlist(tree); - break; - case comp_op: - res = validate_comp_op(tree); - break; - case expr: - res = validate_expr(tree); - break; - case xor_expr: - res = validate_xor_expr(tree); - break; - case and_expr: - res = validate_and_expr(tree); - break; - case shift_expr: - res = validate_shift_expr(tree); - break; - case arith_expr: - res = validate_arith_expr(tree); - break; - case term: - res = validate_term(tree); - break; - case factor: - res = validate_factor(tree); - break; - case power: - res = validate_power(tree); - break; - case atom: - res = validate_atom(tree); - break; - - default: - /* Hopefully never reached! */ - err_string("unrecognized node type"); - res = 0; - break; - } - tree = next; - } - return (res); -} - - -static int -validate_expr_tree(node *tree) -{ - int res = validate_eval_input(tree); - - if (!res && !PyErr_Occurred()) - err_string("could not validate expression tuple"); - - return (res); -} - - -/* file_input: - * (NEWLINE | stmt)* ENDMARKER - */ -static int -validate_file_input(node *tree) -{ - int j; - int nch = NCH(tree) - 1; - int res = ((nch >= 0) - && validate_ntype(CHILD(tree, nch), ENDMARKER)); - - for (j = 0; res && (j < nch); ++j) { - if (TYPE(CHILD(tree, j)) == stmt) - res = validate_stmt(CHILD(tree, j)); - else - res = validate_newline(CHILD(tree, j)); - } - /* This stays in to prevent any internal failures from getting to the - * user. Hopefully, this won't be needed. If a user reports getting - * this, we have some debugging to do. - */ - if (!res && !PyErr_Occurred()) - err_string("VALIDATION FAILURE: report this to the maintainer!"); - - return (res); -} - -static int -validate_encoding_decl(node *tree) -{ - int nch = NCH(tree); - int res = ((nch == 1) - && validate_file_input(CHILD(tree, 0))); - - if (!res && !PyErr_Occurred()) - err_string("Error Parsing encoding_decl"); - - return res; -} - static PyObject* pickle_constructor = NULL; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index f6f08bf..c1ba7ba 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -32,6 +32,12 @@ #include "winreparse.h" #endif +/* On android API level 21, 'AT_EACCESS' is not declared although + * HAVE_FACCESSAT is defined. */ +#ifdef __ANDROID__ +#undef HAVE_FACCESSAT +#endif + #include <stdio.h> /* needed for ctermid() */ #ifdef __cplusplus @@ -127,6 +133,13 @@ corresponding Unix manual entries for more information on calls."); #include <sys/sysctl.h> #endif +#ifdef HAVE_LINUX_RANDOM_H +# include <linux/random.h> +#endif +#ifdef HAVE_GETRANDOM_SYSCALL +# include <sys/syscall.h> +#endif + #if defined(MS_WINDOWS) # define TERMSIZE_USE_CONIO #elif defined(HAVE_SYS_IOCTL_H) @@ -151,6 +164,8 @@ corresponding Unix manual entries for more information on calls."); #define HAVE_GETLOGIN 1 #define HAVE_SPAWNV 1 #define HAVE_EXECV 1 +#define HAVE_WSPAWNV 1 +#define HAVE_WEXECV 1 #define HAVE_PIPE 1 #define HAVE_SYSTEM 1 #define HAVE_CWAIT 1 @@ -634,22 +649,14 @@ fail: #endif /* MS_WINDOWS */ -#ifdef HAVE_LONG_LONG -# define _PyLong_FromDev PyLong_FromLongLong -#else -# define _PyLong_FromDev PyLong_FromLong -#endif +#define _PyLong_FromDev PyLong_FromLongLong #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) static int _Py_Dev_Converter(PyObject *obj, void *p) { -#ifdef HAVE_LONG_LONG *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); -#else - *((dev_t *)p) = PyLong_AsUnsignedLong(obj); -#endif if (PyErr_Occurred()) return 0; return 1; @@ -671,21 +678,20 @@ _Py_Dev_Converter(PyObject *obj, void *p) #endif static int -_fd_converter(PyObject *o, int *p, const char *allowed) +_fd_converter(PyObject *o, int *p) { int overflow; long long_value; PyObject *index = PyNumber_Index(o); if (index == NULL) { - PyErr_Format(PyExc_TypeError, - "argument should be %s, not %.200s", - allowed, Py_TYPE(o)->tp_name); return 0; } + assert(PyLong_Check(index)); long_value = PyLong_AsLongAndOverflow(index, &overflow); Py_DECREF(index); + assert(!PyErr_Occurred()); if (overflow > 0 || long_value > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "fd is greater than maximum"); @@ -708,7 +714,15 @@ dir_fd_converter(PyObject *o, void *p) *(int *)p = DEFAULT_DIR_FD; return 1; } - return _fd_converter(o, (int *)p, "integer"); + else if (PyIndex_Check(o)) { + return _fd_converter(o, (int *)p); + } + else { + PyErr_Format(PyExc_TypeError, + "argument should be integer or None, not %.200s", + Py_TYPE(o)->tp_name); + return 0; + } } @@ -723,7 +737,7 @@ dir_fd_converter(PyObject *o, void *p) * * * On Windows, if we get a (Unicode) string we * extract the wchar_t * and return it; if we get - * bytes we extract the char * and return that. + * bytes we decode to wchar_t * and return that. * * * On all other platforms, strings are encoded * to bytes using PyUnicode_FSConverter, then we @@ -755,7 +769,9 @@ dir_fd_converter(PyObject *o, void *p) * and was not encoded. (Only used on Windows.) * path.narrow * Points to the path if it was expressed as bytes, - * or it was Unicode and was encoded to bytes. + * or it was Unicode and was encoded to bytes. (On Windows, + * is an non-zero integer if the path was expressed as bytes. + * The type is deliberately incompatible to prevent misuse.) * path.fd * Contains a file descriptor if path.accept_fd was true * and the caller provided a signed integer instead of any @@ -799,16 +815,25 @@ typedef struct { const char *argument_name; int nullable; int allow_fd; - wchar_t *wide; - char *narrow; + const wchar_t *wide; +#ifdef MS_WINDOWS + BOOL narrow; +#else + const char *narrow; +#endif int fd; Py_ssize_t length; PyObject *object; PyObject *cleanup; } path_t; +#ifdef MS_WINDOWS +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ + {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL} +#else #define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} +#endif static void path_cleanup(path_t *path) { @@ -818,11 +843,19 @@ path_cleanup(path_t *path) { } static int -path_converter(PyObject *o, void *p) { +path_converter(PyObject *o, void *p) +{ path_t *path = (path_t *)p; - PyObject *unicode, *bytes; + PyObject *bytes, *to_cleanup = NULL; Py_ssize_t length; - char *narrow; + int is_index, is_buffer, is_bytes, is_unicode; + /* Default to failure, forcing explicit signaling of succcess. */ + int ret = 0; + const char *narrow; +#ifdef MS_WINDOWS + PyObject *wo; + const wchar_t *wide; +#endif #define FORMAT_EXCEPTION(exc, fmt) \ PyErr_Format(exc, "%s%s" fmt, \ @@ -836,122 +869,191 @@ path_converter(PyObject *o, void *p) { return 1; } - /* ensure it's always safe to call path_cleanup() */ + /* Ensure it's always safe to call path_cleanup(). */ path->cleanup = NULL; - if (o == Py_None) { - if (!path->nullable) { - FORMAT_EXCEPTION(PyExc_TypeError, - "can't specify None for %s argument"); - return 0; - } + if ((o == Py_None) && path->nullable) { path->wide = NULL; +#ifdef MS_WINDOWS + path->narrow = FALSE; +#else path->narrow = NULL; +#endif path->length = 0; path->object = o; path->fd = -1; return 1; } - unicode = PyUnicode_FromObject(o); - if (unicode) { -#ifdef MS_WINDOWS - wchar_t *wide; + /* Only call this here so that we don't treat the return value of + os.fspath() as an fd or buffer. */ + is_index = path->allow_fd && PyIndex_Check(o); + is_buffer = PyObject_CheckBuffer(o); + is_bytes = PyBytes_Check(o); + is_unicode = PyUnicode_Check(o); + + if (!is_index && !is_buffer && !is_unicode && !is_bytes) { + /* Inline PyOS_FSPath() for better error messages. */ + _Py_IDENTIFIER(__fspath__); + PyObject *func = NULL; - wide = PyUnicode_AsUnicodeAndSize(unicode, &length); + func = _PyObject_LookupSpecial(o, &PyId___fspath__); + if (NULL == func) { + goto error_exit; + } + + o = to_cleanup = PyObject_CallFunctionObjArgs(func, NULL); + Py_DECREF(func); + if (NULL == o) { + goto error_exit; + } + else if (PyUnicode_Check(o)) { + is_unicode = 1; + } + else if (PyBytes_Check(o)) { + is_bytes = 1; + } + else { + goto error_exit; + } + } + + if (is_unicode) { +#ifdef MS_WINDOWS + wide = PyUnicode_AsWideCharString(o, &length); if (!wide) { - Py_DECREF(unicode); - return 0; + goto exit; } if (length > 32767) { FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); - Py_DECREF(unicode); - return 0; + goto exit; } if (wcslen(wide) != length) { - FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character"); - Py_DECREF(unicode); - return 0; + FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); + goto exit; } path->wide = wide; - path->narrow = NULL; path->length = length; path->object = o; path->fd = -1; - path->cleanup = unicode; - return Py_CLEANUP_SUPPORTED; + ret = 1; + goto exit; #else - int converted = PyUnicode_FSConverter(unicode, &bytes); - Py_DECREF(unicode); - if (!converted) - bytes = NULL; + if (!PyUnicode_FSConverter(o, &bytes)) { + goto exit; + } #endif } - else { - PyErr_Clear(); - if (PyObject_CheckBuffer(o)) - bytes = PyBytes_FromObject(o); - else - bytes = NULL; + else if (is_bytes) { + bytes = o; + Py_INCREF(bytes); + } + else if (is_buffer) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "%s%s%s should be %s, not %.200s", + path->function_name ? path->function_name : "", + path->function_name ? ": " : "", + path->argument_name ? path->argument_name : "path", + path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " + "integer or None" : + path->allow_fd ? "string, bytes, os.PathLike or integer" : + path->nullable ? "string, bytes, os.PathLike or None" : + "string, bytes or os.PathLike", + Py_TYPE(o)->tp_name)) { + goto exit; + } + bytes = PyBytes_FromObject(o); if (!bytes) { - PyErr_Clear(); - if (path->allow_fd) { - int fd; - int result = _fd_converter(o, &fd, - "string, bytes or integer"); - if (result) { - path->wide = NULL; - path->narrow = NULL; - path->length = 0; - path->object = o; - path->fd = fd; - return result; - } - } + goto exit; } } - - if (!bytes) { - if (!PyErr_Occurred()) - FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter"); - return 0; - } - + else if (is_index) { + if (!_fd_converter(o, &path->fd)) { + goto exit; + } + path->wide = NULL; #ifdef MS_WINDOWS - if (win32_warn_bytes_api()) { - Py_DECREF(bytes); - return 0; - } + path->narrow = FALSE; +#else + path->narrow = NULL; #endif - - length = PyBytes_GET_SIZE(bytes); -#ifdef MS_WINDOWS - if (length > MAX_PATH-1) { - FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); - Py_DECREF(bytes); - return 0; + path->length = 0; + path->object = o; + ret = 1; + goto exit; + } + else { + error_exit: + PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s", + path->function_name ? path->function_name : "", + path->function_name ? ": " : "", + path->argument_name ? path->argument_name : "path", + path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " + "integer or None" : + path->allow_fd ? "string, bytes, os.PathLike or integer" : + path->nullable ? "string, bytes, os.PathLike or None" : + "string, bytes or os.PathLike", + Py_TYPE(o)->tp_name); + goto exit; } -#endif + length = PyBytes_GET_SIZE(bytes); narrow = PyBytes_AS_STRING(bytes); if ((size_t)length != strlen(narrow)) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); Py_DECREF(bytes); - return 0; + goto exit; } +#ifdef MS_WINDOWS + wo = PyUnicode_DecodeFSDefaultAndSize( + narrow, + length + ); + if (!wo) { + goto exit; + } + + wide = PyUnicode_AsWideCharString(wo, &length); + Py_DECREF(wo); + + if (!wide) { + goto exit; + } + if (length > 32767) { + FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); + goto exit; + } + if (wcslen(wide) != length) { + FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); + goto exit; + } + path->wide = wide; + path->narrow = TRUE; +#else path->wide = NULL; path->narrow = narrow; +#endif path->length = length; path->object = o; path->fd = -1; - path->cleanup = bytes; - return Py_CLEANUP_SUPPORTED; + if (bytes == o) { + Py_DECREF(bytes); + ret = 1; + } + else { + path->cleanup = bytes; + ret = Py_CLEANUP_SUPPORTED; + } + exit: + Py_XDECREF(to_cleanup); + return ret; } static void -argument_unavailable_error(char *function_name, char *argument_name) { +argument_unavailable_error(const char *function_name, const char *argument_name) +{ PyErr_Format(PyExc_NotImplementedError, "%s%s%s unavailable on this platform", (function_name != NULL) ? function_name : "", @@ -974,7 +1076,8 @@ dir_fd_unavailable(PyObject *o, void *p) } static int -fd_specified(char *function_name, int fd) { +fd_specified(const char *function_name, int fd) +{ if (fd == -1) return 0; @@ -983,7 +1086,8 @@ fd_specified(char *function_name, int fd) { } static int -follow_symlinks_specified(char *function_name, int follow_symlinks) { +follow_symlinks_specified(const char *function_name, int follow_symlinks) +{ if (follow_symlinks) return 0; @@ -992,8 +1096,13 @@ follow_symlinks_specified(char *function_name, int follow_symlinks) { } static int -path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) { - if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) { +path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd) +{ + if (!path->wide && (dir_fd != DEFAULT_DIR_FD) +#ifndef MS_WINDOWS + && !path->narrow +#endif + ) { PyErr_Format(PyExc_ValueError, "%s: can't specify dir_fd without matching path", function_name); @@ -1003,7 +1112,8 @@ path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) { } static int -dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) { +dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd) +{ if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) { PyErr_Format(PyExc_ValueError, "%s: can't specify both dir_fd and fd", @@ -1014,8 +1124,9 @@ dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) { } static int -fd_and_follow_symlinks_invalid(char *function_name, int fd, - int follow_symlinks) { +fd_and_follow_symlinks_invalid(const char *function_name, int fd, + int follow_symlinks) +{ if ((fd > 0) && (!follow_symlinks)) { PyErr_Format(PyExc_ValueError, "%s: cannot use fd and follow_symlinks together", @@ -1026,8 +1137,9 @@ fd_and_follow_symlinks_invalid(char *function_name, int fd, } static int -dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd, - int follow_symlinks) { +dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd, + int follow_symlinks) +{ if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { PyErr_Format(PyExc_ValueError, "%s: cannot use dir_fd and follow_symlinks together", @@ -1038,7 +1150,7 @@ dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd, } #ifdef MS_WINDOWS - typedef PY_LONG_LONG Py_off_t; + typedef long long Py_off_t; #else typedef off_t Py_off_t; #endif @@ -1066,41 +1178,13 @@ PyLong_FromPy_off_t(Py_off_t offset) #endif } - -#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900 -/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to - * MSVC 14.0. This should eventually be removed. (issue23524) - */ -#define IOINFO_L2E 5 -#define IOINFO_ARRAYS 64 -#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) -#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS) -#define _NO_CONSOLE_FILENO (intptr_t)-2 - -/* the special case of checking dup2. The target fd must be in a sensible range */ -static int -_PyVerify_fd_dup2(int fd1, int fd2) -{ - if (!_PyVerify_fd(fd1)) - return 0; - if (fd2 == _NO_CONSOLE_FILENO) - return 0; - if ((unsigned)fd2 < _NHANDLE_) - return 1; - else - return 0; -} -#else -#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0) -#endif - #ifdef MS_WINDOWS static int win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) { - char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; + char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; DWORD n_bytes_returned; if (0 == DeviceIoControl( @@ -1159,7 +1243,7 @@ convertenviron(void) for (e = _wenviron; *e != NULL; e++) { PyObject *k; PyObject *v; - wchar_t *p = wcschr(*e, L'='); + const wchar_t *p = wcschr(*e, L'='); if (p == NULL) continue; k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e)); @@ -1187,7 +1271,7 @@ convertenviron(void) for (e = environ; *e != NULL; e++) { PyObject *k; PyObject *v; - char *p = strchr(*e, '='); + const char *p = strchr(*e, '='); if (p == NULL) continue; k = PyBytes_FromStringAndSize(*e, (int)(p-*e)); @@ -1222,7 +1306,7 @@ posix_error(void) #ifdef MS_WINDOWS static PyObject * -win32_error(char* function, const char* filename) +win32_error(const char* function, const char* filename) { /* XXX We should pass the function name along in the future. (winreg.c also wants to pass the function name.) @@ -1237,7 +1321,7 @@ win32_error(char* function, const char* filename) } static PyObject * -win32_error_object(char* function, PyObject* filename) +win32_error_object(const char* function, PyObject* filename) { /* XXX - see win32_error for comments on 'function' */ errno = GetLastError(); @@ -1297,9 +1381,6 @@ posix_fildes_fd(int fd, int (*func)(int)) int res; int async_err = 0; - if (!_PyVerify_fd(fd)) - return posix_error(); - do { Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH @@ -1320,31 +1401,6 @@ posix_fildes_fd(int fd, int (*func)(int)) it also needs to set "magic" environment variables indicating the per-drive current directory, which are of the form =<drive>: */ static BOOL __stdcall -win32_chdir(LPCSTR path) -{ - char new_path[MAX_PATH]; - int result; - char env[4] = "=x:"; - - if(!SetCurrentDirectoryA(path)) - return FALSE; - result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path); - if (!result) - return FALSE; - /* In the ANSI API, there should not be any paths longer - than MAX_PATH-1 (not including the final null character). */ - assert(result < Py_ARRAY_LENGTH(new_path)); - if (strncmp(new_path, "\\\\", 2) == 0 || - strncmp(new_path, "//", 2) == 0) - /* UNC path, nothing to do. */ - return TRUE; - env[1] = new_path[0]; - return SetEnvironmentVariableA(env, new_path); -} - -/* The Unicode version differs from the ANSI version - since the current directory might exceed MAX_PATH characters */ -static BOOL __stdcall win32_wchdir(LPCWSTR path) { wchar_t path_buf[MAX_PATH], *new_path = path_buf; @@ -1390,33 +1446,10 @@ win32_wchdir(LPCWSTR path) #define HAVE_STAT_NSEC 1 #define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1 -static BOOL -attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) -{ - HANDLE hFindFile; - WIN32_FIND_DATAA FileData; - hFindFile = FindFirstFileA(pszFile, &FileData); - if (hFindFile == INVALID_HANDLE_VALUE) - return FALSE; - FindClose(hFindFile); - memset(info, 0, sizeof(*info)); - *reparse_tag = 0; - info->dwFileAttributes = FileData.dwFileAttributes; - info->ftCreationTime = FileData.ftCreationTime; - info->ftLastAccessTime = FileData.ftLastAccessTime; - info->ftLastWriteTime = FileData.ftLastWriteTime; - info->nFileSizeHigh = FileData.nFileSizeHigh; - info->nFileSizeLow = FileData.nFileSizeLow; -/* info->nNumberOfLinks = 1; */ - if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - *reparse_tag = FileData.dwReserved0; - return TRUE; -} - static void -find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData, - BY_HANDLE_FILE_INFORMATION *info, - ULONG *reparse_tag) +find_data_to_file_info(WIN32_FIND_DATAW *pFileData, + BY_HANDLE_FILE_INFORMATION *info, + ULONG *reparse_tag) { memset(info, 0, sizeof(*info)); info->dwFileAttributes = pFileData->dwFileAttributes; @@ -1433,7 +1466,7 @@ find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData, } static BOOL -attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) +attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) { HANDLE hFindFile; WIN32_FIND_DATAW FileData; @@ -1441,7 +1474,7 @@ attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG * if (hFindFile == INVALID_HANDLE_VALUE) return FALSE; FindClose(hFindFile); - find_data_to_file_info_w(&FileData, info, reparse_tag); + find_data_to_file_info(&FileData, info, reparse_tag); return TRUE; } @@ -1458,7 +1491,7 @@ get_target_path(HANDLE hdl, wchar_t **target_path) if(!buf_size) return FALSE; - buf = PyMem_New(wchar_t, buf_size+1); + buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t)); if (!buf) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; @@ -1468,12 +1501,12 @@ get_target_path(HANDLE hdl, wchar_t **target_path) buf, buf_size, VOLUME_NAME_DOS); if(!result_length) { - PyMem_Free(buf); + PyMem_RawFree(buf); return FALSE; } if(!CloseHandle(hdl)) { - PyMem_Free(buf); + PyMem_RawFree(buf); return FALSE; } @@ -1484,10 +1517,7 @@ get_target_path(HANDLE hdl, wchar_t **target_path) } static int -win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result, - BOOL traverse); -static int -win32_xstat_impl(const char *path, struct _Py_stat_struct *result, +win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) { int code; @@ -1495,96 +1525,6 @@ win32_xstat_impl(const char *path, struct _Py_stat_struct *result, BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; wchar_t *target_path; - const char *dot; - - hFile = CreateFileA( - path, - FILE_READ_ATTRIBUTES, /* desired access */ - 0, /* share mode */ - NULL, /* security attributes */ - OPEN_EXISTING, - /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ - /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. - Because of this, calls like GetFinalPathNameByHandle will return - the symlink path again and not the actual final path. */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| - FILE_FLAG_OPEN_REPARSE_POINT, - NULL); - - if (hFile == INVALID_HANDLE_VALUE) { - /* Either the target doesn't exist, or we don't have access to - get a handle to it. If the former, we need to return an error. - If the latter, we can use attributes_from_dir. */ - if (GetLastError() != ERROR_SHARING_VIOLATION) - return -1; - /* Could not get attributes on open file. Fall back to - reading the directory. */ - if (!attributes_from_dir(path, &info, &reparse_tag)) - /* Very strange. This should not fail now */ - return -1; - if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - if (traverse) { - /* Should traverse, but could not open reparse point handle */ - SetLastError(ERROR_SHARING_VIOLATION); - return -1; - } - } - } else { - if (!GetFileInformationByHandle(hFile, &info)) { - CloseHandle(hFile); - return -1; - } - if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - if (!win32_get_reparse_tag(hFile, &reparse_tag)) - return -1; - - /* Close the outer open file handle now that we're about to - reopen it with different flags. */ - if (!CloseHandle(hFile)) - return -1; - - if (traverse) { - /* In order to call GetFinalPathNameByHandle we need to open - the file without the reparse handling flag set. */ - hFile2 = CreateFileA( - path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, - NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (hFile2 == INVALID_HANDLE_VALUE) - return -1; - - if (!get_target_path(hFile2, &target_path)) - return -1; - - code = win32_xstat_impl_w(target_path, result, FALSE); - PyMem_Free(target_path); - return code; - } - } else - CloseHandle(hFile); - } - _Py_attribute_data_to_stat(&info, reparse_tag, result); - - /* Set S_IEXEC if it is an .exe, .bat, ... */ - dot = strrchr(path, '.'); - if (dot) { - if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 || - stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0) - result->st_mode |= 0111; - } - return 0; -} - -static int -win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result, - BOOL traverse) -{ - int code; - HANDLE hFile, hFile2; - BY_HANDLE_FILE_INFORMATION info; - ULONG reparse_tag = 0; - wchar_t *target_path; const wchar_t *dot; hFile = CreateFileW( @@ -1609,7 +1549,7 @@ win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result, return -1; /* Could not get attributes on open file. Fall back to reading the directory. */ - if (!attributes_from_dir_w(path, &info, &reparse_tag)) + if (!attributes_from_dir(path, &info, &reparse_tag)) /* Very strange. This should not fail now */ return -1; if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { @@ -1647,8 +1587,8 @@ win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result, if (!get_target_path(hFile2, &target_path)) return -1; - code = win32_xstat_impl_w(target_path, result, FALSE); - PyMem_Free(target_path); + code = win32_xstat_impl(target_path, result, FALSE); + PyMem_RawFree(target_path); return code; } } else @@ -1667,7 +1607,7 @@ win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result, } static int -win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse) +win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ @@ -1675,16 +1615,6 @@ win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse) errno = 0; return code; } - -static int -win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) -{ - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - int code = win32_xstat_impl_w(path, result, traverse); - errno = 0; - return code; -} /* About the following functions: win32_lstat_w, win32_stat, win32_stat_w In Posix, stat automatically traverses symlinks and returns the stat @@ -1694,34 +1624,20 @@ win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse Therefore, win32_lstat will get the attributes traditionally, and win32_stat will first explicitly resolve the symlink target and then will - call win32_lstat on that result. - - The _w represent Unicode equivalents of the aforementioned ANSI functions. */ + call win32_lstat on that result. */ static int -win32_lstat(const char* path, struct _Py_stat_struct *result) +win32_lstat(const wchar_t* path, struct _Py_stat_struct *result) { return win32_xstat(path, result, FALSE); } static int -win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result) -{ - return win32_xstat_w(path, result, FALSE); -} - -static int -win32_stat(const char* path, struct _Py_stat_struct *result) +win32_stat(const wchar_t* path, struct _Py_stat_struct *result) { return win32_xstat(path, result, TRUE); } -static int -win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result) -{ - return win32_xstat_w(path, result, TRUE); -} - #endif /* MS_WINDOWS */ PyDoc_STRVAR(stat_result__doc__, @@ -2003,7 +1919,7 @@ _pystat_fromstructstat(STRUCT_STAT *st) PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); #ifdef HAVE_LARGEFILE_SUPPORT PyStructSequence_SET_ITEM(v, 1, - PyLong_FromLongLong((PY_LONG_LONG)st->st_ino)); + PyLong_FromLongLong((long long)st->st_ino)); #else PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino)); #endif @@ -2022,7 +1938,7 @@ _pystat_fromstructstat(STRUCT_STAT *st) #endif #ifdef HAVE_LARGEFILE_SUPPORT PyStructSequence_SET_ITEM(v, 6, - PyLong_FromLongLong((PY_LONG_LONG)st->st_size)); + PyLong_FromLongLong((long long)st->st_size)); #else PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size)); #endif @@ -2102,7 +2018,7 @@ _pystat_fromstructstat(STRUCT_STAT *st) static PyObject * -posix_do_stat(char *function_name, path_t *path, +posix_do_stat(const char *function_name, path_t *path, int dir_fd, int follow_symlinks) { STRUCT_STAT st; @@ -2121,28 +2037,26 @@ posix_do_stat(char *function_name, path_t *path, Py_BEGIN_ALLOW_THREADS if (path->fd != -1) result = FSTAT(path->fd, &st); - else #ifdef MS_WINDOWS - if (path->wide) { - if (follow_symlinks) - result = win32_stat_w(path->wide, &st); - else - result = win32_lstat_w(path->wide, &st); - } + else if (follow_symlinks) + result = win32_stat(path->wide, &st); else -#endif -#if defined(HAVE_LSTAT) || defined(MS_WINDOWS) + result = win32_lstat(path->wide, &st); +#else + else +#if defined(HAVE_LSTAT) if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) result = LSTAT(path->narrow, &st); else -#endif +#endif /* HAVE_LSTAT */ #ifdef HAVE_FSTATAT if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) result = fstatat(dir_fd, path->narrow, &st, follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); else -#endif +#endif /* HAVE_FSTATAT */ result = STAT(path->narrow, &st); +#endif /* MS_WINDOWS */ Py_END_ALLOW_THREADS if (result != 0) { @@ -2422,8 +2336,8 @@ class id_t_converter(CConverter): type = 'id_t' format_unit = '" _Py_PARSE_PID "' -class Py_intptr_t_converter(CConverter): - type = 'Py_intptr_t' +class intptr_t_converter(CConverter): + type = 'intptr_t' format_unit = '" _Py_PARSE_INTPTR "' class Py_off_t_converter(CConverter): @@ -2450,7 +2364,7 @@ class sched_param_converter(CConverter): impl_by_reference = True; [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/ /*[clinic input] @@ -2578,10 +2492,7 @@ os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd, #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path->wide != NULL) - attr = GetFileAttributesW(path->wide); - else - attr = GetFileAttributesA(path->narrow); + attr = GetFileAttributesW(path->wide); Py_END_ALLOW_THREADS /* @@ -2705,11 +2616,8 @@ os_chdir_impl(PyObject *module, path_t *path) Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path->wide) - result = win32_wchdir(path->wide); - else - result = win32_chdir(path->narrow); - result = !result; /* on unix, success = 0, on windows, success = !0 */ + /* on unix, success = 0, on windows, success = !0 */ + result = !win32_wchdir(path->wide); #else #ifdef HAVE_FCHDIR if (path->fd != -1) @@ -2804,10 +2712,7 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path->wide) - attr = GetFileAttributesW(path->wide); - else - attr = GetFileAttributesA(path->narrow); + attr = GetFileAttributesW(path->wide); if (attr == INVALID_FILE_ATTRIBUTES) result = 0; else { @@ -2815,10 +2720,7 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, attr &= ~FILE_ATTRIBUTE_READONLY; else attr |= FILE_ATTRIBUTE_READONLY; - if (path->wide) - result = SetFileAttributesW(path->wide, attr); - else - result = SetFileAttributesA(path->narrow, attr); + result = SetFileAttributesW(path->wide, attr); } Py_END_ALLOW_THREADS @@ -3314,12 +3216,22 @@ posix_getcwd(int use_bytes) Py_BEGIN_ALLOW_THREADS do { buflen += chunk; +#ifdef MS_WINDOWS + if (buflen > INT_MAX) { + PyErr_NoMemory(); + break; + } +#endif tmpbuf = PyMem_RawRealloc(buf, buflen); if (tmpbuf == NULL) break; buf = tmpbuf; +#ifdef MS_WINDOWS + cwd = getcwd(buf, (int)buflen); +#else cwd = getcwd(buf, buflen); +#endif } while (cwd == NULL && errno == ERANGE); Py_END_ALLOW_THREADS @@ -3401,7 +3313,7 @@ os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, /*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/ { #ifdef MS_WINDOWS - BOOL result; + BOOL result = FALSE; #else int result; #endif @@ -3413,18 +3325,18 @@ os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, } #endif +#ifndef MS_WINDOWS if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_SetString(PyExc_NotImplementedError, "link: src and dst must be the same type"); return NULL; } +#endif #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS if (src->wide) result = CreateHardLinkW(dst->wide, src->wide, NULL); - else - result = CreateHardLinkA(dst->narrow, src->narrow, NULL); Py_END_ALLOW_THREADS if (!result) @@ -3439,13 +3351,13 @@ os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, dst_dir_fd, dst->narrow, follow_symlinks ? AT_SYMLINK_FOLLOW : 0); else -#endif +#endif /* HAVE_LINKAT */ result = link(src->narrow, dst->narrow); Py_END_ALLOW_THREADS if (result) return path_error2(src, dst); -#endif +#endif /* MS_WINDOWS */ Py_RETURN_NONE; } @@ -3459,99 +3371,39 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) PyObject *v; HANDLE hFindFile = INVALID_HANDLE_VALUE; BOOL result; - WIN32_FIND_DATA FileData; - char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */ - char *bufptr = namebuf; + wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */ /* only claim to have space for MAX_PATH */ Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4; - PyObject *po = NULL; wchar_t *wnamebuf = NULL; - if (!path->narrow) { - WIN32_FIND_DATAW wFileData; - wchar_t *po_wchars; - - if (!path->wide) { /* Default arg: "." */ - po_wchars = L"."; - len = 1; - } else { - po_wchars = path->wide; - len = wcslen(path->wide); - } - /* The +5 is so we can append "\\*.*\0" */ - wnamebuf = PyMem_New(wchar_t, len + 5); - if (!wnamebuf) { - PyErr_NoMemory(); - goto exit; - } - wcscpy(wnamebuf, po_wchars); - if (len > 0) { - wchar_t wch = wnamebuf[len-1]; - if (wch != SEP && wch != ALTSEP && wch != L':') - wnamebuf[len++] = SEP; - wcscpy(wnamebuf + len, L"*.*"); - } - if ((list = PyList_New(0)) == NULL) { - goto exit; - } - Py_BEGIN_ALLOW_THREADS - hFindFile = FindFirstFileW(wnamebuf, &wFileData); - Py_END_ALLOW_THREADS - if (hFindFile == INVALID_HANDLE_VALUE) { - int error = GetLastError(); - if (error == ERROR_FILE_NOT_FOUND) - goto exit; - Py_DECREF(list); - list = path_error(path); - goto exit; - } - do { - /* Skip over . and .. */ - if (wcscmp(wFileData.cFileName, L".") != 0 && - wcscmp(wFileData.cFileName, L"..") != 0) { - v = PyUnicode_FromWideChar(wFileData.cFileName, - wcslen(wFileData.cFileName)); - if (v == NULL) { - Py_DECREF(list); - list = NULL; - break; - } - if (PyList_Append(list, v) != 0) { - Py_DECREF(v); - Py_DECREF(list); - list = NULL; - break; - } - Py_DECREF(v); - } - Py_BEGIN_ALLOW_THREADS - result = FindNextFileW(hFindFile, &wFileData); - Py_END_ALLOW_THREADS - /* FindNextFile sets error to ERROR_NO_MORE_FILES if - it got to the end of the directory. */ - if (!result && GetLastError() != ERROR_NO_MORE_FILES) { - Py_DECREF(list); - list = path_error(path); - goto exit; - } - } while (result == TRUE); + WIN32_FIND_DATAW wFileData; + const wchar_t *po_wchars; + if (!path->wide) { /* Default arg: "." */ + po_wchars = L"."; + len = 1; + } else { + po_wchars = path->wide; + len = wcslen(path->wide); + } + /* The +5 is so we can append "\\*.*\0" */ + wnamebuf = PyMem_New(wchar_t, len + 5); + if (!wnamebuf) { + PyErr_NoMemory(); goto exit; } - strcpy(namebuf, path->narrow); - len = path->length; + wcscpy(wnamebuf, po_wchars); if (len > 0) { - char ch = namebuf[len-1]; - if (ch != '\\' && ch != '/' && ch != ':') - namebuf[len++] = '\\'; - strcpy(namebuf + len, "*.*"); + wchar_t wch = wnamebuf[len-1]; + if (wch != SEP && wch != ALTSEP && wch != L':') + wnamebuf[len++] = SEP; + wcscpy(wnamebuf + len, L"*.*"); + } + if ((list = PyList_New(0)) == NULL) { + goto exit; } - - if ((list = PyList_New(0)) == NULL) - return NULL; - Py_BEGIN_ALLOW_THREADS - hFindFile = FindFirstFile(namebuf, &FileData); + hFindFile = FindFirstFileW(wnamebuf, &wFileData); Py_END_ALLOW_THREADS if (hFindFile == INVALID_HANDLE_VALUE) { int error = GetLastError(); @@ -3563,9 +3415,13 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) } do { /* Skip over . and .. */ - if (strcmp(FileData.cFileName, ".") != 0 && - strcmp(FileData.cFileName, "..") != 0) { - v = PyBytes_FromString(FileData.cFileName); + if (wcscmp(wFileData.cFileName, L".") != 0 && + wcscmp(wFileData.cFileName, L"..") != 0) { + v = PyUnicode_FromWideChar(wFileData.cFileName, + wcslen(wFileData.cFileName)); + if (path->narrow && v) { + Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); + } if (v == NULL) { Py_DECREF(list); list = NULL; @@ -3580,7 +3436,7 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) Py_DECREF(v); } Py_BEGIN_ALLOW_THREADS - result = FindNextFile(hFindFile, &FileData); + result = FindNextFileW(hFindFile, &wFileData); Py_END_ALLOW_THREADS /* FindNextFile sets error to ERROR_NO_MORE_FILES if it got to the end of the directory. */ @@ -3635,7 +3491,7 @@ _posix_listdir(path_t *path, PyObject *list) else #endif { - char *name; + const char *name; if (path->narrow) { name = path->narrow; /* only return bytes if they specified a bytes object */ @@ -3761,41 +3617,29 @@ static PyObject * os__getfullpathname_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/ { - if (!path->narrow) - { - wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf; - wchar_t *wtemp; - DWORD result; - PyObject *v; - - result = GetFullPathNameW(path->wide, - Py_ARRAY_LENGTH(woutbuf), - woutbuf, &wtemp); - if (result > Py_ARRAY_LENGTH(woutbuf)) { - woutbufp = PyMem_New(wchar_t, result); - if (!woutbufp) - return PyErr_NoMemory(); - result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp); - } - if (result) - v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp)); - else - v = win32_error_object("GetFullPathNameW", path->object); - if (woutbufp != woutbuf) - PyMem_Free(woutbufp); - return v; - } - else { - char outbuf[MAX_PATH]; - char *temp; + wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf; + wchar_t *wtemp; + DWORD result; + PyObject *v; - if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf), - outbuf, &temp)) { - win32_error_object("GetFullPathName", path->object); - return NULL; - } - return PyBytes_FromString(outbuf); + result = GetFullPathNameW(path->wide, + Py_ARRAY_LENGTH(woutbuf), + woutbuf, &wtemp); + if (result > Py_ARRAY_LENGTH(woutbuf)) { + woutbufp = PyMem_New(wchar_t, result); + if (!woutbufp) + return PyErr_NoMemory(); + result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp); } + if (result) { + v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp)); + if (path->narrow) + Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); + } else + v = win32_error_object("GetFullPathNameW", path->object); + if (woutbufp != woutbuf) + PyMem_Free(woutbufp); + return v; } @@ -3817,7 +3661,7 @@ os__getfinalpathname_impl(PyObject *module, PyObject *path) wchar_t *target_path; int result_length; PyObject *result; - wchar_t *path_wchar; + const wchar_t *path_wchar; path_wchar = PyUnicode_AsUnicode(path); if (path_wchar == NULL) @@ -3879,10 +3723,7 @@ os__isdir_impl(PyObject *module, path_t *path) DWORD attributes; Py_BEGIN_ALLOW_THREADS - if (!path->narrow) - attributes = GetFileAttributesW(path->wide); - else - attributes = GetFileAttributesA(path->narrow); + attributes = GetFileAttributesW(path->wide); Py_END_ALLOW_THREADS if (attributes == INVALID_FILE_ATTRIBUTES) @@ -3908,7 +3749,8 @@ os__getvolumepathname_impl(PyObject *module, PyObject *path) /*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/ { PyObject *result; - wchar_t *path_wchar, *mountpath=NULL; + const wchar_t *path_wchar; + wchar_t *mountpath=NULL; size_t buflen; BOOL ret; @@ -3979,10 +3821,7 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd) #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path->wide) - result = CreateDirectoryW(path->wide, NULL); - else - result = CreateDirectoryA(path->narrow, NULL); + result = CreateDirectoryW(path->wide, NULL); Py_END_ALLOW_THREADS if (!result) @@ -4002,7 +3841,7 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd) Py_END_ALLOW_THREADS if (result < 0) return path_error(path); -#endif +#endif /* MS_WINDOWS */ Py_RETURN_NONE; } @@ -4106,7 +3945,7 @@ os_setpriority_impl(PyObject *module, int which, int who, int priority) static PyObject * internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace) { - char *function_name = is_replace ? "replace" : "rename"; + const char *function_name = is_replace ? "replace" : "rename"; int dir_fd_specified; #ifdef MS_WINDOWS @@ -4125,31 +3964,28 @@ internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is } #endif - if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { - PyErr_Format(PyExc_ValueError, - "%s: src and dst must be the same type", function_name); - return NULL; - } - #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (src->wide) - result = MoveFileExW(src->wide, dst->wide, flags); - else - result = MoveFileExA(src->narrow, dst->narrow, flags); + result = MoveFileExW(src->wide, dst->wide, flags); Py_END_ALLOW_THREADS if (!result) return path_error2(src, dst); #else + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { + PyErr_Format(PyExc_ValueError, + "%s: src and dst must be the same type", function_name); + return NULL; + } + Py_BEGIN_ALLOW_THREADS #ifdef HAVE_RENAMEAT if (dir_fd_specified) result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow); else #endif - result = rename(src->narrow, dst->narrow); + result = rename(src->narrow, dst->narrow); Py_END_ALLOW_THREADS if (result) @@ -4230,11 +4066,8 @@ os_rmdir_impl(PyObject *module, path_t *path, int dir_fd) Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path->wide) - result = RemoveDirectoryW(path->wide); - else - result = RemoveDirectoryA(path->narrow); - result = !result; /* Windows, success=1, UNIX, success=0 */ + /* Windows, success=1, UNIX, success=0 */ + result = !RemoveDirectoryW(path->wide); #else #ifdef HAVE_UNLINKAT if (dir_fd != DEFAULT_DIR_FD) @@ -4286,7 +4119,7 @@ os_system_impl(PyObject *module, PyObject *command) /*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/ { long result; - char *bytes = PyBytes_AsString(command); + const char *bytes = PyBytes_AsString(command); Py_BEGIN_ALLOW_THREADS result = system(bytes); Py_END_ALLOW_THREADS @@ -4380,11 +4213,8 @@ os_unlink_impl(PyObject *module, path_t *path, int dir_fd) Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS - if (path->wide) - result = Py_DeleteFileW(path->wide); - else - result = DeleteFileA(path->narrow); - result = !result; /* Windows, success=1, UNIX, success=0 */ + /* Windows, success=1, UNIX, success=0 */ + result = !Py_DeleteFileW(path->wide); #else #ifdef HAVE_UNLINKAT if (dir_fd != DEFAULT_DIR_FD) @@ -4566,7 +4396,7 @@ typedef struct { #if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) static int -utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks) +utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks) { #ifdef HAVE_UTIMENSAT int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; @@ -4608,14 +4438,14 @@ utime_fd(utime_t *ut, int fd) #define PATH_UTIME_HAVE_FD 0 #endif +#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES) +# define UTIME_HAVE_NOFOLLOW_SYMLINKS +#endif -#define UTIME_HAVE_NOFOLLOW_SYMLINKS \ - (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)) - -#if UTIME_HAVE_NOFOLLOW_SYMLINKS +#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS static int -utime_nofollow_symlinks(utime_t *ut, char *path) +utime_nofollow_symlinks(utime_t *ut, const char *path) { #ifdef HAVE_UTIMENSAT UTIME_TO_TIMESPEC; @@ -4631,7 +4461,7 @@ utime_nofollow_symlinks(utime_t *ut, char *path) #ifndef MS_WINDOWS static int -utime_default(utime_t *ut, char *path) +utime_default(utime_t *ut, const char *path) { #ifdef HAVE_UTIMENSAT UTIME_TO_TIMESPEC; @@ -4774,7 +4604,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, utime.now = 1; } -#if !UTIME_HAVE_NOFOLLOW_SYMLINKS +#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS) if (follow_symlinks_specified("utime", follow_symlinks)) goto exit; #endif @@ -4795,14 +4625,9 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path->wide) - hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, - NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, NULL); - else - hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0, - NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, NULL); + hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, + NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL); Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { path_error(path); @@ -4828,7 +4653,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, #else /* MS_WINDOWS */ Py_BEGIN_ALLOW_THREADS -#if UTIME_HAVE_NOFOLLOW_SYMLINKS +#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) result = utime_nofollow_symlinks(&utime, path->narrow); else @@ -4888,9 +4713,15 @@ os__exit_impl(PyObject *module, int status) return NULL; /* Make gcc -Wall happy */ } +#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) +#define EXECV_CHAR wchar_t +#else +#define EXECV_CHAR char +#endif + #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) static void -free_string_array(char **array, Py_ssize_t count) +free_string_array(EXECV_CHAR **array, Py_ssize_t count) { Py_ssize_t i; for (i = 0; i < count; i++) @@ -4899,10 +4730,15 @@ free_string_array(char **array, Py_ssize_t count) } static -int fsconvert_strdup(PyObject *o, char**out) +int fsconvert_strdup(PyObject *o, EXECV_CHAR**out) { - PyObject *bytes; Py_ssize_t size; +#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) + *out = PyUnicode_AsWideCharString(o, &size); + if (!*out) + return 0; +#else + PyObject *bytes; if (!PyUnicode_FSConverter(o, &bytes)) return 0; size = PyBytes_GET_SIZE(bytes); @@ -4913,25 +4749,24 @@ int fsconvert_strdup(PyObject *o, char**out) } memcpy(*out, PyBytes_AsString(bytes), size+1); Py_DECREF(bytes); +#endif return 1; } #endif #if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) -static char** +static EXECV_CHAR** parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) { - char **envlist; Py_ssize_t i, pos, envc; PyObject *keys=NULL, *vals=NULL; - PyObject *key, *val, *key2, *val2; - char *p, *k, *v; - size_t len; + PyObject *key, *val, *keyval; + EXECV_CHAR **envlist; i = PyMapping_Size(env); if (i < 0) return NULL; - envlist = PyMem_NEW(char *, i + 1); + envlist = PyMem_NEW(EXECV_CHAR *, i + 1); if (envlist == NULL) { PyErr_NoMemory(); return NULL; @@ -4955,28 +4790,16 @@ parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) if (!key || !val) goto error; - if (PyUnicode_FSConverter(key, &key2) == 0) + keyval = PyUnicode_FromFormat("%U=%U", key, val); + if (!keyval) goto error; - if (PyUnicode_FSConverter(val, &val2) == 0) { - Py_DECREF(key2); - goto error; - } - - k = PyBytes_AsString(key2); - v = PyBytes_AsString(val2); - len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2; - p = PyMem_NEW(char, len); - if (p == NULL) { - PyErr_NoMemory(); - Py_DECREF(key2); - Py_DECREF(val2); + if (!fsconvert_strdup(keyval, &envlist[envc++])) { + Py_DECREF(keyval); goto error; } - PyOS_snprintf(p, len, "%s=%s", k, v); - envlist[envc++] = p; - Py_DECREF(key2); - Py_DECREF(val2); + + Py_DECREF(keyval); } Py_DECREF(vals); Py_DECREF(keys); @@ -4988,17 +4811,15 @@ parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) error: Py_XDECREF(keys); Py_XDECREF(vals); - while (--envc >= 0) - PyMem_DEL(envlist[envc]); - PyMem_DEL(envlist); + free_string_array(envlist, envc); return NULL; } -static char** +static EXECV_CHAR** parse_arglist(PyObject* argv, Py_ssize_t *argc) { int i; - char **argvlist = PyMem_NEW(char *, *argc+1); + EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1); if (argvlist == NULL) { PyErr_NoMemory(); return NULL; @@ -5020,6 +4841,7 @@ fail: free_string_array(argvlist, *argc); return NULL; } + #endif @@ -5027,7 +4849,7 @@ fail: /*[clinic input] os.execv - path: FSConverter + path: path_t Path of executable file. argv: object Tuple or list of strings. @@ -5037,17 +4859,15 @@ Execute an executable path with arguments, replacing current process. [clinic start generated code]*/ static PyObject * -os_execv_impl(PyObject *module, PyObject *path, PyObject *argv) -/*[clinic end generated code: output=b21dc34deeb5b004 input=96041559925e5229]*/ +os_execv_impl(PyObject *module, path_t *path, PyObject *argv) +/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/ { - char *path_char; - char **argvlist; + EXECV_CHAR **argvlist; Py_ssize_t argc; /* execv has two arguments: (path, argv), where argv is a list or tuple of strings. */ - path_char = PyBytes_AsString(path); if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list"); @@ -5064,7 +4884,11 @@ os_execv_impl(PyObject *module, PyObject *path, PyObject *argv) return NULL; } - execv(path_char, argvlist); +#ifdef HAVE_WEXECV + _wexecv(path->wide, argvlist); +#else + execv(path->narrow, argvlist); +#endif /* If we get here it's definitely an error */ @@ -5090,8 +4914,8 @@ static PyObject * os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) /*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/ { - char **argvlist = NULL; - char **envlist; + EXECV_CHAR **argvlist = NULL; + EXECV_CHAR **envlist; Py_ssize_t argc, envc; /* execve has three arguments: (path, argv, env), where @@ -5124,30 +4948,33 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) fexecve(path->fd, argvlist, envlist); else #endif +#ifdef HAVE_WEXECV + _wexecve(path->wide, argvlist, envlist); +#else execve(path->narrow, argvlist, envlist); +#endif /* If we get here it's definitely an error */ path_error(path); - while (--envc >= 0) - PyMem_DEL(envlist[envc]); - PyMem_DEL(envlist); + free_string_array(envlist, envc); fail: if (argvlist) free_string_array(argvlist, argc); return NULL; } + #endif /* HAVE_EXECV */ -#ifdef HAVE_SPAWNV +#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) /*[clinic input] os.spawnv mode: int Mode of process creation. - path: FSConverter + path: path_t Path of executable file. argv: object Tuple or list of strings. @@ -5157,20 +4984,18 @@ Execute the program specified by path in a new process. [clinic start generated code]*/ static PyObject * -os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv) -/*[clinic end generated code: output=c427c0ce40f10638 input=042c91dfc1e6debc]*/ +os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) +/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/ { - char *path_char; - char **argvlist; + EXECV_CHAR **argvlist; int i; Py_ssize_t argc; - Py_intptr_t spawnval; + intptr_t spawnval; PyObject *(*getitem)(PyObject *, Py_ssize_t); /* spawnv has three arguments: (mode, path, argv), where argv is a list or tuple of strings. */ - path_char = PyBytes_AsString(path); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -5185,7 +5010,7 @@ os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv) return NULL; } - argvlist = PyMem_NEW(char *, argc+1); + argvlist = PyMem_NEW(EXECV_CHAR *, argc+1); if (argvlist == NULL) { return PyErr_NoMemory(); } @@ -5205,7 +5030,11 @@ os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv) mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS - spawnval = _spawnv(mode, path_char, argvlist); +#ifdef HAVE_WSPAWNV + spawnval = _wspawnv(mode, path->wide, argvlist); +#else + spawnval = _spawnv(mode, path->narrow, argvlist); +#endif Py_END_ALLOW_THREADS free_string_array(argvlist, argc); @@ -5222,7 +5051,7 @@ os.spawnve mode: int Mode of process creation. - path: FSConverter + path: path_t Path of executable file. argv: object Tuple or list of strings. @@ -5234,16 +5063,15 @@ Execute the program specified by path in a new process. [clinic start generated code]*/ static PyObject * -os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv, +os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, PyObject *env) -/*[clinic end generated code: output=ebcfa5f7ba2f4219 input=02362fd937963f8f]*/ +/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/ { - char *path_char; - char **argvlist; - char **envlist; + EXECV_CHAR **argvlist; + EXECV_CHAR **envlist; PyObject *res = NULL; Py_ssize_t argc, i, envc; - Py_intptr_t spawnval; + intptr_t spawnval; PyObject *(*getitem)(PyObject *, Py_ssize_t); Py_ssize_t lastarg = 0; @@ -5251,7 +5079,6 @@ os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv, argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - path_char = PyBytes_AsString(path); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -5271,7 +5098,7 @@ os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv, goto fail_0; } - argvlist = PyMem_NEW(char *, argc+1); + argvlist = PyMem_NEW(EXECV_CHAR *, argc+1); if (argvlist == NULL) { PyErr_NoMemory(); goto fail_0; @@ -5295,7 +5122,11 @@ os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv, mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS - spawnval = _spawnve(mode, path_char, argvlist, envlist); +#ifdef HAVE_WSPAWNV + spawnval = _wspawnve(mode, path->wide, argvlist, envlist); +#else + spawnval = _spawnve(mode, path->narrow, argvlist, envlist); +#endif Py_END_ALLOW_THREADS if (spawnval == -1) @@ -5758,14 +5589,14 @@ os.sched_getaffinity pid: pid_t / -Return the affinity of the process identified by pid. +Return the affinity of the process identified by pid (or the current process if zero). The affinity is returned as a set of CPU identifiers. [clinic start generated code]*/ static PyObject * os_sched_getaffinity_impl(PyObject *module, pid_t pid) -/*[clinic end generated code: output=f726f2c193c17a4f input=eaf161936874b8a1]*/ +/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/ { int cpu, ncpus, count; size_t setsize; @@ -5926,7 +5757,7 @@ os_openpty_impl(PyObject *module) if (_Py_set_inheritable(master_fd, 0, NULL) < 0) goto posix_error; -#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) +#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC) ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ #ifndef __hpux @@ -6251,7 +6082,7 @@ static PyObject * posix_initgroups(PyObject *self, PyObject *args) { PyObject *oname; - char *username; + const char *username; int res; #ifdef __APPLE__ int gid; @@ -6998,7 +6829,7 @@ os_waitpid_impl(PyObject *module, pid_t pid, int options) /* MS C has a variant of waitpid() that's usable for most purposes. */ /*[clinic input] os.waitpid - pid: Py_intptr_t + pid: intptr_t options: int / @@ -7011,11 +6842,11 @@ The options argument is ignored on Windows. [clinic start generated code]*/ static PyObject * -os_waitpid_impl(PyObject *module, Py_intptr_t pid, int options) -/*[clinic end generated code: output=15f1ce005a346b09 input=444c8f51cca5b862]*/ +os_waitpid_impl(PyObject *module, intptr_t pid, int options) +/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/ { int status; - Py_intptr_t res; + intptr_t res; int async_err = 0; do { @@ -7125,16 +6956,16 @@ exit: static PyObject * win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) { - wchar_t *path; + const wchar_t *path; DWORD n_bytes_returned; DWORD io_result; PyObject *po, *result; - int dir_fd; + int dir_fd; HANDLE reparse_point_handle; - char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; - wchar_t *print_name; + char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; + const wchar_t *print_name; static char *keywords[] = {"path", "dir_fd", NULL}; @@ -7202,22 +7033,19 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) #if defined(MS_WINDOWS) /* Grab CreateSymbolicLinkW dynamically from kernel32 */ -static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL; -static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL; +static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL; static int check_CreateSymbolicLink(void) { HINSTANCE hKernel32; /* only recheck */ - if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA) + if (Py_CreateSymbolicLinkW) return 1; hKernel32 = GetModuleHandleW(L"KERNEL32"); *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32, "CreateSymbolicLinkW"); - *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32, - "CreateSymbolicLinkA"); - return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA); + return Py_CreateSymbolicLinkW != NULL; } /* Remove the last portion of the path */ @@ -7234,20 +7062,6 @@ _dirnameW(WCHAR *path) *ptr = 0; } -/* Remove the last portion of the path */ -static void -_dirnameA(char *path) -{ - char *ptr; - - /* walk the path from the end until a backslash is encountered */ - for(ptr = path + strlen(path); ptr != path; ptr--) { - if (*ptr == '\\' || *ptr == '/') - break; - } - *ptr = 0; -} - /* Is this path absolute? */ static int _is_absW(const WCHAR *path) @@ -7256,14 +7070,6 @@ _is_absW(const WCHAR *path) } -/* Is this path absolute? */ -static int -_is_absA(const char *path) -{ - return path[0] == '\\' || path[0] == '/' || path[1] == ':'; - -} - /* join root and rest with a backslash */ static void _joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) @@ -7285,30 +7091,9 @@ _joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) wcscpy(dest_path+root_len, rest); } -/* join root and rest with a backslash */ -static void -_joinA(char *dest_path, const char *root, const char *rest) -{ - size_t root_len; - - if (_is_absA(rest)) { - strcpy(dest_path, rest); - return; - } - - root_len = strlen(root); - - strcpy(dest_path, root); - if(root_len) { - dest_path[root_len] = '\\'; - root_len++; - } - strcpy(dest_path+root_len, rest); -} - /* Return True if the path at src relative to dest is a directory */ static int -_check_dirW(WCHAR *src, WCHAR *dest) +_check_dirW(LPCWSTR src, LPCWSTR dest) { WIN32_FILE_ATTRIBUTE_DATA src_info; WCHAR dest_parent[MAX_PATH]; @@ -7324,25 +7109,6 @@ _check_dirW(WCHAR *src, WCHAR *dest) && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ); } - -/* Return True if the path at src relative to dest is a directory */ -static int -_check_dirA(char *src, char *dest) -{ - WIN32_FILE_ATTRIBUTE_DATA src_info; - char dest_parent[MAX_PATH]; - char src_resolved[MAX_PATH] = ""; - - /* dest_parent = os.path.dirname(dest) */ - strcpy(dest_parent, dest); - _dirnameA(dest_parent); - /* src_resolved = os.path.join(dest_parent, src) */ - _joinA(src_resolved, dest_parent, src); - return ( - GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info) - && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY - ); -} #endif @@ -7402,18 +7168,10 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (dst->wide) { - /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirW(src->wide, dst->wide); - result = Py_CreateSymbolicLinkW(dst->wide, src->wide, - target_is_directory); - } - else { - /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirA(src->narrow, dst->narrow); - result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow, - target_is_directory); - } + /* if src is a directory, ensure target_is_directory==1 */ + target_is_directory |= _check_dirW(src->wide, dst->wide); + result = Py_CreateSymbolicLinkW(dst->wide, src->wide, + target_is_directory); Py_END_ALLOW_THREADS if (!result) @@ -7718,16 +7476,14 @@ os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd) do { Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path->wide) - fd = _wopen(path->wide, flags, mode); - else + fd = _wopen(path->wide, flags, mode); #endif #ifdef HAVE_OPENAT if (dir_fd != DEFAULT_DIR_FD) fd = openat(dir_fd, path->narrow, flags, mode); else -#endif fd = open(path->narrow, flags, mode); +#endif Py_END_ALLOW_THREADS } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); _Py_END_SUPPRESS_IPH @@ -7762,8 +7518,6 @@ os_close_impl(PyObject *module, int fd) /*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/ { int res; - if (!_PyVerify_fd(fd)) - return posix_error(); /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/ * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html * for more details. @@ -7796,9 +7550,8 @@ os_closerange_impl(PyObject *module, int fd_low, int fd_high) int i; Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH - for (i = fd_low; i < fd_high; i++) - if (_PyVerify_fd(i)) - close(i); + for (i = Py_MAX(fd_low, 0); i < fd_high; i++) + close(i); _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS Py_RETURN_NONE; @@ -7842,7 +7595,7 @@ os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable) int dup3_works = -1; #endif - if (!_PyVerify_fd_dup2(fd, fd2)) + if (fd < 0 || fd2 < 0) return posix_error(); /* dup2() can fail with EINTR if the target FD is already open, because it @@ -7966,10 +7719,6 @@ os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) { Py_off_t result; - if (!_PyVerify_fd(fd)) { - posix_error(); - return -1; - } #ifdef SEEK_SET /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ switch (how) { @@ -7982,10 +7731,6 @@ os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) if (PyErr_Occurred()) return -1; - if (!_PyVerify_fd(fd)) { - posix_error(); - return -1; - } Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS @@ -8193,10 +7938,6 @@ os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset) buffer = PyBytes_FromStringAndSize((char *)NULL, length); if (buffer == NULL) return NULL; - if (!_PyVerify_fd(fd)) { - Py_DECREF(buffer); - return posix_error(); - } do { Py_BEGIN_ALLOW_THREADS @@ -8359,7 +8100,7 @@ done: if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile", keywords, &out, &in, &offobj, &count)) return NULL; -#ifdef linux +#ifdef __linux__ if (offobj == Py_None) { do { Py_BEGIN_ALLOW_THREADS @@ -8439,8 +8180,6 @@ os_isatty_impl(PyObject *module, int fd) /*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/ { int return_value; - if (!_PyVerify_fd(fd)) - return 0; _Py_BEGIN_SUPPRESS_IPH return_value = isatty(fd); _Py_END_SUPPRESS_IPH @@ -8479,8 +8218,8 @@ os_pipe_impl(PyObject *module) Py_BEGIN_ALLOW_THREADS ok = CreatePipe(&read, &write, &attr, 0); if (ok) { - fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY); - fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY); + fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY); + fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY); if (fds[0] == -1 || fds[1] == -1) { CloseHandle(read); CloseHandle(write); @@ -8632,11 +8371,6 @@ os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset) Py_ssize_t size; int async_err = 0; - if (!_PyVerify_fd(fd)) { - posix_error(); - return -1; - } - do { Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH @@ -8819,9 +8553,6 @@ os_ftruncate_impl(PyObject *module, int fd, Py_off_t length) int result; int async_err = 0; - if (!_PyVerify_fd(fd)) - return posix_error(); - do { Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH @@ -8868,10 +8599,7 @@ os_truncate_impl(PyObject *module, path_t *path, Py_off_t length) Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS - if (path->wide) - fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT); - else - fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT); + fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT); if (fd < 0) result = -1; else { @@ -9015,7 +8743,7 @@ static PyObject * os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) /*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/ { - wchar_t *env; + const wchar_t *env; PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value); if (unicode == NULL) { @@ -9061,8 +8789,8 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) { PyObject *bytes = NULL; char *env; - char *name_string = PyBytes_AsString(name); - char *value_string = PyBytes_AsString(value); + const char *name_string = PyBytes_AsString(name); + const char *value_string = PyBytes_AsString(value); bytes = PyBytes_FromFormat("%s=%s", name_string, value_string); if (bytes == NULL) { @@ -9340,17 +9068,17 @@ _pystatvfs_fromstructstatvfs(struct statvfs st) { PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); PyStructSequence_SET_ITEM(v, 2, - PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks)); + PyLong_FromLongLong((long long) st.f_blocks)); PyStructSequence_SET_ITEM(v, 3, - PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree)); + PyLong_FromLongLong((long long) st.f_bfree)); PyStructSequence_SET_ITEM(v, 4, - PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail)); + PyLong_FromLongLong((long long) st.f_bavail)); PyStructSequence_SET_ITEM(v, 5, - PyLong_FromLongLong((PY_LONG_LONG) st.f_files)); + PyLong_FromLongLong((long long) st.f_files)); PyStructSequence_SET_ITEM(v, 6, - PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree)); + PyLong_FromLongLong((long long) st.f_ffree)); PyStructSequence_SET_ITEM(v, 7, - PyLong_FromLongLong((PY_LONG_LONG) st.f_favail)); + PyLong_FromLongLong((long long) st.f_favail)); PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); #endif @@ -9481,8 +9209,8 @@ os__getdiskusage_impl(PyObject *module, Py_UNICODE *path) * sufficiently pervasive that it's not worth the loss of readability. */ struct constdef { - char *name; - long value; + const char *name; + int value; }; static int @@ -9490,7 +9218,10 @@ conv_confname(PyObject *arg, int *valuep, struct constdef *table, size_t tablesize) { if (PyLong_Check(arg)) { - *valuep = PyLong_AS_LONG(arg); + int value = _PyLong_AsInt(arg); + if (value == -1 && PyErr_Occurred()) + return 0; + *valuep = value; return 1; } else { @@ -10451,7 +10182,7 @@ cmp_constdefs(const void *v1, const void *v2) static int setup_confname_table(struct constdef *table, size_t tablesize, - char *tablename, PyObject *module) + const char *tablename, PyObject *module) { PyObject *d = NULL; size_t i; @@ -10522,31 +10253,8 @@ os_abort_impl(PyObject *module) } #ifdef MS_WINDOWS -/* AC 3.5: change to path_t? but that might change exceptions */ -PyDoc_STRVAR(win32_startfile__doc__, -"startfile(filepath [, operation])\n\ -\n\ -Start a file with its associated application.\n\ -\n\ -When \"operation\" is not specified or \"open\", this acts like\n\ -double-clicking the file in Explorer, or giving the file name as an\n\ -argument to the DOS \"start\" command: the file is opened with whatever\n\ -application (if any) its extension is associated.\n\ -When another \"operation\" is given, it specifies what should be done with\n\ -the file. A typical operation is \"print\".\n\ -\n\ -startfile returns as soon as the associated application is launched.\n\ -There is no option to wait for the application to close, and no way\n\ -to retrieve the application's exit status.\n\ -\n\ -The filepath is relative to the current directory. If you want to use\n\ -an absolute path, make sure the first character is not a slash (\"/\");\n\ -the underlying Win32 ShellExecute function doesn't work if it is."); - /* Grab ShellExecute dynamically from shell32 */ static int has_ShellExecute = -1; -static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR, - LPCSTR, INT); static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT); static int @@ -10560,12 +10268,9 @@ check_ShellExecute() hShell32 = LoadLibraryW(L"SHELL32"); Py_END_ALLOW_THREADS if (hShell32) { - *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32, - "ShellExecuteA"); *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32, "ShellExecuteW"); - has_ShellExecute = Py_ShellExecuteA && - Py_ShellExecuteW; + has_ShellExecute = Py_ShellExecuteW != NULL; } else { has_ShellExecute = 0; } @@ -10574,17 +10279,37 @@ check_ShellExecute() } +/*[clinic input] +os.startfile + filepath: path_t + operation: Py_UNICODE = NULL + +startfile(filepath [, operation]) + +Start a file with its associated application. + +When "operation" is not specified or "open", this acts like +double-clicking the file in Explorer, or giving the file name as an +argument to the DOS "start" command: the file is opened with whatever +application (if any) its extension is associated. +When another "operation" is given, it specifies what should be done with +the file. A typical operation is "print". + +startfile returns as soon as the associated application is launched. +There is no option to wait for the application to close, and no way +to retrieve the application's exit status. + +The filepath is relative to the current directory. If you want to use +an absolute path, make sure the first character is not a slash ("/"); +the underlying Win32 ShellExecute function doesn't work if it is. +[clinic start generated code]*/ + static PyObject * -win32_startfile(PyObject *self, PyObject *args) +os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation) +/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/ { - PyObject *ofilepath; - char *filepath; - char *operation = NULL; - wchar_t *wpath, *woperation; HINSTANCE rc; - PyObject *unipath, *uoperation = NULL; - if(!check_ShellExecute()) { /* If the OS doesn't have ShellExecute, return a NotImplementedError. */ @@ -10592,68 +10317,16 @@ win32_startfile(PyObject *self, PyObject *args) "startfile not available on this platform"); } - if (!PyArg_ParseTuple(args, "U|s:startfile", - &unipath, &operation)) { - PyErr_Clear(); - goto normal; - } - - if (operation) { - uoperation = PyUnicode_DecodeASCII(operation, - strlen(operation), NULL); - if (!uoperation) { - PyErr_Clear(); - operation = NULL; - goto normal; - } - } - - wpath = PyUnicode_AsUnicode(unipath); - if (wpath == NULL) - goto normal; - if (uoperation) { - woperation = PyUnicode_AsUnicode(uoperation); - if (woperation == NULL) - goto normal; - } - else - woperation = NULL; - Py_BEGIN_ALLOW_THREADS - rc = Py_ShellExecuteW((HWND)0, woperation, wpath, + rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide, NULL, NULL, SW_SHOWNORMAL); Py_END_ALLOW_THREADS - Py_XDECREF(uoperation); if (rc <= (HINSTANCE)32) { - win32_error_object("startfile", unipath); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; - -normal: - if (!PyArg_ParseTuple(args, "O&|s:startfile", - PyUnicode_FSConverter, &ofilepath, - &operation)) + win32_error_object("startfile", filepath->object); return NULL; - if (win32_warn_bytes_api()) { - Py_DECREF(ofilepath); - return NULL; - } - filepath = PyBytes_AsString(ofilepath); - Py_BEGIN_ALLOW_THREADS - rc = Py_ShellExecuteA((HWND)0, operation, filepath, - NULL, NULL, SW_SHOWNORMAL); - Py_END_ALLOW_THREADS - if (rc <= (HINSTANCE)32) { - PyObject *errval = win32_error("startfile", filepath); - Py_DECREF(ofilepath); - return errval; } - Py_DECREF(ofilepath); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* MS_WINDOWS */ @@ -10821,7 +10494,7 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, for (i = 0; ; i++) { void *ptr; ssize_t result; - static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; + static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; Py_ssize_t buffer_size = buffer_sizes[i]; if (!buffer_size) { path_error(path); @@ -10985,9 +10658,9 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) name = path->narrow ? path->narrow : "."; for (i = 0; ; i++) { - char *start, *trace, *end; + const char *start, *trace, *end; ssize_t length; - static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 }; + static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 }; Py_ssize_t buffer_size = buffer_sizes[i]; if (!buffer_size) { /* ERANGE */ @@ -11078,8 +10751,7 @@ os_urandom_impl(PyObject *module, Py_ssize_t size) if (bytes == NULL) return NULL; - result = _PyOS_URandom(PyBytes_AS_STRING(bytes), - PyBytes_GET_SIZE(bytes)); + result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes)); if (result == -1) { Py_DECREF(bytes); return NULL; @@ -11199,11 +10871,15 @@ get_terminal_size(PyObject *self, PyObject *args) os.cpu_count Return the number of CPUs in the system; return None if indeterminable. + +This number is not equivalent to the number of CPUs the current process can +use. The number of usable CPUs can be obtained with +``len(os.sched_getaffinity(0))`` [clinic start generated code]*/ static PyObject * os_cpu_count_impl(PyObject *module) -/*[clinic end generated code: output=5fc29463c3936a9c input=d55e2f8f3823a628]*/ +/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/ { int ncpu = 0; #ifdef MS_WINDOWS @@ -11247,11 +10923,6 @@ os_get_inheritable_impl(PyObject *module, int fd) /*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/ { int return_value; - if (!_PyVerify_fd(fd)) { - posix_error(); - return -1; - } - _Py_BEGIN_SUPPRESS_IPH return_value = _Py_get_inheritable(fd); _Py_END_SUPPRESS_IPH @@ -11273,8 +10944,6 @@ os_set_inheritable_impl(PyObject *module, int fd, int inheritable) /*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/ { int result; - if (!_PyVerify_fd(fd)) - return posix_error(); _Py_BEGIN_SUPPRESS_IPH result = _Py_set_inheritable(fd, inheritable, NULL); @@ -11288,15 +10957,15 @@ os_set_inheritable_impl(PyObject *module, int fd, int inheritable) #ifdef MS_WINDOWS /*[clinic input] os.get_handle_inheritable -> bool - handle: Py_intptr_t + handle: intptr_t / Get the close-on-exe flag of the specified file descriptor. [clinic start generated code]*/ static int -os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle) -/*[clinic end generated code: output=9e5389b0aa0916ce input=5f7759443aae3dc5]*/ +os_get_handle_inheritable_impl(PyObject *module, intptr_t handle) +/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/ { DWORD flags; @@ -11311,7 +10980,7 @@ os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle) /*[clinic input] os.set_handle_inheritable - handle: Py_intptr_t + handle: intptr_t inheritable: bool / @@ -11319,9 +10988,9 @@ Set the inheritable flag of the specified handle. [clinic start generated code]*/ static PyObject * -os_set_handle_inheritable_impl(PyObject *module, Py_intptr_t handle, +os_set_handle_inheritable_impl(PyObject *module, intptr_t handle, int inheritable) -/*[clinic end generated code: output=b1e67bfa3213d745 input=e64b2b2730469def]*/ +/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/ { DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0; if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { @@ -11348,9 +11017,6 @@ posix_get_blocking(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:get_blocking", &fd)) return NULL; - if (!_PyVerify_fd(fd)) - return posix_error(); - _Py_BEGIN_SUPPRESS_IPH blocking = _Py_get_blocking(fd); _Py_END_SUPPRESS_IPH @@ -11374,9 +11040,6 @@ posix_set_blocking(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking)) return NULL; - if (!_PyVerify_fd(fd)) - return posix_error(); - _Py_BEGIN_SUPPRESS_IPH result = _Py_set_blocking(fd, blocking); _Py_END_SUPPRESS_IPH @@ -11460,16 +11123,16 @@ DirEntry_fetch_stat(DirEntry *self, int follow_symlinks) struct _Py_stat_struct st; #ifdef MS_WINDOWS - wchar_t *path; + const wchar_t *path; path = PyUnicode_AsUnicode(self->path); if (!path) return NULL; if (follow_symlinks) - result = win32_stat_w(path, &st); + result = win32_stat(path, &st); else - result = win32_lstat_w(path, &st); + result = win32_lstat(path, &st); if (result != 0) { return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, @@ -11477,7 +11140,7 @@ DirEntry_fetch_stat(DirEntry *self, int follow_symlinks) } #else /* POSIX */ PyObject *bytes; - char *path; + const char *path; if (!PyUnicode_FSConverter(self->path, &bytes)) return NULL; @@ -11661,14 +11324,14 @@ DirEntry_inode(DirEntry *self) { #ifdef MS_WINDOWS if (!self->got_file_index) { - wchar_t *path; + const wchar_t *path; struct _Py_stat_struct stat; path = PyUnicode_AsUnicode(self->path); if (!path) return NULL; - if (win32_lstat_w(path, &stat) != 0) { + if (win32_lstat(path, &stat) != 0) { return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, self->path); } @@ -11676,10 +11339,10 @@ DirEntry_inode(DirEntry *self) self->win32_file_index = stat.st_ino; self->got_file_index = 1; } - return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index); + return PyLong_FromLongLong((long long)self->win32_file_index); #else /* POSIX */ #ifdef HAVE_LARGEFILE_SUPPORT - return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino); + return PyLong_FromLongLong((long long)self->d_ino); #else return PyLong_FromLong((long)self->d_ino); #endif @@ -11692,6 +11355,13 @@ DirEntry_repr(DirEntry *self) return PyUnicode_FromFormat("<DirEntry %R>", self->name); } +static PyObject * +DirEntry_fspath(DirEntry *self) +{ + Py_INCREF(self->path); + return self->path; +} + static PyMemberDef DirEntry_members[] = { {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY, "the entry's base filename, relative to scandir() \"path\" argument"}, @@ -11716,6 +11386,9 @@ static PyMethodDef DirEntry_methods[] = { {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS, "return inode of the entry; cached per entry", }, + {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS, + "returns the path for the entry", + }, {NULL} }; @@ -11755,7 +11428,7 @@ static PyTypeObject DirEntryType = { #ifdef MS_WINDOWS static wchar_t * -join_path_filenameW(wchar_t *path_wide, wchar_t* filename) +join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename) { Py_ssize_t path_len; Py_ssize_t size; @@ -11807,6 +11480,11 @@ DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW) entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1); if (!entry->name) goto error; + if (path->narrow) { + Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name)); + if (!entry->name) + goto error; + } joined_path = join_path_filenameW(path->wide, dataW->cFileName); if (!joined_path) @@ -11816,8 +11494,13 @@ DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW) PyMem_Free(joined_path); if (!entry->path) goto error; + if (path->narrow) { + Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path)); + if (!entry->path) + goto error; + } - find_data_to_file_info_w(dataW, &file_info, &reparse_tag); + find_data_to_file_info(dataW, &file_info, &reparse_tag); _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat); return (PyObject *)entry; @@ -11830,7 +11513,7 @@ error: #else /* POSIX */ static char * -join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len) +join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len) { Py_ssize_t path_len; Py_ssize_t size; @@ -11862,7 +11545,7 @@ join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len) } static PyObject * -DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len, +DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len, ino_t d_ino #ifdef HAVE_DIRENT_D_TYPE , unsigned char d_type @@ -11925,8 +11608,14 @@ typedef struct { #ifdef MS_WINDOWS +static int +ScandirIterator_is_closed(ScandirIterator *iterator) +{ + return iterator->handle == INVALID_HANDLE_VALUE; +} + static void -ScandirIterator_close(ScandirIterator *iterator) +ScandirIterator_closedir(ScandirIterator *iterator) { HANDLE handle = iterator->handle; @@ -11946,7 +11635,7 @@ ScandirIterator_iternext(ScandirIterator *iterator) BOOL success; PyObject *entry; - /* Happens if the iterator is iterated twice */ + /* Happens if the iterator is iterated twice, or closed explicitly */ if (iterator->handle == INVALID_HANDLE_VALUE) return NULL; @@ -11977,14 +11666,20 @@ ScandirIterator_iternext(ScandirIterator *iterator) } /* Error or no more files */ - ScandirIterator_close(iterator); + ScandirIterator_closedir(iterator); return NULL; } #else /* POSIX */ +static int +ScandirIterator_is_closed(ScandirIterator *iterator) +{ + return !iterator->dirp; +} + static void -ScandirIterator_close(ScandirIterator *iterator) +ScandirIterator_closedir(ScandirIterator *iterator) { DIR *dirp = iterator->dirp; @@ -12006,7 +11701,7 @@ ScandirIterator_iternext(ScandirIterator *iterator) int is_dot; PyObject *entry; - /* Happens if the iterator is iterated twice */ + /* Happens if the iterator is iterated twice, or closed explicitly */ if (!iterator->dirp) return NULL; @@ -12043,21 +11738,76 @@ ScandirIterator_iternext(ScandirIterator *iterator) } /* Error or no more files */ - ScandirIterator_close(iterator); + ScandirIterator_closedir(iterator); return NULL; } #endif +static PyObject * +ScandirIterator_close(ScandirIterator *self, PyObject *args) +{ + ScandirIterator_closedir(self); + Py_RETURN_NONE; +} + +static PyObject * +ScandirIterator_enter(PyObject *self, PyObject *args) +{ + Py_INCREF(self); + return self; +} + +static PyObject * +ScandirIterator_exit(ScandirIterator *self, PyObject *args) +{ + ScandirIterator_closedir(self); + Py_RETURN_NONE; +} + static void -ScandirIterator_dealloc(ScandirIterator *iterator) +ScandirIterator_finalize(ScandirIterator *iterator) { - ScandirIterator_close(iterator); - Py_XDECREF(iterator->path.object); + PyObject *error_type, *error_value, *error_traceback; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + if (!ScandirIterator_is_closed(iterator)) { + ScandirIterator_closedir(iterator); + + if (PyErr_ResourceWarning((PyObject *)iterator, 1, + "unclosed scandir iterator %R", iterator)) { + /* Spurious errors can appear at shutdown */ + if (PyErr_ExceptionMatches(PyExc_Warning)) { + PyErr_WriteUnraisable((PyObject *) iterator); + } + } + } + + Py_CLEAR(iterator->path.object); path_cleanup(&iterator->path); + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +static void +ScandirIterator_dealloc(ScandirIterator *iterator) +{ + if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) + return; + Py_TYPE(iterator)->tp_free((PyObject *)iterator); } +static PyMethodDef ScandirIterator_methods[] = { + {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, + {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, + {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, + {NULL} +}; + static PyTypeObject ScandirIteratorType = { PyVarObject_HEAD_INIT(NULL, 0) MODNAME ".ScandirIterator", /* tp_name */ @@ -12079,7 +11829,8 @@ static PyTypeObject ScandirIteratorType = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ + Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -12087,6 +11838,27 @@ static PyTypeObject ScandirIteratorType = { 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)ScandirIterator_iternext, /* tp_iternext */ + ScandirIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + (destructor)ScandirIterator_finalize, /* tp_finalize */ }; static PyObject * @@ -12097,7 +11869,7 @@ posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs) #ifdef MS_WINDOWS wchar_t *path_strW; #else - char *path; + const char *path; #endif iterator = PyObject_New(ScandirIterator, &ScandirIteratorType); @@ -12124,11 +11896,6 @@ posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs) Py_XINCREF(iterator->path.object); #ifdef MS_WINDOWS - if (iterator->path.narrow) { - PyErr_SetString(PyExc_TypeError, - "os.scandir() doesn't support bytes path on Windows, use Unicode instead"); - goto error; - } iterator->first_time = 1; path_strW = join_path_filenameW(iterator->path.wide, L"*.*"); @@ -12169,6 +11936,124 @@ error: return NULL; } +/* + Return the file system path representation of the object. + + If the object is str or bytes, then allow it to pass through with + an incremented refcount. If the object defines __fspath__(), then + return the result of that method. All other types raise a TypeError. +*/ +PyObject * +PyOS_FSPath(PyObject *path) +{ + /* For error message reasons, this function is manually inlined in + path_converter(). */ + _Py_IDENTIFIER(__fspath__); + PyObject *func = NULL; + PyObject *path_repr = NULL; + + if (PyUnicode_Check(path) || PyBytes_Check(path)) { + Py_INCREF(path); + return path; + } + + func = _PyObject_LookupSpecial(path, &PyId___fspath__); + if (NULL == func) { + return PyErr_Format(PyExc_TypeError, + "expected str, bytes or os.PathLike object, " + "not %.200s", + Py_TYPE(path)->tp_name); + } + + path_repr = PyObject_CallFunctionObjArgs(func, NULL); + Py_DECREF(func); + if (NULL == path_repr) { + return NULL; + } + + if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) { + PyErr_Format(PyExc_TypeError, + "expected %.200s.__fspath__() to return str or bytes, " + "not %.200s", Py_TYPE(path)->tp_name, + Py_TYPE(path_repr)->tp_name); + Py_DECREF(path_repr); + return NULL; + } + + return path_repr; +} + +/*[clinic input] +os.fspath + + path: object + +Return the file system path representation of the object. + +If the object is str or bytes, then allow it to pass through as-is. If the +object defines __fspath__(), then return the result of that method. All other +types raise a TypeError. +[clinic start generated code]*/ + +static PyObject * +os_fspath_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/ +{ + return PyOS_FSPath(path); +} + +#ifdef HAVE_GETRANDOM_SYSCALL +/*[clinic input] +os.getrandom + + size: Py_ssize_t + flags: int=0 + +Obtain a series of random bytes. +[clinic start generated code]*/ + +static PyObject * +os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags) +/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/ +{ + char *buffer; + Py_ssize_t n; + PyObject *bytes; + + if (size < 0) { + errno = EINVAL; + return posix_error(); + } + + buffer = PyMem_Malloc(size); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + + while (1) { + n = syscall(SYS_getrandom, buffer, size, flags); + if (n < 0 && errno == EINTR) { + if (PyErr_CheckSignals() < 0) { + return NULL; + } + continue; + } + break; + } + + if (n < 0) { + PyMem_Free(buffer); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + bytes = PyBytes_FromStringAndSize(buffer, n); + PyMem_Free(buffer); + + return bytes; +} +#endif /* HAVE_GETRANDOM_SYSCALL */ #include "clinic/posixmodule.c.h" @@ -12260,7 +12145,7 @@ static PyMethodDef posix_methods[] = { OS_KILLPG_METHODDEF OS_PLOCK_METHODDEF #ifdef MS_WINDOWS - {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__}, + OS_STARTFILE_METHODDEF #endif OS_SETUID_METHODDEF OS_SETEUID_METHODDEF @@ -12369,6 +12254,8 @@ static PyMethodDef posix_methods[] = { {"scandir", (PyCFunction)posix_scandir, METH_VARARGS | METH_KEYWORDS, posix_scandir__doc__}, + OS_FSPATH_METHODDEF + OS_GETRANDOM_METHODDEF {NULL, NULL} /* Sentinel */ }; @@ -12380,7 +12267,6 @@ enable_symlink() HANDLE tok; TOKEN_PRIVILEGES tok_priv; LUID luid; - int meth_idx = 0; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok)) return 0; @@ -12483,12 +12369,14 @@ all_ins(PyObject *m) #ifdef O_LARGEFILE if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1; #endif +#ifndef __GNU__ #ifdef O_SHLOCK if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1; #endif #ifdef O_EXLOCK if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1; #endif +#endif #ifdef O_EXEC if (PyModule_AddIntMacro(m, O_EXEC)) return -1; #endif @@ -12791,28 +12679,33 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1; #endif -#ifdef RTLD_LAZY +#if HAVE_DECL_RTLD_LAZY if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1; #endif -#ifdef RTLD_NOW +#if HAVE_DECL_RTLD_NOW if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1; #endif -#ifdef RTLD_GLOBAL +#if HAVE_DECL_RTLD_GLOBAL if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1; #endif -#ifdef RTLD_LOCAL +#if HAVE_DECL_RTLD_LOCAL if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1; #endif -#ifdef RTLD_NODELETE +#if HAVE_DECL_RTLD_NODELETE if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1; #endif -#ifdef RTLD_NOLOAD +#if HAVE_DECL_RTLD_NOLOAD if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1; #endif -#ifdef RTLD_DEEPBIND +#if HAVE_DECL_RTLD_DEEPBIND if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1; #endif +#ifdef HAVE_GETRANDOM_SYSCALL + if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1; + if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1; +#endif + return 0; } @@ -12830,7 +12723,7 @@ static struct PyModuleDef posixmodule = { }; -static char *have_functions[] = { +static const char * const have_functions[] = { #ifdef HAVE_FACCESSAT "HAVE_FACCESSAT", @@ -12965,7 +12858,7 @@ INITFUNC(void) { PyObject *m, *v; PyObject *list; - char **trace; + const char * const *trace; #if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) win32_can_symlink = enable_symlink(); @@ -13141,6 +13034,9 @@ INITFUNC(void) } PyModule_AddObject(m, "_have_functions", list); + Py_INCREF((PyObject *) &DirEntryType); + PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType); + initialized = 1; return m; diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index 7416cf7..784e9d0 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -75,10 +75,18 @@ mkpwent(struct passwd *p) #define SETS(i,val) sets(v, i, val) SETS(setIndex++, p->pw_name); +#if defined(HAVE_STRUCT_PASSWD_PW_PASSWD) && !defined(__ANDROID__) SETS(setIndex++, p->pw_passwd); +#else + SETS(setIndex++, ""); +#endif PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); +#if defined(HAVE_STRUCT_PASSWD_PW_GECOS) SETS(setIndex++, p->pw_gecos); +#else + SETS(setIndex++, ""); +#endif SETS(setIndex++, p->pw_dir); SETS(setIndex++, p->pw_shell); diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index eb322c2..b19b7be 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -91,7 +91,7 @@ static struct HandlerInfo handler_info[64]; * false on an exception. */ static int -set_error_attr(PyObject *err, char *name, int value) +set_error_attr(PyObject *err, const char *name, int value) { PyObject *v = PyLong_FromLong(value); @@ -218,7 +218,7 @@ flag_error(xmlparseobject *self) } static PyObject* -call_with_frame(char *funcname, int lineno, PyObject* func, PyObject* args, +call_with_frame(const char *funcname, int lineno, PyObject* func, PyObject* args, xmlparseobject *self) { PyObject *res; @@ -747,7 +747,8 @@ pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, s += MAX_CHUNK_SIZE; slen -= MAX_CHUNK_SIZE; } - assert(MAX_CHUNK_SIZE < INT_MAX && slen < INT_MAX); + Py_BUILD_ASSERT(MAX_CHUNK_SIZE <= INT_MAX); + assert(slen <= INT_MAX); rc = XML_Parse(self->itself, s, (int)slen, isfinal); done: @@ -765,7 +766,7 @@ readinst(char *buf, int buf_size, PyObject *meth) { PyObject *str; Py_ssize_t len; - char *ptr; + const char *ptr; str = PyObject_CallFunction(meth, "n", buf_size); if (str == NULL) @@ -1225,12 +1226,8 @@ xmlparse_dealloc(xmlparseobject *self) self->itself = NULL; if (self->handlers != NULL) { - PyObject *temp; - for (i = 0; handler_info[i].name != NULL; i++) { - temp = self->handlers[i]; - self->handlers[i] = NULL; - Py_XDECREF(temp); - } + for (i = 0; handler_info[i].name != NULL; i++) + Py_CLEAR(self->handlers[i]); PyMem_Free(self->handlers); self->handlers = NULL; } @@ -1344,7 +1341,6 @@ sethandler(xmlparseobject *self, PyObject *name, PyObject* v) int handlernum = handlername2int(name); if (handlernum >= 0) { xmlhandler c_handler = NULL; - PyObject *temp = self->handlers[handlernum]; if (v == Py_None) { /* If this is the character data handler, and a character @@ -1366,8 +1362,7 @@ sethandler(xmlparseobject *self, PyObject *name, PyObject* v) Py_INCREF(v); c_handler = handler_info[handlernum].handler; } - self->handlers[handlernum] = v; - Py_XDECREF(temp); + Py_XSETREF(self->handlers[handlernum], v); handler_info[handlernum].setter(self->itself, c_handler); return 1; } @@ -1706,7 +1701,15 @@ MODULE_INITFUNC(void) PyModule_AddStringConstant(m, "native_encoding", "UTF-8"); sys_modules = PySys_GetObject("modules"); + if (sys_modules == NULL) { + Py_DECREF(m); + return NULL; + } d = PyModule_GetDict(m); + if (d == NULL) { + Py_DECREF(m); + return NULL; + } errors_module = PyDict_GetItem(d, errmod_name); if (errors_module == NULL) { errors_module = PyModule_New(MODULE_NAME ".errors"); @@ -1727,9 +1730,11 @@ MODULE_INITFUNC(void) } } Py_DECREF(modelmod_name); - if (errors_module == NULL || model_module == NULL) + if (errors_module == NULL || model_module == NULL) { /* Don't core dump later! */ + Py_DECREF(m); return NULL; + } #if XML_COMBINED_VERSION > 19505 { @@ -1897,15 +1902,12 @@ static void clear_handlers(xmlparseobject *self, int initial) { int i = 0; - PyObject *temp; for (; handler_info[i].name != NULL; i++) { if (initial) self->handlers[i] = NULL; else { - temp = self->handlers[i]; - self->handlers[i] = NULL; - Py_XDECREF(temp); + Py_CLEAR(self->handlers[i]); handler_info[i].setter(self->itself, NULL); } } diff --git a/Modules/readline.c b/Modules/readline.c index 54f15bc..3b94d4a 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -343,10 +343,8 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *args) Py_CLEAR(*hook_var); } else if (PyCallable_Check(function)) { - PyObject *tmp = *hook_var; Py_INCREF(function); - *hook_var = function; - Py_XDECREF(tmp); + Py_XSETREF(*hook_var, function); } else { PyErr_Format(PyExc_TypeError, @@ -604,6 +602,24 @@ PyDoc_STRVAR(doc_add_history, "add_history(string) -> None\n\ add an item to the history buffer"); +static int should_auto_add_history = 1; + +/* Enable or disable automatic history */ + +static PyObject * +py_set_auto_history(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "p:set_auto_history", + &should_auto_add_history)) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(doc_set_auto_history, +"set_auto_history(enabled) -> None\n\ +Enables or disables automatic history."); + /* Get the tab-completion word-delimiters that readline uses */ @@ -822,6 +838,7 @@ static struct PyMethodDef readline_methods[] = {"set_completer_delims", set_completer_delims, METH_O, doc_set_completer_delims}, + {"set_auto_history", py_set_auto_history, METH_VARARGS, doc_set_auto_history}, {"add_history", py_add_history, METH_O, doc_add_history}, {"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history}, {"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history}, @@ -857,7 +874,7 @@ on_hook(PyObject *func) if (r == Py_None) result = 0; else { - result = PyLong_AsLong(r); + result = _PyLong_AsInt(r); if (result == -1 && PyErr_Occurred()) goto error; } @@ -1327,7 +1344,7 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) /* we have a valid line */ n = strlen(p); - if (n > 0) { + if (should_auto_add_history && n > 0) { const char *line; int length = _py_get_history_length(); if (length > 0) diff --git a/Modules/resource.c b/Modules/resource.c index 3a1cf09..6702b7a 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -135,13 +135,11 @@ py2rlimit(PyObject *curobj, PyObject *maxobj, struct rlimit *rl_out) static PyObject* rlimit2py(struct rlimit rl) { -#if defined(HAVE_LONG_LONG) if (sizeof(rl.rlim_cur) > sizeof(long)) { return Py_BuildValue("LL", - (PY_LONG_LONG) rl.rlim_cur, - (PY_LONG_LONG) rl.rlim_max); + (long long) rl.rlim_cur, + (long long) rl.rlim_max); } -#endif return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max); } @@ -438,11 +436,9 @@ PyInit_resource(void) PyModule_AddIntMacro(m, RLIMIT_NPTS); #endif -#if defined(HAVE_LONG_LONG) if (sizeof(RLIM_INFINITY) > sizeof(long)) { - v = PyLong_FromLongLong((PY_LONG_LONG) RLIM_INFINITY); + v = PyLong_FromLongLong((long long) RLIM_INFINITY); } else -#endif { v = PyLong_FromLong((long) RLIM_INFINITY); } diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 00324a5..49fa1f5 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -4,6 +4,10 @@ have any value except INVALID_SOCKET. */ +#if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE +#endif + #include "Python.h" #include <structmember.h> @@ -1793,7 +1797,7 @@ static PyTypeObject kqueue_queue_Type; */ #if !defined(__OpenBSD__) # define IDENT_TYPE T_UINTPTRT -# define IDENT_CAST Py_intptr_t +# define IDENT_CAST intptr_t # define DATA_TYPE T_INTPTRT # define DATA_FMT_UNIT INTPTRT_FMT_UNIT # define IDENT_AsType PyLong_AsUintptr_t @@ -1842,7 +1846,7 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds) PyObject *pfd; static char *kwlist[] = {"ident", "filter", "flags", "fflags", "data", "udata", NULL}; - static char *fmt = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent"; + static const char fmt[] = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent"; EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */ @@ -1872,7 +1876,7 @@ static PyObject * kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, int op) { - Py_intptr_t result = 0; + intptr_t result = 0; if (!kqueue_event_Check(o)) { if (op == Py_EQ || op == Py_NE) { @@ -2127,7 +2131,7 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) if (_PyTime_FromSecondsObject(&timeout, otimeout, _PyTime_ROUND_CEILING) < 0) { PyErr_Format(PyExc_TypeError, - "timeout argument must be an number " + "timeout argument must be a number " "or None, got %.200s", Py_TYPE(otimeout)->tp_name); return NULL; @@ -2452,6 +2456,10 @@ PyInit_select(void) #ifdef POLLMSG PyModule_AddIntMacro(m, POLLMSG); #endif +#ifdef POLLRDHUP + /* Kernel 2.6.17+ */ + PyModule_AddIntMacro(m, POLLRDHUP); +#endif } #endif /* HAVE_POLL */ @@ -2473,12 +2481,18 @@ PyInit_select(void) PyModule_AddIntMacro(m, EPOLLPRI); PyModule_AddIntMacro(m, EPOLLERR); PyModule_AddIntMacro(m, EPOLLHUP); +#ifdef EPOLLRDHUP + /* Kernel 2.6.17 */ + PyModule_AddIntMacro(m, EPOLLRDHUP); +#endif PyModule_AddIntMacro(m, EPOLLET); #ifdef EPOLLONESHOT /* Kernel 2.6.2+ */ PyModule_AddIntMacro(m, EPOLLONESHOT); #endif - /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */ +#ifdef EPOLLEXCLUSIVE + PyModule_AddIntMacro(m, EPOLLEXCLUSIVE); +#endif #ifdef EPOLLRDNORM PyModule_AddIntMacro(m, EPOLLRDNORM); diff --git a/Modules/sha1module.c b/Modules/sha1module.c index 6cb32ed..d5065ce 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -30,7 +30,7 @@ class SHA1Type "SHA1object *" "&PyType_Type" #if SIZEOF_INT == 4 typedef unsigned int SHA1_INT32; /* 32-bit integer */ -typedef PY_LONG_LONG SHA1_INT64; /* 64-bit integer */ +typedef long long SHA1_INT64; /* 64-bit integer */ #else /* not defined. compilation will die. */ #endif diff --git a/Modules/sha512module.c b/Modules/sha512module.c index f9ff0ea..f5f9e18 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -27,15 +27,13 @@ class SHA512Type "SHAobject *" "&PyType_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81a3ccde92bcfe8d]*/ -#ifdef PY_LONG_LONG /* If no PY_LONG_LONG, don't compile anything! */ - /* Some useful types */ typedef unsigned char SHA_BYTE; #if SIZEOF_INT == 4 typedef unsigned int SHA_INT32; /* 32-bit integer */ -typedef unsigned PY_LONG_LONG SHA_INT64; /* 64-bit integer */ +typedef unsigned long long SHA_INT64; /* 64-bit integer */ #else /* not defined. compilation will die. */ #endif @@ -121,12 +119,12 @@ static void SHAcopy(SHAobject *src, SHAobject *dest) /* Various logical functions */ #define ROR64(x, y) \ - ( ((((x) & Py_ULL(0xFFFFFFFFFFFFFFFF))>>((unsigned PY_LONG_LONG)(y) & 63)) | \ - ((x)<<((unsigned PY_LONG_LONG)(64-((y) & 63))))) & Py_ULL(0xFFFFFFFFFFFFFFFF)) + ( ((((x) & Py_ULL(0xFFFFFFFFFFFFFFFF))>>((unsigned long long)(y) & 63)) | \ + ((x)<<((unsigned long long)(64-((y) & 63))))) & Py_ULL(0xFFFFFFFFFFFFFFFF)) #define Ch(x,y,z) (z ^ (x & (y ^ z))) #define Maj(x,y,z) (((x | y) & z) | (x & y)) #define S(x, n) ROR64((x),(n)) -#define R(x, n) (((x) & Py_ULL(0xFFFFFFFFFFFFFFFF)) >> ((unsigned PY_LONG_LONG)n)) +#define R(x, n) (((x) & Py_ULL(0xFFFFFFFFFFFFFFFF)) >> ((unsigned long long)n)) #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) #define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) @@ -803,5 +801,3 @@ PyInit__sha512(void) PyModule_AddObject(m, "SHA512Type", (PyObject *)&SHA512type); return m; } - -#endif diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index a1a18b0..8ca5791 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -198,7 +198,7 @@ static int report_wakeup_write_error(void *data) { int save_errno = errno; - errno = (int) (Py_intptr_t) data; + errno = (int) (intptr_t) data; PyErr_SetFromErrno(PyExc_OSError); PySys_WriteStderr("Exception ignored when trying to write to the " "signal wakeup fd:\n"); @@ -277,7 +277,7 @@ trip_signal(int sig_num) if (rc < 0) { Py_AddPendingCall(report_wakeup_write_error, - (void *)(Py_intptr_t)errno); + (void *)(intptr_t)errno); } } } @@ -579,7 +579,7 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args) } fd = (int)sockfd; - if ((SOCKET_T)fd != sockfd || !_PyVerify_fd(fd)) { + if ((SOCKET_T)fd != sockfd) { PyErr_SetString(PyExc_ValueError, "invalid fd"); return NULL; } @@ -609,11 +609,6 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args) if (fd != -1) { int blocking; - if (!_PyVerify_fd(fd)) { - PyErr_SetString(PyExc_ValueError, "invalid fd"); - return NULL; - } - if (_Py_fstat(fd, &status) != 0) return NULL; @@ -1271,210 +1266,169 @@ PyInit__signal(void) } #ifdef SIGHUP - x = PyLong_FromLong(SIGHUP); - PyDict_SetItemString(d, "SIGHUP", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGHUP)) + goto finally; #endif #ifdef SIGINT - x = PyLong_FromLong(SIGINT); - PyDict_SetItemString(d, "SIGINT", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGINT)) + goto finally; #endif #ifdef SIGBREAK - x = PyLong_FromLong(SIGBREAK); - PyDict_SetItemString(d, "SIGBREAK", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGBREAK)) + goto finally; #endif #ifdef SIGQUIT - x = PyLong_FromLong(SIGQUIT); - PyDict_SetItemString(d, "SIGQUIT", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGQUIT)) + goto finally; #endif #ifdef SIGILL - x = PyLong_FromLong(SIGILL); - PyDict_SetItemString(d, "SIGILL", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGILL)) + goto finally; #endif #ifdef SIGTRAP - x = PyLong_FromLong(SIGTRAP); - PyDict_SetItemString(d, "SIGTRAP", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGTRAP)) + goto finally; #endif #ifdef SIGIOT - x = PyLong_FromLong(SIGIOT); - PyDict_SetItemString(d, "SIGIOT", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGIOT)) + goto finally; #endif #ifdef SIGABRT - x = PyLong_FromLong(SIGABRT); - PyDict_SetItemString(d, "SIGABRT", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGABRT)) + goto finally; #endif #ifdef SIGEMT - x = PyLong_FromLong(SIGEMT); - PyDict_SetItemString(d, "SIGEMT", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGEMT)) + goto finally; #endif #ifdef SIGFPE - x = PyLong_FromLong(SIGFPE); - PyDict_SetItemString(d, "SIGFPE", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGFPE)) + goto finally; #endif #ifdef SIGKILL - x = PyLong_FromLong(SIGKILL); - PyDict_SetItemString(d, "SIGKILL", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGKILL)) + goto finally; #endif #ifdef SIGBUS - x = PyLong_FromLong(SIGBUS); - PyDict_SetItemString(d, "SIGBUS", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGBUS)) + goto finally; #endif #ifdef SIGSEGV - x = PyLong_FromLong(SIGSEGV); - PyDict_SetItemString(d, "SIGSEGV", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGSEGV)) + goto finally; #endif #ifdef SIGSYS - x = PyLong_FromLong(SIGSYS); - PyDict_SetItemString(d, "SIGSYS", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGSYS)) + goto finally; #endif #ifdef SIGPIPE - x = PyLong_FromLong(SIGPIPE); - PyDict_SetItemString(d, "SIGPIPE", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGPIPE)) + goto finally; #endif #ifdef SIGALRM - x = PyLong_FromLong(SIGALRM); - PyDict_SetItemString(d, "SIGALRM", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGALRM)) + goto finally; #endif #ifdef SIGTERM - x = PyLong_FromLong(SIGTERM); - PyDict_SetItemString(d, "SIGTERM", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGTERM)) + goto finally; #endif #ifdef SIGUSR1 - x = PyLong_FromLong(SIGUSR1); - PyDict_SetItemString(d, "SIGUSR1", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGUSR1)) + goto finally; #endif #ifdef SIGUSR2 - x = PyLong_FromLong(SIGUSR2); - PyDict_SetItemString(d, "SIGUSR2", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGUSR2)) + goto finally; #endif #ifdef SIGCLD - x = PyLong_FromLong(SIGCLD); - PyDict_SetItemString(d, "SIGCLD", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGCLD)) + goto finally; #endif #ifdef SIGCHLD - x = PyLong_FromLong(SIGCHLD); - PyDict_SetItemString(d, "SIGCHLD", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGCHLD)) + goto finally; #endif #ifdef SIGPWR - x = PyLong_FromLong(SIGPWR); - PyDict_SetItemString(d, "SIGPWR", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGPWR)) + goto finally; #endif #ifdef SIGIO - x = PyLong_FromLong(SIGIO); - PyDict_SetItemString(d, "SIGIO", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGIO)) + goto finally; #endif #ifdef SIGURG - x = PyLong_FromLong(SIGURG); - PyDict_SetItemString(d, "SIGURG", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGURG)) + goto finally; #endif #ifdef SIGWINCH - x = PyLong_FromLong(SIGWINCH); - PyDict_SetItemString(d, "SIGWINCH", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGWINCH)) + goto finally; #endif #ifdef SIGPOLL - x = PyLong_FromLong(SIGPOLL); - PyDict_SetItemString(d, "SIGPOLL", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGPOLL)) + goto finally; #endif #ifdef SIGSTOP - x = PyLong_FromLong(SIGSTOP); - PyDict_SetItemString(d, "SIGSTOP", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGSTOP)) + goto finally; #endif #ifdef SIGTSTP - x = PyLong_FromLong(SIGTSTP); - PyDict_SetItemString(d, "SIGTSTP", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGTSTP)) + goto finally; #endif #ifdef SIGCONT - x = PyLong_FromLong(SIGCONT); - PyDict_SetItemString(d, "SIGCONT", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGCONT)) + goto finally; #endif #ifdef SIGTTIN - x = PyLong_FromLong(SIGTTIN); - PyDict_SetItemString(d, "SIGTTIN", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGTTIN)) + goto finally; #endif #ifdef SIGTTOU - x = PyLong_FromLong(SIGTTOU); - PyDict_SetItemString(d, "SIGTTOU", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGTTOU)) + goto finally; #endif #ifdef SIGVTALRM - x = PyLong_FromLong(SIGVTALRM); - PyDict_SetItemString(d, "SIGVTALRM", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGVTALRM)) + goto finally; #endif #ifdef SIGPROF - x = PyLong_FromLong(SIGPROF); - PyDict_SetItemString(d, "SIGPROF", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGPROF)) + goto finally; #endif #ifdef SIGXCPU - x = PyLong_FromLong(SIGXCPU); - PyDict_SetItemString(d, "SIGXCPU", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGXCPU)) + goto finally; #endif #ifdef SIGXFSZ - x = PyLong_FromLong(SIGXFSZ); - PyDict_SetItemString(d, "SIGXFSZ", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGXFSZ)) + goto finally; #endif #ifdef SIGRTMIN - x = PyLong_FromLong(SIGRTMIN); - PyDict_SetItemString(d, "SIGRTMIN", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGRTMIN)) + goto finally; #endif #ifdef SIGRTMAX - x = PyLong_FromLong(SIGRTMAX); - PyDict_SetItemString(d, "SIGRTMAX", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGRTMAX)) + goto finally; #endif #ifdef SIGINFO - x = PyLong_FromLong(SIGINFO); - PyDict_SetItemString(d, "SIGINFO", x); - Py_XDECREF(x); + if (PyModule_AddIntMacro(m, SIGINFO)) + goto finally; #endif #ifdef ITIMER_REAL - x = PyLong_FromLong(ITIMER_REAL); - PyDict_SetItemString(d, "ITIMER_REAL", x); - Py_DECREF(x); + if (PyModule_AddIntMacro(m, ITIMER_REAL)) + goto finally; #endif #ifdef ITIMER_VIRTUAL - x = PyLong_FromLong(ITIMER_VIRTUAL); - PyDict_SetItemString(d, "ITIMER_VIRTUAL", x); - Py_DECREF(x); + if (PyModule_AddIntMacro(m, ITIMER_VIRTUAL)) + goto finally; #endif #ifdef ITIMER_PROF - x = PyLong_FromLong(ITIMER_PROF); - PyDict_SetItemString(d, "ITIMER_PROF", x); - Py_DECREF(x); + if (PyModule_AddIntMacro(m, ITIMER_PROF)) + goto finally; #endif #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) @@ -1485,15 +1439,13 @@ PyInit__signal(void) #endif #ifdef CTRL_C_EVENT - x = PyLong_FromLong(CTRL_C_EVENT); - PyDict_SetItemString(d, "CTRL_C_EVENT", x); - Py_DECREF(x); + if (PyModule_AddIntMacro(m, CTRL_C_EVENT)) + goto finally; #endif #ifdef CTRL_BREAK_EVENT - x = PyLong_FromLong(CTRL_BREAK_EVENT); - PyDict_SetItemString(d, "CTRL_BREAK_EVENT", x); - Py_DECREF(x); + if (PyModule_AddIntMacro(m, CTRL_BREAK_EVENT)) + goto finally; #endif #ifdef MS_WINDOWS diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index d059617..dd8bfb0 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -136,7 +136,7 @@ sendall(data[, flags]) -- send all data\n\ send(data[, flags]) -- send data, may not send all of it\n\ sendto(data[, flags], addr) -- send data to a given address\n\ setblocking(0 | 1) -- set or clear the blocking I/O flag\n\ -setsockopt(level, optname, value) -- set socket options\n\ +setsockopt(level, optname, value[, optlen]) -- set socket options\n\ settimeout(None | float) -- set or clear the timeout\n\ shutdown(how) -- shut down traffic in one or both directions\n\ if_nameindex() -- return all network interface indices and names\n\ @@ -153,7 +153,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ On the other hand, not all Linux versions agree, so there the settings computed by the configure script are needed! */ -#ifndef linux +#ifndef __linux__ # undef HAVE_GETHOSTBYNAME_R_3_ARG # undef HAVE_GETHOSTBYNAME_R_5_ARG # undef HAVE_GETHOSTBYNAME_R_6_ARG @@ -163,7 +163,11 @@ if_indextoname(index) -- return the corresponding interface name\n\ # include <sys/uio.h> #endif -#ifndef WITH_THREAD +#if !defined(WITH_THREAD) +# undef HAVE_GETHOSTBYNAME_R +#endif + +#if defined(__ANDROID__) && __ANDROID_API__ < 23 # undef HAVE_GETHOSTBYNAME_R #endif @@ -172,7 +176,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ # define HAVE_GETHOSTBYNAME_R_3_ARG # elif defined(__sun) || defined(__sgi) # define HAVE_GETHOSTBYNAME_R_5_ARG -# elif defined(linux) +# elif defined(__linux__) /* Rely on the configure script */ # else # undef HAVE_GETHOSTBYNAME_R @@ -282,6 +286,36 @@ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82& #include <net/if.h> #endif +#ifdef HAVE_SOCKADDR_ALG +#include <linux/if_alg.h> +#ifndef AF_ALG +#define AF_ALG 38 +#endif +#ifndef SOL_ALG +#define SOL_ALG 279 +#endif + +/* Linux 3.19 */ +#ifndef ALG_SET_AEAD_ASSOCLEN +#define ALG_SET_AEAD_ASSOCLEN 4 +#endif +#ifndef ALG_SET_AEAD_AUTHSIZE +#define ALG_SET_AEAD_AUTHSIZE 5 +#endif +/* Linux 4.8 */ +#ifndef ALG_SET_PUBKEY +#define ALG_SET_PUBKEY 6 +#endif + +#ifndef ALG_OP_SIGN +#define ALG_OP_SIGN 2 +#endif +#ifndef ALG_OP_VERIFY +#define ALG_OP_VERIFY 3 +#endif + +#endif /* HAVE_SOCKADDR_ALG */ + /* Generic socket object definitions and includes */ #define PySocket_BUILDING_SOCKET #include "socketmodule.h" @@ -606,24 +640,35 @@ internal_setblocking(PySocketSockObject *s, int block) #ifndef MS_WINDOWS #if (defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)) block = !block; - ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block); + if (ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block) == -1) + goto error; #else delay_flag = fcntl(s->sock_fd, F_GETFL, 0); + if (delay_flag == -1) + goto error; if (block) new_delay_flag = delay_flag & (~O_NONBLOCK); else new_delay_flag = delay_flag | O_NONBLOCK; if (new_delay_flag != delay_flag) - fcntl(s->sock_fd, F_SETFL, new_delay_flag); + if (fcntl(s->sock_fd, F_SETFL, new_delay_flag) == -1) + goto error; #endif #else /* MS_WINDOWS */ arg = !block; - ioctlsocket(s->sock_fd, FIONBIO, &arg); + if (ioctlsocket(s->sock_fd, FIONBIO, &arg) != 0) + goto error; #endif /* MS_WINDOWS */ Py_END_ALLOW_THREADS - /* Since these don't return anything */ - return 1; + return 0; + error: +#ifndef MS_WINDOWS + PyErr_SetFromErrno(PyExc_OSError); +#else + PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); +#endif + return -1; } static int @@ -871,7 +916,7 @@ sock_call(PySocketSockObject *s, /* Default timeout for new sockets */ static _PyTime_t defaulttimeout = _PYTIME_FROMSECONDS(-1); -static void +static int init_sockobject(PySocketSockObject *s, SOCKET_T fd, int family, int type, int proto) { @@ -888,10 +933,13 @@ init_sockobject(PySocketSockObject *s, #endif { s->sock_timeout = defaulttimeout; - if (defaulttimeout >= 0) - internal_setblocking(s, 0); + if (defaulttimeout >= 0) { + if (internal_setblocking(s, 0) == -1) { + return -1; + } + } } - + return 0; } @@ -906,8 +954,12 @@ new_sockobject(SOCKET_T fd, int family, int type, int proto) PySocketSockObject *s; s = (PySocketSockObject *) PyType_GenericNew(&sock_type, NULL, NULL); - if (s != NULL) - init_sockobject(s, fd, family, type, proto); + if (s == NULL) + return NULL; + if (init_sockobject(s, fd, family, type, proto) == -1) { + Py_DECREF(s); + return NULL; + } return s; } @@ -926,7 +978,7 @@ static PyThread_type_lock netdb_lock; an error occurred; then an exception is raised. */ static int -setipaddr(char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af) +setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af) { struct addrinfo hints, *res; int error; @@ -1107,7 +1159,7 @@ makeipaddr(struct sockaddr *addr, int addrlen) an error occurred. */ static int -setbdaddr(char *name, bdaddr_t *bdaddr) +setbdaddr(const char *name, bdaddr_t *bdaddr) { unsigned int b0, b1, b2, b3, b4, b5; char ch; @@ -1180,7 +1232,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) case AF_UNIX: { struct sockaddr_un *a = (struct sockaddr_un *) addr; -#ifdef linux +#ifdef __linux__ if (a->sun_path[0] == 0) { /* Linux abstract namespace */ addrlen -= offsetof(struct sockaddr_un, sun_path); return PyBytes_FromStringAndSize(a->sun_path, addrlen); @@ -1371,6 +1423,22 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } #endif +#ifdef HAVE_SOCKADDR_ALG + case AF_ALG: + { + struct sockaddr_alg *a = (struct sockaddr_alg *)addr; + return Py_BuildValue("s#s#HH", + a->salg_type, + strnlen((const char*)a->salg_type, + sizeof(a->salg_type)), + a->salg_name, + strnlen((const char*)a->salg_name, + sizeof(a->salg_name)), + a->salg_feat, + a->salg_mask); + } +#endif + /* More cases here... */ default: @@ -1401,7 +1469,7 @@ static int idna_converter(PyObject *obj, struct maybe_idna *data) { size_t len; - PyObject *obj2, *obj3; + PyObject *obj2; if (obj == NULL) { idna_cleanup(data); return 1; @@ -1416,31 +1484,27 @@ idna_converter(PyObject *obj, struct maybe_idna *data) data->buf = PyByteArray_AsString(obj); len = PyByteArray_Size(obj); } - else if (PyUnicode_Check(obj) && PyUnicode_READY(obj) == 0 && PyUnicode_IS_COMPACT_ASCII(obj)) { - data->buf = PyUnicode_DATA(obj); - len = PyUnicode_GET_LENGTH(obj); - } - else { - obj2 = PyUnicode_FromObject(obj); - if (!obj2) { - PyErr_Format(PyExc_TypeError, "string or unicode text buffer expected, not %s", - obj->ob_type->tp_name); - return 0; + else if (PyUnicode_Check(obj)) { + if (PyUnicode_READY(obj) == 0 && PyUnicode_IS_COMPACT_ASCII(obj)) { + data->buf = PyUnicode_DATA(obj); + len = PyUnicode_GET_LENGTH(obj); } - obj3 = PyUnicode_AsEncodedString(obj2, "idna", NULL); - Py_DECREF(obj2); - if (!obj3) { - PyErr_SetString(PyExc_TypeError, "encoding of hostname failed"); - return 0; - } - if (!PyBytes_Check(obj3)) { - Py_DECREF(obj3); - PyErr_SetString(PyExc_TypeError, "encoding of hostname failed to return bytes"); - return 0; + else { + obj2 = PyUnicode_AsEncodedString(obj, "idna", NULL); + if (!obj2) { + PyErr_SetString(PyExc_TypeError, "encoding of hostname failed"); + return 0; + } + assert(PyBytes_Check(obj2)); + data->obj = obj2; + data->buf = PyBytes_AS_STRING(obj2); + len = PyBytes_GET_SIZE(obj2); } - data->obj = obj3; - data->buf = PyBytes_AS_STRING(obj3); - len = PyBytes_GET_SIZE(obj3); + } + else { + PyErr_Format(PyExc_TypeError, "str, bytes or bytearray expected, not %s", + obj->ob_type->tp_name); + return 0; } if (strlen(data->buf) != len) { Py_CLEAR(data->obj); @@ -1483,7 +1547,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, assert(path.len >= 0); addr = (struct sockaddr_un*)addr_ret; -#ifdef linux +#ifdef __linux__ if (path.len > 0 && *(const char *)path.buf == 0) { /* Linux abstract namespace extension */ if ((size_t)path.len > sizeof addr->sun_path) { @@ -1940,6 +2004,36 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 0; } #endif +#ifdef HAVE_SOCKADDR_ALG + case AF_ALG: + { + struct sockaddr_alg *sa; + char *type; + char *name; + sa = (struct sockaddr_alg *)addr_ret; + + memset(sa, 0, sizeof(*sa)); + sa->salg_family = AF_ALG; + + if (!PyArg_ParseTuple(args, "ss|HH:getsockaddrarg", + &type, &name, &sa->salg_feat, &sa->salg_mask)) + return 0; + /* sockaddr_alg has fixed-sized char arrays for type and name */ + if (strlen(type) > sizeof(sa->salg_type)) { + PyErr_SetString(PyExc_ValueError, "AF_ALG type too long."); + return 0; + } + strncpy((char *)sa->salg_type, type, sizeof(sa->salg_type)); + if (strlen(name) > sizeof(sa->salg_name)) { + PyErr_SetString(PyExc_ValueError, "AF_ALG name too long."); + return 0; + } + strncpy((char *)sa->salg_name, name, sizeof(sa->salg_name)); + + *len_ret = sizeof(*sa); + return 1; + } +#endif /* More cases here... */ @@ -2061,6 +2155,13 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) return 0; } #endif +#ifdef HAVE_SOCKADDR_ALG + case AF_ALG: + { + *len_ret = sizeof (struct sockaddr_alg); + return 1; + } +#endif /* More cases here... */ @@ -2220,10 +2321,21 @@ static int sock_accept_impl(PySocketSockObject *s, void *data) { struct sock_accept *ctx = data; + struct sockaddr *addr = SAS2SA(ctx->addrbuf); + socklen_t *paddrlen = ctx->addrlen; +#ifdef HAVE_SOCKADDR_ALG + /* AF_ALG does not support accept() with addr and raises + * ECONNABORTED instead. */ + if (s->sock_family == AF_ALG) { + addr = NULL; + paddrlen = NULL; + *ctx->addrlen = 0; + } +#endif #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) if (accept4_works != 0) { - ctx->result = accept4(s->sock_fd, SAS2SA(ctx->addrbuf), ctx->addrlen, + ctx->result = accept4(s->sock_fd, addr, paddrlen, SOCK_CLOEXEC); if (ctx->result == INVALID_SOCKET && accept4_works == -1) { /* On Linux older than 2.6.28, accept4() fails with ENOSYS */ @@ -2231,9 +2343,9 @@ sock_accept_impl(PySocketSockObject *s, void *data) } } if (accept4_works == 0) - ctx->result = accept(s->sock_fd, SAS2SA(ctx->addrbuf), ctx->addrlen); + ctx->result = accept(s->sock_fd, addr, paddrlen); #else - ctx->result = accept(s->sock_fd, SAS2SA(ctx->addrbuf), ctx->addrlen); + ctx->result = accept(s->sock_fd, addr, paddrlen); #endif #ifdef MS_WINDOWS @@ -2329,10 +2441,10 @@ sock_setblocking(PySocketSockObject *s, PyObject *arg) return NULL; s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0); - internal_setblocking(s, block); - - Py_INCREF(Py_None); - return Py_None; + if (internal_setblocking(s, block) == -1) { + return NULL; + } + Py_RETURN_NONE; } PyDoc_STRVAR(setblocking_doc, @@ -2398,10 +2510,10 @@ sock_settimeout(PySocketSockObject *s, PyObject *arg) return NULL; s->sock_timeout = timeout; - internal_setblocking(s, timeout < 0); - - Py_INCREF(Py_None); - return Py_None; + if (internal_setblocking(s, timeout < 0) == -1) { + return NULL; + } + Py_RETURN_NONE; } PyDoc_STRVAR(settimeout_doc, @@ -2435,9 +2547,12 @@ operations. A timeout of None indicates that timeouts on socket \n\ operations are disabled."); /* s.setsockopt() method. - With an integer third argument, sets an integer option. + With an integer third argument, sets an integer optval with optlen=4. + With None as third argument and an integer fourth argument, set + optval=NULL with unsigned int as optlen. With a string third argument, sets an option from a buffer; - use optional built-in module 'struct' to encode the string. */ + use optional built-in module 'struct' to encode the string. +*/ static PyObject * sock_setsockopt(PySocketSockObject *s, PyObject *args) @@ -2447,31 +2562,64 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args) int res; Py_buffer optval; int flag; + unsigned int optlen; + PyObject *none; + /* setsockopt(level, opt, flag) */ if (PyArg_ParseTuple(args, "iii:setsockopt", &level, &optname, &flag)) { res = setsockopt(s->sock_fd, level, optname, (char*)&flag, sizeof flag); + goto done; } - else { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "iiy*:setsockopt", - &level, &optname, &optval)) - return NULL; - res = setsockopt(s->sock_fd, level, optname, optval.buf, optval.len); + + PyErr_Clear(); + /* setsockopt(level, opt, None, flag) */ + if (PyArg_ParseTuple(args, "iiO!I:setsockopt", + &level, &optname, Py_TYPE(Py_None), &none, &optlen)) { + assert(sizeof(socklen_t) >= sizeof(unsigned int)); + res = setsockopt(s->sock_fd, level, optname, + NULL, (socklen_t)optlen); + goto done; + } + + PyErr_Clear(); + /* setsockopt(level, opt, buffer) */ + if (!PyArg_ParseTuple(args, "iiy*:setsockopt", + &level, &optname, &optval)) + return NULL; + +#ifdef MS_WINDOWS + if (optval.len > INT_MAX) { PyBuffer_Release(&optval); + PyErr_Format(PyExc_OverflowError, + "socket option is larger than %i bytes", + INT_MAX); + return NULL; } - if (res < 0) + res = setsockopt(s->sock_fd, level, optname, + optval.buf, (int)optval.len); +#else + res = setsockopt(s->sock_fd, level, optname, optval.buf, optval.len); +#endif + PyBuffer_Release(&optval); + +done: + if (res < 0) { return s->errorhandler(); - Py_INCREF(Py_None); - return Py_None; + } + + Py_RETURN_NONE; } PyDoc_STRVAR(setsockopt_doc, -"setsockopt(level, option, value)\n\ +"setsockopt(level, option, value: int)\n\ +setsockopt(level, option, value: buffer)\n\ +setsockopt(level, option, None, optlen: int)\n\ \n\ Set a socket option. See the Unix manual for level and option.\n\ -The value argument can either be an integer or a string."); +The value argument can either be an integer, a string buffer, or \n\ +None, optlen."); /* s.getsockopt() method. @@ -2563,17 +2711,22 @@ static PyObject * sock_close(PySocketSockObject *s) { SOCKET_T fd; + int res; - /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/ - * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html - * for more details. - */ fd = s->sock_fd; if (fd != INVALID_SOCKET) { s->sock_fd = INVALID_SOCKET; + + /* We do not want to retry upon EINTR: see + http://lwn.net/Articles/576478/ and + http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html + for more details. */ Py_BEGIN_ALLOW_THREADS - (void) SOCKETCLOSE(fd); + res = SOCKETCLOSE(fd); Py_END_ALLOW_THREADS + if (res < 0) { + return s->errorhandler(); + } } Py_INCREF(Py_None); return Py_None; @@ -3756,6 +3909,51 @@ struct sock_sendmsg { }; static int +sock_sendmsg_iovec(PySocketSockObject *s, PyObject *data_arg, + struct msghdr *msg, + Py_buffer **databufsout, Py_ssize_t *ndatabufsout) { + Py_ssize_t ndataparts, ndatabufs = 0; + int result = -1; + struct iovec *iovs = NULL; + PyObject *data_fast = NULL; + Py_buffer *databufs = NULL; + + /* Fill in an iovec for each message part, and save the Py_buffer + structs to release afterwards. */ + if ((data_fast = PySequence_Fast(data_arg, + "sendmsg() argument 1 must be an " + "iterable")) == NULL) + goto finally; + ndataparts = PySequence_Fast_GET_SIZE(data_fast); + if (ndataparts > INT_MAX) { + PyErr_SetString(PyExc_OSError, "sendmsg() argument 1 is too long"); + goto finally; + } + msg->msg_iovlen = ndataparts; + if (ndataparts > 0 && + ((msg->msg_iov = iovs = PyMem_New(struct iovec, ndataparts)) == NULL || + (databufs = PyMem_New(Py_buffer, ndataparts)) == NULL)) { + PyErr_NoMemory(); + goto finally; + } + for (; ndatabufs < ndataparts; ndatabufs++) { + if (!PyArg_Parse(PySequence_Fast_GET_ITEM(data_fast, ndatabufs), + "y*;sendmsg() argument 1 must be an iterable of " + "bytes-like objects", + &databufs[ndatabufs])) + goto finally; + iovs[ndatabufs].iov_base = databufs[ndatabufs].buf; + iovs[ndatabufs].iov_len = databufs[ndatabufs].len; + } + result = 0; + finally: + *databufsout = databufs; + *ndatabufsout = ndatabufs; + Py_XDECREF(data_fast); + return result; +} + +static int sock_sendmsg_impl(PySocketSockObject *s, void *data) { struct sock_sendmsg *ctx = data; @@ -3769,9 +3967,8 @@ sock_sendmsg_impl(PySocketSockObject *s, void *data) static PyObject * sock_sendmsg(PySocketSockObject *s, PyObject *args) { - Py_ssize_t i, ndataparts, ndatabufs = 0, ncmsgs, ncmsgbufs = 0; + Py_ssize_t i, ndatabufs = 0, ncmsgs, ncmsgbufs = 0; Py_buffer *databufs = NULL; - struct iovec *iovs = NULL; sock_addr_t addrbuf; struct msghdr msg = {0}; struct cmsginfo { @@ -3782,7 +3979,7 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) void *controlbuf = NULL; size_t controllen, controllen_last; int addrlen, flags = 0; - PyObject *data_arg, *cmsg_arg = NULL, *addr_arg = NULL, *data_fast = NULL, + PyObject *data_arg, *cmsg_arg = NULL, *addr_arg = NULL, *cmsg_fast = NULL, *retval = NULL; struct sock_sendmsg ctx; @@ -3800,31 +3997,9 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) /* Fill in an iovec for each message part, and save the Py_buffer structs to release afterwards. */ - if ((data_fast = PySequence_Fast(data_arg, - "sendmsg() argument 1 must be an " - "iterable")) == NULL) - goto finally; - ndataparts = PySequence_Fast_GET_SIZE(data_fast); - if (ndataparts > INT_MAX) { - PyErr_SetString(PyExc_OSError, "sendmsg() argument 1 is too long"); - goto finally; - } - msg.msg_iovlen = ndataparts; - if (ndataparts > 0 && - ((msg.msg_iov = iovs = PyMem_New(struct iovec, ndataparts)) == NULL || - (databufs = PyMem_New(Py_buffer, ndataparts)) == NULL)) { - PyErr_NoMemory(); + if (sock_sendmsg_iovec(s, data_arg, &msg, &databufs, &ndatabufs) == -1) { goto finally; } - for (; ndatabufs < ndataparts; ndatabufs++) { - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(data_fast, ndatabufs), - "y*;sendmsg() argument 1 must be an iterable of " - "bytes-like objects", - &databufs[ndatabufs])) - goto finally; - iovs[ndatabufs].iov_base = databufs[ndatabufs].buf; - iovs[ndatabufs].iov_len = databufs[ndatabufs].len; - } if (cmsg_arg == NULL) ncmsgs = 0; @@ -3954,8 +4129,6 @@ finally: for (i = 0; i < ndatabufs; i++) PyBuffer_Release(&databufs[i]); PyMem_Free(databufs); - PyMem_Free(iovs); - Py_XDECREF(data_fast); return retval; } @@ -3977,6 +4150,165 @@ the message. The return value is the number of bytes of non-ancillary\n\ data sent."); #endif /* CMSG_LEN */ +#ifdef HAVE_SOCKADDR_ALG +static PyObject* +sock_sendmsg_afalg(PySocketSockObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *retval = NULL; + + Py_ssize_t i, ndatabufs = 0; + Py_buffer *databufs = NULL; + PyObject *data_arg = NULL; + + Py_buffer iv = {NULL, NULL}; + + PyObject *opobj = NULL; + int op = -1; + + PyObject *assoclenobj = NULL; + int assoclen = -1; + + unsigned int *uiptr; + int flags = 0; + + struct msghdr msg; + struct cmsghdr *header = NULL; + struct af_alg_iv *alg_iv = NULL; + struct sock_sendmsg ctx; + Py_ssize_t controllen; + void *controlbuf = NULL; + static char *keywords[] = {"msg", "op", "iv", "assoclen", "flags", 0}; + + if (self->sock_family != AF_ALG) { + PyErr_SetString(PyExc_OSError, + "algset is only supported for AF_ALG"); + return NULL; + } + + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "|O$O!y*O!i:sendmsg_afalg", keywords, + &data_arg, + &PyLong_Type, &opobj, &iv, + &PyLong_Type, &assoclenobj, &flags)) + return NULL; + + /* op is a required, keyword-only argument >= 0 */ + if (opobj != NULL) { + op = _PyLong_AsInt(opobj); + } + if (op < 0) { + /* override exception from _PyLong_AsInt() */ + PyErr_SetString(PyExc_TypeError, + "Invalid or missing argument 'op'"); + goto finally; + } + /* assoclen is optional but must be >= 0 */ + if (assoclenobj != NULL) { + assoclen = _PyLong_AsInt(assoclenobj); + if (assoclen == -1 && PyErr_Occurred()) { + goto finally; + } + if (assoclen < 0) { + PyErr_SetString(PyExc_TypeError, + "assoclen must be positive"); + goto finally; + } + } + + controllen = CMSG_SPACE(4); + if (iv.buf != NULL) { + controllen += CMSG_SPACE(sizeof(*alg_iv) + iv.len); + } + if (assoclen >= 0) { + controllen += CMSG_SPACE(4); + } + + controlbuf = PyMem_Malloc(controllen); + if (controlbuf == NULL) { + return PyErr_NoMemory(); + } + memset(controlbuf, 0, controllen); + + memset(&msg, 0, sizeof(msg)); + msg.msg_controllen = controllen; + msg.msg_control = controlbuf; + + /* Fill in an iovec for each message part, and save the Py_buffer + structs to release afterwards. */ + if (data_arg != NULL) { + if (sock_sendmsg_iovec(self, data_arg, &msg, &databufs, &ndatabufs) == -1) { + goto finally; + } + } + + /* set operation to encrypt or decrypt */ + header = CMSG_FIRSTHDR(&msg); + if (header == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "unexpected NULL result from CMSG_FIRSTHDR"); + goto finally; + } + header->cmsg_level = SOL_ALG; + header->cmsg_type = ALG_SET_OP; + header->cmsg_len = CMSG_LEN(4); + uiptr = (void*)CMSG_DATA(header); + *uiptr = (unsigned int)op; + + /* set initialization vector */ + if (iv.buf != NULL) { + header = CMSG_NXTHDR(&msg, header); + if (header == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "unexpected NULL result from CMSG_NXTHDR(iv)"); + goto finally; + } + header->cmsg_level = SOL_ALG; + header->cmsg_type = ALG_SET_IV; + header->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv.len); + alg_iv = (void*)CMSG_DATA(header); + alg_iv->ivlen = iv.len; + memcpy(alg_iv->iv, iv.buf, iv.len); + } + + /* set length of associated data for AEAD */ + if (assoclen >= 0) { + header = CMSG_NXTHDR(&msg, header); + if (header == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "unexpected NULL result from CMSG_NXTHDR(assoc)"); + goto finally; + } + header->cmsg_level = SOL_ALG; + header->cmsg_type = ALG_SET_AEAD_ASSOCLEN; + header->cmsg_len = CMSG_LEN(4); + uiptr = (void*)CMSG_DATA(header); + *uiptr = (unsigned int)assoclen; + } + + ctx.msg = &msg; + ctx.flags = flags; + if (sock_call(self, 1, sock_sendmsg_impl, &ctx) < 0) + goto finally; + + retval = PyLong_FromSsize_t(ctx.result); + + finally: + PyMem_Free(controlbuf); + if (iv.buf != NULL) { + PyBuffer_Release(&iv); + } + for (i = 0; i < ndatabufs; i++) + PyBuffer_Release(&databufs[i]); + PyMem_Free(databufs); + return retval; +} + +PyDoc_STRVAR(sendmsg_afalg_doc, +"sendmsg_afalg([msg], *, op[, iv[, assoclen[, flags=MSG_MORE]]])\n\ +\n\ +Set operation mode, IV and length of associated data for an AF_ALG\n\ +operation socket."); +#endif /* s.shutdown(how) method */ @@ -4035,6 +4367,17 @@ sock_ioctl(PySocketSockObject *s, PyObject *arg) return set_error(); } return PyLong_FromUnsignedLong(recv); } +#if defined(SIO_LOOPBACK_FAST_PATH) + case SIO_LOOPBACK_FAST_PATH: { + unsigned int option; + if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option)) + return NULL; + if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option), + NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { + return set_error(); + } + return PyLong_FromUnsignedLong(recv); } +#endif default: PyErr_Format(PyExc_ValueError, "invalid ioctl command %d", cmd); return NULL; @@ -4045,7 +4388,8 @@ PyDoc_STRVAR(sock_ioctl_doc, \n\ Control the socket with WSAIoctl syscall. Currently supported 'cmd' values are\n\ SIO_RCVALL: 'option' must be one of the socket.RCVALL_* constants.\n\ -SIO_KEEPALIVE_VALS: 'option' is a tuple of (onoff, timeout, interval)."); +SIO_KEEPALIVE_VALS: 'option' is a tuple of (onoff, timeout, interval).\n\ +SIO_LOOPBACK_FAST_PATH: 'option' is a boolean value, and is disabled by default"); #endif #if defined(MS_WINDOWS) @@ -4144,6 +4488,10 @@ static PyMethodDef sock_methods[] = { {"sendmsg", (PyCFunction)sock_sendmsg, METH_VARARGS, sendmsg_doc}, #endif +#ifdef HAVE_SOCKADDR_ALG + {"sendmsg_afalg", (PyCFunction)sock_sendmsg_afalg, METH_VARARGS | METH_KEYWORDS, + sendmsg_afalg_doc}, +#endif {NULL, NULL} /* sentinel */ }; @@ -4164,22 +4512,45 @@ static PyGetSetDef sock_getsetlist[] = { First close the file description. */ static void -sock_dealloc(PySocketSockObject *s) +sock_finalize(PySocketSockObject *s) { + SOCKET_T fd; + PyObject *error_type, *error_value, *error_traceback; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + if (s->sock_fd != INVALID_SOCKET) { - PyObject *exc, *val, *tb; - Py_ssize_t old_refcount = Py_REFCNT(s); - ++Py_REFCNT(s); - PyErr_Fetch(&exc, &val, &tb); - if (PyErr_WarnFormat(PyExc_ResourceWarning, 1, - "unclosed %R", s)) + if (PyErr_ResourceWarning((PyObject *)s, 1, "unclosed %R", s)) { /* Spurious errors can appear at shutdown */ - if (PyErr_ExceptionMatches(PyExc_Warning)) - PyErr_WriteUnraisable((PyObject *) s); - PyErr_Restore(exc, val, tb); - (void) SOCKETCLOSE(s->sock_fd); - Py_REFCNT(s) = old_refcount; + if (PyErr_ExceptionMatches(PyExc_Warning)) { + PyErr_WriteUnraisable((PyObject *)s); + } + } + + /* Only close the socket *after* logging the ResourceWarning warning + to allow the logger to call socket methods like + socket.getsockname(). If the socket is closed before, socket + methods fails with the EBADF error. */ + fd = s->sock_fd; + s->sock_fd = INVALID_SOCKET; + + /* We do not want to retry upon EINTR: see sock_close() */ + Py_BEGIN_ALLOW_THREADS + (void) SOCKETCLOSE(fd); + Py_END_ALLOW_THREADS } + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +static void +sock_dealloc(PySocketSockObject *s) +{ + if (PyObject_CallFinalizerFromDealloc((PyObject *)s) < 0) + return; + Py_TYPE(s)->tp_free((PyObject *)s); } @@ -4367,7 +4738,10 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) } #endif } - init_sockobject(s, fd, family, type, proto); + if (init_sockobject(s, fd, family, type, proto) == -1) { + SOCKETCLOSE(fd); + return -1; + } return 0; @@ -4396,7 +4770,8 @@ static PyTypeObject sock_type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ sock_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -4416,6 +4791,15 @@ static PyTypeObject sock_type = { PyType_GenericAlloc, /* tp_alloc */ sock_new, /* tp_new */ PyObject_Del, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + (destructor)sock_finalize, /* tp_finalize */ }; @@ -5451,10 +5835,6 @@ socket_inet_ntop(PyObject *self, PyObject *args) } else { return PyUnicode_FromString(retval); } - - /* NOTREACHED */ - PyErr_SetString(PyExc_RuntimeError, "invalid handling of inet_ntop"); - return NULL; } #elif defined(MS_WINDOWS) @@ -6188,9 +6568,6 @@ PyInit__socket(void) PyModule_AddIntMacro(m, AF_UNSPEC); #endif PyModule_AddIntMacro(m, AF_INET); -#ifdef AF_INET6 - PyModule_AddIntMacro(m, AF_INET6); -#endif /* AF_INET6 */ #if defined(AF_UNIX) PyModule_AddIntMacro(m, AF_UNIX); #endif /* AF_UNIX */ @@ -6221,6 +6598,9 @@ PyInit__socket(void) /* Reserved for Werner's ATM */ PyModule_AddIntMacro(m, AF_AAL5); #endif +#ifdef HAVE_SOCKADDR_ALG + PyModule_AddIntMacro(m, AF_ALG); /* Linux crypto */ +#endif #ifdef AF_X25 /* Reserved for X.25 project */ PyModule_AddIntMacro(m, AF_X25); @@ -6282,6 +6662,9 @@ PyInit__socket(void) #ifdef NETLINK_TAPBASE PyModule_AddIntMacro(m, NETLINK_TAPBASE); #endif +#ifdef NETLINK_CRYPTO + PyModule_AddIntMacro(m, NETLINK_CRYPTO); +#endif #endif /* AF_NETLINK */ #ifdef AF_ROUTE /* Alias to emulate 4.4BSD */ @@ -6435,11 +6818,30 @@ PyInit__socket(void) PyModule_AddIntMacro(m, TIPC_TOP_SRV); #endif +#ifdef HAVE_SOCKADDR_ALG + /* Socket options */ + PyModule_AddIntMacro(m, ALG_SET_KEY); + PyModule_AddIntMacro(m, ALG_SET_IV); + PyModule_AddIntMacro(m, ALG_SET_OP); + PyModule_AddIntMacro(m, ALG_SET_AEAD_ASSOCLEN); + PyModule_AddIntMacro(m, ALG_SET_AEAD_AUTHSIZE); + PyModule_AddIntMacro(m, ALG_SET_PUBKEY); + + /* Operations */ + PyModule_AddIntMacro(m, ALG_OP_DECRYPT); + PyModule_AddIntMacro(m, ALG_OP_ENCRYPT); + PyModule_AddIntMacro(m, ALG_OP_SIGN); + PyModule_AddIntMacro(m, ALG_OP_VERIFY); +#endif + /* Socket types */ PyModule_AddIntMacro(m, SOCK_STREAM); PyModule_AddIntMacro(m, SOCK_DGRAM); /* We have incomplete socket support. */ +#ifdef SOCK_RAW + /* SOCK_RAW is marked as optional in the POSIX specification */ PyModule_AddIntMacro(m, SOCK_RAW); +#endif PyModule_AddIntMacro(m, SOCK_SEQPACKET); #if defined(SOCK_RDM) PyModule_AddIntMacro(m, SOCK_RDM); @@ -6482,9 +6884,11 @@ PyInit__socket(void) #ifdef SO_OOBINLINE PyModule_AddIntMacro(m, SO_OOBINLINE); #endif +#ifndef __GNU__ #ifdef SO_REUSEPORT PyModule_AddIntMacro(m, SO_REUSEPORT); #endif +#endif #ifdef SO_SNDBUF PyModule_AddIntMacro(m, SO_SNDBUF); #endif @@ -6521,6 +6925,12 @@ PyInit__socket(void) #ifdef LOCAL_PEERCRED PyModule_AddIntMacro(m, LOCAL_PEERCRED); #endif +#ifdef SO_PASSSEC + PyModule_AddIntMacro(m, SO_PASSSEC); +#endif +#ifdef SO_PEERSEC + PyModule_AddIntMacro(m, SO_PEERSEC); +#endif #ifdef SO_BINDTODEVICE PyModule_AddIntMacro(m, SO_BINDTODEVICE); #endif @@ -6530,6 +6940,12 @@ PyInit__socket(void) #ifdef SO_MARK PyModule_AddIntMacro(m, SO_MARK); #endif +#ifdef SO_DOMAIN + PyModule_AddIntMacro(m, SO_DOMAIN); +#endif +#ifdef SO_PROTOCOL + PyModule_AddIntMacro(m, SO_PROTOCOL); +#endif /* Maximum number of connections for "listen" */ #ifdef SOMAXCONN @@ -6688,6 +7104,9 @@ PyInit__socket(void) #ifdef SOL_RDS PyModule_AddIntMacro(m, SOL_RDS); #endif +#ifdef HAVE_SOCKADDR_ALG + PyModule_AddIntMacro(m, SOL_ALG); +#endif #ifdef RDS_CANCEL_SENT_TO PyModule_AddIntMacro(m, RDS_CANCEL_SENT_TO); #endif @@ -7225,8 +7644,16 @@ PyInit__socket(void) #ifdef SIO_RCVALL { - DWORD codes[] = {SIO_RCVALL, SIO_KEEPALIVE_VALS}; - const char *names[] = {"SIO_RCVALL", "SIO_KEEPALIVE_VALS"}; + DWORD codes[] = {SIO_RCVALL, SIO_KEEPALIVE_VALS, +#if defined(SIO_LOOPBACK_FAST_PATH) + SIO_LOOPBACK_FAST_PATH +#endif + }; + const char *names[] = {"SIO_RCVALL", "SIO_KEEPALIVE_VALS", +#if defined(SIO_LOOPBACK_FAST_PATH) + "SIO_LOOPBACK_FAST_PATH" +#endif + }; int i; for(i = 0; i<Py_ARRAY_LENGTH(codes); ++i) { PyObject *tmp; diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c index 4b9f3cd..556a715 100644 --- a/Modules/spwdmodule.c +++ b/Modules/spwdmodule.c @@ -137,7 +137,10 @@ spwd_getspnam_impl(PyObject *module, PyObject *arg) if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) goto out; if ((p = getspnam(name)) == NULL) { - PyErr_SetString(PyExc_KeyError, "getspnam(): name not found"); + if (errno != 0) + PyErr_SetFromErrno(PyExc_OSError); + else + PyErr_SetString(PyExc_KeyError, "getspnam(): name not found"); goto out; } retval = mkspent(p); diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h index 128c71e..0865fc6 100644 --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -367,14 +367,12 @@ SRE(info)(SRE_STATE* state, SRE_CODE* pattern) #define RETURN_ON_FAILURE(i) \ do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0) -#define SFY(x) #x - #define DATA_STACK_ALLOC(state, type, ptr) \ do { \ alloc_pos = state->data_stack_base; \ TRACE(("allocating %s in %" PY_FORMAT_SIZE_T "d " \ "(%" PY_FORMAT_SIZE_T "d)\n", \ - SFY(type), alloc_pos, sizeof(type))); \ + Py_STRINGIFY(type), alloc_pos, sizeof(type))); \ if (sizeof(type) > state->data_stack_size - alloc_pos) { \ int j = data_stack_grow(state, sizeof(type)); \ if (j < 0) return j; \ @@ -387,7 +385,7 @@ do { \ #define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \ do { \ - TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", SFY(type), pos)); \ + TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", Py_STRINGIFY(type), pos)); \ ptr = (type*)(state->data_stack+pos); \ } while (0) @@ -531,7 +529,7 @@ entrance: if (ctx->pattern[0] == SRE_OP_INFO) { /* optimization info block */ /* <INFO> <1=skip> <2=flags> <3=min> ... */ - if (ctx->pattern[3] && (Py_uintptr_t)(end - ctx->ptr) < ctx->pattern[3]) { + if (ctx->pattern[3] && (uintptr_t)(end - ctx->ptr) < ctx->pattern[3]) { TRACE(("reject (got %" PY_FORMAT_SIZE_T "d chars, " "need %" PY_FORMAT_SIZE_T "d)\n", end - ctx->ptr, (Py_ssize_t) ctx->pattern[3])); @@ -1256,7 +1254,32 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) prefix, prefix_len, prefix_skip)); TRACE(("charset = %p\n", charset)); -#if defined(USE_FAST_SEARCH) + if (prefix_len == 1) { + /* pattern starts with a literal character */ + SRE_CHAR c = (SRE_CHAR) prefix[0]; +#if SIZEOF_SRE_CHAR < 4 + if ((SRE_CODE) c != prefix[0]) + return 0; /* literal can't match: doesn't fit in char width */ +#endif + end = (SRE_CHAR *)state->end; + while (ptr < end) { + while (*ptr != c) { + if (++ptr >= end) + return 0; + } + TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr)); + state->start = ptr; + state->ptr = ptr + prefix_skip; + if (flags & SRE_INFO_LITERAL) + return 1; /* we got all of it */ + status = SRE(match)(state, pattern + 2*prefix_skip, 0); + if (status != 0) + return status; + ++ptr; + } + return 0; + } + if (prefix_len > 1) { /* pattern starts with a known prefix. use the overlap table to skip forward as fast as we possibly can */ @@ -1305,32 +1328,8 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) } return 0; } -#endif - if (pattern[0] == SRE_OP_LITERAL) { - /* pattern starts with a literal character. this is used - for short prefixes, and if fast search is disabled */ - SRE_CHAR c = (SRE_CHAR) pattern[1]; -#if SIZEOF_SRE_CHAR < 4 - if ((SRE_CODE) c != pattern[1]) - return 0; /* literal can't match: doesn't fit in char width */ -#endif - end = (SRE_CHAR *)state->end; - while (ptr < end) { - while (*ptr != c) { - if (++ptr >= end) - return 0; - } - TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr)); - state->start = ptr; - state->ptr = ++ptr; - if (flags & SRE_INFO_LITERAL) - return 1; /* we got all of it */ - status = SRE(match)(state, pattern + 2, 0); - if (status != 0) - break; - } - } else if (charset) { + if (charset) { /* pattern starts with a character from a known set */ end = (SRE_CHAR *)state->end; for (;;) { diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index f84cc78..34a6fc5 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -79,6 +79,7 @@ PyInit__symtable(void) PyModule_AddIntMacro(m, DEF_FREE_CLASS); PyModule_AddIntMacro(m, DEF_IMPORT); PyModule_AddIntMacro(m, DEF_BOUND); + PyModule_AddIntMacro(m, DEF_ANNOT); PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock); PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock); diff --git a/Modules/timemodule.c b/Modules/timemodule.c index d2caacd..9474644 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -311,7 +311,7 @@ tmtotuple(struct tm *p) Returns non-zero on success (parallels PyArg_ParseTuple). */ static int -parse_time_t_args(PyObject *args, char *format, time_t *pwhen) +parse_time_t_args(PyObject *args, const char *format, time_t *pwhen) { PyObject *ot = NULL; time_t whent; @@ -732,10 +732,10 @@ _asctime(struct tm *timeptr) { /* Inspired by Open Group reference implementation available at * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */ - static char wday_name[7][4] = { + static const char wday_name[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - static char mon_name[12][4] = { + static const char mon_name[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; @@ -1034,6 +1034,7 @@ py_process_time(_Py_clock_info_t *info) } #endif + /* Currently, Python 3 requires clock() to build: see issue #22624 */ return floatclock(info); #endif } diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index fe4e908..7d518fa 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -884,7 +884,7 @@ _gethash(const char *s, int len, int scale) return h; } -static char *hangul_syllables[][3] = { +static const char * const hangul_syllables[][3] = { { "G", "A", "" }, { "GG", "AE", "G" }, { "N", "YA", "GG" }, @@ -1057,7 +1057,7 @@ find_syllable(const char *str, int *len, int *pos, int count, int column) int i, len1; *len = -1; for (i = 0; i < count; i++) { - char *s = hangul_syllables[i][column]; + const char *s = hangul_syllables[i][column]; len1 = Py_SAFE_DOWNCAST(strlen(s), size_t, int); if (len1 <= *len) continue; diff --git a/Modules/winreparse.h b/Modules/winreparse.h index 66f7775..28049c9 100644 --- a/Modules/winreparse.h +++ b/Modules/winreparse.h @@ -2,7 +2,7 @@ #define Py_WINREPARSE_H #ifdef MS_WINDOWS -#include <Windows.h> +#include <windows.h> #ifdef __cplusplus extern "C" { @@ -10,9 +10,10 @@ extern "C" { /* The following structure was copied from http://msdn.microsoft.com/en-us/library/ff552012.aspx as the required - include doesn't seem to be present in the Windows SDK (at least as included - with Visual Studio Express). */ -typedef struct _REPARSE_DATA_BUFFER { + include km\ntifs.h isn't present in the Windows SDK (at least as included + with Visual Studio Express). Use unique names to avoid conflicting with + the structure as defined by Min GW. */ +typedef struct { ULONG ReparseTag; USHORT ReparseDataLength; USHORT Reserved; @@ -38,11 +39,11 @@ typedef struct _REPARSE_DATA_BUFFER { UCHAR DataBuffer[1]; } GenericReparseBuffer; }; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; +} _Py_REPARSE_DATA_BUFFER, *_Py_PREPARSE_DATA_BUFFER; -#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\ - GenericReparseBuffer) -#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) +#define _Py_REPARSE_DATA_BUFFER_HEADER_SIZE \ + FIELD_OFFSET(_Py_REPARSE_DATA_BUFFER, GenericReparseBuffer) +#define _Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) #ifdef __cplusplus } diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 40c1760..c1a9be9 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -89,7 +89,7 @@ Xxo_getattro(XxoObject *self, PyObject *name) } static int -Xxo_setattr(XxoObject *self, char *name, PyObject *v) +Xxo_setattr(XxoObject *self, const char *name, PyObject *v) { if (self->x_attr == NULL) { self->x_attr = PyDict_New(); diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c index 85230d9..0764407 100644 --- a/Modules/xxmodule.c +++ b/Modules/xxmodule.c @@ -76,7 +76,7 @@ Xxo_getattro(XxoObject *self, PyObject *name) } static int -Xxo_setattr(XxoObject *self, char *name, PyObject *v) +Xxo_setattr(XxoObject *self, const char *name, PyObject *v) { if (self->x_attr == NULL) { self->x_attr = PyDict_New(); diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index fccb616..4cded31 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -57,7 +57,7 @@ typedef struct } compobject; static void -zlib_error(z_stream zst, int err, char *msg) +zlib_error(z_stream zst, int err, const char *msg) { const char *zmsg = Z_NULL; /* In case of a version mismatch, zst.msg won't be initialized. @@ -199,18 +199,18 @@ arrange_output_buffer(z_stream *zst, PyObject **buffer, Py_ssize_t length) /*[clinic input] zlib.compress - bytes: Py_buffer + data: Py_buffer Binary data to be compressed. - level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION - Compression level, in 0-9. / + level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION + Compression level, in 0-9 or -1. Returns a bytes object containing compressed data. [clinic start generated code]*/ static PyObject * -zlib_compress_impl(PyObject *module, Py_buffer *bytes, int level) -/*[clinic end generated code: output=ae64c2c3076321a0 input=be3abe9934bda4b3]*/ +zlib_compress_impl(PyObject *module, Py_buffer *data, int level) +/*[clinic end generated code: output=d80906d73f6294c8 input=638d54b6315dbed3]*/ { PyObject *RetVal = NULL; Byte *ibuf; @@ -218,8 +218,8 @@ zlib_compress_impl(PyObject *module, Py_buffer *bytes, int level) int err, flush; z_stream zst; - ibuf = bytes->buf; - ibuflen = bytes->len; + ibuf = data->buf; + ibuflen = data->len; zst.opaque = NULL; zst.zalloc = PyZlib_Malloc; @@ -318,11 +318,11 @@ zlib.decompress data: Py_buffer Compressed data. + / wbits: int(c_default="MAX_WBITS") = MAX_WBITS The window buffer size and container format. bufsize: ssize_t(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE The initial output buffer size. - / Returns a bytes object containing the uncompressed data. [clinic start generated code]*/ @@ -330,7 +330,7 @@ Returns a bytes object containing the uncompressed data. static PyObject * zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, Py_ssize_t bufsize) -/*[clinic end generated code: output=77c7e35111dc8c42 input=c13dd2c5696cd17f]*/ +/*[clinic end generated code: output=77c7e35111dc8c42 input=21960936208e9a5b]*/ { PyObject *RetVal = NULL; Byte *ibuf; @@ -750,11 +750,11 @@ zlib.Decompress.decompress data: Py_buffer The binary data to decompress. + / max_length: ssize_t = 0 The maximum allowable length of the decompressed data. Unconsumed input data will be stored in the unconsumed_tail attribute. - / Return a bytes object containing the decompressed version of the data. @@ -766,7 +766,7 @@ Call the flush() method to clear these buffers. static PyObject * zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, Py_ssize_t max_length) -/*[clinic end generated code: output=6e5173c74e710352 input=d6de9b53c4566b8a]*/ +/*[clinic end generated code: output=6e5173c74e710352 input=b85a212a012b770a]*/ { int err = Z_OK; Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE, hard_limit; @@ -1333,7 +1333,7 @@ PyDoc_STRVAR(zlib_module_documentation, "zlib library, which is based on GNU zip.\n" "\n" "adler32(string[, start]) -- Compute an Adler-32 checksum.\n" -"compress(string[, level]) -- Compress string, with compression level in 0-9.\n" +"compress(data[, level]) -- Compress data, with compression level 0-9 or -1.\n" "compressobj([level[, ...]]) -- Return a compressor object.\n" "crc32(string[, start]) -- Compute a CRC-32 checksum.\n" "decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n" |