mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 13:52:28 +00:00
Make numerous improvements
- Python static hello world now 1.8mb - Python static fully loaded now 10mb - Python HTTPS client now uses MbedTLS - Python REPL now completes import stmts - Increase stack size for Python for now - Begin synthesizing posixpath and ntpath - Restore Python \N{UNICODE NAME} support - Restore Python NFKD symbol normalization - Add optimized code path for Intel SHA-NI - Get more Python unit tests passing faster - Get Python help() pagination working on NT - Python hashlib now supports MbedTLS PBKDF2 - Make memcpy/memmove/memcmp/bcmp/etc. faster - Add Mersenne Twister and Vigna to LIBC_RAND - Provide privileged __printf() for error code - Fix zipos opendir() so that it reports ENOTDIR - Add basic chmod() implementation for Windows NT - Add Cosmo's best functions to Python cosmo module - Pin function trace indent depth to that of caller - Show memory diagram on invalid access in MODE=dbg - Differentiate stack overflow on crash in MODE=dbg - Add stb_truetype and tools for analyzing font files - Upgrade to UNICODE 13 and reduce its binary footprint - COMPILE.COM now logs resource usage of build commands - Start implementing basic poll() support on bare metal - Set getauxval(AT_EXECFN) to GetModuleFileName() on NT - Add descriptions to strerror() in non-TINY build modes - Add COUNTBRANCH() macro to help with micro-optimizations - Make error / backtrace / asan / memory code more unbreakable - Add fast perfect C implementation of μ-Law and a-Law audio codecs - Make strtol() functions consistent with other libc implementations - Improve Linenoise implementation (see also github.com/jart/bestline) - COMPILE.COM now suppresses stdout/stderr of successful build commands
This commit is contained in:
parent
fa7b4f5bd1
commit
39bf41f4eb
806 changed files with 77494 additions and 63859 deletions
|
@ -2448,3 +2448,8 @@ PyInit__collections(void)
|
|||
|
||||
return m;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__collections = {
|
||||
"_collections",
|
||||
PyInit__collections,
|
||||
};
|
||||
|
|
207
third_party/python/Modules/_decimal/_decimal.c
vendored
207
third_party/python/Modules/_decimal/_decimal.c
vendored
|
@ -28,6 +28,7 @@
|
|||
│ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/boolobject.h"
|
||||
#include "third_party/python/Include/complexobject.h"
|
||||
|
@ -103,13 +104,10 @@ libmpdec (BSD-2)\\n\
|
|||
Copyright 2008-2016 Stefan Krah\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
#define CONFIG_64
|
||||
|
||||
#if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02040100
|
||||
#error "libmpdec version >= 2.4.1 required"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Type sizes with assertions in mpdecimal.h and pyport.h:
|
||||
* sizeof(size_t) == sizeof(Py_ssize_t)
|
||||
|
@ -346,8 +344,9 @@ runtime_error_ptr(const char *mesg)
|
|||
return runtime_error_ptr("internal error in " funcname)
|
||||
|
||||
static void
|
||||
dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */
|
||||
{ /* GCOV_NOT_REACHED */
|
||||
dec_traphandler(mpd_context_t *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
return; /* GCOV_NOT_REACHED */
|
||||
}
|
||||
|
||||
|
@ -355,14 +354,12 @@ static PyObject *
|
|||
flags_as_exception(uint32_t flags)
|
||||
{
|
||||
DecCondMap *cm;
|
||||
|
||||
for (cm = signal_map; cm->name != NULL; cm++) {
|
||||
if (flags&cm->flag) {
|
||||
return cm->ex;
|
||||
}
|
||||
}
|
||||
|
||||
INTERNAL_ERROR_PTR("flags_as_exception"); /* GCOV_NOT_REACHED */
|
||||
INTERNAL_ERROR_PTR("flags_as_exception");
|
||||
}
|
||||
|
||||
Py_LOCAL_INLINE(uint32_t)
|
||||
|
@ -606,22 +603,26 @@ getround(PyObject *v)
|
|||
a context, it cannot be deleted. */
|
||||
|
||||
static int
|
||||
signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
|
||||
signaldict_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
(void)args;
|
||||
(void)kwds;
|
||||
SdFlagAddr(self) = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Py_ssize_t
|
||||
signaldict_len(PyObject *self UNUSED)
|
||||
signaldict_len(PyObject *self)
|
||||
{
|
||||
(void)self;
|
||||
return SIGNAL_MAP_LEN;
|
||||
}
|
||||
|
||||
static PyObject *SignalTuple;
|
||||
static PyObject *
|
||||
signaldict_iter(PyObject *self UNUSED)
|
||||
signaldict_iter(PyObject *self)
|
||||
{
|
||||
(void)self;
|
||||
return PyTuple_Type.tp_iter(SignalTuple);
|
||||
}
|
||||
|
||||
|
@ -724,8 +725,9 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
signaldict_copy(PyObject *self, PyObject *args UNUSED)
|
||||
signaldict_copy(PyObject *self, PyObject *args)
|
||||
{
|
||||
(void)args;
|
||||
return flags_as_dict(SdFlags(self));
|
||||
}
|
||||
|
||||
|
@ -792,15 +794,17 @@ static PyTypeObject PyDecSignalDictMixin_Type =
|
|||
|
||||
#define Dec_CONTEXT_GET_SSIZE(mem) \
|
||||
static PyObject * \
|
||||
context_get##mem(PyObject *self, void *closure UNUSED) \
|
||||
context_get##mem(PyObject *self, void *closure) \
|
||||
{ \
|
||||
(void)closure; \
|
||||
return PyLong_FromSsize_t(mpd_get##mem(CTX(self))); \
|
||||
}
|
||||
|
||||
#define Dec_CONTEXT_GET_ULONG(mem) \
|
||||
static PyObject * \
|
||||
context_get##mem(PyObject *self, void *closure UNUSED) \
|
||||
context_get##mem(PyObject *self, void *closure) \
|
||||
{ \
|
||||
(void)closure; \
|
||||
return PyLong_FromUnsignedLong(mpd_get##mem(CTX(self))); \
|
||||
}
|
||||
|
||||
|
@ -815,7 +819,7 @@ Dec_CONTEXT_GET_ULONG(status)
|
|||
#endif
|
||||
|
||||
static PyObject *
|
||||
context_getround(PyObject *self, void *closure UNUSED)
|
||||
context_getround(PyObject *self, void *closure)
|
||||
{
|
||||
int i = mpd_getround(CTX(self));
|
||||
|
||||
|
@ -824,33 +828,33 @@ context_getround(PyObject *self, void *closure UNUSED)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
context_getcapitals(PyObject *self, void *closure UNUSED)
|
||||
context_getcapitals(PyObject *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(CtxCaps(self));
|
||||
}
|
||||
|
||||
#ifdef EXTRA_FUNCTIONALITY
|
||||
static PyObject *
|
||||
context_getallcr(PyObject *self, void *closure UNUSED)
|
||||
context_getallcr(PyObject *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(mpd_getcr(CTX(self)));
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
context_getetiny(PyObject *self, PyObject *dummy UNUSED)
|
||||
context_getetiny(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
return PyLong_FromSsize_t(mpd_etiny(CTX(self)));
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
context_getetop(PyObject *self, PyObject *dummy UNUSED)
|
||||
context_getetop(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
return PyLong_FromSsize_t(mpd_etop(CTX(self)));
|
||||
}
|
||||
|
||||
static int
|
||||
context_setprec(PyObject *self, PyObject *value, void *closure UNUSED)
|
||||
context_setprec(PyObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
mpd_context_t *ctx;
|
||||
mpd_ssize_t x;
|
||||
|
@ -870,7 +874,7 @@ context_setprec(PyObject *self, PyObject *value, void *closure UNUSED)
|
|||
}
|
||||
|
||||
static int
|
||||
context_setemin(PyObject *self, PyObject *value, void *closure UNUSED)
|
||||
context_setemin(PyObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
mpd_context_t *ctx;
|
||||
mpd_ssize_t x;
|
||||
|
@ -890,7 +894,7 @@ context_setemin(PyObject *self, PyObject *value, void *closure UNUSED)
|
|||
}
|
||||
|
||||
static int
|
||||
context_setemax(PyObject *self, PyObject *value, void *closure UNUSED)
|
||||
context_setemax(PyObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
mpd_context_t *ctx;
|
||||
mpd_ssize_t x;
|
||||
|
@ -972,7 +976,7 @@ context_unsafe_setemax(PyObject *self, PyObject *value)
|
|||
#endif
|
||||
|
||||
static int
|
||||
context_setround(PyObject *self, PyObject *value, void *closure UNUSED)
|
||||
context_setround(PyObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
mpd_context_t *ctx;
|
||||
int x;
|
||||
|
@ -991,7 +995,7 @@ context_setround(PyObject *self, PyObject *value, void *closure UNUSED)
|
|||
}
|
||||
|
||||
static int
|
||||
context_setcapitals(PyObject *self, PyObject *value, void *closure UNUSED)
|
||||
context_setcapitals(PyObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
mpd_ssize_t x;
|
||||
|
||||
|
@ -1011,7 +1015,7 @@ context_setcapitals(PyObject *self, PyObject *value, void *closure UNUSED)
|
|||
|
||||
#ifdef EXTRA_FUNCTIONALITY
|
||||
static int
|
||||
context_settraps(PyObject *self, PyObject *value, void *closure UNUSED)
|
||||
context_settraps(PyObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
mpd_context_t *ctx;
|
||||
uint32_t flags;
|
||||
|
@ -1075,7 +1079,7 @@ context_settraps_dict(PyObject *self, PyObject *value)
|
|||
|
||||
#ifdef EXTRA_FUNCTIONALITY
|
||||
static int
|
||||
context_setstatus(PyObject *self, PyObject *value, void *closure UNUSED)
|
||||
context_setstatus(PyObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
mpd_context_t *ctx;
|
||||
uint32_t flags;
|
||||
|
@ -1138,7 +1142,7 @@ context_setstatus_dict(PyObject *self, PyObject *value)
|
|||
}
|
||||
|
||||
static int
|
||||
context_setclamp(PyObject *self, PyObject *value, void *closure UNUSED)
|
||||
context_setclamp(PyObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
mpd_context_t *ctx;
|
||||
mpd_ssize_t x;
|
||||
|
@ -1159,7 +1163,7 @@ context_setclamp(PyObject *self, PyObject *value, void *closure UNUSED)
|
|||
|
||||
#ifdef EXTRA_FUNCTIONALITY
|
||||
static int
|
||||
context_setallcr(PyObject *self, PyObject *value, void *closure UNUSED)
|
||||
context_setallcr(PyObject *self, PyObject *value, void *closure)
|
||||
{
|
||||
mpd_context_t *ctx;
|
||||
mpd_ssize_t x;
|
||||
|
@ -1222,14 +1226,14 @@ context_setattr(PyObject *self, PyObject *name, PyObject *value)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
context_clear_traps(PyObject *self, PyObject *dummy UNUSED)
|
||||
context_clear_traps(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
CTX(self)->traps = 0;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
context_clear_flags(PyObject *self, PyObject *dummy UNUSED)
|
||||
context_clear_flags(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
CTX(self)->status = 0;
|
||||
Py_RETURN_NONE;
|
||||
|
@ -1245,7 +1249,7 @@ static mpd_context_t dflt_ctx = {
|
|||
};
|
||||
|
||||
static PyObject *
|
||||
context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED)
|
||||
context_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyDecContextObject *self = NULL;
|
||||
mpd_context_t *ctx;
|
||||
|
@ -1445,7 +1449,7 @@ init_extended_context(PyObject *v)
|
|||
#ifdef EXTRA_FUNCTIONALITY
|
||||
/* Factory function for creating IEEE interchange format contexts */
|
||||
static PyObject *
|
||||
ieee_context(PyObject *dummy UNUSED, PyObject *v)
|
||||
ieee_context(PyObject *dummy, PyObject *v)
|
||||
{
|
||||
PyObject *context;
|
||||
mpd_ssize_t bits;
|
||||
|
@ -1480,7 +1484,7 @@ error:
|
|||
#endif
|
||||
|
||||
static PyObject *
|
||||
context_copy(PyObject *self, PyObject *args UNUSED)
|
||||
context_copy(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *copy;
|
||||
|
||||
|
@ -1497,7 +1501,7 @@ context_copy(PyObject *self, PyObject *args UNUSED)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
context_reduce(PyObject *self, PyObject *args UNUSED)
|
||||
context_reduce(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *flags;
|
||||
PyObject *traps;
|
||||
|
@ -1601,7 +1605,7 @@ current_context(void)
|
|||
|
||||
/* Return a new reference to the current context */
|
||||
static PyObject *
|
||||
PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
|
||||
PyDec_GetCurrentContext(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *context;
|
||||
|
||||
|
@ -1613,7 +1617,7 @@ PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
|
|||
|
||||
/* Set the module context to a new context, decrement old reference */
|
||||
static PyObject *
|
||||
PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
|
||||
PyDec_SetCurrentContext(PyObject *self, PyObject *v)
|
||||
{
|
||||
CONTEXT_CHECK(v);
|
||||
|
||||
|
@ -1728,7 +1732,7 @@ current_context(void)
|
|||
|
||||
/* Return a new reference to the current context */
|
||||
static PyObject *
|
||||
PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
|
||||
PyDec_GetCurrentContext(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *context;
|
||||
|
||||
|
@ -1743,7 +1747,7 @@ PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
|
|||
|
||||
/* Set the thread local context to a new context, decrement old reference */
|
||||
static PyObject *
|
||||
PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
|
||||
PyDec_SetCurrentContext(PyObject *self, PyObject *v)
|
||||
{
|
||||
PyObject *dict;
|
||||
|
||||
|
@ -1786,7 +1790,7 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
|
|||
* owns one reference to the global (outer) context and one
|
||||
* to the local (inner) context. */
|
||||
static PyObject *
|
||||
ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds)
|
||||
ctxmanager_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"ctx", NULL};
|
||||
PyDecContextManagerObject *self;
|
||||
|
@ -1833,7 +1837,7 @@ ctxmanager_dealloc(PyDecContextManagerObject *self)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED)
|
||||
ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *ret;
|
||||
|
||||
|
@ -1849,7 +1853,7 @@ ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED)
|
|||
|
||||
static PyObject *
|
||||
ctxmanager_restore_global(PyDecContextManagerObject *self,
|
||||
PyObject *args UNUSED)
|
||||
PyObject *args)
|
||||
{
|
||||
PyObject *ret;
|
||||
|
||||
|
@ -1970,21 +1974,17 @@ numeric_as_ascii(const PyObject *u, int strip_ws, int ignore_underscores)
|
|||
char *res, *cp;
|
||||
Py_ssize_t j, len;
|
||||
int d;
|
||||
|
||||
if (PyUnicode_READY(u) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kind = PyUnicode_KIND(u);
|
||||
data = PyUnicode_DATA(u);
|
||||
len = PyUnicode_GET_LENGTH(u);
|
||||
|
||||
cp = res = PyMem_Malloc(len+1);
|
||||
if (res == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
if (strip_ws) {
|
||||
while (len > 0 && is_space(kind, data, len-1)) {
|
||||
|
@ -1994,7 +1994,6 @@ numeric_as_ascii(const PyObject *u, int strip_ws, int ignore_underscores)
|
|||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
for (; j < len; j++) {
|
||||
ch = PyUnicode_READ(kind, data, j);
|
||||
if (ignore_underscores && ch == '_') {
|
||||
|
@ -2028,12 +2027,10 @@ PyDecType_FromCString(PyTypeObject *type, const char *s,
|
|||
{
|
||||
PyObject *dec;
|
||||
uint32_t status = 0;
|
||||
|
||||
dec = PyDecType_New(type);
|
||||
if (dec == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mpd_qset_string(MPD(dec), s, CTX(context), &status);
|
||||
if (dec_addstatus(context, status)) {
|
||||
Py_DECREF(dec);
|
||||
|
@ -2052,14 +2049,11 @@ PyDecType_FromCStringExact(PyTypeObject *type, const char *s,
|
|||
PyObject *dec;
|
||||
uint32_t status = 0;
|
||||
mpd_context_t maxctx;
|
||||
|
||||
dec = PyDecType_New(type);
|
||||
if (dec == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mpd_maxcontext(&maxctx);
|
||||
|
||||
mpd_qset_string(MPD(dec), s, &maxctx, &status);
|
||||
if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
|
||||
/* we want exact results */
|
||||
|
@ -2070,7 +2064,6 @@ PyDecType_FromCStringExact(PyTypeObject *type, const char *s,
|
|||
Py_DECREF(dec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dec;
|
||||
}
|
||||
|
||||
|
@ -2081,12 +2074,10 @@ PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u,
|
|||
{
|
||||
PyObject *dec;
|
||||
char *s;
|
||||
|
||||
s = numeric_as_ascii(u, 0, 0);
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dec = PyDecType_FromCString(type, s, context);
|
||||
PyMem_Free(s);
|
||||
return dec;
|
||||
|
@ -2101,12 +2092,10 @@ PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u,
|
|||
{
|
||||
PyObject *dec;
|
||||
char *s;
|
||||
|
||||
s = numeric_as_ascii(u, 1, 1);
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dec = PyDecType_FromCStringExact(type, s, context);
|
||||
PyMem_Free(s);
|
||||
return dec;
|
||||
|
@ -2116,18 +2105,8 @@ PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u,
|
|||
Py_LOCAL_INLINE(void)
|
||||
_dec_settriple(PyObject *dec, uint8_t sign, uint32_t v, mpd_ssize_t exp)
|
||||
{
|
||||
|
||||
#ifdef CONFIG_64
|
||||
MPD(dec)->data[0] = v;
|
||||
MPD(dec)->len = 1;
|
||||
#else
|
||||
uint32_t q, r;
|
||||
q = v / MPD_RADIX;
|
||||
r = v - q * MPD_RADIX;
|
||||
MPD(dec)->data[1] = q;
|
||||
MPD(dec)->data[0] = r;
|
||||
MPD(dec)->len = q ? 2 : 1;
|
||||
#endif
|
||||
mpd_set_flags(MPD(dec), sign);
|
||||
MPD(dec)->exp = exp;
|
||||
mpd_setdigits(MPD(dec));
|
||||
|
@ -3475,7 +3454,7 @@ dec_as_long(PyObject *dec, PyObject *context, int round)
|
|||
|
||||
/* Convert a Decimal to its exact integer ratio representation. */
|
||||
static PyObject *
|
||||
dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED)
|
||||
dec_as_integer_ratio(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *numerator = NULL;
|
||||
PyObject *denominator = NULL;
|
||||
|
@ -3737,7 +3716,7 @@ PyDec_Round(PyObject *dec, PyObject *args)
|
|||
static PyTypeObject *DecimalTuple = NULL;
|
||||
/* Return the DecimalTuple representation of a PyDecObject. */
|
||||
static PyObject *
|
||||
PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED)
|
||||
PyDec_AsTuple(PyObject *dec, PyObject *dummy)
|
||||
{
|
||||
PyObject *result = NULL;
|
||||
PyObject *sign = NULL;
|
||||
|
@ -3890,7 +3869,7 @@ nm_##MPDFUNC(PyObject *self, PyObject *other) \
|
|||
/* Boolean function without a context arg. */
|
||||
#define Dec_BoolFunc(MPDFUNC) \
|
||||
static PyObject * \
|
||||
dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED) \
|
||||
dec_##MPDFUNC(PyObject *self, PyObject *dummy) \
|
||||
{ \
|
||||
return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \
|
||||
}
|
||||
|
@ -4209,7 +4188,7 @@ Dec_BoolFuncVA(mpd_issubnormal)
|
|||
|
||||
/* Unary functions, no context arg */
|
||||
static PyObject *
|
||||
dec_mpd_adjexp(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_mpd_adjexp(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
mpd_ssize_t retval;
|
||||
|
||||
|
@ -4224,21 +4203,21 @@ dec_mpd_adjexp(PyObject *self, PyObject *dummy UNUSED)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
dec_canonical(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_canonical(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
Py_INCREF(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
dec_conjugate(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_conjugate(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
Py_INCREF(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED)
|
||||
dec_mpd_radix(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
PyObject *result;
|
||||
|
||||
|
@ -4252,7 +4231,7 @@ dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
PyObject *result;
|
||||
uint32_t status = 0;
|
||||
|
@ -4272,7 +4251,7 @@ dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
PyObject *result;
|
||||
uint32_t status = 0;
|
||||
|
@ -4518,7 +4497,7 @@ dec_richcompare(PyObject *v, PyObject *w, int op)
|
|||
|
||||
/* __ceil__ */
|
||||
static PyObject *
|
||||
dec_ceil(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_ceil(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
PyObject *context;
|
||||
|
||||
|
@ -4528,7 +4507,7 @@ dec_ceil(PyObject *self, PyObject *dummy UNUSED)
|
|||
|
||||
/* __complex__ */
|
||||
static PyObject *
|
||||
dec_complex(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_complex(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
PyObject *f;
|
||||
double x;
|
||||
|
@ -4549,7 +4528,7 @@ dec_complex(PyObject *self, PyObject *dummy UNUSED)
|
|||
|
||||
/* __copy__ and __deepcopy__ */
|
||||
static PyObject *
|
||||
dec_copy(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_copy(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
Py_INCREF(self);
|
||||
return self;
|
||||
|
@ -4557,10 +4536,9 @@ dec_copy(PyObject *self, PyObject *dummy UNUSED)
|
|||
|
||||
/* __floor__ */
|
||||
static PyObject *
|
||||
dec_floor(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_floor(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
PyObject *context;
|
||||
|
||||
CURRENT_CONTEXT(context);
|
||||
return dec_as_long(self, context, MPD_ROUND_FLOOR);
|
||||
}
|
||||
|
@ -4569,7 +4547,6 @@ dec_floor(PyObject *self, PyObject *dummy UNUSED)
|
|||
static Py_hash_t
|
||||
_dec_hash(PyDecObject *v)
|
||||
{
|
||||
#if defined(CONFIG_64) && _PyHASH_BITS == 61
|
||||
/* 2**61 - 1 */
|
||||
mpd_uint_t p_data[1] = {2305843009213693951ULL};
|
||||
mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data};
|
||||
|
@ -4577,17 +4554,6 @@ _dec_hash(PyDecObject *v)
|
|||
mpd_uint_t inv10_p_data[1] = {2075258708292324556ULL};
|
||||
mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
|
||||
0, 19, 1, 1, inv10_p_data};
|
||||
#elif defined(CONFIG_32) && _PyHASH_BITS == 31
|
||||
/* 2**31 - 1 */
|
||||
mpd_uint_t p_data[2] = {147483647UL, 2};
|
||||
mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 10, 2, 2, p_data};
|
||||
/* Inverse of 10 modulo p */
|
||||
mpd_uint_t inv10_p_data[2] = {503238553UL, 1};
|
||||
mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
|
||||
0, 10, 2, 2, inv10_p_data};
|
||||
#else
|
||||
#error "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS"
|
||||
#endif
|
||||
const Py_hash_t py_hash_inf = 314159;
|
||||
const Py_hash_t py_hash_nan = 0;
|
||||
mpd_uint_t ten_data[1] = {10};
|
||||
|
@ -4700,7 +4666,7 @@ dec_hash(PyDecObject *self)
|
|||
|
||||
/* __reduce__ */
|
||||
static PyObject *
|
||||
dec_reduce(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_reduce(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
PyObject *result, *str;
|
||||
|
||||
|
@ -4717,7 +4683,7 @@ dec_reduce(PyObject *self, PyObject *dummy UNUSED)
|
|||
|
||||
/* __sizeof__ */
|
||||
static PyObject *
|
||||
dec_sizeof(PyObject *v, PyObject *dummy UNUSED)
|
||||
dec_sizeof(PyObject *v, PyObject *dummy)
|
||||
{
|
||||
Py_ssize_t res;
|
||||
|
||||
|
@ -4730,7 +4696,7 @@ dec_sizeof(PyObject *v, PyObject *dummy UNUSED)
|
|||
|
||||
/* __trunc__ */
|
||||
static PyObject *
|
||||
dec_trunc(PyObject *self, PyObject *dummy UNUSED)
|
||||
dec_trunc(PyObject *self, PyObject *dummy)
|
||||
{
|
||||
PyObject *context;
|
||||
|
||||
|
@ -4740,14 +4706,14 @@ dec_trunc(PyObject *self, PyObject *dummy UNUSED)
|
|||
|
||||
/* real and imag */
|
||||
static PyObject *
|
||||
dec_real(PyObject *self, void *closure UNUSED)
|
||||
dec_real(PyObject *self, void *closure)
|
||||
{
|
||||
Py_INCREF(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
dec_imag(PyObject *self UNUSED, void *closure UNUSED)
|
||||
dec_imag(PyObject *self, void *closure)
|
||||
{
|
||||
PyObject *result;
|
||||
|
||||
|
@ -5105,7 +5071,6 @@ ctx_##MPDFUNC(PyObject *context, PyObject *args) \
|
|||
return result; \
|
||||
}
|
||||
|
||||
|
||||
/* Unary arithmetic functions */
|
||||
DecCtx_UnaryFunc(mpd_qabs)
|
||||
DecCtx_UnaryFunc(mpd_qexp)
|
||||
|
@ -5145,13 +5110,10 @@ ctx_mpd_qdivmod(PyObject *context, PyObject *args)
|
|||
PyObject *q, *r;
|
||||
uint32_t status = 0;
|
||||
PyObject *ret;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CONVERT_BINOP_RAISE(&a, &b, v, w, context);
|
||||
|
||||
q = dec_alloc();
|
||||
if (q == NULL) {
|
||||
Py_DECREF(a);
|
||||
|
@ -5165,7 +5127,6 @@ ctx_mpd_qdivmod(PyObject *context, PyObject *args)
|
|||
Py_DECREF(q);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status);
|
||||
Py_DECREF(a);
|
||||
Py_DECREF(b);
|
||||
|
@ -5174,7 +5135,6 @@ ctx_mpd_qdivmod(PyObject *context, PyObject *args)
|
|||
Py_DECREF(q);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = Py_BuildValue("(OO)", q, r);
|
||||
Py_DECREF(r);
|
||||
Py_DECREF(q);
|
||||
|
@ -5190,14 +5150,11 @@ ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds)
|
|||
PyObject *a, *b, *c = NULL;
|
||||
PyObject *result;
|
||||
uint32_t status = 0;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist,
|
||||
&base, &exp, &mod)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CONVERT_BINOP_RAISE(&a, &b, base, exp, context);
|
||||
|
||||
if (mod != Py_None) {
|
||||
if (!convert_op(TYPE_ERR, &c, mod, context)) {
|
||||
Py_DECREF(a);
|
||||
|
@ -5205,7 +5162,6 @@ ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds)
|
|||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
result = dec_alloc();
|
||||
if (result == NULL) {
|
||||
Py_DECREF(a);
|
||||
|
@ -5213,7 +5169,6 @@ ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds)
|
|||
Py_XDECREF(c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (c == NULL) {
|
||||
mpd_qpow(MPD(result), MPD(a), MPD(b),
|
||||
CTX(context), &status);
|
||||
|
@ -5229,7 +5184,6 @@ ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds)
|
|||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -5255,14 +5209,13 @@ DecCtx_BoolFunc_NO_CTX(mpd_issnan)
|
|||
DecCtx_BoolFunc_NO_CTX(mpd_iszero)
|
||||
|
||||
static PyObject *
|
||||
ctx_iscanonical(PyObject *context UNUSED, PyObject *v)
|
||||
ctx_iscanonical(PyObject *context, PyObject *v)
|
||||
{
|
||||
if (!PyDec_Check(v)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"argument must be a Decimal");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mpd_iscanonical(MPD(v)) ? incr_true() : incr_false();
|
||||
}
|
||||
|
||||
|
@ -5271,23 +5224,20 @@ static PyObject *
|
|||
PyDecContext_Apply(PyObject *context, PyObject *v)
|
||||
{
|
||||
PyObject *result, *a;
|
||||
|
||||
CONVERT_OP_RAISE(&a, v, context);
|
||||
|
||||
result = dec_apply(a, context);
|
||||
Py_DECREF(a);
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
ctx_canonical(PyObject *context UNUSED, PyObject *v)
|
||||
ctx_canonical(PyObject *context, PyObject *v)
|
||||
{
|
||||
if (!PyDec_Check(v)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"argument must be a Decimal");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(v);
|
||||
return v;
|
||||
}
|
||||
|
@ -5297,22 +5247,18 @@ ctx_mpd_qcopy_abs(PyObject *context, PyObject *v)
|
|||
{
|
||||
PyObject *result, *a;
|
||||
uint32_t status = 0;
|
||||
|
||||
CONVERT_OP_RAISE(&a, v, context);
|
||||
|
||||
result = dec_alloc();
|
||||
if (result == NULL) {
|
||||
Py_DECREF(a);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mpd_qcopy_abs(MPD(result), MPD(a), &status);
|
||||
Py_DECREF(a);
|
||||
if (dec_addstatus(context, status)) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -5320,7 +5266,6 @@ static PyObject *
|
|||
ctx_copy_decimal(PyObject *context, PyObject *v)
|
||||
{
|
||||
PyObject *result;
|
||||
|
||||
CONVERT_OP_RAISE(&result, v, context);
|
||||
return result;
|
||||
}
|
||||
|
@ -5330,22 +5275,18 @@ ctx_mpd_qcopy_negate(PyObject *context, PyObject *v)
|
|||
{
|
||||
PyObject *result, *a;
|
||||
uint32_t status = 0;
|
||||
|
||||
CONVERT_OP_RAISE(&a, v, context);
|
||||
|
||||
result = dec_alloc();
|
||||
if (result == NULL) {
|
||||
Py_DECREF(a);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mpd_qcopy_negate(MPD(result), MPD(a), &status);
|
||||
Py_DECREF(a);
|
||||
if (dec_addstatus(context, status)) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -5357,12 +5298,9 @@ ctx_mpd_class(PyObject *context, PyObject *v)
|
|||
{
|
||||
PyObject *a;
|
||||
const char *cp;
|
||||
|
||||
CONVERT_OP_RAISE(&a, v, context);
|
||||
|
||||
cp = mpd_class(MPD(a), CTX(context));
|
||||
Py_DECREF(a);
|
||||
|
||||
return PyUnicode_FromString(cp);
|
||||
}
|
||||
|
||||
|
@ -5373,19 +5311,15 @@ ctx_mpd_to_sci(PyObject *context, PyObject *v)
|
|||
PyObject *a;
|
||||
mpd_ssize_t size;
|
||||
char *s;
|
||||
|
||||
CONVERT_OP_RAISE(&a, v, context);
|
||||
|
||||
size = mpd_to_sci_size(&s, MPD(a), CtxCaps(context));
|
||||
Py_DECREF(a);
|
||||
if (size < 0) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = unicode_fromascii(s, size);
|
||||
mpd_free(s);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -5396,19 +5330,15 @@ ctx_mpd_to_eng(PyObject *context, PyObject *v)
|
|||
PyObject *a;
|
||||
mpd_ssize_t size;
|
||||
char *s;
|
||||
|
||||
CONVERT_OP_RAISE(&a, v, context);
|
||||
|
||||
size = mpd_to_eng_size(&s, MPD(a), CtxCaps(context));
|
||||
Py_DECREF(a);
|
||||
if (size < 0) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = unicode_fromascii(s, size);
|
||||
mpd_free(s);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -5566,13 +5496,6 @@ static PyMethodDef context_methods [] =
|
|||
{ "clear_flags", context_clear_flags, METH_NOARGS, doc_ctx_clear_flags },
|
||||
{ "clear_traps", context_clear_traps, METH_NOARGS, doc_ctx_clear_traps },
|
||||
|
||||
#ifdef CONFIG_32
|
||||
/* Unsafe set functions with relaxed range checks */
|
||||
{ "_unsafe_setprec", context_unsafe_setprec, METH_O, NULL },
|
||||
{ "_unsafe_setemin", context_unsafe_setemin, METH_O, NULL },
|
||||
{ "_unsafe_setemax", context_unsafe_setemax, METH_O, NULL },
|
||||
#endif
|
||||
|
||||
/* Miscellaneous */
|
||||
{ "__copy__", (PyCFunction)context_copy, METH_NOARGS, NULL },
|
||||
{ "__reduce__", context_reduce, METH_NOARGS, NULL },
|
||||
|
|
|
@ -42,7 +42,6 @@ asm(".include \"libc/disclaimer.inc\"");
|
|||
/* Calculations in base MPD_RADIX */
|
||||
/*********************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* Knuth, TAOCP, Volume 2, 4.3.1:
|
||||
* w := sum of u (len m) and v (len n)
|
||||
|
@ -56,9 +55,7 @@ _mpd_baseadd(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v,
|
|||
mpd_uint_t s;
|
||||
mpd_uint_t carry = 0;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(n > 0 && m >= n);
|
||||
|
||||
/* add n members of u and v */
|
||||
for (i = 0; i < n; i++) {
|
||||
s = u[i] + (v[i] + carry);
|
||||
|
@ -75,7 +72,6 @@ _mpd_baseadd(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v,
|
|||
for (; i < m; i++) {
|
||||
w[i] = u[i];
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
|
@ -89,9 +85,7 @@ _mpd_baseaddto(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n)
|
|||
mpd_uint_t s;
|
||||
mpd_uint_t carry = 0;
|
||||
mpd_size_t i;
|
||||
|
||||
if (n == 0) return;
|
||||
|
||||
/* add n members of u to w */
|
||||
for (i = 0; i < n; i++) {
|
||||
s = w[i] + (u[i] + carry);
|
||||
|
@ -116,21 +110,17 @@ _mpd_shortadd(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v)
|
|||
mpd_uint_t s;
|
||||
mpd_uint_t carry;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(m > 0);
|
||||
|
||||
/* add v to w */
|
||||
s = w[0] + v;
|
||||
carry = (s < v) | (s >= MPD_RADIX);
|
||||
w[0] = carry ? s-MPD_RADIX : s;
|
||||
|
||||
/* if there is a carry, propagate it */
|
||||
for (i = 1; carry && i < m; i++) {
|
||||
s = w[i] + carry;
|
||||
carry = (s == MPD_RADIX);
|
||||
w[i] = carry ? 0 : s;
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
|
@ -141,16 +131,13 @@ _mpd_baseincr(mpd_uint_t *u, mpd_size_t n)
|
|||
mpd_uint_t s;
|
||||
mpd_uint_t carry = 1;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(n > 0);
|
||||
|
||||
/* if there is a carry, propagate it */
|
||||
for (i = 0; carry && i < n; i++) {
|
||||
s = u[i] + carry;
|
||||
carry = (s == MPD_RADIX);
|
||||
u[i] = carry ? 0 : s;
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
|
@ -166,9 +153,7 @@ _mpd_basesub(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v,
|
|||
mpd_uint_t d;
|
||||
mpd_uint_t borrow = 0;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(m > 0 && n > 0);
|
||||
|
||||
/* subtract n members of v from u */
|
||||
for (i = 0; i < n; i++) {
|
||||
d = u[i] - (v[i] + borrow);
|
||||
|
@ -197,9 +182,7 @@ _mpd_basesubfrom(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n)
|
|||
mpd_uint_t d;
|
||||
mpd_uint_t borrow = 0;
|
||||
mpd_size_t i;
|
||||
|
||||
if (n == 0) return;
|
||||
|
||||
/* subtract n members of u from w */
|
||||
for (i = 0; i < n; i++) {
|
||||
d = w[i] - (u[i] + borrow);
|
||||
|
@ -221,15 +204,11 @@ _mpd_shortmul(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v)
|
|||
mpd_uint_t hi, lo;
|
||||
mpd_uint_t carry = 0;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(n > 0);
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
_mpd_mul_words(&hi, &lo, u[i], v);
|
||||
lo = carry + lo;
|
||||
if (lo < carry) hi++;
|
||||
|
||||
_mpd_div_words_r(&carry, &w[i], hi, lo);
|
||||
}
|
||||
w[i] = carry;
|
||||
|
@ -247,19 +226,15 @@ _mpd_basemul(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v,
|
|||
mpd_uint_t hi, lo;
|
||||
mpd_uint_t carry;
|
||||
mpd_size_t i, j;
|
||||
|
||||
assert(m > 0 && n > 0);
|
||||
|
||||
for (j=0; j < n; j++) {
|
||||
carry = 0;
|
||||
for (i=0; i < m; i++) {
|
||||
|
||||
_mpd_mul_words(&hi, &lo, u[i], v[j]);
|
||||
lo = w[i+j] + lo;
|
||||
if (lo < w[i+j]) hi++;
|
||||
lo = carry + lo;
|
||||
if (lo < carry) hi++;
|
||||
|
||||
_mpd_div_words_r(&carry, &w[i+j], hi, lo);
|
||||
}
|
||||
w[j+m] = carry;
|
||||
|
@ -276,18 +251,13 @@ _mpd_shortdiv(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v)
|
|||
mpd_uint_t hi, lo;
|
||||
mpd_uint_t rem = 0;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(n > 0);
|
||||
|
||||
for (i=n-1; i != MPD_SIZE_MAX; i--) {
|
||||
|
||||
_mpd_mul_words(&hi, &lo, rem, MPD_RADIX);
|
||||
lo = u[i] + lo;
|
||||
if (lo < u[i]) hi++;
|
||||
|
||||
_mpd_div_words(&w[i], &rem, hi, lo, v);
|
||||
}
|
||||
|
||||
return rem;
|
||||
}
|
||||
|
||||
|
@ -315,13 +285,10 @@ _mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r,
|
|||
mpd_uint_t carry;
|
||||
mpd_size_t i, j, m;
|
||||
int retval = 0;
|
||||
|
||||
assert(n > 1 && nplusm >= n);
|
||||
m = sub_size_t(nplusm, n);
|
||||
|
||||
/* D1: normalize */
|
||||
d = MPD_RADIX / (vconst[n-1] + 1);
|
||||
|
||||
if (nplusm >= MPD_MINALLOC_MAX) {
|
||||
if ((u = mpd_alloc(nplusm+1, sizeof *u)) == NULL) {
|
||||
return -1;
|
||||
|
@ -333,17 +300,13 @@ _mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r,
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
_mpd_shortmul(u, uconst, nplusm, d);
|
||||
_mpd_shortmul(v, vconst, n, d);
|
||||
|
||||
/* D2: loop */
|
||||
for (j=m; j != MPD_SIZE_MAX; j--) {
|
||||
|
||||
/* D3: calculate qhat and rhat */
|
||||
rhat = _mpd_shortdiv(w2, u+j+n-1, 2, v[n-1]);
|
||||
qhat = w2[1] * MPD_RADIX + w2[0];
|
||||
|
||||
while (1) {
|
||||
if (qhat < MPD_RADIX) {
|
||||
_mpd_singlemul(w2, qhat, v[n-2]);
|
||||
|
@ -362,14 +325,10 @@ _mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r,
|
|||
/* D4: multiply and subtract */
|
||||
carry = 0;
|
||||
for (i=0; i <= n; i++) {
|
||||
|
||||
_mpd_mul_words(&hi, &lo, qhat, v[i]);
|
||||
|
||||
lo = carry + lo;
|
||||
if (lo < carry) hi++;
|
||||
|
||||
_mpd_div_words_r(&hi, &lo, hi, lo);
|
||||
|
||||
x = u[i+j] - lo;
|
||||
carry = (u[i+j] < x);
|
||||
u[i+j] = carry ? x+MPD_RADIX : x;
|
||||
|
@ -383,7 +342,6 @@ _mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r,
|
|||
(void)_mpd_baseadd(u+j, u+j, v, n+1, n);
|
||||
}
|
||||
}
|
||||
|
||||
/* D8: unnormalize */
|
||||
if (r != NULL) {
|
||||
_mpd_shortdiv(r, u, n, d);
|
||||
|
@ -393,11 +351,9 @@ _mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r,
|
|||
else {
|
||||
retval = !_mpd_isallzero(u, n);
|
||||
}
|
||||
|
||||
|
||||
if (u != ustatic) mpd_free(u);
|
||||
if (v != vstatic) mpd_free(v);
|
||||
return retval;
|
||||
if (u != ustatic) mpd_free(u);
|
||||
if (v != vstatic) mpd_free(v);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -428,23 +384,13 @@ void
|
|||
_mpd_baseshiftl(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t n, mpd_size_t m,
|
||||
mpd_size_t shift)
|
||||
{
|
||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
|
||||
/* spurious uninitialized warnings */
|
||||
mpd_uint_t l=l, lprev=lprev, h=h;
|
||||
#else
|
||||
mpd_uint_t l, lprev, h;
|
||||
#endif
|
||||
mpd_uint_t l=l, lprev=lprev, h=h; /* b/c warnings */
|
||||
mpd_uint_t q, r;
|
||||
mpd_uint_t ph;
|
||||
|
||||
assert(m > 0 && n >= m);
|
||||
|
||||
_mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS);
|
||||
|
||||
if (r != 0) {
|
||||
|
||||
ph = mpd_pow10[r];
|
||||
|
||||
--m; --n;
|
||||
_mpd_divmod_pow10(&h, &lprev, src[m--], MPD_RDIGITS-r);
|
||||
if (h != 0) { /* r + msdigits > rdigits <==> h != 0 */
|
||||
|
@ -464,7 +410,6 @@ _mpd_baseshiftl(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t n, mpd_size_t m,
|
|||
dest[m+q] = src[m];
|
||||
}
|
||||
}
|
||||
|
||||
mpd_uint_zero(dest, q);
|
||||
}
|
||||
|
||||
|
@ -497,29 +442,19 @@ mpd_uint_t
|
|||
_mpd_baseshiftr(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t slen,
|
||||
mpd_size_t shift)
|
||||
{
|
||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
|
||||
/* spurious uninitialized warnings */
|
||||
mpd_uint_t l=l, h=h, hprev=hprev; /* low, high, previous high */
|
||||
#else
|
||||
mpd_uint_t l, h, hprev; /* low, high, previous high */
|
||||
#endif
|
||||
mpd_uint_t rnd, rest; /* rounding digit, rest */
|
||||
mpd_uint_t q, r;
|
||||
mpd_size_t i, j;
|
||||
mpd_uint_t ph;
|
||||
|
||||
assert(slen > 0);
|
||||
|
||||
_mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS);
|
||||
|
||||
rnd = rest = 0;
|
||||
if (r != 0) {
|
||||
|
||||
ph = mpd_pow10[MPD_RDIGITS-r];
|
||||
|
||||
_mpd_divmod_pow10(&hprev, &rest, src[q], r);
|
||||
_mpd_divmod_pow10(&rnd, &rest, rest, r-1);
|
||||
|
||||
if (rest == 0 && q > 0) {
|
||||
rest = !_mpd_isallzero(src, q);
|
||||
}
|
||||
|
@ -544,14 +479,12 @@ _mpd_baseshiftr(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t slen,
|
|||
dest[j] = src[q+j];
|
||||
}
|
||||
}
|
||||
|
||||
/* 0-4 ==> rnd+rest < 0.5 */
|
||||
/* 5 ==> rnd+rest == 0.5 */
|
||||
/* 6-9 ==> rnd+rest > 0.5 */
|
||||
return (rnd == 0 || rnd == 5) ? rnd + !!rest : rnd;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* Calculations in base b */
|
||||
/*********************************************************************/
|
||||
|
@ -566,21 +499,17 @@ _mpd_shortadd_b(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v, mpd_uint_t b)
|
|||
mpd_uint_t s;
|
||||
mpd_uint_t carry;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(m > 0);
|
||||
|
||||
/* add v to w */
|
||||
s = w[0] + v;
|
||||
carry = (s < v) | (s >= b);
|
||||
w[0] = carry ? s-b : s;
|
||||
|
||||
/* if there is a carry, propagate it */
|
||||
for (i = 1; carry && i < m; i++) {
|
||||
s = w[i] + carry;
|
||||
carry = (s == b);
|
||||
w[i] = carry ? 0 : s;
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
|
@ -591,18 +520,13 @@ _mpd_shortmul_c(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v)
|
|||
mpd_uint_t hi, lo;
|
||||
mpd_uint_t carry = 0;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(n > 0);
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
_mpd_mul_words(&hi, &lo, u[i], v);
|
||||
lo = carry + lo;
|
||||
if (lo < carry) hi++;
|
||||
|
||||
_mpd_div_words_r(&carry, &w[i], hi, lo);
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
|
@ -614,18 +538,13 @@ _mpd_shortmul_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n,
|
|||
mpd_uint_t hi, lo;
|
||||
mpd_uint_t carry = 0;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(n > 0);
|
||||
|
||||
for (i=0; i < n; i++) {
|
||||
|
||||
_mpd_mul_words(&hi, &lo, u[i], v);
|
||||
lo = carry + lo;
|
||||
if (lo < carry) hi++;
|
||||
|
||||
_mpd_div_words(&carry, &w[i], hi, lo, b);
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
|
@ -640,17 +559,12 @@ _mpd_shortdiv_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n,
|
|||
mpd_uint_t hi, lo;
|
||||
mpd_uint_t rem = 0;
|
||||
mpd_size_t i;
|
||||
|
||||
assert(n > 0);
|
||||
|
||||
for (i=n-1; i != MPD_SIZE_MAX; i--) {
|
||||
|
||||
_mpd_mul_words(&hi, &lo, rem, b);
|
||||
lo = u[i] + lo;
|
||||
if (lo < u[i]) hi++;
|
||||
|
||||
_mpd_div_words(&w[i], &rem, hi, lo, v);
|
||||
}
|
||||
|
||||
return rem;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
mpd_uint_t _mpd_baseadd(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v,
|
||||
mpd_size_t m, mpd_size_t n);
|
||||
|
@ -36,7 +35,6 @@ void _mpd_baseshiftl(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t n,
|
|||
mpd_uint_t _mpd_baseshiftr(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t slen,
|
||||
mpd_size_t shift);
|
||||
|
||||
#ifdef CONFIG_64
|
||||
extern const mpd_uint_t mprime_rdx;
|
||||
|
||||
/*
|
||||
|
@ -66,12 +64,10 @@ _mpd_div_words_r(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo)
|
|||
{
|
||||
mpd_uint_t n_adj, h, l, t;
|
||||
mpd_uint_t n1_neg;
|
||||
|
||||
/* n1_neg = if lo >= 2**63 then MPD_UINT_MAX else 0 */
|
||||
n1_neg = (lo & (1ULL<<63)) ? MPD_UINT_MAX : 0;
|
||||
/* n_adj = if lo >= 2**63 then lo+MPD_RADIX else lo */
|
||||
n_adj = lo + (n1_neg & MPD_RADIX);
|
||||
|
||||
/* (h, l) = if lo >= 2**63 then m'*(hi+1) else m'*hi */
|
||||
_mpd_mul_words(&h, &l, mprime_rdx, hi-n1_neg);
|
||||
l = l + n_adj;
|
||||
|
@ -80,10 +76,8 @@ _mpd_div_words_r(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo)
|
|||
/* At this point t == qest, with q == qest or q == qest+1:
|
||||
* 1) 0 <= 2**64*hi + lo - qest*MPD_RADIX < 2*MPD_RADIX
|
||||
*/
|
||||
|
||||
/* t = 2**64-1 - qest = 2**64 - (qest+1) */
|
||||
t = MPD_UINT_MAX - t;
|
||||
|
||||
/* (h, l) = 2**64*MPD_RADIX - (qest+1)*MPD_RADIX */
|
||||
_mpd_mul_words(&h, &l, t, MPD_RADIX);
|
||||
l = l + lo;
|
||||
|
@ -100,25 +94,15 @@ _mpd_div_words_r(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo)
|
|||
* b) q := h - t == qest
|
||||
* c) r := l + MPD_RADIX = r
|
||||
*/
|
||||
|
||||
*q = (h - t);
|
||||
*r = l + (MPD_RADIX & h);
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
_mpd_div_words_r(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo)
|
||||
{
|
||||
_mpd_div_words(q, r, hi, lo, MPD_RADIX);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply two single base MPD_RADIX words, store result in array w[2]. */
|
||||
static inline void
|
||||
_mpd_singlemul(mpd_uint_t w[2], mpd_uint_t u, mpd_uint_t v)
|
||||
{
|
||||
mpd_uint_t hi, lo;
|
||||
|
||||
_mpd_mul_words(&hi, &lo, u, v);
|
||||
_mpd_div_words_r(&w[1], &w[0], hi, lo);
|
||||
}
|
||||
|
@ -128,21 +112,17 @@ static inline void
|
|||
_mpd_mul_2_le2(mpd_uint_t w[4], mpd_uint_t u[2], mpd_uint_t v[2], mpd_ssize_t m)
|
||||
{
|
||||
mpd_uint_t hi, lo;
|
||||
|
||||
_mpd_mul_words(&hi, &lo, u[0], v[0]);
|
||||
_mpd_div_words_r(&w[1], &w[0], hi, lo);
|
||||
|
||||
_mpd_mul_words(&hi, &lo, u[1], v[0]);
|
||||
lo = w[1] + lo;
|
||||
if (lo < w[1]) hi++;
|
||||
_mpd_div_words_r(&w[2], &w[1], hi, lo);
|
||||
if (m == 1) return;
|
||||
|
||||
_mpd_mul_words(&hi, &lo, u[0], v[1]);
|
||||
lo = w[1] + lo;
|
||||
if (lo < w[1]) hi++;
|
||||
_mpd_div_words_r(&w[3], &w[1], hi, lo);
|
||||
|
||||
_mpd_mul_words(&hi, &lo, u[1], v[1]);
|
||||
lo = w[2] + lo;
|
||||
if (lo < w[2]) hi++;
|
||||
|
@ -151,7 +131,6 @@ _mpd_mul_2_le2(mpd_uint_t w[4], mpd_uint_t u[2], mpd_uint_t v[2], mpd_ssize_t m)
|
|||
_mpd_div_words_r(&w[3], &w[2], hi, lo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test if all words from data[len-1] to data[0] are zero. If len is 0, nothing
|
||||
* is tested and the coefficient is regarded as "all zero".
|
||||
|
@ -178,6 +157,5 @@ _mpd_isallnine(const mpd_uint_t *data, mpd_ssize_t len)
|
|||
return 1;
|
||||
}
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
|
||||
#endif /* BASEARITH_H */
|
||||
|
|
137
third_party/python/Modules/_decimal/libmpdec/bits.h
vendored
137
third_party/python/Modules/_decimal/libmpdec/bits.h
vendored
|
@ -3,41 +3,35 @@
|
|||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Check if n is a power of 2. */
|
||||
/*
|
||||
* Check if 𝑛 is a power of 2.
|
||||
*/
|
||||
static inline int
|
||||
ispower2(mpd_size_t n)
|
||||
{
|
||||
return n != 0 && (n & (n-1)) == 0;
|
||||
}
|
||||
|
||||
#if defined(ANSI)
|
||||
#error oh no
|
||||
/*
|
||||
* Return the most significant bit position of n from 0 to 31 (63).
|
||||
* Assumptions: n != 0.
|
||||
* Returns most significant bit position of 𝑛.
|
||||
* Assumptions: 𝑛 ≠ 0
|
||||
*/
|
||||
static inline int
|
||||
mpd_bsr(mpd_size_t n)
|
||||
{
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
return __builtin_clzll(n) ^ (sizeof(long long) * CHAR_BIT - 1);
|
||||
#else
|
||||
int pos = 0;
|
||||
mpd_size_t tmp;
|
||||
|
||||
#ifdef CONFIG_64
|
||||
tmp = n >> 32;
|
||||
if (tmp != 0) { n = tmp; pos += 32; }
|
||||
#endif
|
||||
tmp = n >> 16;
|
||||
if (tmp != 0) { n = tmp; pos += 16; }
|
||||
tmp = n >> 8;
|
||||
if (tmp != 0) { n = tmp; pos += 8; }
|
||||
tmp = n >> 4;
|
||||
if (tmp != 0) { n = tmp; pos += 4; }
|
||||
tmp = n >> 2;
|
||||
if (tmp != 0) { n = tmp; pos += 2; }
|
||||
tmp = n >> 1;
|
||||
if (tmp != 0) { n = tmp; pos += 1; }
|
||||
|
||||
tmp = n >> 32; if (tmp != 0) { n = tmp; pos += 32; }
|
||||
tmp = n >> 16; if (tmp != 0) { n = tmp; pos += 16; }
|
||||
tmp = n >> 8; if (tmp != 0) { n = tmp; pos += 8; }
|
||||
tmp = n >> 4; if (tmp != 0) { n = tmp; pos += 4; }
|
||||
tmp = n >> 2; if (tmp != 0) { n = tmp; pos += 2; }
|
||||
tmp = n >> 1; if (tmp != 0) { n = tmp; pos += 1; }
|
||||
return pos + (int)n - 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -47,9 +41,10 @@ mpd_bsr(mpd_size_t n)
|
|||
static inline int
|
||||
mpd_bsf(mpd_size_t n)
|
||||
{
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
return __builtin_ctzll(n);
|
||||
#else
|
||||
int pos;
|
||||
|
||||
#ifdef CONFIG_64
|
||||
pos = 63;
|
||||
if (n & 0x00000000FFFFFFFFULL) { pos -= 32; } else { n >>= 32; }
|
||||
if (n & 0x000000000000FFFFULL) { pos -= 16; } else { n >>= 16; }
|
||||
|
@ -57,104 +52,8 @@ mpd_bsf(mpd_size_t n)
|
|||
if (n & 0x000000000000000FULL) { pos -= 4; } else { n >>= 4; }
|
||||
if (n & 0x0000000000000003ULL) { pos -= 2; } else { n >>= 2; }
|
||||
if (n & 0x0000000000000001ULL) { pos -= 1; }
|
||||
#else
|
||||
pos = 31;
|
||||
if (n & 0x000000000000FFFFUL) { pos -= 16; } else { n >>= 16; }
|
||||
if (n & 0x00000000000000FFUL) { pos -= 8; } else { n >>= 8; }
|
||||
if (n & 0x000000000000000FUL) { pos -= 4; } else { n >>= 4; }
|
||||
if (n & 0x0000000000000003UL) { pos -= 2; } else { n >>= 2; }
|
||||
if (n & 0x0000000000000001UL) { pos -= 1; }
|
||||
#endif
|
||||
return pos;
|
||||
}
|
||||
/* END ANSI */
|
||||
|
||||
#elif defined(ASM)
|
||||
/*
|
||||
* Bit scan reverse. Assumptions: a != 0.
|
||||
*/
|
||||
static inline int
|
||||
mpd_bsr(mpd_size_t a)
|
||||
{
|
||||
mpd_size_t retval;
|
||||
|
||||
__asm__ (
|
||||
#ifdef CONFIG_64
|
||||
"bsrq %1, %0\n\t"
|
||||
#else
|
||||
"bsr %1, %0\n\t"
|
||||
#endif
|
||||
:"=r" (retval)
|
||||
:"r" (a)
|
||||
:"cc"
|
||||
);
|
||||
|
||||
return (int)retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bit scan forward. Assumptions: a != 0.
|
||||
*/
|
||||
static inline int
|
||||
mpd_bsf(mpd_size_t a)
|
||||
{
|
||||
mpd_size_t retval;
|
||||
__asm__ (
|
||||
#ifdef CONFIG_64
|
||||
"bsfq %1, %0\n\t"
|
||||
#else
|
||||
"bsf %1, %0\n\t"
|
||||
#endif
|
||||
:"=r" (retval)
|
||||
:"r" (a)
|
||||
:"cc"
|
||||
);
|
||||
return (int)retval;
|
||||
}
|
||||
/* END ASM */
|
||||
|
||||
#elif defined(MASM)
|
||||
#include <intrin.h>
|
||||
/*
|
||||
* Bit scan reverse. Assumptions: a != 0.
|
||||
*/
|
||||
static inline int __cdecl
|
||||
mpd_bsr(mpd_size_t a)
|
||||
{
|
||||
unsigned long retval;
|
||||
|
||||
#ifdef CONFIG_64
|
||||
_BitScanReverse64(&retval, a);
|
||||
#else
|
||||
_BitScanReverse(&retval, a);
|
||||
#endif
|
||||
|
||||
return (int)retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bit scan forward. Assumptions: a != 0.
|
||||
*/
|
||||
static inline int __cdecl
|
||||
mpd_bsf(mpd_size_t a)
|
||||
{
|
||||
unsigned long retval;
|
||||
|
||||
#ifdef CONFIG_64
|
||||
_BitScanForward64(&retval, a);
|
||||
#else
|
||||
_BitScanForward(&retval, a);
|
||||
#endif
|
||||
|
||||
return (int)retval;
|
||||
}
|
||||
/* END MASM (_MSC_VER) */
|
||||
#else
|
||||
#error "missing preprocessor definitions"
|
||||
#endif /* BSR/BSF */
|
||||
|
||||
|
||||
#endif /* BITS_H */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -36,86 +36,45 @@ libmpdec (BSD-2)\\n\
|
|||
Copyright 2008-2016 Stefan Krah\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
#if defined(CONFIG_64)
|
||||
/* number-theory.c */
|
||||
const mpd_uint_t mpd_moduli[3] = {
|
||||
18446744069414584321ULL, 18446744056529682433ULL, 18446742974197923841ULL
|
||||
};
|
||||
const mpd_uint_t mpd_roots[3] = {7ULL, 10ULL, 19ULL};
|
||||
|
||||
/* number-theory.c */
|
||||
const mpd_uint_t mpd_moduli[3] = {
|
||||
18446744069414584321ULL, 18446744056529682433ULL, 18446742974197923841ULL
|
||||
};
|
||||
const mpd_uint_t mpd_roots[3] = {7ULL, 10ULL, 19ULL};
|
||||
/* crt.c */
|
||||
const mpd_uint_t INV_P1_MOD_P2 = 18446744055098026669ULL;
|
||||
const mpd_uint_t INV_P1P2_MOD_P3 = 287064143708160ULL;
|
||||
const mpd_uint_t LH_P1P2 = 18446744052234715137ULL; /* (P1*P2) % 2^64 */
|
||||
const mpd_uint_t UH_P1P2 = 18446744052234715141ULL; /* (P1*P2) / 2^64 */
|
||||
|
||||
/* crt.c */
|
||||
const mpd_uint_t INV_P1_MOD_P2 = 18446744055098026669ULL;
|
||||
const mpd_uint_t INV_P1P2_MOD_P3 = 287064143708160ULL;
|
||||
const mpd_uint_t LH_P1P2 = 18446744052234715137ULL; /* (P1*P2) % 2^64 */
|
||||
const mpd_uint_t UH_P1P2 = 18446744052234715141ULL; /* (P1*P2) / 2^64 */
|
||||
/* transpose.c */
|
||||
const mpd_size_t mpd_bits[64] = {
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
|
||||
32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608,
|
||||
16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824,
|
||||
2147483648ULL, 4294967296ULL, 8589934592ULL, 17179869184ULL, 34359738368ULL,
|
||||
68719476736ULL, 137438953472ULL, 274877906944ULL, 549755813888ULL,
|
||||
1099511627776ULL, 2199023255552ULL, 4398046511104, 8796093022208ULL,
|
||||
17592186044416ULL, 35184372088832ULL, 70368744177664ULL, 140737488355328ULL,
|
||||
281474976710656ULL, 562949953421312ULL, 1125899906842624ULL,
|
||||
2251799813685248ULL, 4503599627370496ULL, 9007199254740992ULL,
|
||||
18014398509481984ULL, 36028797018963968ULL, 72057594037927936ULL,
|
||||
144115188075855872ULL, 288230376151711744ULL, 576460752303423488ULL,
|
||||
1152921504606846976ULL, 2305843009213693952ULL, 4611686018427387904ULL,
|
||||
9223372036854775808ULL
|
||||
};
|
||||
|
||||
/* transpose.c */
|
||||
const mpd_size_t mpd_bits[64] = {
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
|
||||
32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608,
|
||||
16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824,
|
||||
2147483648ULL, 4294967296ULL, 8589934592ULL, 17179869184ULL, 34359738368ULL,
|
||||
68719476736ULL, 137438953472ULL, 274877906944ULL, 549755813888ULL,
|
||||
1099511627776ULL, 2199023255552ULL, 4398046511104, 8796093022208ULL,
|
||||
17592186044416ULL, 35184372088832ULL, 70368744177664ULL, 140737488355328ULL,
|
||||
281474976710656ULL, 562949953421312ULL, 1125899906842624ULL,
|
||||
2251799813685248ULL, 4503599627370496ULL, 9007199254740992ULL,
|
||||
18014398509481984ULL, 36028797018963968ULL, 72057594037927936ULL,
|
||||
144115188075855872ULL, 288230376151711744ULL, 576460752303423488ULL,
|
||||
1152921504606846976ULL, 2305843009213693952ULL, 4611686018427387904ULL,
|
||||
9223372036854775808ULL
|
||||
};
|
||||
/* mpdecimal.c */
|
||||
const mpd_uint_t mpd_pow10[MPD_RDIGITS+1] = {
|
||||
1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,
|
||||
10000000000ULL,100000000000ULL,1000000000000ULL,10000000000000ULL,
|
||||
100000000000000ULL,1000000000000000ULL,10000000000000000ULL,
|
||||
100000000000000000ULL,1000000000000000000ULL,10000000000000000000ULL
|
||||
};
|
||||
|
||||
/* mpdecimal.c */
|
||||
const mpd_uint_t mpd_pow10[MPD_RDIGITS+1] = {
|
||||
1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,
|
||||
10000000000ULL,100000000000ULL,1000000000000ULL,10000000000000ULL,
|
||||
100000000000000ULL,1000000000000000ULL,10000000000000000ULL,
|
||||
100000000000000000ULL,1000000000000000000ULL,10000000000000000000ULL
|
||||
};
|
||||
|
||||
/* magic number for constant division by MPD_RADIX */
|
||||
const mpd_uint_t mprime_rdx = 15581492618384294730ULL;
|
||||
|
||||
#elif defined(CONFIG_32)
|
||||
|
||||
/* number-theory.c */
|
||||
const mpd_uint_t mpd_moduli[3] = {2113929217UL, 2013265921UL, 1811939329UL};
|
||||
const mpd_uint_t mpd_roots[3] = {5UL, 31UL, 13UL};
|
||||
|
||||
/* PentiumPro modular multiplication: These constants have to be loaded as
|
||||
* 80 bit long doubles, which are not supported by certain compilers. */
|
||||
const uint32_t mpd_invmoduli[3][3] = {
|
||||
{4293885170U, 2181570688U, 16352U}, /* ((long double) 1 / 2113929217UL) */
|
||||
{1698898177U, 2290649223U, 16352U}, /* ((long double) 1 / 2013265921UL) */
|
||||
{2716021846U, 2545165803U, 16352U} /* ((long double) 1 / 1811939329UL) */
|
||||
};
|
||||
|
||||
const float MPD_TWO63 = 9223372036854775808.0; /* 2^63 */
|
||||
|
||||
/* crt.c */
|
||||
const mpd_uint_t INV_P1_MOD_P2 = 2013265901UL;
|
||||
const mpd_uint_t INV_P1P2_MOD_P3 = 54UL;
|
||||
const mpd_uint_t LH_P1P2 = 4127195137UL; /* (P1*P2) % 2^32 */
|
||||
const mpd_uint_t UH_P1P2 = 990904320UL; /* (P1*P2) / 2^32 */
|
||||
|
||||
/* transpose.c */
|
||||
const mpd_size_t mpd_bits[32] = {
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
|
||||
32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608,
|
||||
16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824,
|
||||
2147483648UL
|
||||
};
|
||||
|
||||
/* mpdecimal.c */
|
||||
const mpd_uint_t mpd_pow10[MPD_RDIGITS+1] = {
|
||||
1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000
|
||||
};
|
||||
|
||||
#else
|
||||
#error "CONFIG_64 or CONFIG_32 must be defined."
|
||||
#endif
|
||||
/* magic number for constant division by MPD_RADIX */
|
||||
const mpd_uint_t mprime_rdx = 15581492618384294730ULL;
|
||||
|
||||
const char *mpd_round_string[MPD_ROUND_GUARD] = {
|
||||
"ROUND_UP", /* round away from 0 */
|
||||
|
|
|
@ -3,35 +3,12 @@
|
|||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
/* choice of optimized functions */
|
||||
#if defined(CONFIG_64)
|
||||
/* x64 */
|
||||
#define MULMOD(a, b) x64_mulmod(a, b, umod)
|
||||
#define MULMOD2C(a0, a1, w) x64_mulmod2c(a0, a1, w, umod)
|
||||
#define MULMOD2(a0, b0, a1, b1) x64_mulmod2(a0, b0, a1, b1, umod)
|
||||
#define POWMOD(base, exp) x64_powmod(base, exp, umod)
|
||||
#define SETMODULUS(modnum) std_setmodulus(modnum, &umod)
|
||||
#define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod)
|
||||
#elif defined(PPRO)
|
||||
/* PentiumPro (or later) gcc inline asm */
|
||||
#define MULMOD(a, b) ppro_mulmod(a, b, &dmod, dinvmod)
|
||||
#define MULMOD2C(a0, a1, w) ppro_mulmod2c(a0, a1, w, &dmod, dinvmod)
|
||||
#define MULMOD2(a0, b0, a1, b1) ppro_mulmod2(a0, b0, a1, b1, &dmod, dinvmod)
|
||||
#define POWMOD(base, exp) ppro_powmod(base, exp, &dmod, dinvmod)
|
||||
#define SETMODULUS(modnum) ppro_setmodulus(modnum, &umod, &dmod, dinvmod)
|
||||
#define SIZE3_NTT(x0, x1, x2, w3table) ppro_size3_ntt(x0, x1, x2, w3table, umod, &dmod, dinvmod)
|
||||
#else
|
||||
/* ANSI C99 */
|
||||
#define MULMOD(a, b) std_mulmod(a, b, umod)
|
||||
#define MULMOD2C(a0, a1, w) std_mulmod2c(a0, a1, w, umod)
|
||||
#define MULMOD2(a0, b0, a1, b1) std_mulmod2(a0, b0, a1, b1, umod)
|
||||
#define POWMOD(base, exp) std_powmod(base, exp, umod)
|
||||
#define SETMODULUS(modnum) std_setmodulus(modnum, &umod)
|
||||
#define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod)
|
||||
#endif
|
||||
#define MULMOD(a, b) x64_mulmod(a, b, umod)
|
||||
#define MULMOD2C(a0, a1, w) x64_mulmod2c(a0, a1, w, umod)
|
||||
#define MULMOD2(a0, b0, a1, b1) x64_mulmod2(a0, b0, a1, b1, umod)
|
||||
#define POWMOD(base, exp) x64_powmod(base, exp, umod)
|
||||
#define SETMODULUS(modnum) std_setmodulus(modnum, &umod)
|
||||
#define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod)
|
||||
|
||||
/* PentiumPro (or later) gcc inline asm */
|
||||
extern const float MPD_TWO63;
|
||||
|
@ -49,11 +26,4 @@ extern const mpd_uint_t INV_P1P2_MOD_P3;
|
|||
extern const mpd_uint_t LH_P1P2;
|
||||
extern const mpd_uint_t UH_P1P2;
|
||||
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
|
||||
|
||||
#endif /* CONSTANTS_H */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -38,14 +38,14 @@ Copyright 2008-2016 Stefan Krah\"");
|
|||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
void
|
||||
mpd_dflt_traphandler(mpd_context_t *ctx UNUSED)
|
||||
mpd_dflt_traphandler(mpd_context_t *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
raise(SIGFPE);
|
||||
}
|
||||
|
||||
void (* mpd_traphandler)(mpd_context_t *) = mpd_dflt_traphandler;
|
||||
|
||||
|
||||
/* Set guaranteed minimum number of coefficient words. The function may
|
||||
be used once at program start. Setting MPD_MINALLOC to out-of-bounds
|
||||
values is a catastrophic error, so in that case the function exits rather
|
||||
|
@ -54,7 +54,6 @@ void
|
|||
mpd_setminalloc(mpd_ssize_t n)
|
||||
{
|
||||
static int minalloc_is_set = 0;
|
||||
|
||||
if (minalloc_is_set) {
|
||||
mpd_err_warn("mpd_setminalloc: ignoring request to set "
|
||||
"MPD_MINALLOC a second time\n");
|
||||
|
@ -71,18 +70,14 @@ void
|
|||
mpd_init(mpd_context_t *ctx, mpd_ssize_t prec)
|
||||
{
|
||||
mpd_ssize_t ideal_minalloc;
|
||||
|
||||
mpd_defaultcontext(ctx);
|
||||
|
||||
if (!mpd_qsetprec(ctx, prec)) {
|
||||
mpd_addstatus_raise(ctx, MPD_Invalid_context);
|
||||
return;
|
||||
}
|
||||
|
||||
ideal_minalloc = 2 * ((prec+MPD_RDIGITS-1) / MPD_RDIGITS);
|
||||
if (ideal_minalloc < MPD_MINALLOC_MIN) ideal_minalloc = MPD_MINALLOC_MIN;
|
||||
if (ideal_minalloc > MPD_MINALLOC_MAX) ideal_minalloc = MPD_MINALLOC_MAX;
|
||||
|
||||
mpd_setminalloc(ideal_minalloc);
|
||||
}
|
||||
|
||||
|
@ -134,7 +129,6 @@ mpd_ieee_context(mpd_context_t *ctx, int bits)
|
|||
if (bits <= 0 || bits > MPD_IEEE_CONTEXT_MAX_BITS || bits % 32) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->prec = 9 * (bits/32) - 2;
|
||||
ctx->emax = 3 * ((mpd_ssize_t)1<<(bits/16+3));
|
||||
ctx->emin = 1 - ctx->emax;
|
||||
|
@ -144,7 +138,6 @@ mpd_ieee_context(mpd_context_t *ctx, int bits)
|
|||
ctx->newtrap=0;
|
||||
ctx->clamp=1;
|
||||
ctx->allcr=1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -196,7 +189,6 @@ mpd_getcr(const mpd_context_t *ctx)
|
|||
return ctx->allcr;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mpd_qsetprec(mpd_context_t *ctx, mpd_ssize_t prec)
|
||||
{
|
||||
|
@ -277,7 +269,6 @@ mpd_qsetcr(mpd_context_t *ctx, int c)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags)
|
||||
{
|
||||
|
|
|
@ -44,8 +44,8 @@ Copyright 2008-2016 Stefan Krah\"");
|
|||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
|
||||
/* Bignum: Fast convolution using the Number Theoretic Transform. Used for
|
||||
the multiplication of very large coefficients. */
|
||||
/* Bignum: Fast convolution using the Number Theoretic Transform.
|
||||
Used for the multiplication of very large coefficients. */
|
||||
|
||||
|
||||
/* Convolute the data in c1 and c2. Result is in c1. */
|
||||
|
@ -54,17 +54,10 @@ fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum)
|
|||
{
|
||||
int (*fnt)(mpd_uint_t *, mpd_size_t, int);
|
||||
int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int);
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_uint_t n_inv, umod;
|
||||
mpd_size_t i;
|
||||
|
||||
|
||||
SETMODULUS(modnum);
|
||||
n_inv = POWMOD(n, (umod-2));
|
||||
|
||||
if (ispower2(n)) {
|
||||
if (n > SIX_STEP_THRESHOLD) {
|
||||
fnt = six_step_fnt;
|
||||
|
@ -79,7 +72,6 @@ fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum)
|
|||
fnt = four_step_fnt;
|
||||
inv_fnt = inv_four_step_fnt;
|
||||
}
|
||||
|
||||
if (!fnt(c1, n, modnum)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -95,7 +87,6 @@ fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum)
|
|||
c1[i] = x0;
|
||||
c1[i+1] = x1;
|
||||
}
|
||||
|
||||
if (!inv_fnt(c1, n, modnum)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -111,7 +102,6 @@ fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum)
|
|||
c1[i+2] = x2;
|
||||
c1[i+3] = x3;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -121,17 +111,10 @@ fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum)
|
|||
{
|
||||
int (*fnt)(mpd_uint_t *, mpd_size_t, int);
|
||||
int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int);
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_uint_t n_inv, umod;
|
||||
mpd_size_t i;
|
||||
|
||||
|
||||
SETMODULUS(modnum);
|
||||
n_inv = POWMOD(n, (umod-2));
|
||||
|
||||
if (ispower2(n)) {
|
||||
if (n > SIX_STEP_THRESHOLD) {
|
||||
fnt = six_step_fnt;
|
||||
|
@ -146,7 +129,6 @@ fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum)
|
|||
fnt = four_step_fnt;
|
||||
inv_fnt = inv_four_step_fnt;
|
||||
}
|
||||
|
||||
if (!fnt(c1, n, modnum)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -157,7 +139,6 @@ fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum)
|
|||
c1[i] = x0;
|
||||
c1[i+1] = x1;
|
||||
}
|
||||
|
||||
if (!inv_fnt(c1, n, modnum)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -173,6 +154,5 @@ fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum)
|
|||
c1[i+2] = x2;
|
||||
c1[i+3] = x3;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
#ifndef CONVOLUTE_H
|
||||
#define CONVOLUTE_H
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
#define SIX_STEP_THRESHOLD 4096
|
||||
|
||||
int fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum);
|
||||
int fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum);
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
int fnt_convolute(mpd_uint_t *, mpd_uint_t *, mpd_size_t, int);
|
||||
int fnt_autoconvolute(mpd_uint_t *, mpd_size_t, int);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,23 +38,18 @@ libmpdec (BSD-2)\\n\
|
|||
Copyright 2008-2016 Stefan Krah\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
|
||||
/* Bignum: Chinese Remainder Theorem, extends the maximum transform length. */
|
||||
|
||||
|
||||
/* Multiply P1P2 by v, store result in w. */
|
||||
static inline void
|
||||
_crt_mulP1P2_3(mpd_uint_t w[3], mpd_uint_t v)
|
||||
{
|
||||
mpd_uint_t hi1, hi2, lo;
|
||||
|
||||
_mpd_mul_words(&hi1, &lo, LH_P1P2, v);
|
||||
w[0] = lo;
|
||||
|
||||
_mpd_mul_words(&hi2, &lo, UH_P1P2, v);
|
||||
lo = hi1 + lo;
|
||||
if (lo < hi1) hi2++;
|
||||
|
||||
w[1] = lo;
|
||||
w[2] = hi2;
|
||||
}
|
||||
|
@ -65,15 +60,12 @@ _crt_add3(mpd_uint_t w[3], mpd_uint_t v[3])
|
|||
{
|
||||
mpd_uint_t carry;
|
||||
mpd_uint_t s;
|
||||
|
||||
s = w[0] + v[0];
|
||||
carry = (s < w[0]);
|
||||
w[0] = s;
|
||||
|
||||
s = w[1] + (v[1] + carry);
|
||||
carry = (s < w[1]);
|
||||
w[1] = s;
|
||||
|
||||
w[2] = w[2] + (v[2] + carry);
|
||||
}
|
||||
|
||||
|
@ -83,21 +75,17 @@ _crt_div3(mpd_uint_t *w, const mpd_uint_t *u, mpd_uint_t v)
|
|||
{
|
||||
mpd_uint_t r1 = u[2];
|
||||
mpd_uint_t r2;
|
||||
|
||||
if (r1 < v) {
|
||||
w[2] = 0;
|
||||
}
|
||||
else {
|
||||
_mpd_div_word(&w[2], &r1, u[2], v); /* GCOV_NOT_REACHED */
|
||||
}
|
||||
|
||||
_mpd_div_words(&w[1], &r2, r1, u[1], v);
|
||||
_mpd_div_words(&w[0], &r1, r2, u[0], v);
|
||||
|
||||
return r1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Chinese Remainder Theorem:
|
||||
* Algorithm from Joerg Arndt, "Matters Computational",
|
||||
|
@ -138,45 +126,32 @@ crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t rsize)
|
|||
{
|
||||
mpd_uint_t p1 = mpd_moduli[P1];
|
||||
mpd_uint_t umod;
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_uint_t a1, a2, a3;
|
||||
mpd_uint_t s;
|
||||
mpd_uint_t z[3], t[3];
|
||||
mpd_uint_t carry[3] = {0,0,0};
|
||||
mpd_uint_t hi, lo;
|
||||
mpd_size_t i;
|
||||
|
||||
for (i = 0; i < rsize; i++) {
|
||||
|
||||
a1 = x1[i];
|
||||
a2 = x2[i];
|
||||
a3 = x3[i];
|
||||
|
||||
SETMODULUS(P2);
|
||||
s = ext_submod(a2, a1, umod);
|
||||
s = MULMOD(s, INV_P1_MOD_P2);
|
||||
|
||||
_mpd_mul_words(&hi, &lo, s, p1);
|
||||
lo = lo + a1;
|
||||
if (lo < a1) hi++;
|
||||
|
||||
SETMODULUS(P3);
|
||||
s = dw_submod(a3, hi, lo, umod);
|
||||
s = MULMOD(s, INV_P1P2_MOD_P3);
|
||||
|
||||
z[0] = lo;
|
||||
z[1] = hi;
|
||||
z[2] = 0;
|
||||
|
||||
_crt_mulP1P2_3(t, s);
|
||||
_crt_add3(z, t);
|
||||
_crt_add3(carry, z);
|
||||
|
||||
x1[i] = _crt_div3(carry, carry, MPD_RADIX);
|
||||
}
|
||||
|
||||
assert(carry[0] == 0 && carry[1] == 0 && carry[2] == 0);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,8 @@
|
|||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
void crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t nmemb);
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,10 +39,8 @@ libmpdec (BSD-2)\\n\
|
|||
Copyright 2008-2016 Stefan Krah\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
|
||||
/* Bignum: The actual transform routine (decimation in frequency). */
|
||||
|
||||
|
||||
/*
|
||||
* Generate index pairs (x, bitreverse(x)) and carry out the permutation.
|
||||
* n must be a power of two.
|
||||
|
@ -55,7 +53,6 @@ bitreverse_permute(mpd_uint_t a[], mpd_size_t n)
|
|||
mpd_size_t x = 0;
|
||||
mpd_size_t r = 0;
|
||||
mpd_uint_t t;
|
||||
|
||||
do { /* Invariant: r = bitreverse(x) */
|
||||
if (r > x) {
|
||||
t = a[x];
|
||||
|
@ -72,105 +69,68 @@ bitreverse_permute(mpd_uint_t a[], mpd_size_t n)
|
|||
} while (x < n);
|
||||
}
|
||||
|
||||
|
||||
/* Fast Number Theoretic Transform, decimation in frequency. */
|
||||
void
|
||||
fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams)
|
||||
{
|
||||
mpd_uint_t *wtable = tparams->wtable;
|
||||
mpd_uint_t umod;
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_uint_t u0, u1, v0, v1;
|
||||
mpd_uint_t w, w0, w1, wstep;
|
||||
mpd_size_t m, mhalf;
|
||||
mpd_size_t j, r;
|
||||
|
||||
|
||||
assert(ispower2(n));
|
||||
assert(n >= 4);
|
||||
|
||||
SETMODULUS(tparams->modnum);
|
||||
|
||||
/* m == n */
|
||||
mhalf = n / 2;
|
||||
for (j = 0; j < mhalf; j += 2) {
|
||||
|
||||
w0 = wtable[j];
|
||||
w1 = wtable[j+1];
|
||||
|
||||
u0 = a[j];
|
||||
v0 = a[j+mhalf];
|
||||
|
||||
u1 = a[j+1];
|
||||
v1 = a[j+1+mhalf];
|
||||
|
||||
a[j] = addmod(u0, v0, umod);
|
||||
v0 = submod(u0, v0, umod);
|
||||
|
||||
a[j+1] = addmod(u1, v1, umod);
|
||||
v1 = submod(u1, v1, umod);
|
||||
|
||||
MULMOD2(&v0, w0, &v1, w1);
|
||||
|
||||
a[j+mhalf] = v0;
|
||||
a[j+1+mhalf] = v1;
|
||||
|
||||
}
|
||||
|
||||
wstep = 2;
|
||||
for (m = n/2; m >= 2; m>>=1, wstep<<=1) {
|
||||
|
||||
mhalf = m / 2;
|
||||
|
||||
/* j == 0 */
|
||||
for (r = 0; r < n; r += 2*m) {
|
||||
|
||||
u0 = a[r];
|
||||
v0 = a[r+mhalf];
|
||||
|
||||
u1 = a[m+r];
|
||||
v1 = a[m+r+mhalf];
|
||||
|
||||
a[r] = addmod(u0, v0, umod);
|
||||
v0 = submod(u0, v0, umod);
|
||||
|
||||
a[m+r] = addmod(u1, v1, umod);
|
||||
v1 = submod(u1, v1, umod);
|
||||
|
||||
a[r+mhalf] = v0;
|
||||
a[m+r+mhalf] = v1;
|
||||
}
|
||||
|
||||
for (j = 1; j < mhalf; j++) {
|
||||
|
||||
w = wtable[j*wstep];
|
||||
|
||||
for (r = 0; r < n; r += 2*m) {
|
||||
|
||||
u0 = a[r+j];
|
||||
v0 = a[r+j+mhalf];
|
||||
|
||||
u1 = a[m+r+j];
|
||||
v1 = a[m+r+j+mhalf];
|
||||
|
||||
a[r+j] = addmod(u0, v0, umod);
|
||||
v0 = submod(u0, v0, umod);
|
||||
|
||||
a[m+r+j] = addmod(u1, v1, umod);
|
||||
v1 = submod(u1, v1, umod);
|
||||
|
||||
MULMOD2C(&v0, &v1, w);
|
||||
|
||||
a[r+j+mhalf] = v0;
|
||||
a[m+r+j+mhalf] = v1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bitreverse_permute(a, n);
|
||||
}
|
||||
|
|
|
@ -2,13 +2,7 @@
|
|||
#define DIF_RADIX2_H
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/numbertheory.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
void fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams);
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
void fnt_dif2(mpd_uint_t[], mpd_size_t, struct fnt_params *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,25 +40,20 @@ libmpdec (BSD-2)\\n\
|
|||
Copyright 2008-2016 Stefan Krah\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
|
||||
/* Bignum: Fast transform for medium-sized coefficients. */
|
||||
|
||||
|
||||
/* forward transform, sign = -1 */
|
||||
int
|
||||
std_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
||||
{
|
||||
struct fnt_params *tparams;
|
||||
|
||||
assert(ispower2(n));
|
||||
assert(n >= 4);
|
||||
assert(n <= 3*MPD_MAXTRANSFORM_2N);
|
||||
|
||||
if ((tparams = _mpd_init_fnt_params(n, -1, modnum)) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
fnt_dif2(a, n, tparams);
|
||||
|
||||
mpd_free(tparams);
|
||||
return 1;
|
||||
}
|
||||
|
@ -68,16 +63,13 @@ int
|
|||
std_inv_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
||||
{
|
||||
struct fnt_params *tparams;
|
||||
|
||||
assert(ispower2(n));
|
||||
assert(n >= 4);
|
||||
assert(n <= 3*MPD_MAXTRANSFORM_2N);
|
||||
|
||||
if ((tparams = _mpd_init_fnt_params(n, 1, modnum)) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
fnt_dif2(a, n, tparams);
|
||||
|
||||
mpd_free(tparams);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
#ifndef FNT_H
|
||||
#define FNT_H
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
int std_fnt(mpd_uint_t a[], mpd_size_t n, int modnum);
|
||||
int std_inv_fnt(mpd_uint_t a[], mpd_size_t n, int modnum);
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
int std_fnt(mpd_uint_t[], mpd_size_t, int);
|
||||
int std_inv_fnt(mpd_uint_t[], mpd_size_t, int);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,12 +40,261 @@ libmpdec (BSD-2)\\n\
|
|||
Copyright 2008-2016 Stefan Krah\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
|
||||
/* Bignum: Cache efficient Matrix Fourier Transform for arrays of the
|
||||
form 3 * 2**n (See literature/matrix-transform.txt). */
|
||||
/*
|
||||
Cache Efficient Matrix Fourier Transform
|
||||
for arrays of form 3×2ⁿ
|
||||
|
||||
|
||||
#ifndef PPRO
|
||||
The Matrix Fourier Transform
|
||||
════════════════════════════
|
||||
|
||||
In libmpdec, the Matrix Fourier Transform [1] is called four-step
|
||||
transform after a variant that appears in [2]. The algorithm requires
|
||||
that the input array can be viewed as an R*C matrix.
|
||||
|
||||
All operations are done modulo p. For readability, the proofs drop all
|
||||
instances of (mod p).
|
||||
|
||||
|
||||
Algorithm four-step (forward transform)
|
||||
───────────────────────────────────────
|
||||
|
||||
a := input array
|
||||
d := len(a) = R * C
|
||||
p := prime
|
||||
w := primitive root of unity of the prime field
|
||||
r := w**((p-1)/d)
|
||||
A := output array
|
||||
|
||||
1) Apply a length R FNT to each column.
|
||||
|
||||
2) Multiply each matrix element (addressed by j*C+m) by r**(j*m).
|
||||
|
||||
3) Apply a length C FNT to each row.
|
||||
|
||||
4) Transpose the matrix.
|
||||
|
||||
|
||||
Proof (forward transform)
|
||||
─────────────────────────
|
||||
|
||||
The algorithm can be derived starting from the regular definition of
|
||||
the finite-field transform of length d:
|
||||
|
||||
d-1
|
||||
,────
|
||||
\
|
||||
A[k] = | a[l] × r**(k × l)
|
||||
/
|
||||
`────
|
||||
l = 0
|
||||
|
||||
|
||||
The sum can be rearranged into the sum of the sums of columns:
|
||||
|
||||
C-1 R-1
|
||||
,──── ,────
|
||||
\ \
|
||||
= | | a[i × C + j] × r**(k × (i × C + j))
|
||||
/ /
|
||||
`──── `────
|
||||
j = 0 i = 0
|
||||
|
||||
|
||||
Extracting a constant from the inner sum:
|
||||
|
||||
C-1 R-1
|
||||
,──── ,────
|
||||
\ \
|
||||
= | rᵏ×j × | a[i × C + j] × r**(k × i × C)
|
||||
/ /
|
||||
`──── `────
|
||||
j = 0 i = 0
|
||||
|
||||
|
||||
Without any loss of generality, let k = n × R + m,
|
||||
where n < C and m < R:
|
||||
|
||||
C-1 R-1
|
||||
,──── ,────
|
||||
\ \
|
||||
A[n×R+m] = | r**(R×n×j) × r**(m×j) × | a[i×C+j] × r**(R×C×n×i) × r**(C×m×i)
|
||||
/ /
|
||||
`──── `────
|
||||
j = 0 i = 0
|
||||
|
||||
|
||||
Since r = w ** ((p-1) / (R×C)):
|
||||
|
||||
a) r**(R×C×n×i) = w**((p-1)×n×i) = 1
|
||||
|
||||
b) r**(C×m×i) = w**((p-1) / R) ** (m×i) = r_R ** (m×i)
|
||||
|
||||
c) r**(R×n×j) = w**((p-1) / C) ** (n×j) = r_C ** (n×j)
|
||||
|
||||
r_R := root of the subfield of length R.
|
||||
r_C := root of the subfield of length C.
|
||||
|
||||
|
||||
C-1 R-1
|
||||
,──── ,────
|
||||
\ \
|
||||
A[n×R+m] = | r_C**(n×j) × [ r**(m×j) × | a[i×C+j] × r_R**(m×i) ]
|
||||
/ ^ /
|
||||
`──── | `──── 1) transform the columns
|
||||
j = 0 | i = 0
|
||||
^ |
|
||||
| `-- 2) multiply
|
||||
|
|
||||
`-- 3) transform the rows
|
||||
|
||||
|
||||
Note that the entire RHS is a function of n and m and that the results
|
||||
for each pair (n, m) are stored in Fortran order.
|
||||
|
||||
Let the term in square brackets be 𝑓(m, j). Step 1) and 2) precalculate
|
||||
the term for all (m, j). After that, the original matrix is now a lookup
|
||||
table with the mth element in the jth column at location m × C + j.
|
||||
|
||||
Let the complete RHS be g(m, n). Step 3) does an in-place transform of
|
||||
length n on all rows. After that, the original matrix is now a lookup
|
||||
table with the mth element in the nth column at location m × C + n.
|
||||
|
||||
But each (m, n) pair should be written to location n × R + m. Therefore,
|
||||
step 4) transposes the result of step 3).
|
||||
|
||||
|
||||
|
||||
Algorithm four-step (inverse transform)
|
||||
───────────────────────────────────────
|
||||
|
||||
A := input array
|
||||
d := len(A) = R × C
|
||||
p := prime
|
||||
d′ := d⁽ᵖ⁻²⁾ # inverse of d
|
||||
w := primitive root of unity of the prime field
|
||||
r := w**((p-1)/d) # root of the subfield
|
||||
r′ := w**((p-1) - (p-1)/d) # inverse of r
|
||||
a := output array
|
||||
|
||||
0) View the matrix as a C×R matrix.
|
||||
|
||||
1) Transpose the matrix, producing an R×C matrix.
|
||||
|
||||
2) Apply a length C FNT to each row.
|
||||
|
||||
3) Multiply each matrix element (addressed by i×C+n) by r**(i×n).
|
||||
|
||||
4) Apply a length R FNT to each column.
|
||||
|
||||
|
||||
Proof (inverse transform)
|
||||
─────────────────────────
|
||||
|
||||
The algorithm can be derived starting from the regular definition of
|
||||
the finite-field inverse transform of length d:
|
||||
|
||||
d-1
|
||||
,────
|
||||
\
|
||||
a[k] = d′ × | A[l] × r′ ** (k × l)
|
||||
/
|
||||
`────
|
||||
l = 0
|
||||
|
||||
|
||||
The sum can be rearranged into the sum of the sums of columns. Note
|
||||
that at this stage we still have a C*R matrix, so C denotes the number
|
||||
of rows:
|
||||
|
||||
R-1 C-1
|
||||
,──── ,────
|
||||
\ \
|
||||
= d′ × | | a[j × R + i] × r′ ** (k × (j × R + i))
|
||||
/ /
|
||||
`──── `────
|
||||
i = 0 j = 0
|
||||
|
||||
|
||||
Extracting a constant from the inner sum:
|
||||
|
||||
R-1 C-1
|
||||
,──── ,────
|
||||
\ \
|
||||
= d′ × | r′ ** (k×i) × | a[j × R + i] × r′ ** (k × j × R)
|
||||
/ /
|
||||
`──── `────
|
||||
i = 0 j = 0
|
||||
|
||||
|
||||
Without any loss of generality, let k = m * C + n,
|
||||
where m < R and n < C:
|
||||
|
||||
R-1 C-1
|
||||
,──── ,────
|
||||
\ \
|
||||
A[m×C+n] = d′ × | r′ ** (C×m×i) × r′ ** (n×i) × | a[j×R+i] × r′ ** (R×C×m×j) × r′ ** (R×n×j)
|
||||
/ /
|
||||
`──── `────
|
||||
i = 0 j = 0
|
||||
|
||||
|
||||
Since r′ = w**((p-1) - (p-1)/d) and d = R×C:
|
||||
|
||||
a) r′ ** (R×C×m×j) = w**((p-1)×R×C×m×j - (p-1)×m×j) = 1
|
||||
|
||||
b) r′ ** (C×m×i) = w**((p-1)×C - (p-1)/R) ** (m×i) = r_R′ ** (m×i)
|
||||
|
||||
c) r′ ** (R×n×j) = r_C′ ** (n×j)
|
||||
|
||||
d) d′ = d⁽ᵖ⁻²⁾ = (R×C)⁽ᵖ⁻²⁾ = R⁽ᵖ⁻²⁾ × C⁽ᵖ⁻²⁾ = R′ × C′
|
||||
|
||||
r_R′ := inverse of the root of the subfield of length R.
|
||||
r_C′ := inverse of the root of the subfield of length C.
|
||||
R′ := inverse of R
|
||||
C′ := inverse of C
|
||||
|
||||
|
||||
R-1 C-1
|
||||
,──── ,──── 2) transform the rows of a^T
|
||||
\ \
|
||||
A[m×C+n] = R′ × | r_R′ ** (m×i) × [ r′ ** (n×i) × C′ × | a[j×R+i] × r_C′ ** (n×j) ]
|
||||
/ ^ / ^
|
||||
`──── | `──── |
|
||||
i = 0 | j = 0 |
|
||||
^ | `── 1) Transpose input matrix
|
||||
| `── 3) multiply to address elements by
|
||||
| i × C + j
|
||||
`── 3) transform the columns
|
||||
|
||||
|
||||
|
||||
Note that the entire RHS is a function of m and n and that the results
|
||||
for each pair (m, n) are stored in C order.
|
||||
|
||||
Let the term in square brackets be 𝑓(n, i). Without step 1), the sum
|
||||
would perform a length C transform on the columns of the input matrix.
|
||||
This is a) inefficient and b) the results are needed in C order, so
|
||||
step 1) exchanges rows and columns.
|
||||
|
||||
Step 2) and 3) precalculate 𝑓(n, i) for all (n, i). After that, the
|
||||
original matrix is now a lookup table with the ith element in the nth
|
||||
column at location i × C + n.
|
||||
|
||||
Let the complete RHS be g(m, n). Step 4) does an in-place transform of
|
||||
length m on all columns. After that, the original matrix is now a lookup
|
||||
table with the mth element in the nth column at location m × C + n,
|
||||
which means that all A[k] = A[m × C + n] are in the correct order.
|
||||
|
||||
|
||||
──
|
||||
|
||||
[1] Joerg Arndt: "Matters Computational"
|
||||
http://www.jjj.de/fxt/
|
||||
[2] David H. Bailey: FFTs in External or Hierarchical Memory
|
||||
http://crd.lbl.gov/~dhbailey/dhbpapers/
|
||||
*/
|
||||
|
||||
static inline void
|
||||
std_size3_ntt(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3,
|
||||
mpd_uint_t w3table[3], mpd_uint_t umod)
|
||||
|
@ -53,90 +302,32 @@ std_size3_ntt(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3,
|
|||
mpd_uint_t r1, r2;
|
||||
mpd_uint_t w;
|
||||
mpd_uint_t s, tmp;
|
||||
|
||||
|
||||
/* k = 0 -> w = 1 */
|
||||
s = *x1;
|
||||
s = addmod(s, *x2, umod);
|
||||
s = addmod(s, *x3, umod);
|
||||
|
||||
r1 = s;
|
||||
|
||||
/* k = 1 */
|
||||
s = *x1;
|
||||
|
||||
w = w3table[1];
|
||||
tmp = MULMOD(*x2, w);
|
||||
s = addmod(s, tmp, umod);
|
||||
|
||||
w = w3table[2];
|
||||
tmp = MULMOD(*x3, w);
|
||||
s = addmod(s, tmp, umod);
|
||||
|
||||
r2 = s;
|
||||
|
||||
/* k = 2 */
|
||||
s = *x1;
|
||||
|
||||
w = w3table[2];
|
||||
tmp = MULMOD(*x2, w);
|
||||
s = addmod(s, tmp, umod);
|
||||
|
||||
w = w3table[1];
|
||||
tmp = MULMOD(*x3, w);
|
||||
s = addmod(s, tmp, umod);
|
||||
|
||||
*x3 = s;
|
||||
*x2 = r2;
|
||||
*x1 = r1;
|
||||
}
|
||||
#else /* PPRO */
|
||||
static inline void
|
||||
ppro_size3_ntt(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_uint_t w3table[3],
|
||||
mpd_uint_t umod, double *dmod, uint32_t dinvmod[3])
|
||||
{
|
||||
mpd_uint_t r1, r2;
|
||||
mpd_uint_t w;
|
||||
mpd_uint_t s, tmp;
|
||||
|
||||
|
||||
/* k = 0 -> w = 1 */
|
||||
s = *x1;
|
||||
s = addmod(s, *x2, umod);
|
||||
s = addmod(s, *x3, umod);
|
||||
|
||||
r1 = s;
|
||||
|
||||
/* k = 1 */
|
||||
s = *x1;
|
||||
|
||||
w = w3table[1];
|
||||
tmp = ppro_mulmod(*x2, w, dmod, dinvmod);
|
||||
s = addmod(s, tmp, umod);
|
||||
|
||||
w = w3table[2];
|
||||
tmp = ppro_mulmod(*x3, w, dmod, dinvmod);
|
||||
s = addmod(s, tmp, umod);
|
||||
|
||||
r2 = s;
|
||||
|
||||
/* k = 2 */
|
||||
s = *x1;
|
||||
|
||||
w = w3table[2];
|
||||
tmp = ppro_mulmod(*x2, w, dmod, dinvmod);
|
||||
s = addmod(s, tmp, umod);
|
||||
|
||||
w = w3table[1];
|
||||
tmp = ppro_mulmod(*x3, w, dmod, dinvmod);
|
||||
s = addmod(s, tmp, umod);
|
||||
|
||||
*x3 = s;
|
||||
*x2 = r2;
|
||||
*x1 = r1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* forward transform, sign = -1; transform length = 3 * 2**n */
|
||||
int
|
||||
|
@ -148,25 +339,15 @@ four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
mpd_uint_t kernel, w0, w1, wstep;
|
||||
mpd_uint_t *s, *p0, *p1, *p2;
|
||||
mpd_uint_t umod;
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_size_t i, k;
|
||||
|
||||
|
||||
assert(n >= 48);
|
||||
assert(n <= 3*MPD_MAXTRANSFORM_2N);
|
||||
|
||||
|
||||
/* Length R transform on the columns. */
|
||||
SETMODULUS(modnum);
|
||||
_mpd_init_w3table(w3table, -1, modnum);
|
||||
for (p0=a, p1=p0+C, p2=p0+2*C; p0<a+C; p0++,p1++,p2++) {
|
||||
|
||||
SIZE3_NTT(p0, p1, p2, w3table);
|
||||
}
|
||||
|
||||
/* Multiply each matrix element (addressed by i*C+k) by r**(i*k). */
|
||||
kernel = _mpd_getkernel(n, -1, modnum);
|
||||
for (i = 1; i < R; i++) {
|
||||
|
@ -182,20 +363,17 @@ four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
a[i*C+k+1] = x1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Length C transform on the rows. */
|
||||
for (s = a; s < a+n; s += C) {
|
||||
if (!six_step_fnt(s, C, modnum)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* An unordered transform is sufficient for convolution. */
|
||||
/* Transpose the matrix. */
|
||||
transpose_3xpow2(a, R, C);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -209,30 +387,20 @@ inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
mpd_uint_t kernel, w0, w1, wstep;
|
||||
mpd_uint_t *s, *p0, *p1, *p2;
|
||||
mpd_uint_t umod;
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_size_t i, k;
|
||||
|
||||
|
||||
assert(n >= 48);
|
||||
assert(n <= 3*MPD_MAXTRANSFORM_2N);
|
||||
|
||||
|
||||
#if 0
|
||||
/* An unordered transform is sufficient for convolution. */
|
||||
/* Transpose the matrix, producing an R*C matrix. */
|
||||
transpose_3xpow2(a, C, R);
|
||||
#endif
|
||||
|
||||
/* Length C transform on the rows. */
|
||||
for (s = a; s < a+n; s += C) {
|
||||
if (!inv_six_step_fnt(s, C, modnum)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply each matrix element (addressed by i*C+k) by r**(i*k). */
|
||||
SETMODULUS(modnum);
|
||||
kernel = _mpd_getkernel(n, 1, modnum);
|
||||
|
@ -249,13 +417,10 @@ inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
a[i*C+k+1] = x1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Length R transform on the columns. */
|
||||
_mpd_init_w3table(w3table, 1, modnum);
|
||||
for (p0=a, p1=p0+C, p2=p0+2*C; p0<a+C; p0++,p1++,p2++) {
|
||||
|
||||
SIZE3_NTT(p0, p1, p2, w3table);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
#ifndef FOUR_STEP_H
|
||||
#define FOUR_STEP_H
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
int four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
|
||||
int inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
int four_step_fnt(mpd_uint_t *, mpd_size_t, int);
|
||||
int inv_four_step_fnt(mpd_uint_t *, mpd_size_t, int);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -70,7 +70,6 @@ _mpd_strneq(const char *s, const char *l, const char *u, size_t n)
|
|||
}
|
||||
s++; u++; l++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -79,12 +78,10 @@ strtoexp(const char *s)
|
|||
{
|
||||
char *end;
|
||||
mpd_ssize_t retval;
|
||||
|
||||
errno = 0;
|
||||
retval = mpd_strtossize(s, &end, 10);
|
||||
if (errno == 0 && !(*s != '\0' && *end == '\0'))
|
||||
errno = EINVAL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -206,11 +203,9 @@ mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx,
|
|||
const char *dpoint = NULL, *exp = NULL;
|
||||
size_t digits;
|
||||
uint8_t sign = MPD_POS;
|
||||
|
||||
mpd_set_flags(dec, 0);
|
||||
dec->len = 0;
|
||||
dec->exp = 0;
|
||||
|
||||
/* sign */
|
||||
if (*s == '+') {
|
||||
s++;
|
||||
|
@ -220,7 +215,6 @@ mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx,
|
|||
sign = MPD_NEG;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (_mpd_strneq(s, "nan", "NAN", 3)) { /* NaN */
|
||||
s += 3;
|
||||
mpd_setspecial(dec, sign, MPD_NAN);
|
||||
|
@ -265,7 +259,6 @@ mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx,
|
|||
/* scan for start of coefficient, decimal point, indicator, end */
|
||||
if ((coeff = scan_dpoint_exp(s, &dpoint, &exp, &end)) == NULL)
|
||||
goto conversion_error;
|
||||
|
||||
/* numeric-value: [exponent-part] */
|
||||
if (exp) {
|
||||
/* exponent-part */
|
||||
|
@ -273,17 +266,15 @@ mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx,
|
|||
dec->exp = strtoexp(exp);
|
||||
if (errno) {
|
||||
if (!(errno == ERANGE &&
|
||||
(dec->exp == MPD_SSIZE_MAX ||
|
||||
dec->exp == MPD_SSIZE_MIN)))
|
||||
(dec->exp == MPD_SSIZE_MAX ||
|
||||
dec->exp == MPD_SSIZE_MIN)))
|
||||
goto conversion_error;
|
||||
}
|
||||
}
|
||||
|
||||
digits = end - coeff;
|
||||
digits = end - coeff;
|
||||
if (dpoint) {
|
||||
size_t fracdigits = end-dpoint-1;
|
||||
if (dpoint > coeff) digits--;
|
||||
|
||||
if (fracdigits > MPD_MAX_PREC) {
|
||||
goto conversion_error;
|
||||
}
|
||||
|
@ -304,9 +295,7 @@ mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx,
|
|||
dec->exp = MPD_SSIZE_MIN+1;
|
||||
}
|
||||
}
|
||||
|
||||
_mpd_idiv_word(&q, &r, (mpd_ssize_t)digits, MPD_RDIGITS);
|
||||
|
||||
len = (r == 0) ? q : q+1;
|
||||
if (len == 0) {
|
||||
goto conversion_error; /* GCOV_NOT_REACHED */
|
||||
|
@ -316,13 +305,10 @@ mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx,
|
|||
return;
|
||||
}
|
||||
dec->len = len;
|
||||
|
||||
string_to_coeff(dec->data, coeff, dpoint, (int)r, len);
|
||||
|
||||
mpd_setdigits(dec);
|
||||
mpd_qfinalize(dec, ctx, status);
|
||||
return;
|
||||
|
||||
conversion_error:
|
||||
/* standard wants a positive NaN */
|
||||
mpd_seterror(dec, MPD_Conversion_syntax, status);
|
||||
|
@ -336,7 +322,6 @@ static inline char *
|
|||
word_to_string(char *s, mpd_uint_t x, int n, char *dot)
|
||||
{
|
||||
switch(n) {
|
||||
#ifdef CONFIG_64
|
||||
case 20: EXTRACT_DIGIT(s, x, 10000000000000000000ULL, dot); /* GCOV_NOT_REACHED */
|
||||
case 19: EXTRACT_DIGIT(s, x, 1000000000000000000ULL, dot);
|
||||
case 18: EXTRACT_DIGIT(s, x, 100000000000000000ULL, dot);
|
||||
|
@ -347,7 +332,6 @@ word_to_string(char *s, mpd_uint_t x, int n, char *dot)
|
|||
case 13: EXTRACT_DIGIT(s, x, 1000000000000ULL, dot);
|
||||
case 12: EXTRACT_DIGIT(s, x, 100000000000ULL, dot);
|
||||
case 11: EXTRACT_DIGIT(s, x, 10000000000ULL, dot);
|
||||
#endif
|
||||
case 10: EXTRACT_DIGIT(s, x, 1000000000UL, dot);
|
||||
case 9: EXTRACT_DIGIT(s, x, 100000000UL, dot);
|
||||
case 8: EXTRACT_DIGIT(s, x, 10000000UL, dot);
|
||||
|
@ -359,7 +343,6 @@ word_to_string(char *s, mpd_uint_t x, int n, char *dot)
|
|||
case 2: EXTRACT_DIGIT(s, x, 10UL, dot);
|
||||
default: if (s == dot) *s++ = '.'; *s++ = '0' + (char)x;
|
||||
}
|
||||
|
||||
*s = '\0';
|
||||
return s;
|
||||
}
|
||||
|
@ -369,13 +352,11 @@ static inline char *
|
|||
exp_to_string(char *s, mpd_ssize_t x)
|
||||
{
|
||||
char sign = '+';
|
||||
|
||||
if (x < 0) {
|
||||
sign = '-';
|
||||
x = -x;
|
||||
}
|
||||
*s++ = sign;
|
||||
|
||||
return word_to_string(s, x, mpd_word_digits(x), NULL);
|
||||
}
|
||||
|
||||
|
@ -572,7 +553,6 @@ _mpd_to_string(char **result, const mpd_t *dec, int flags, mpd_ssize_t dplace)
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (mpd_isnegative(dec)) {
|
||||
*cp++ = '-';
|
||||
}
|
||||
|
@ -678,8 +658,6 @@ _mpd_copy_utf8(char dest[5], const char *s)
|
|||
const uchar *cp = (const uchar *)s;
|
||||
uchar lb, ub;
|
||||
int count, i;
|
||||
|
||||
|
||||
if (*cp == 0) {
|
||||
/* empty string */
|
||||
dest[0] = '\0';
|
||||
|
@ -727,7 +705,6 @@ _mpd_copy_utf8(char dest[5], const char *s)
|
|||
/* invalid */
|
||||
goto error;
|
||||
}
|
||||
|
||||
dest[0] = *cp++;
|
||||
if (*cp < lb || ub < *cp) {
|
||||
goto error;
|
||||
|
@ -740,9 +717,7 @@ _mpd_copy_utf8(char dest[5], const char *s)
|
|||
dest[i] = *cp++;
|
||||
}
|
||||
dest[i] = '\0';
|
||||
|
||||
return count;
|
||||
|
||||
error:
|
||||
dest[0] = '\0';
|
||||
return -1;
|
||||
|
@ -787,7 +762,6 @@ mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps)
|
|||
spec->sep = "";
|
||||
spec->grouping = "";
|
||||
|
||||
|
||||
/* presume that the first character is a UTF-8 fill character */
|
||||
if ((n = _mpd_copy_utf8(spec->fill, cp)) < 0) {
|
||||
return 0;
|
||||
|
@ -910,9 +884,8 @@ typedef struct {
|
|||
static inline void
|
||||
_mpd_bcopy(char *dest, const char *src, mpd_ssize_t n)
|
||||
{
|
||||
while (--n >= 0) {
|
||||
dest[n] = src[n];
|
||||
}
|
||||
/* [jart] just use memmove */
|
||||
memmove(dest, src, n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -921,7 +894,6 @@ _mbstr_copy_char(mpd_mbstr_t *dest, const char *src, mpd_ssize_t n)
|
|||
dest->nbytes += n;
|
||||
dest->nchars += (n > 0 ? 1 : 0);
|
||||
dest->cur -= n;
|
||||
|
||||
if (dest->data != NULL) {
|
||||
_mpd_bcopy(dest->data+dest->cur, src, n);
|
||||
}
|
||||
|
@ -933,7 +905,6 @@ _mbstr_copy_ascii(mpd_mbstr_t *dest, const char *src, mpd_ssize_t n)
|
|||
dest->nbytes += n;
|
||||
dest->nchars += n;
|
||||
dest->cur -= n;
|
||||
|
||||
if (dest->data != NULL) {
|
||||
_mpd_bcopy(dest->data+dest->cur, src, n);
|
||||
}
|
||||
|
@ -945,7 +916,6 @@ _mbstr_copy_pad(mpd_mbstr_t *dest, mpd_ssize_t n)
|
|||
dest->nbytes += n;
|
||||
dest->nchars += n;
|
||||
dest->cur -= n;
|
||||
|
||||
if (dest->data != NULL) {
|
||||
char *cp = dest->data + dest->cur;
|
||||
while (--n >= 0) {
|
||||
|
@ -1452,9 +1422,7 @@ mpd_snprint_flags(char *dest, int nmemb, uint32_t flags)
|
|||
{
|
||||
char *cp;
|
||||
int n, j;
|
||||
|
||||
assert(nmemb >= MPD_MAX_FLAG_STRING);
|
||||
|
||||
*dest = '\0'; cp = dest;
|
||||
for (j = 0; j < MPD_NUM_FLAGS; j++) {
|
||||
if (flags & (1U<<j)) {
|
||||
|
@ -1463,11 +1431,9 @@ mpd_snprint_flags(char *dest, int nmemb, uint32_t flags)
|
|||
cp += n; nmemb -= n;
|
||||
}
|
||||
}
|
||||
|
||||
if (cp != dest) {
|
||||
*(--cp) = '\0';
|
||||
}
|
||||
|
||||
return (int)(cp-dest);
|
||||
}
|
||||
|
||||
|
@ -1477,17 +1443,14 @@ mpd_lsnprint_flags(char *dest, int nmemb, uint32_t flags, const char *flag_strin
|
|||
{
|
||||
char *cp;
|
||||
int n, j;
|
||||
|
||||
assert(nmemb >= MPD_MAX_FLAG_LIST);
|
||||
if (flag_string == NULL) {
|
||||
flag_string = mpd_flag_string;
|
||||
}
|
||||
|
||||
*dest = '[';
|
||||
*(dest+1) = '\0';
|
||||
cp = dest+1;
|
||||
--nmemb;
|
||||
|
||||
for (j = 0; j < MPD_NUM_FLAGS; j++) {
|
||||
if (flags & (1U<<j)) {
|
||||
n = snprintf(cp, nmemb, "%s, ", flag_string[j]);
|
||||
|
@ -1495,15 +1458,12 @@ mpd_lsnprint_flags(char *dest, int nmemb, uint32_t flags, const char *flag_strin
|
|||
cp += n; nmemb -= n;
|
||||
}
|
||||
}
|
||||
|
||||
/* erase the last ", " */
|
||||
if (cp != dest+1) {
|
||||
cp -= 2;
|
||||
}
|
||||
|
||||
*cp++ = ']';
|
||||
*cp = '\0';
|
||||
|
||||
return (int)(cp-dest); /* strlen, without NUL terminator */
|
||||
}
|
||||
|
||||
|
@ -1514,17 +1474,14 @@ mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char *signal_s
|
|||
char *cp;
|
||||
int n, j;
|
||||
int ieee_invalid_done = 0;
|
||||
|
||||
assert(nmemb >= MPD_MAX_SIGNAL_LIST);
|
||||
if (signal_string == NULL) {
|
||||
signal_string = mpd_signal_string;
|
||||
}
|
||||
|
||||
*dest = '[';
|
||||
*(dest+1) = '\0';
|
||||
cp = dest+1;
|
||||
--nmemb;
|
||||
|
||||
for (j = 0; j < MPD_NUM_FLAGS; j++) {
|
||||
uint32_t f = flags & (1U<<j);
|
||||
if (f) {
|
||||
|
@ -1539,15 +1496,12 @@ mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char *signal_s
|
|||
cp += n; nmemb -= n;
|
||||
}
|
||||
}
|
||||
|
||||
/* erase the last ", " */
|
||||
if (cp != dest+1) {
|
||||
cp -= 2;
|
||||
}
|
||||
|
||||
*cp++ = ']';
|
||||
*cp = '\0';
|
||||
|
||||
return (int)(cp-dest); /* strlen, without NUL terminator */
|
||||
}
|
||||
|
||||
|
@ -1556,7 +1510,6 @@ void
|
|||
mpd_fprint(FILE *file, const mpd_t *dec)
|
||||
{
|
||||
char *decstring;
|
||||
|
||||
decstring = mpd_to_sci(dec, 1);
|
||||
if (decstring != NULL) {
|
||||
fprintf(file, "%s\n", decstring);
|
||||
|
@ -1571,7 +1524,6 @@ void
|
|||
mpd_print(const mpd_t *dec)
|
||||
{
|
||||
char *decstring;
|
||||
|
||||
decstring = mpd_to_sci(dec, 1);
|
||||
if (decstring != NULL) {
|
||||
printf("%s\n", decstring);
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
#ifndef MPALLOC_H
|
||||
#define MPALLOC_H
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status);
|
||||
int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status);
|
||||
int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status);
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
int mpd_switch_to_dyn(mpd_t *, mpd_ssize_t, uint32_t *);
|
||||
int mpd_switch_to_dyn_zero(mpd_t *, mpd_ssize_t, uint32_t *);
|
||||
int mpd_realloc_dyn(mpd_t *, mpd_ssize_t, uint32_t *);
|
||||
|
||||
#endif
|
||||
|
|
1170
third_party/python/Modules/_decimal/libmpdec/mpdecimal.c
vendored
1170
third_party/python/Modules/_decimal/libmpdec/mpdecimal.c
vendored
File diff suppressed because it is too large
Load diff
|
@ -5,85 +5,19 @@
|
|||
#include "libc/limits.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "third_party/python/pyconfig.h"
|
||||
COSMOPOLITAN_C_START_
|
||||
/* clang-format off */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#define MPD_CLEAR_STDC_LIMIT_MACROS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC_STDC_INLINE__
|
||||
#define __GNUC_STDC_INLINE__ 1
|
||||
#endif
|
||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
||||
#define UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define UNUSED
|
||||
#endif
|
||||
#if (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) && \
|
||||
defined(__GNUC__) && __GNUC__ >= 4 && !defined(__INTEL_COMPILER)
|
||||
#define MPD_PRAGMA(x) _Pragma(x)
|
||||
#define MPD_HIDE_SYMBOLS_START "GCC visibility push(hidden)"
|
||||
#define MPD_HIDE_SYMBOLS_END "GCC visibility pop"
|
||||
#else
|
||||
#define MPD_PRAGMA(x)
|
||||
#define MPD_HIDE_SYMBOLS_START
|
||||
#define MPD_HIDE_SYMBOLS_END
|
||||
#endif
|
||||
#define EXTINLINE
|
||||
|
||||
|
||||
/* This header file is internal for the purpose of building _decimal.so.
|
||||
* All symbols should have local scope in the DSO. */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
/******************************************************************************/
|
||||
/* Version */
|
||||
/******************************************************************************/
|
||||
|
||||
#define MPD_VERSION "2.4.2"
|
||||
#define MPD_MAJOR_VERSION 2
|
||||
#define MPD_MINOR_VERSION 4
|
||||
#define MPD_MICRO_VERSION 2
|
||||
|
||||
#define MPD_VERSION "2.4.2"
|
||||
|
||||
#define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \
|
||||
(MPD_MINOR_VERSION << 16) | \
|
||||
(MPD_MICRO_VERSION << 8))
|
||||
|
||||
const char *mpd_version(void);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Configuration */
|
||||
/******************************************************************************/
|
||||
|
||||
#if defined(CONFIG_64) || defined(CONFIG_32)
|
||||
#error "cannot use CONFIG_64 or CONFIG_32 with UNIVERSAL."
|
||||
#endif
|
||||
#if defined(__ppc__)
|
||||
#define CONFIG_32
|
||||
#define ANSI
|
||||
#elif defined(__ppc64__)
|
||||
#define CONFIG_64
|
||||
#define ANSI
|
||||
#elif defined(__i386__)
|
||||
#define CONFIG_32
|
||||
#define ANSI
|
||||
#elif defined(__x86_64__)
|
||||
#define CONFIG_64
|
||||
#define ASM
|
||||
#else
|
||||
#error "unknown architecture for universal build."
|
||||
#endif
|
||||
|
||||
|
||||
/* BEGIN CONFIG_64 */
|
||||
#if defined(CONFIG_64)
|
||||
/* types for modular and base arithmetic */
|
||||
#define MPD_UINT_MAX UINT64_MAX
|
||||
#define MPD_BITS_PER_UINT 64
|
||||
typedef uint64_t mpd_uint_t; /* unsigned mod type */
|
||||
|
@ -97,7 +31,6 @@ typedef size_t mpd_size_t; /* unsigned size type */
|
|||
typedef int64_t mpd_ssize_t;
|
||||
#define _mpd_strtossize strtoll
|
||||
|
||||
/* decimal arithmetic */
|
||||
#define MPD_RADIX 10000000000000000000ULL /* 10**19 */
|
||||
#define MPD_RDIGITS 19
|
||||
#define MPD_MAX_POW10 19
|
||||
|
@ -117,57 +50,6 @@ typedef int64_t mpd_ssize_t;
|
|||
/* conversion specifiers */
|
||||
#define PRI_mpd_uint_t PRIu64
|
||||
#define PRI_mpd_ssize_t PRIi64
|
||||
/* END CONFIG_64 */
|
||||
|
||||
|
||||
/* BEGIN CONFIG_32 */
|
||||
#elif defined(CONFIG_32)
|
||||
/* types for modular and base arithmetic */
|
||||
#define MPD_UINT_MAX UINT32_MAX
|
||||
#define MPD_BITS_PER_UINT 32
|
||||
typedef uint32_t mpd_uint_t; /* unsigned mod type */
|
||||
|
||||
#ifndef LEGACY_COMPILER
|
||||
#define MPD_UUINT_MAX UINT64_MAX
|
||||
typedef uint64_t mpd_uuint_t; /* double width unsigned mod type */
|
||||
#endif
|
||||
|
||||
#define MPD_SIZE_MAX SIZE_MAX
|
||||
typedef size_t mpd_size_t; /* unsigned size type */
|
||||
|
||||
/* type for dec->len, dec->exp, ctx->prec */
|
||||
#define MPD_SSIZE_MAX INT32_MAX
|
||||
#define MPD_SSIZE_MIN INT32_MIN
|
||||
typedef int32_t mpd_ssize_t;
|
||||
#define _mpd_strtossize strtol
|
||||
|
||||
/* decimal arithmetic */
|
||||
#define MPD_RADIX 1000000000UL /* 10**9 */
|
||||
#define MPD_RDIGITS 9
|
||||
#define MPD_MAX_POW10 9
|
||||
#define MPD_EXPDIGITS 10 /* MPD_EXPDIGITS <= MPD_RDIGITS+1 */
|
||||
|
||||
#define MPD_MAXTRANSFORM_2N 33554432UL /* 2**25 */
|
||||
#define MPD_MAX_PREC 425000000L
|
||||
#define MPD_MAX_PREC_LOG2 32
|
||||
#define MPD_ELIMIT 425000001L
|
||||
#define MPD_MAX_EMAX 425000000L /* ELIMIT-1 */
|
||||
#define MPD_MIN_EMIN (-425000000L) /* -EMAX */
|
||||
#define MPD_MIN_ETINY (MPD_MIN_EMIN-(MPD_MAX_PREC-1))
|
||||
#define MPD_EXP_INF 1000000001L /* allows for emax=999999999 in the tests */
|
||||
#define MPD_EXP_CLAMP (-2000000001L) /* allows for emin=-999999999 in the tests */
|
||||
#define MPD_MAXIMPORT 94444445L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */
|
||||
|
||||
/* conversion specifiers */
|
||||
#define PRI_mpd_uint_t PRIu32
|
||||
#define PRI_mpd_ssize_t PRIi32
|
||||
/* END CONFIG_32 */
|
||||
|
||||
#else
|
||||
#error "define CONFIG_64 or CONFIG_32"
|
||||
#endif
|
||||
/* END CONFIG */
|
||||
|
||||
|
||||
#if MPD_SIZE_MAX != MPD_UINT_MAX
|
||||
#error "unsupported platform: need mpd_size_t == mpd_uint_t"
|
||||
|
@ -256,39 +138,35 @@ typedef struct mpd_context_t {
|
|||
#define MPD_DECIMAL64 64
|
||||
#define MPD_DECIMAL128 128
|
||||
|
||||
|
||||
#define MPD_MINALLOC_MIN 2
|
||||
#define MPD_MINALLOC_MAX 64
|
||||
|
||||
extern mpd_ssize_t MPD_MINALLOC;
|
||||
extern void (* mpd_traphandler)(mpd_context_t *);
|
||||
void mpd_dflt_traphandler(mpd_context_t *);
|
||||
|
||||
void mpd_setminalloc(mpd_ssize_t n);
|
||||
void mpd_init(mpd_context_t *ctx, mpd_ssize_t prec);
|
||||
|
||||
void mpd_maxcontext(mpd_context_t *ctx);
|
||||
void mpd_defaultcontext(mpd_context_t *ctx);
|
||||
void mpd_basiccontext(mpd_context_t *ctx);
|
||||
int mpd_ieee_context(mpd_context_t *ctx, int bits);
|
||||
|
||||
mpd_ssize_t mpd_getprec(const mpd_context_t *ctx);
|
||||
mpd_ssize_t mpd_getemax(const mpd_context_t *ctx);
|
||||
mpd_ssize_t mpd_getemin(const mpd_context_t *ctx);
|
||||
int mpd_getround(const mpd_context_t *ctx);
|
||||
uint32_t mpd_gettraps(const mpd_context_t *ctx);
|
||||
uint32_t mpd_getstatus(const mpd_context_t *ctx);
|
||||
int mpd_getclamp(const mpd_context_t *ctx);
|
||||
int mpd_getcr(const mpd_context_t *ctx);
|
||||
|
||||
int mpd_qsetprec(mpd_context_t *ctx, mpd_ssize_t prec);
|
||||
int mpd_qsetemax(mpd_context_t *ctx, mpd_ssize_t emax);
|
||||
int mpd_qsetemin(mpd_context_t *ctx, mpd_ssize_t emin);
|
||||
int mpd_qsetround(mpd_context_t *ctx, int newround);
|
||||
int mpd_qsettraps(mpd_context_t *ctx, uint32_t flags);
|
||||
int mpd_qsetstatus(mpd_context_t *ctx, uint32_t flags);
|
||||
int mpd_qsetclamp(mpd_context_t *ctx, int c);
|
||||
int mpd_qsetcr(mpd_context_t *ctx, int c);
|
||||
void mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags);
|
||||
void mpd_setminalloc(mpd_ssize_t);
|
||||
void mpd_init(mpd_context_t *, mpd_ssize_t);
|
||||
void mpd_maxcontext(mpd_context_t *);
|
||||
void mpd_defaultcontext(mpd_context_t *);
|
||||
void mpd_basiccontext(mpd_context_t *);
|
||||
int mpd_ieee_context(mpd_context_t *, int);
|
||||
mpd_ssize_t mpd_getprec(const mpd_context_t *);
|
||||
mpd_ssize_t mpd_getemax(const mpd_context_t *);
|
||||
mpd_ssize_t mpd_getemin(const mpd_context_t *);
|
||||
int mpd_getround(const mpd_context_t *);
|
||||
uint32_t mpd_gettraps(const mpd_context_t *);
|
||||
uint32_t mpd_getstatus(const mpd_context_t *);
|
||||
int mpd_getclamp(const mpd_context_t *);
|
||||
int mpd_getcr(const mpd_context_t *);
|
||||
int mpd_qsetprec(mpd_context_t *, mpd_ssize_t);
|
||||
int mpd_qsetemax(mpd_context_t *, mpd_ssize_t);
|
||||
int mpd_qsetemin(mpd_context_t *, mpd_ssize_t);
|
||||
int mpd_qsetround(mpd_context_t *, int);
|
||||
int mpd_qsettraps(mpd_context_t *, uint32_t);
|
||||
int mpd_qsetstatus(mpd_context_t *, uint32_t);
|
||||
int mpd_qsetclamp(mpd_context_t *, int);
|
||||
int mpd_qsetcr(mpd_context_t *, int);
|
||||
void mpd_addstatus_raise(mpd_context_t *, uint32_t);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -308,7 +186,6 @@ void mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags);
|
|||
#define MPD_CONST_DATA ((uint8_t)128)
|
||||
#define MPD_DATAFLAGS (MPD_STATIC_DATA|MPD_SHARED_DATA|MPD_CONST_DATA)
|
||||
|
||||
/* mpd_t */
|
||||
typedef struct mpd_t {
|
||||
uint8_t flags;
|
||||
mpd_ssize_t exp;
|
||||
|
@ -318,7 +195,6 @@ typedef struct mpd_t {
|
|||
mpd_uint_t *data;
|
||||
} mpd_t;
|
||||
|
||||
|
||||
typedef unsigned char uchar;
|
||||
|
||||
|
||||
|
@ -340,388 +216,352 @@ typedef struct mpd_spec_t {
|
|||
} mpd_spec_t;
|
||||
|
||||
/* output to a string */
|
||||
char *mpd_to_sci(const mpd_t *dec, int fmt);
|
||||
char *mpd_to_eng(const mpd_t *dec, int fmt);
|
||||
mpd_ssize_t mpd_to_sci_size(char **res, const mpd_t *dec, int fmt);
|
||||
mpd_ssize_t mpd_to_eng_size(char **res, const mpd_t *dec, int fmt);
|
||||
int mpd_validate_lconv(mpd_spec_t *spec);
|
||||
int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps);
|
||||
char *mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status);
|
||||
char *mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, uint32_t *status);
|
||||
char *mpd_to_sci(const mpd_t *, int);
|
||||
char *mpd_to_eng(const mpd_t *, int);
|
||||
mpd_ssize_t mpd_to_sci_size(char **, const mpd_t *, int);
|
||||
mpd_ssize_t mpd_to_eng_size(char **, const mpd_t *, int);
|
||||
int mpd_validate_lconv(mpd_spec_t *);
|
||||
int mpd_parse_fmt_str(mpd_spec_t *, const char *, int);
|
||||
char *mpd_qformat_spec(const mpd_t *, const mpd_spec_t *, const mpd_context_t *, uint32_t *);
|
||||
char *mpd_qformat(const mpd_t *, const char *, const mpd_context_t *, uint32_t *);
|
||||
|
||||
#define MPD_NUM_FLAGS 15
|
||||
#define MPD_MAX_FLAG_STRING 208
|
||||
#define MPD_MAX_FLAG_LIST (MPD_MAX_FLAG_STRING+18)
|
||||
#define MPD_MAX_SIGNAL_LIST 121
|
||||
int mpd_snprint_flags(char *dest, int nmemb, uint32_t flags);
|
||||
int mpd_lsnprint_flags(char *dest, int nmemb, uint32_t flags, const char *flag_string[]);
|
||||
int mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char *signal_string[]);
|
||||
|
||||
int mpd_snprint_flags(char *, int, uint32_t);
|
||||
int mpd_lsnprint_flags(char *, int, uint32_t, const char *[]);
|
||||
int mpd_lsnprint_signals(char *, int, uint32_t, const char *[]);
|
||||
|
||||
/* output to a file */
|
||||
void mpd_fprint(FILE *file, const mpd_t *dec);
|
||||
void mpd_print(const mpd_t *dec);
|
||||
void mpd_fprint(FILE *, const mpd_t *);
|
||||
void mpd_print(const mpd_t *);
|
||||
|
||||
/* assignment from a string */
|
||||
void mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qset_string(mpd_t *, const char *s, const mpd_context_t *, uint32_t *);
|
||||
|
||||
/* set to NaN with error flags */
|
||||
void mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status);
|
||||
void mpd_seterror(mpd_t *, uint32_t, uint32_t *);
|
||||
/* set a special with sign and type */
|
||||
void mpd_setspecial(mpd_t *dec, uint8_t sign, uint8_t type);
|
||||
void mpd_setspecial(mpd_t *, uint8_t, uint8_t);
|
||||
/* set coefficient to zero or all nines */
|
||||
void mpd_zerocoeff(mpd_t *result);
|
||||
void mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_zerocoeff(mpd_t *);
|
||||
void mpd_qmaxcoeff(mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
|
||||
/* quietly assign a C integer type to an mpd_t */
|
||||
void mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
#ifndef LEGACY_COMPILER
|
||||
void mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
#endif
|
||||
void mpd_qset_ssize(mpd_t *, mpd_ssize_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qset_i32(mpd_t *, int32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qset_uint(mpd_t *, mpd_uint_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qset_u32(mpd_t *, uint32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qset_i64(mpd_t *, int64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qset_u64(mpd_t *, uint64_t, const mpd_context_t *, uint32_t *);
|
||||
|
||||
/* quietly assign a C integer type to an mpd_t with a static coefficient */
|
||||
void mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsset_ssize(mpd_t *, mpd_ssize_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsset_i32(mpd_t *, int32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsset_uint(mpd_t *, mpd_uint_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsset_u32(mpd_t *, uint32_t, const mpd_context_t *, uint32_t *);
|
||||
mpd_ssize_t mpd_qget_ssize(const mpd_t *, uint32_t *);
|
||||
mpd_uint_t mpd_qget_uint(const mpd_t *, uint32_t *);
|
||||
mpd_uint_t mpd_qabs_uint(const mpd_t *, uint32_t *);
|
||||
int32_t mpd_qget_i32(const mpd_t *, uint32_t *);
|
||||
uint32_t mpd_qget_u32(const mpd_t *, uint32_t *);
|
||||
int64_t mpd_qget_i64(const mpd_t *, uint32_t *);
|
||||
uint64_t mpd_qget_u64(const mpd_t *, uint32_t *);
|
||||
int mpd_qcheck_nan(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
int mpd_qcheck_nans(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qfinalize(mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
const char *mpd_class(const mpd_t *, const mpd_context_t *);
|
||||
mpd_t *mpd_qncopy(const mpd_t *);
|
||||
int mpd_qcopy(mpd_t *, const mpd_t *, uint32_t *);
|
||||
int mpd_qcopy_abs(mpd_t *, const mpd_t *, uint32_t *);
|
||||
int mpd_qcopy_negate(mpd_t *, const mpd_t *, uint32_t *);
|
||||
int mpd_qcopy_sign(mpd_t *, const mpd_t *, const mpd_t *, uint32_t *);
|
||||
void mpd_qand(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qinvert(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qlogb(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qor(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qscaleb(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qxor(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
int mpd_same_quantum(const mpd_t *, const mpd_t *);
|
||||
void mpd_qrotate(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
int mpd_qshiftl(mpd_t *, const mpd_t *, mpd_ssize_t, uint32_t *);
|
||||
mpd_uint_t mpd_qshiftr(mpd_t *, const mpd_t *, mpd_ssize_t, uint32_t *);
|
||||
mpd_uint_t mpd_qshiftr_inplace(mpd_t *, mpd_ssize_t);
|
||||
void mpd_qshift(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qshiftn(mpd_t *, const mpd_t *, mpd_ssize_t, const mpd_context_t *, uint32_t *);
|
||||
int mpd_qcmp(const mpd_t *, const mpd_t *, uint32_t *);
|
||||
int mpd_qcompare(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
int mpd_qcompare_signal(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
int mpd_cmp_total(const mpd_t *, const mpd_t *);
|
||||
int mpd_cmp_total_mag(const mpd_t *, const mpd_t *);
|
||||
int mpd_compare_total(mpd_t *, const mpd_t *, const mpd_t *);
|
||||
int mpd_compare_total_mag(mpd_t *, const mpd_t *, const mpd_t *);
|
||||
void mpd_qround_to_intx(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qround_to_int(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qtrunc(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qfloor(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qceil(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qabs(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmax(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmax_mag(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmin(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmin_mag(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qminus(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qplus(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qnext_minus(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qnext_plus(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qnext_toward(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qquantize(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qrescale(mpd_t *, const mpd_t *, mpd_ssize_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qrescale_fmt(mpd_t *, const mpd_t *, mpd_ssize_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qreduce(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qadd(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qadd_ssize(mpd_t *, const mpd_t *, mpd_ssize_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qadd_i32(mpd_t *, const mpd_t *, int32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qadd_uint(mpd_t *, const mpd_t *, mpd_uint_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qadd_u32(mpd_t *, const mpd_t *, uint32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsub(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsub_ssize(mpd_t *, const mpd_t *, mpd_ssize_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsub_i32(mpd_t *, const mpd_t *, int32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsub_uint(mpd_t *, const mpd_t *, mpd_uint_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsub_u32(mpd_t *, const mpd_t *, uint32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmul(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmul_ssize(mpd_t *, const mpd_t *, mpd_ssize_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmul_i32(mpd_t *, const mpd_t *, int32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmul_uint(mpd_t *, const mpd_t *, mpd_uint_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmul_u32(mpd_t *, const mpd_t *, uint32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qfma(mpd_t *, const mpd_t *, const mpd_t *, const mpd_t *c, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qdiv(mpd_t *q, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qdiv_ssize(mpd_t *, const mpd_t *, mpd_ssize_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qdiv_i32(mpd_t *, const mpd_t *, int32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qdiv_uint(mpd_t *, const mpd_t *, mpd_uint_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qdiv_u32(mpd_t *, const mpd_t *, uint32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qdivint(mpd_t *q, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qrem(mpd_t *r, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qrem_near(mpd_t *r, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qpow(mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qpowmod(mpd_t *, const mpd_t *, const mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qexp(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qln10(mpd_t *, mpd_ssize_t, uint32_t *);
|
||||
void mpd_qln(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qlog10(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsqrt(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qinvroot(mpd_t *, const mpd_t *, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qadd_i64(mpd_t *, const mpd_t *, int64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qadd_u64(mpd_t *, const mpd_t *, uint64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsub_i64(mpd_t *, const mpd_t *, int64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsub_u64(mpd_t *, const mpd_t *, uint64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmul_i64(mpd_t *, const mpd_t *, int64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qmul_u64(mpd_t *, const mpd_t *, uint64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qdiv_i64(mpd_t *, const mpd_t *, int64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qdiv_u64(mpd_t *, const mpd_t *, uint64_t, const mpd_context_t *, uint32_t *);
|
||||
|
||||
/* quietly get a C integer type from an mpd_t */
|
||||
mpd_ssize_t mpd_qget_ssize(const mpd_t *dec, uint32_t *status);
|
||||
mpd_uint_t mpd_qget_uint(const mpd_t *dec, uint32_t *status);
|
||||
mpd_uint_t mpd_qabs_uint(const mpd_t *dec, uint32_t *status);
|
||||
|
||||
int32_t mpd_qget_i32(const mpd_t *dec, uint32_t *status);
|
||||
uint32_t mpd_qget_u32(const mpd_t *dec, uint32_t *status);
|
||||
#ifndef LEGACY_COMPILER
|
||||
int64_t mpd_qget_i64(const mpd_t *dec, uint32_t *status);
|
||||
uint64_t mpd_qget_u64(const mpd_t *dec, uint32_t *status);
|
||||
#endif
|
||||
|
||||
/* quiet functions */
|
||||
int mpd_qcheck_nan(mpd_t *nanresult, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
int mpd_qcheck_nans(mpd_t *nanresult, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status);
|
||||
|
||||
const char *mpd_class(const mpd_t *a, const mpd_context_t *ctx);
|
||||
|
||||
int mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status);
|
||||
mpd_t *mpd_qncopy(const mpd_t *a);
|
||||
int mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status);
|
||||
int mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status);
|
||||
int mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status);
|
||||
|
||||
void mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
int mpd_same_quantum(const mpd_t *a, const mpd_t *b);
|
||||
|
||||
void mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
int mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status);
|
||||
mpd_uint_t mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status);
|
||||
mpd_uint_t mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n);
|
||||
void mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, const mpd_context_t *ctx, uint32_t *status);
|
||||
|
||||
int mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status);
|
||||
int mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
int mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
int mpd_cmp_total(const mpd_t *a, const mpd_t *b);
|
||||
int mpd_cmp_total_mag(const mpd_t *a, const mpd_t *b);
|
||||
int mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b);
|
||||
int mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b);
|
||||
|
||||
void mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
|
||||
void mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qrescale_fmt(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qadd_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qadd_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qadd_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qadd_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmul_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmul_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qdiv_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qdiv_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qdiv_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qdiv_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status);
|
||||
void mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
|
||||
|
||||
#ifndef LEGACY_COMPILER
|
||||
void mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
|
||||
#endif
|
||||
|
||||
|
||||
size_t mpd_sizeinbase(const mpd_t *a, uint32_t base);
|
||||
void mpd_qimport_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen,
|
||||
uint8_t srcsign, uint32_t srcbase,
|
||||
const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qimport_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen,
|
||||
uint8_t srcsign, uint32_t srcbase,
|
||||
const mpd_context_t *ctx, uint32_t *status);
|
||||
size_t mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t base,
|
||||
const mpd_t *src, uint32_t *status);
|
||||
size_t mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t base,
|
||||
const mpd_t *src, uint32_t *status);
|
||||
size_t mpd_sizeinbase(const mpd_t *, uint32_t);
|
||||
void mpd_qimport_u16(mpd_t *, const uint16_t *, size_t, uint8_t, uint32_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qimport_u32(mpd_t *, const uint32_t *, size_t, uint8_t, uint32_t, const mpd_context_t *, uint32_t *);
|
||||
size_t mpd_qexport_u16(uint16_t **, size_t, uint32_t, const mpd_t *, uint32_t *);
|
||||
size_t mpd_qexport_u32(uint32_t **, size_t, uint32_t, const mpd_t *, uint32_t *);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Signalling functions */
|
||||
/******************************************************************************/
|
||||
|
||||
char *mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx);
|
||||
void mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
|
||||
void mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
|
||||
size_t mpd_export_u16(uint16_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
|
||||
size_t mpd_export_u32(uint32_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
|
||||
void mpd_finalize(mpd_t *result, mpd_context_t *ctx);
|
||||
int mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
int mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx);
|
||||
void mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx);
|
||||
void mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
|
||||
void mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
|
||||
void mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
|
||||
void mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
|
||||
void mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
|
||||
void mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
|
||||
void mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
|
||||
void mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
|
||||
#ifndef LEGACY_COMPILER
|
||||
void mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
|
||||
void mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
|
||||
#endif
|
||||
mpd_ssize_t mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx);
|
||||
mpd_uint_t mpd_get_uint(const mpd_t *a, mpd_context_t *ctx);
|
||||
mpd_uint_t mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx);
|
||||
int32_t mpd_get_i32(const mpd_t *a, mpd_context_t *ctx);
|
||||
uint32_t mpd_get_u32(const mpd_t *a, mpd_context_t *ctx);
|
||||
#ifndef LEGACY_COMPILER
|
||||
int64_t mpd_get_i64(const mpd_t *a, mpd_context_t *ctx);
|
||||
uint64_t mpd_get_u64(const mpd_t *a, mpd_context_t *ctx);
|
||||
#endif
|
||||
void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
|
||||
mpd_uint_t mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
|
||||
void mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
|
||||
void mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
int mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
int mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
int mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
|
||||
void mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
|
||||
void mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
|
||||
void mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
|
||||
void mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
|
||||
void mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
|
||||
void mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
|
||||
void mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
|
||||
void mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
|
||||
void mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
|
||||
void mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
|
||||
void mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
|
||||
void mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, mpd_context_t *ctx);
|
||||
void mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
|
||||
void mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
|
||||
void mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
|
||||
void mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
|
||||
void mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx);
|
||||
void mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, mpd_context_t *ctx);
|
||||
void mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx);
|
||||
void mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
|
||||
void mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
void mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
|
||||
|
||||
#ifndef LEGACY_COMPILER
|
||||
void mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
|
||||
void mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
|
||||
void mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
|
||||
void mpd_sub_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
|
||||
void mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
|
||||
void mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
|
||||
void mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
|
||||
void mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
|
||||
#endif
|
||||
char *mpd_format(const mpd_t *, const char *, mpd_context_t *);
|
||||
void mpd_import_u16(mpd_t *, const uint16_t *, size_t, uint8_t, uint32_t, mpd_context_t *);
|
||||
void mpd_import_u32(mpd_t *, const uint32_t *, size_t, uint8_t, uint32_t, mpd_context_t *);
|
||||
size_t mpd_export_u16(uint16_t **, size_t, uint32_t, const mpd_t *, mpd_context_t *);
|
||||
size_t mpd_export_u32(uint32_t **, size_t, uint32_t, const mpd_t *, mpd_context_t *);
|
||||
void mpd_finalize(mpd_t *, mpd_context_t *);
|
||||
int mpd_check_nan(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
int mpd_check_nans(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_set_string(mpd_t *, const char *s, mpd_context_t *);
|
||||
void mpd_maxcoeff(mpd_t *, mpd_context_t *);
|
||||
void mpd_sset_ssize(mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
void mpd_sset_i32(mpd_t *, int32_t, mpd_context_t *);
|
||||
void mpd_sset_uint(mpd_t *, mpd_uint_t, mpd_context_t *);
|
||||
void mpd_sset_u32(mpd_t *, uint32_t, mpd_context_t *);
|
||||
void mpd_set_ssize(mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
void mpd_set_i32(mpd_t *, int32_t, mpd_context_t *);
|
||||
void mpd_set_uint(mpd_t *, mpd_uint_t, mpd_context_t *);
|
||||
void mpd_set_u32(mpd_t *, uint32_t, mpd_context_t *);
|
||||
void mpd_set_i64(mpd_t *, int64_t, mpd_context_t *);
|
||||
void mpd_set_u64(mpd_t *, uint64_t, mpd_context_t *);
|
||||
mpd_ssize_t mpd_get_ssize(const mpd_t *, mpd_context_t *);
|
||||
mpd_uint_t mpd_get_uint(const mpd_t *, mpd_context_t *);
|
||||
mpd_uint_t mpd_abs_uint(const mpd_t *, mpd_context_t *);
|
||||
int32_t mpd_get_i32(const mpd_t *, mpd_context_t *);
|
||||
uint32_t mpd_get_u32(const mpd_t *, mpd_context_t *);
|
||||
int64_t mpd_get_i64(const mpd_t *, mpd_context_t *);
|
||||
uint64_t mpd_get_u64(const mpd_t *, mpd_context_t *);
|
||||
void mpd_and(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_copy(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_canonical(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_copy_abs(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_copy_negate(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_copy_sign(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_invert(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_logb(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_or(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_rotate(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_scaleb(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_shiftl(mpd_t *, const mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
mpd_uint_t mpd_shiftr(mpd_t *, const mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
void mpd_shiftn(mpd_t *, const mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
void mpd_shift(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_xor(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_abs(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
int mpd_cmp(const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
int mpd_compare(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
int mpd_compare_signal(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_add(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_add_ssize(mpd_t *, const mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
void mpd_add_i32(mpd_t *, const mpd_t *, int32_t, mpd_context_t *);
|
||||
void mpd_add_uint(mpd_t *, const mpd_t *, mpd_uint_t, mpd_context_t *);
|
||||
void mpd_add_u32(mpd_t *, const mpd_t *, uint32_t, mpd_context_t *);
|
||||
void mpd_sub(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_sub_ssize(mpd_t *, const mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
void mpd_sub_i32(mpd_t *, const mpd_t *, int32_t, mpd_context_t *);
|
||||
void mpd_sub_uint(mpd_t *, const mpd_t *, mpd_uint_t, mpd_context_t *);
|
||||
void mpd_sub_u32(mpd_t *, const mpd_t *, uint32_t, mpd_context_t *);
|
||||
void mpd_div(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_div_ssize(mpd_t *, const mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
void mpd_div_i32(mpd_t *, const mpd_t *, int32_t, mpd_context_t *);
|
||||
void mpd_div_uint(mpd_t *, const mpd_t *, mpd_uint_t, mpd_context_t *);
|
||||
void mpd_div_u32(mpd_t *, const mpd_t *, uint32_t, mpd_context_t *);
|
||||
void mpd_divmod(mpd_t *, mpd_t *r, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_divint(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_exp(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_fma(mpd_t *, const mpd_t *, const mpd_t *, const mpd_t *c, mpd_context_t *);
|
||||
void mpd_ln(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_log10(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_max(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_max_mag(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_min(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_min_mag(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_minus(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_mul(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_mul_ssize(mpd_t *, const mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
void mpd_mul_i32(mpd_t *, const mpd_t *, int32_t, mpd_context_t *);
|
||||
void mpd_mul_uint(mpd_t *, const mpd_t *, mpd_uint_t, mpd_context_t *);
|
||||
void mpd_mul_u32(mpd_t *, const mpd_t *, uint32_t, mpd_context_t *);
|
||||
void mpd_next_minus(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_next_plus(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_next_toward(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_plus(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_pow(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_powmod(mpd_t *, const mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_quantize(mpd_t *, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_rescale(mpd_t *, const mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
void mpd_reduce(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_rem(mpd_t *r, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_rem_near(mpd_t *r, const mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_round_to_intx(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_round_to_int(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_trunc(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_floor(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_ceil(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_sqrt(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_invroot(mpd_t *, const mpd_t *, mpd_context_t *);
|
||||
void mpd_add_i64(mpd_t *, const mpd_t *, int64_t, mpd_context_t *);
|
||||
void mpd_add_u64(mpd_t *, const mpd_t *, uint64_t, mpd_context_t *);
|
||||
void mpd_sub_i64(mpd_t *, const mpd_t *, int64_t, mpd_context_t *);
|
||||
void mpd_sub_u64(mpd_t *, const mpd_t *, uint64_t, mpd_context_t *);
|
||||
void mpd_div_i64(mpd_t *, const mpd_t *, int64_t, mpd_context_t *);
|
||||
void mpd_div_u64(mpd_t *, const mpd_t *, uint64_t, mpd_context_t *);
|
||||
void mpd_mul_i64(mpd_t *, const mpd_t *, int64_t, mpd_context_t *);
|
||||
void mpd_mul_u64(mpd_t *, const mpd_t *, uint64_t, mpd_context_t *);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Configuration specific */
|
||||
/******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_64
|
||||
void mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status);
|
||||
void mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
|
||||
void mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
|
||||
#endif
|
||||
void mpd_qsset_i64(mpd_t *, int64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_qsset_u64(mpd_t *, uint64_t, const mpd_context_t *, uint32_t *);
|
||||
void mpd_sset_i64(mpd_t *, int64_t, mpd_context_t *);
|
||||
void mpd_sset_u64(mpd_t *, uint64_t, mpd_context_t *);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Get attributes of a decimal */
|
||||
/******************************************************************************/
|
||||
|
||||
EXTINLINE mpd_ssize_t mpd_adjexp(const mpd_t *dec);
|
||||
EXTINLINE mpd_ssize_t mpd_etiny(const mpd_context_t *ctx);
|
||||
EXTINLINE mpd_ssize_t mpd_etop(const mpd_context_t *ctx);
|
||||
EXTINLINE mpd_uint_t mpd_msword(const mpd_t *dec);
|
||||
EXTINLINE int mpd_word_digits(mpd_uint_t word);
|
||||
mpd_ssize_t mpd_adjexp(const mpd_t *);
|
||||
mpd_ssize_t mpd_etiny(const mpd_context_t *);
|
||||
mpd_ssize_t mpd_etop(const mpd_context_t *);
|
||||
mpd_uint_t mpd_msword(const mpd_t *);
|
||||
int mpd_word_digits(mpd_uint_t);
|
||||
/* most significant digit of a word */
|
||||
EXTINLINE mpd_uint_t mpd_msd(mpd_uint_t word);
|
||||
mpd_uint_t mpd_msd(mpd_uint_t);
|
||||
/* least significant digit of a word */
|
||||
EXTINLINE mpd_uint_t mpd_lsd(mpd_uint_t word);
|
||||
mpd_uint_t mpd_lsd(mpd_uint_t);
|
||||
/* coefficient size needed to store 'digits' */
|
||||
EXTINLINE mpd_ssize_t mpd_digits_to_size(mpd_ssize_t digits);
|
||||
mpd_ssize_t mpd_digits_to_size(mpd_ssize_t);
|
||||
/* number of digits in the exponent, undefined for MPD_SSIZE_MIN */
|
||||
EXTINLINE int mpd_exp_digits(mpd_ssize_t exp);
|
||||
EXTINLINE int mpd_iscanonical(const mpd_t *dec UNUSED);
|
||||
EXTINLINE int mpd_isfinite(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isinfinite(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isinteger(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isnan(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isnegative(const mpd_t *dec);
|
||||
EXTINLINE int mpd_ispositive(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isqnan(const mpd_t *dec);
|
||||
EXTINLINE int mpd_issigned(const mpd_t *dec);
|
||||
EXTINLINE int mpd_issnan(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isspecial(const mpd_t *dec);
|
||||
EXTINLINE int mpd_iszero(const mpd_t *dec);
|
||||
int mpd_exp_digits(mpd_ssize_t);
|
||||
int mpd_iscanonical(const mpd_t *);
|
||||
int mpd_isfinite(const mpd_t *);
|
||||
int mpd_isinfinite(const mpd_t *);
|
||||
int mpd_isinteger(const mpd_t *);
|
||||
int mpd_isnan(const mpd_t *);
|
||||
int mpd_isnegative(const mpd_t *);
|
||||
int mpd_ispositive(const mpd_t *);
|
||||
int mpd_isqnan(const mpd_t *);
|
||||
int mpd_issigned(const mpd_t *);
|
||||
int mpd_issnan(const mpd_t *);
|
||||
int mpd_isspecial(const mpd_t *);
|
||||
int mpd_iszero(const mpd_t *);
|
||||
/* undefined for special numbers */
|
||||
EXTINLINE int mpd_iszerocoeff(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx);
|
||||
EXTINLINE int mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx);
|
||||
int mpd_iszerocoeff(const mpd_t *);
|
||||
int mpd_isnormal(const mpd_t *, const mpd_context_t *);
|
||||
int mpd_issubnormal(const mpd_t *, const mpd_context_t *);
|
||||
/* odd word */
|
||||
EXTINLINE int mpd_isoddword(mpd_uint_t word);
|
||||
int mpd_isoddword(mpd_uint_t);
|
||||
/* odd coefficient */
|
||||
EXTINLINE int mpd_isoddcoeff(const mpd_t *dec);
|
||||
int mpd_isoddcoeff(const mpd_t *);
|
||||
/* odd decimal, only defined for integers */
|
||||
int mpd_isodd(const mpd_t *dec);
|
||||
int mpd_isodd(const mpd_t *);
|
||||
/* even decimal, only defined for integers */
|
||||
int mpd_iseven(const mpd_t *dec);
|
||||
int mpd_iseven(const mpd_t *);
|
||||
/* 0 if dec is positive, 1 if dec is negative */
|
||||
EXTINLINE uint8_t mpd_sign(const mpd_t *dec);
|
||||
uint8_t mpd_sign(const mpd_t *);
|
||||
/* 1 if dec is positive, -1 if dec is negative */
|
||||
EXTINLINE int mpd_arith_sign(const mpd_t *dec);
|
||||
EXTINLINE long mpd_radix(void);
|
||||
EXTINLINE int mpd_isdynamic(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isstatic(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isdynamic_data(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isstatic_data(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isshared_data(const mpd_t *dec);
|
||||
EXTINLINE int mpd_isconst_data(const mpd_t *dec);
|
||||
EXTINLINE mpd_ssize_t mpd_trail_zeros(const mpd_t *dec);
|
||||
int mpd_arith_sign(const mpd_t *);
|
||||
long mpd_radix(void);
|
||||
int mpd_isdynamic(const mpd_t *);
|
||||
int mpd_isstatic(const mpd_t *);
|
||||
int mpd_isdynamic_data(const mpd_t *);
|
||||
int mpd_isstatic_data(const mpd_t *);
|
||||
int mpd_isshared_data(const mpd_t *);
|
||||
int mpd_isconst_data(const mpd_t *);
|
||||
mpd_ssize_t mpd_trail_zeros(const mpd_t *);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Set attributes of a decimal */
|
||||
/******************************************************************************/
|
||||
|
||||
/* set number of decimal digits in the coefficient */
|
||||
EXTINLINE void mpd_setdigits(mpd_t *result);
|
||||
EXTINLINE void mpd_set_sign(mpd_t *result, uint8_t sign);
|
||||
/* copy sign from another decimal */
|
||||
EXTINLINE void mpd_signcpy(mpd_t *result, const mpd_t *a);
|
||||
EXTINLINE void mpd_set_infinity(mpd_t *result);
|
||||
EXTINLINE void mpd_set_qnan(mpd_t *result);
|
||||
EXTINLINE void mpd_set_snan(mpd_t *result);
|
||||
EXTINLINE void mpd_set_negative(mpd_t *result);
|
||||
EXTINLINE void mpd_set_positive(mpd_t *result);
|
||||
EXTINLINE void mpd_set_dynamic(mpd_t *result);
|
||||
EXTINLINE void mpd_set_static(mpd_t *result);
|
||||
EXTINLINE void mpd_set_dynamic_data(mpd_t *result);
|
||||
EXTINLINE void mpd_set_static_data(mpd_t *result);
|
||||
EXTINLINE void mpd_set_shared_data(mpd_t *result);
|
||||
EXTINLINE void mpd_set_const_data(mpd_t *result);
|
||||
EXTINLINE void mpd_clear_flags(mpd_t *result);
|
||||
EXTINLINE void mpd_set_flags(mpd_t *result, uint8_t flags);
|
||||
EXTINLINE void mpd_copy_flags(mpd_t *result, const mpd_t *a);
|
||||
void mpd_setdigits(mpd_t *);
|
||||
void mpd_set_sign(mpd_t *, uint8_t);
|
||||
void mpd_signcpy(mpd_t *, const mpd_t *);
|
||||
void mpd_set_infinity(mpd_t *);
|
||||
void mpd_set_qnan(mpd_t *);
|
||||
void mpd_set_snan(mpd_t *);
|
||||
void mpd_set_negative(mpd_t *);
|
||||
void mpd_set_positive(mpd_t *);
|
||||
void mpd_set_dynamic(mpd_t *);
|
||||
void mpd_set_static(mpd_t *);
|
||||
void mpd_set_dynamic_data(mpd_t *);
|
||||
void mpd_set_static_data(mpd_t *);
|
||||
void mpd_set_shared_data(mpd_t *);
|
||||
void mpd_set_const_data(mpd_t *);
|
||||
void mpd_clear_flags(mpd_t *);
|
||||
void mpd_set_flags(mpd_t *, uint8_t);
|
||||
void mpd_copy_flags(mpd_t *, const mpd_t *);
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -743,45 +583,30 @@ EXTINLINE void mpd_copy_flags(mpd_t *result, const mpd_t *a);
|
|||
/* Memory handling */
|
||||
/******************************************************************************/
|
||||
|
||||
extern void *(* mpd_mallocfunc)(size_t size);
|
||||
extern void *(* mpd_callocfunc)(size_t nmemb, size_t size);
|
||||
extern void *(* mpd_reallocfunc)(void *ptr, size_t size);
|
||||
extern void (* mpd_free)(void *ptr);
|
||||
extern void *(*mpd_mallocfunc)(size_t);
|
||||
extern void *(*mpd_callocfunc)(size_t, size_t);
|
||||
extern void *(*mpd_reallocfunc)(void *, size_t);
|
||||
extern void (*mpd_free)(void *);
|
||||
|
||||
void *mpd_callocfunc_em(size_t nmemb, size_t size);
|
||||
void *mpd_callocfunc_em(size_t, size_t);
|
||||
|
||||
void *mpd_alloc(mpd_size_t nmemb, mpd_size_t size);
|
||||
void *mpd_calloc(mpd_size_t nmemb, mpd_size_t size);
|
||||
void *mpd_realloc(void *ptr, mpd_size_t nmemb, mpd_size_t size, uint8_t *err);
|
||||
void *mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size);
|
||||
void *mpd_alloc(mpd_size_t, mpd_size_t);
|
||||
void *mpd_calloc(mpd_size_t, mpd_size_t);
|
||||
void *mpd_realloc(void *, mpd_size_t, mpd_size_t, uint8_t *);
|
||||
void *mpd_sh_alloc(mpd_size_t, mpd_size_t, mpd_size_t);
|
||||
|
||||
mpd_t *mpd_qnew(void);
|
||||
mpd_t *mpd_new(mpd_context_t *ctx);
|
||||
mpd_t *mpd_qnew_size(mpd_ssize_t size);
|
||||
EXTINLINE void mpd_del(mpd_t *dec);
|
||||
mpd_t *mpd_new(mpd_context_t *);
|
||||
mpd_t *mpd_qnew_size(mpd_ssize_t);
|
||||
void mpd_del(mpd_t *);
|
||||
|
||||
EXTINLINE void mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len);
|
||||
EXTINLINE int mpd_qresize(mpd_t *result, mpd_ssize_t size, uint32_t *status);
|
||||
EXTINLINE int mpd_qresize_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status);
|
||||
EXTINLINE void mpd_minalloc(mpd_t *result);
|
||||
|
||||
int mpd_resize(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx);
|
||||
int mpd_resize_zero(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx);
|
||||
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef MPD_CLEAR_STDC_LIMIT_MACROS
|
||||
#undef MPD_CLEAR_STDC_LIMIT_MACROS
|
||||
#undef __STDC_LIMIT_MACROS
|
||||
#endif
|
||||
} /* END extern "C" */
|
||||
#endif
|
||||
void mpd_uint_zero(mpd_uint_t *, mpd_size_t);
|
||||
int mpd_qresize(mpd_t *, mpd_ssize_t, uint32_t *);
|
||||
int mpd_qresize_zero(mpd_t *, mpd_ssize_t, uint32_t *);
|
||||
void mpd_minalloc(mpd_t *);
|
||||
|
||||
int mpd_resize(mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
int mpd_resize_zero(mpd_t *, mpd_ssize_t, mpd_context_t *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* MPDECIMAL_H */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -38,10 +38,8 @@ libmpdec (BSD-2)\\n\
|
|||
Copyright 2008-2016 Stefan Krah\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
|
||||
/* Bignum: Initialize the Number Theoretic Transform. */
|
||||
|
||||
|
||||
/*
|
||||
* Return the nth root of unity in F(p). This corresponds to e**((2*pi*i)/n)
|
||||
* in the Fourier transform. We have w**n == 1 (mod p).
|
||||
|
@ -53,16 +51,10 @@ mpd_uint_t
|
|||
_mpd_getkernel(mpd_uint_t n, int sign, int modnum)
|
||||
{
|
||||
mpd_uint_t umod, p, r, xi;
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
|
||||
SETMODULUS(modnum);
|
||||
r = mpd_roots[modnum]; /* primitive root of F(p) */
|
||||
p = umod;
|
||||
xi = (p-1) / n;
|
||||
|
||||
if (sign == -1)
|
||||
return POWMOD(r, (p-1-xi));
|
||||
else
|
||||
|
@ -80,38 +72,28 @@ _mpd_init_fnt_params(mpd_size_t n, int sign, int modnum)
|
|||
{
|
||||
struct fnt_params *tparams;
|
||||
mpd_uint_t umod;
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_uint_t kernel, w;
|
||||
mpd_uint_t i;
|
||||
mpd_size_t nhalf;
|
||||
|
||||
assert(ispower2(n));
|
||||
assert(sign == -1 || sign == 1);
|
||||
assert(P1 <= modnum && modnum <= P3);
|
||||
|
||||
nhalf = n/2;
|
||||
tparams = mpd_sh_alloc(sizeof *tparams, nhalf, sizeof (mpd_uint_t));
|
||||
if (tparams == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SETMODULUS(modnum);
|
||||
kernel = _mpd_getkernel(n, sign, modnum);
|
||||
|
||||
tparams->modnum = modnum;
|
||||
tparams->modulus = umod;
|
||||
tparams->kernel = kernel;
|
||||
|
||||
/* wtable[] := w**0, w**1, ..., w**(nhalf-1) */
|
||||
w = 1;
|
||||
for (i = 0; i < nhalf; i++) {
|
||||
tparams->wtable[i] = w;
|
||||
w = MULMOD(w, kernel);
|
||||
}
|
||||
|
||||
return tparams;
|
||||
}
|
||||
|
||||
|
@ -120,15 +102,9 @@ void
|
|||
_mpd_init_w3table(mpd_uint_t w3table[3], int sign, int modnum)
|
||||
{
|
||||
mpd_uint_t umod;
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_uint_t kernel;
|
||||
|
||||
SETMODULUS(modnum);
|
||||
kernel = _mpd_getkernel(3, sign, modnum);
|
||||
|
||||
w3table[0] = 1;
|
||||
w3table[1] = kernel;
|
||||
w3table[2] = POWMOD(kernel, 2);
|
||||
|
|
|
@ -2,40 +2,20 @@
|
|||
#define NUMBER_THEORY_H
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/constants.h"
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
/* transform parameters */
|
||||
struct fnt_params {
|
||||
int modnum;
|
||||
mpd_uint_t modulus;
|
||||
mpd_uint_t kernel;
|
||||
mpd_uint_t wtable[];
|
||||
int modnum;
|
||||
mpd_uint_t modulus;
|
||||
mpd_uint_t kernel;
|
||||
mpd_uint_t wtable[];
|
||||
};
|
||||
|
||||
mpd_uint_t _mpd_getkernel(mpd_uint_t n, int sign, int modnum);
|
||||
struct fnt_params *_mpd_init_fnt_params(mpd_size_t n, int sign, int modnum);
|
||||
void _mpd_init_w3table(mpd_uint_t w3table[3], int sign, int modnum);
|
||||
mpd_uint_t _mpd_getkernel(mpd_uint_t, int, int);
|
||||
struct fnt_params *_mpd_init_fnt_params(mpd_size_t, int, int);
|
||||
void _mpd_init_w3table(mpd_uint_t[3], int, int);
|
||||
|
||||
#ifdef PPRO
|
||||
static inline void
|
||||
ppro_setmodulus(int modnum, mpd_uint_t *umod, double *dmod, uint32_t dinvmod[3])
|
||||
{
|
||||
*dmod = *umod = mpd_moduli[modnum];
|
||||
dinvmod[0] = mpd_invmoduli[modnum][0];
|
||||
dinvmod[1] = mpd_invmoduli[modnum][1];
|
||||
dinvmod[2] = mpd_invmoduli[modnum][2];
|
||||
static inline void std_setmodulus(int modnum, mpd_uint_t *umod) {
|
||||
*umod = mpd_moduli[modnum];
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
std_setmodulus(int modnum, mpd_uint_t *umod)
|
||||
{
|
||||
*umod = mpd_moduli[modnum];
|
||||
}
|
||||
#endif
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,10 +41,66 @@ libmpdec (BSD-2)\\n\
|
|||
Copyright 2008-2016 Stefan Krah\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/*
|
||||
Cache Efficient Matrix Fourier Transform
|
||||
for arrays of form 2ⁿ
|
||||
|
||||
/* Bignum: Cache efficient Matrix Fourier Transform for arrays of the
|
||||
form 2**n (See literature/six-step.txt). */
|
||||
|
||||
The Six Step Transform
|
||||
══════════════════════
|
||||
|
||||
In libmpdec, the six-step transform is the Matrix Fourier Transform in
|
||||
disguise. It is called six-step transform after a variant that appears
|
||||
in [1]. The algorithm requires that the input array can be viewed as an
|
||||
R×C matrix.
|
||||
|
||||
|
||||
Algorithm six-step (forward transform)
|
||||
──────────────────────────────────────
|
||||
|
||||
1a) Transpose the matrix.
|
||||
|
||||
1b) Apply a length R FNT to each row.
|
||||
|
||||
1c) Transpose the matrix.
|
||||
|
||||
2) Multiply each matrix element (addressed by j×C+m) by r**(j×m).
|
||||
|
||||
3) Apply a length C FNT to each row.
|
||||
|
||||
4) Transpose the matrix.
|
||||
|
||||
Note that steps 1a) - 1c) are exactly equivalent to step 1) of the Matrix
|
||||
Fourier Transform. For large R, it is faster to transpose twice and do
|
||||
a transform on the rows than to perform a column transpose directly.
|
||||
|
||||
|
||||
Algorithm six-step (inverse transform)
|
||||
──────────────────────────────────────
|
||||
|
||||
0) View the matrix as a C×R matrix.
|
||||
|
||||
1) Transpose the matrix, producing an R×C matrix.
|
||||
|
||||
2) Apply a length C FNT to each row.
|
||||
|
||||
3) Multiply each matrix element (addressed by i×C+n) by r**(i×n).
|
||||
|
||||
4a) Transpose the matrix.
|
||||
|
||||
4b) Apply a length R FNT to each row.
|
||||
|
||||
4c) Transpose the matrix.
|
||||
|
||||
Again, steps 4a) - 4c) are equivalent to step 4) of the Matrix Fourier
|
||||
Transform.
|
||||
|
||||
|
||||
──
|
||||
|
||||
[1] David H. Bailey: FFTs in External or Hierarchical Memory
|
||||
http://crd.lbl.gov/~dhbailey/dhbpapers/
|
||||
*/
|
||||
|
||||
/* forward transform with sign = -1 */
|
||||
int
|
||||
|
@ -54,28 +110,18 @@ six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
mpd_size_t log2n, C, R;
|
||||
mpd_uint_t kernel;
|
||||
mpd_uint_t umod;
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_uint_t *x, w0, w1, wstep;
|
||||
mpd_size_t i, k;
|
||||
|
||||
|
||||
assert(ispower2(n));
|
||||
assert(n >= 16);
|
||||
assert(n <= MPD_MAXTRANSFORM_2N);
|
||||
|
||||
log2n = mpd_bsr(n);
|
||||
C = ((mpd_size_t)1) << (log2n / 2); /* number of columns */
|
||||
R = ((mpd_size_t)1) << (log2n - (log2n / 2)); /* number of rows */
|
||||
|
||||
|
||||
/* Transpose the matrix. */
|
||||
if (!transpose_pow2(a, R, C)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Length R transform on the rows. */
|
||||
if ((tparams = _mpd_init_fnt_params(R, -1, modnum)) == NULL) {
|
||||
return 0;
|
||||
|
@ -83,13 +129,11 @@ six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
for (x = a; x < a+n; x += R) {
|
||||
fnt_dif2(x, R, tparams);
|
||||
}
|
||||
|
||||
/* Transpose the matrix. */
|
||||
if (!transpose_pow2(a, C, R)) {
|
||||
mpd_free(tparams);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Multiply each matrix element (addressed by i*C+k) by r**(i*k). */
|
||||
SETMODULUS(modnum);
|
||||
kernel = _mpd_getkernel(n, -1, modnum);
|
||||
|
@ -106,7 +150,6 @@ six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
a[i*C+k+1] = x1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Length C transform on the rows. */
|
||||
if (C != R) {
|
||||
mpd_free(tparams);
|
||||
|
@ -118,7 +161,6 @@ six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
fnt_dif2(x, C, tparams);
|
||||
}
|
||||
mpd_free(tparams);
|
||||
|
||||
#if 0
|
||||
/* An unordered transform is sufficient for convolution. */
|
||||
/* Transpose the matrix. */
|
||||
|
@ -126,11 +168,9 @@ six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* reverse transform, sign = 1 */
|
||||
int
|
||||
inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
||||
|
@ -139,23 +179,14 @@ inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
mpd_size_t log2n, C, R;
|
||||
mpd_uint_t kernel;
|
||||
mpd_uint_t umod;
|
||||
#ifdef PPRO
|
||||
double dmod;
|
||||
uint32_t dinvmod[3];
|
||||
#endif
|
||||
mpd_uint_t *x, w0, w1, wstep;
|
||||
mpd_size_t i, k;
|
||||
|
||||
|
||||
assert(ispower2(n));
|
||||
assert(n >= 16);
|
||||
assert(n <= MPD_MAXTRANSFORM_2N);
|
||||
|
||||
log2n = mpd_bsr(n);
|
||||
C = ((mpd_size_t)1) << (log2n / 2); /* number of columns */
|
||||
R = ((mpd_size_t)1) << (log2n - (log2n / 2)); /* number of rows */
|
||||
|
||||
|
||||
#if 0
|
||||
/* An unordered transform is sufficient for convolution. */
|
||||
/* Transpose the matrix, producing an R*C matrix. */
|
||||
|
@ -163,7 +194,6 @@ inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Length C transform on the rows. */
|
||||
if ((tparams = _mpd_init_fnt_params(C, 1, modnum)) == NULL) {
|
||||
return 0;
|
||||
|
@ -171,7 +201,6 @@ inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
for (x = a; x < a+n; x += C) {
|
||||
fnt_dif2(x, C, tparams);
|
||||
}
|
||||
|
||||
/* Multiply each matrix element (addressed by i*C+k) by r**(i*k). */
|
||||
SETMODULUS(modnum);
|
||||
kernel = _mpd_getkernel(n, 1, modnum);
|
||||
|
@ -188,13 +217,11 @@ inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
a[i*C+k+1] = x1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Transpose the matrix. */
|
||||
if (!transpose_pow2(a, R, C)) {
|
||||
mpd_free(tparams);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Length R transform on the rows. */
|
||||
if (R != C) {
|
||||
mpd_free(tparams);
|
||||
|
@ -206,11 +233,9 @@ inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
|
|||
fnt_dif2(x, R, tparams);
|
||||
}
|
||||
mpd_free(tparams);
|
||||
|
||||
/* Transpose the matrix. */
|
||||
if (!transpose_pow2(a, C, R)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -4,11 +4,9 @@
|
|||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
int six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
|
||||
int inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,22 +39,18 @@ libmpdec (BSD-2)\\n\
|
|||
Copyright 2008-2016 Stefan Krah\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
|
||||
#define BUFSIZE 4096
|
||||
#define SIDE 128
|
||||
|
||||
|
||||
/* Bignum: The transpose functions are used for very large transforms
|
||||
in sixstep.c and fourstep.c. */
|
||||
|
||||
|
||||
/* Definition of the matrix transpose */
|
||||
void
|
||||
std_trans(mpd_uint_t dest[], mpd_uint_t src[], mpd_size_t rows, mpd_size_t cols)
|
||||
{
|
||||
mpd_size_t idest, isrc;
|
||||
mpd_size_t r, c;
|
||||
|
||||
for (r = 0; r < rows; r++) {
|
||||
isrc = r * cols;
|
||||
idest = r;
|
||||
|
@ -83,10 +79,7 @@ swap_halfrows_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols, int dir
|
|||
mpd_size_t m, r=0;
|
||||
mpd_size_t offset;
|
||||
mpd_size_t next;
|
||||
|
||||
|
||||
assert(cols == mul_size_t(2, rows));
|
||||
|
||||
if (dir == FORWARD_CYCLE) {
|
||||
r = rows;
|
||||
}
|
||||
|
@ -96,52 +89,36 @@ swap_halfrows_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols, int dir
|
|||
else {
|
||||
abort(); /* GCOV_NOT_REACHED */
|
||||
}
|
||||
|
||||
m = cols - 1;
|
||||
hmax = rows; /* cycles start at odd halfrows */
|
||||
dbits = 8 * sizeof *done;
|
||||
if ((done = mpd_calloc(hmax/(sizeof *done) + 1, sizeof *done)) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (hn = 1; hn <= hmax; hn += 2) {
|
||||
|
||||
if (done[hn/dbits] & mpd_bits[hn%dbits]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
readbuf = buf1; writebuf = buf2;
|
||||
|
||||
for (offset = 0; offset < cols/2; offset += b) {
|
||||
|
||||
stride = (offset + b < cols/2) ? b : cols/2-offset;
|
||||
|
||||
hp = matrix + hn*cols/2;
|
||||
memcpy(readbuf, hp+offset, stride*(sizeof *readbuf));
|
||||
pointerswap(&readbuf, &writebuf);
|
||||
|
||||
next = mulmod_size_t(hn, r, m);
|
||||
hp = matrix + next*cols/2;
|
||||
|
||||
while (next != hn) {
|
||||
|
||||
memcpy(readbuf, hp+offset, stride*(sizeof *readbuf));
|
||||
memcpy(hp+offset, writebuf, stride*(sizeof *writebuf));
|
||||
pointerswap(&readbuf, &writebuf);
|
||||
|
||||
done[next/dbits] |= mpd_bits[next%dbits];
|
||||
|
||||
next = mulmod_size_t(next, r, m);
|
||||
hp = matrix + next*cols/2;
|
||||
|
||||
}
|
||||
|
||||
memcpy(hp+offset, writebuf, stride*(sizeof *writebuf));
|
||||
|
||||
done[hn/dbits] |= mpd_bits[hn%dbits];
|
||||
}
|
||||
}
|
||||
|
||||
mpd_free(done);
|
||||
return 1;
|
||||
}
|
||||
|
@ -153,7 +130,6 @@ squaretrans(mpd_uint_t *buf, mpd_size_t cols)
|
|||
mpd_uint_t tmp;
|
||||
mpd_size_t idest, isrc;
|
||||
mpd_size_t r, c;
|
||||
|
||||
for (r = 0; r < cols; r++) {
|
||||
c = r+1;
|
||||
isrc = r*cols + c;
|
||||
|
@ -182,13 +158,9 @@ squaretrans_pow2(mpd_uint_t *matrix, mpd_size_t size)
|
|||
mpd_size_t b = size;
|
||||
mpd_size_t r, c;
|
||||
mpd_size_t i;
|
||||
|
||||
while (b > SIDE) b >>= 1;
|
||||
|
||||
for (r = 0; r < size; r += b) {
|
||||
|
||||
for (c = r; c < size; c += b) {
|
||||
|
||||
from = matrix + r*size + c;
|
||||
to = buf1;
|
||||
for (i = 0; i < b; i++) {
|
||||
|
@ -197,7 +169,6 @@ squaretrans_pow2(mpd_uint_t *matrix, mpd_size_t size)
|
|||
to += b;
|
||||
}
|
||||
squaretrans(buf1, b);
|
||||
|
||||
if (r == c) {
|
||||
to = matrix + r*size + c;
|
||||
from = buf1;
|
||||
|
@ -217,7 +188,6 @@ squaretrans_pow2(mpd_uint_t *matrix, mpd_size_t size)
|
|||
to += b;
|
||||
}
|
||||
squaretrans(buf2, b);
|
||||
|
||||
to = matrix + c*size + r;
|
||||
from = buf1;
|
||||
for (i = 0; i < b; i++) {
|
||||
|
@ -225,7 +195,6 @@ squaretrans_pow2(mpd_uint_t *matrix, mpd_size_t size)
|
|||
from += b;
|
||||
to += size;
|
||||
}
|
||||
|
||||
to = matrix + r*size + c;
|
||||
from = buf2;
|
||||
for (i = 0; i < b; i++) {
|
||||
|
@ -236,7 +205,6 @@ squaretrans_pow2(mpd_uint_t *matrix, mpd_size_t size)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -247,10 +215,8 @@ int
|
|||
transpose_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols)
|
||||
{
|
||||
mpd_size_t size = mul_size_t(rows, cols);
|
||||
|
||||
assert(ispower2(rows));
|
||||
assert(ispower2(cols));
|
||||
|
||||
if (cols == rows) {
|
||||
squaretrans_pow2(matrix, rows);
|
||||
}
|
||||
|
@ -269,8 +235,7 @@ transpose_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols)
|
|||
}
|
||||
}
|
||||
else {
|
||||
abort(); /* GCOV_NOT_REACHED */
|
||||
unreachable;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
/* clang-format off */
|
||||
|
||||
/* Internal header file: all symbols have local scope in the DSO */
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
|
||||
|
||||
enum {FORWARD_CYCLE, BACKWARD_CYCLE};
|
||||
|
||||
|
@ -20,6 +19,5 @@ static inline void pointerswap(mpd_uint_t **a, mpd_uint_t **b)
|
|||
*a = tmp;
|
||||
}
|
||||
|
||||
MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,68 +4,57 @@
|
|||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
/* clang-format off */
|
||||
|
||||
#if defined(__GNUC__) && defined(__x86_64__) && !defined(__STRICT_ANSI__)
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Low level native arithmetic on basic types */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
/** ------------------------------------------------------------
|
||||
** Double width multiplication and division
|
||||
** ------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_64)
|
||||
#if defined(ANSI)
|
||||
#if defined(HAVE_UINT128_T)
|
||||
static inline void
|
||||
_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
|
||||
{
|
||||
__uint128_t hl;
|
||||
|
||||
hl = (__uint128_t)a * b;
|
||||
|
||||
*hi = hl >> 64;
|
||||
*lo = (mpd_uint_t)hl;
|
||||
mpd_uint_t h, l;
|
||||
asm ( "mulq %3\n\t"
|
||||
: "=d" (h), "=a" (l)
|
||||
: "%a" (a), "rm" (b)
|
||||
: "cc"
|
||||
);
|
||||
*hi = h;
|
||||
*lo = l;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo,
|
||||
mpd_uint_t d)
|
||||
{
|
||||
__uint128_t hl;
|
||||
|
||||
hl = ((__uint128_t)hi<<64) + lo;
|
||||
*q = (mpd_uint_t)(hl / d); /* quotient is known to fit */
|
||||
*r = (mpd_uint_t)(hl - (__uint128_t)(*q) * d);
|
||||
mpd_uint_t qq, rr;
|
||||
asm ( "divq %4\n\t"
|
||||
: "=a" (qq), "=d" (rr)
|
||||
: "a" (lo), "d" (hi), "rm" (d)
|
||||
: "cc"
|
||||
);
|
||||
*q = qq;
|
||||
*r = rr;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void
|
||||
_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
|
||||
{
|
||||
uint32_t w[4], carry;
|
||||
uint32_t ah, al, bh, bl;
|
||||
uint64_t hl;
|
||||
|
||||
ah = (uint32_t)(a>>32); al = (uint32_t)a;
|
||||
bh = (uint32_t)(b>>32); bl = (uint32_t)b;
|
||||
|
||||
hl = (uint64_t)al * bl;
|
||||
w[0] = (uint32_t)hl;
|
||||
carry = (uint32_t)(hl>>32);
|
||||
|
||||
hl = (uint64_t)ah * bl + carry;
|
||||
w[1] = (uint32_t)hl;
|
||||
w[2] = (uint32_t)(hl>>32);
|
||||
|
||||
hl = (uint64_t)al * bh + w[1];
|
||||
w[1] = (uint32_t)hl;
|
||||
carry = (uint32_t)(hl>>32);
|
||||
|
||||
hl = ((uint64_t)ah * bh + w[2]) + carry;
|
||||
w[2] = (uint32_t)hl;
|
||||
w[3] = (uint32_t)(hl>>32);
|
||||
|
||||
*hi = ((uint64_t)w[3]<<32) + w[2];
|
||||
*lo = ((uint64_t)w[1]<<32) + w[0];
|
||||
}
|
||||
|
@ -82,9 +71,7 @@ static inline int
|
|||
nlz(uint64_t x)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (x == 0) return(64);
|
||||
|
||||
n = 0;
|
||||
if (x <= 0x00000000FFFFFFFF) {n = n +32; x = x <<32;}
|
||||
if (x <= 0x0000FFFFFFFFFFFF) {n = n +16; x = x <<16;}
|
||||
|
@ -92,7 +79,6 @@ nlz(uint64_t x)
|
|||
if (x <= 0x0FFFFFFFFFFFFFFF) {n = n + 4; x = x << 4;}
|
||||
if (x <= 0x3FFFFFFFFFFFFFFF) {n = n + 2; x = x << 2;}
|
||||
if (x <= 0x7FFFFFFFFFFFFFFF) {n = n + 1;}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -107,21 +93,16 @@ _mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t u1, mpd_uint_t u0,
|
|||
un32, un21, un10,
|
||||
rhat, t;
|
||||
int s;
|
||||
|
||||
assert(u1 < v);
|
||||
|
||||
s = nlz(v);
|
||||
v = v << s;
|
||||
vn1 = v >> 32;
|
||||
vn0 = v & 0xFFFFFFFF;
|
||||
|
||||
t = (s == 0) ? 0 : u0 >> (64 - s);
|
||||
un32 = (u1 << s) | t;
|
||||
un10 = u0 << s;
|
||||
|
||||
un1 = un10 >> 32;
|
||||
un0 = un10 & 0xFFFFFFFF;
|
||||
|
||||
q1 = un32 / vn1;
|
||||
rhat = un32 - q1*vn1;
|
||||
again1:
|
||||
|
@ -130,7 +111,6 @@ again1:
|
|||
rhat = rhat + vn1;
|
||||
if (rhat < b) goto again1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Before again1 we had:
|
||||
* (1) q1*vn1 + rhat = un32
|
||||
|
@ -157,7 +137,6 @@ again1:
|
|||
* on the result.
|
||||
*/
|
||||
un21 = un32*b + un1 - q1*v;
|
||||
|
||||
q0 = un21 / vn1;
|
||||
rhat = un21 - q0*vn1;
|
||||
again2:
|
||||
|
@ -166,55 +145,18 @@ again2:
|
|||
rhat = rhat + vn1;
|
||||
if (rhat < b) goto again2;
|
||||
}
|
||||
|
||||
*q = q1*b + q0;
|
||||
*r = (un21*b + un0 - q0*v) >> s;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* END ANSI */
|
||||
#elif defined(ASM)
|
||||
static inline void
|
||||
_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
|
||||
{
|
||||
mpd_uint_t h, l;
|
||||
|
||||
__asm__ ( "mulq %3\n\t"
|
||||
: "=d" (h), "=a" (l)
|
||||
: "%a" (a), "rm" (b)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
*hi = h;
|
||||
*lo = l;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo,
|
||||
mpd_uint_t d)
|
||||
{
|
||||
mpd_uint_t qq, rr;
|
||||
|
||||
__asm__ ( "divq %4\n\t"
|
||||
: "=a" (qq), "=d" (rr)
|
||||
: "a" (lo), "d" (hi), "rm" (d)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
*q = qq;
|
||||
*r = rr;
|
||||
}
|
||||
/* END GCC ASM */
|
||||
#else
|
||||
#error "need platform specific 128 bit multiplication and division"
|
||||
#endif
|
||||
#endif /* ANSI */
|
||||
|
||||
#define DIVMOD(q, r, v, d) *q = v / d; *r = v - *q * d
|
||||
|
||||
static inline void
|
||||
_mpd_divmod_pow10(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t exp)
|
||||
{
|
||||
assert(exp <= 19);
|
||||
|
||||
if (exp <= 9) {
|
||||
if (exp <= 4) {
|
||||
switch (exp) {
|
||||
|
@ -251,240 +193,13 @@ _mpd_divmod_pow10(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t exp)
|
|||
case 16: DIVMOD(q, r, v, 10000000000000000ULL); break;
|
||||
case 17: DIVMOD(q, r, v, 100000000000000000ULL); break;
|
||||
case 18: DIVMOD(q, r, v, 1000000000000000000ULL); break;
|
||||
case 19: DIVMOD(q, r, v, 10000000000000000000ULL); break; /* GCOV_NOT_REACHED */
|
||||
case 19: DIVMOD(q, r, v, 10000000000000000000ULL); break;
|
||||
default: unreachable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* END CONFIG_64 */
|
||||
#elif defined(CONFIG_32)
|
||||
#if defined(ANSI)
|
||||
#if !defined(LEGACY_COMPILER)
|
||||
static inline void
|
||||
_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
|
||||
{
|
||||
mpd_uuint_t hl;
|
||||
|
||||
hl = (mpd_uuint_t)a * b;
|
||||
|
||||
*hi = hl >> 32;
|
||||
*lo = (mpd_uint_t)hl;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo,
|
||||
mpd_uint_t d)
|
||||
{
|
||||
mpd_uuint_t hl;
|
||||
|
||||
hl = ((mpd_uuint_t)hi<<32) + lo;
|
||||
*q = (mpd_uint_t)(hl / d); /* quotient is known to fit */
|
||||
*r = (mpd_uint_t)(hl - (mpd_uuint_t)(*q) * d);
|
||||
}
|
||||
/* END ANSI + uint64_t */
|
||||
#else
|
||||
static inline void
|
||||
_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
|
||||
{
|
||||
uint16_t w[4], carry;
|
||||
uint16_t ah, al, bh, bl;
|
||||
uint32_t hl;
|
||||
|
||||
ah = (uint16_t)(a>>16); al = (uint16_t)a;
|
||||
bh = (uint16_t)(b>>16); bl = (uint16_t)b;
|
||||
|
||||
hl = (uint32_t)al * bl;
|
||||
w[0] = (uint16_t)hl;
|
||||
carry = (uint16_t)(hl>>16);
|
||||
|
||||
hl = (uint32_t)ah * bl + carry;
|
||||
w[1] = (uint16_t)hl;
|
||||
w[2] = (uint16_t)(hl>>16);
|
||||
|
||||
hl = (uint32_t)al * bh + w[1];
|
||||
w[1] = (uint16_t)hl;
|
||||
carry = (uint16_t)(hl>>16);
|
||||
|
||||
hl = ((uint32_t)ah * bh + w[2]) + carry;
|
||||
w[2] = (uint16_t)hl;
|
||||
w[3] = (uint16_t)(hl>>16);
|
||||
|
||||
*hi = ((uint32_t)w[3]<<16) + w[2];
|
||||
*lo = ((uint32_t)w[1]<<16) + w[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* By Henry S. Warren: http://www.hackersdelight.org/HDcode/divlu.c.txt
|
||||
* http://www.hackersdelight.org/permissions.htm:
|
||||
* "You are free to use, copy, and distribute any of the code on this web
|
||||
* site, whether modified by you or not. You need not give attribution."
|
||||
*
|
||||
* Slightly modified, comments are mine.
|
||||
*/
|
||||
static inline int
|
||||
nlz(uint32_t x)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (x == 0) return(32);
|
||||
|
||||
n = 0;
|
||||
if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
|
||||
if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
|
||||
if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
|
||||
if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
|
||||
if (x <= 0x7FFFFFFF) {n = n + 1;}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t u1, mpd_uint_t u0,
|
||||
mpd_uint_t v)
|
||||
{
|
||||
const mpd_uint_t b = 65536;
|
||||
mpd_uint_t un1, un0,
|
||||
vn1, vn0,
|
||||
q1, q0,
|
||||
un32, un21, un10,
|
||||
rhat, t;
|
||||
int s;
|
||||
|
||||
assert(u1 < v);
|
||||
|
||||
s = nlz(v);
|
||||
v = v << s;
|
||||
vn1 = v >> 16;
|
||||
vn0 = v & 0xFFFF;
|
||||
|
||||
t = (s == 0) ? 0 : u0 >> (32 - s);
|
||||
un32 = (u1 << s) | t;
|
||||
un10 = u0 << s;
|
||||
|
||||
un1 = un10 >> 16;
|
||||
un0 = un10 & 0xFFFF;
|
||||
|
||||
q1 = un32 / vn1;
|
||||
rhat = un32 - q1*vn1;
|
||||
again1:
|
||||
if (q1 >= b || q1*vn0 > b*rhat + un1) {
|
||||
q1 = q1 - 1;
|
||||
rhat = rhat + vn1;
|
||||
if (rhat < b) goto again1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Before again1 we had:
|
||||
* (1) q1*vn1 + rhat = un32
|
||||
* (2) q1*vn1*b + rhat*b + un1 = un32*b + un1
|
||||
*
|
||||
* The statements inside the if-clause do not change the value
|
||||
* of the left-hand side of (2), and the loop is only exited
|
||||
* if q1*vn0 <= rhat*b + un1, so:
|
||||
*
|
||||
* (3) q1*vn1*b + q1*vn0 <= un32*b + un1
|
||||
* (4) q1*v <= un32*b + un1
|
||||
* (5) 0 <= un32*b + un1 - q1*v
|
||||
*
|
||||
* By (5) we are certain that the possible add-back step from
|
||||
* Knuth's algorithm D is never required.
|
||||
*
|
||||
* Since the final quotient is less than 2**32, the following
|
||||
* must be true:
|
||||
*
|
||||
* (6) un32*b + un1 - q1*v <= UINT32_MAX
|
||||
*
|
||||
* This means that in the following line, the high words
|
||||
* of un32*b and q1*v can be discarded without any effect
|
||||
* on the result.
|
||||
*/
|
||||
un21 = un32*b + un1 - q1*v;
|
||||
|
||||
q0 = un21 / vn1;
|
||||
rhat = un21 - q0*vn1;
|
||||
again2:
|
||||
if (q0 >= b || q0*vn0 > b*rhat + un0) {
|
||||
q0 = q0 - 1;
|
||||
rhat = rhat + vn1;
|
||||
if (rhat < b) goto again2;
|
||||
}
|
||||
|
||||
*q = q1*b + q0;
|
||||
*r = (un21*b + un0 - q0*v) >> s;
|
||||
}
|
||||
#endif /* END ANSI + LEGACY_COMPILER */
|
||||
|
||||
/* END ANSI */
|
||||
#elif defined(ASM)
|
||||
static inline void
|
||||
_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
|
||||
{
|
||||
mpd_uint_t h, l;
|
||||
|
||||
__asm__ ( "mull %3\n\t"
|
||||
: "=d" (h), "=a" (l)
|
||||
: "%a" (a), "rm" (b)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
*hi = h;
|
||||
*lo = l;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo,
|
||||
mpd_uint_t d)
|
||||
{
|
||||
mpd_uint_t qq, rr;
|
||||
|
||||
__asm__ ( "divl %4\n\t"
|
||||
: "=a" (qq), "=d" (rr)
|
||||
: "a" (lo), "d" (hi), "rm" (d)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
*q = qq;
|
||||
*r = rr;
|
||||
}
|
||||
/* END GCC ASM */
|
||||
#else
|
||||
#error "need platform specific 64 bit multiplication and division"
|
||||
#endif
|
||||
|
||||
#define DIVMOD(q, r, v, d) *q = v / d; *r = v - *q * d
|
||||
static inline void
|
||||
_mpd_divmod_pow10(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t exp)
|
||||
{
|
||||
assert(exp <= 9);
|
||||
|
||||
if (exp <= 4) {
|
||||
switch (exp) {
|
||||
case 0: *q = v; *r = 0; break;
|
||||
case 1: DIVMOD(q, r, v, 10UL); break;
|
||||
case 2: DIVMOD(q, r, v, 100UL); break;
|
||||
case 3: DIVMOD(q, r, v, 1000UL); break;
|
||||
case 4: DIVMOD(q, r, v, 10000UL); break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (exp) {
|
||||
case 5: DIVMOD(q, r, v, 100000UL); break;
|
||||
case 6: DIVMOD(q, r, v, 1000000UL); break;
|
||||
case 7: DIVMOD(q, r, v, 10000000UL); break;
|
||||
case 8: DIVMOD(q, r, v, 100000000UL); break;
|
||||
case 9: DIVMOD(q, r, v, 1000000000UL); break; /* GCOV_NOT_REACHED */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* END CONFIG_32 */
|
||||
|
||||
/* NO CONFIG */
|
||||
#else
|
||||
#error "define CONFIG_64 or CONFIG_32"
|
||||
#endif /* CONFIG */
|
||||
|
||||
|
||||
static inline void
|
||||
_mpd_div_word(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t d)
|
||||
{
|
||||
|
@ -499,7 +214,6 @@ _mpd_idiv_word(mpd_ssize_t *q, mpd_ssize_t *r, mpd_ssize_t v, mpd_ssize_t d)
|
|||
*r = v - *q * d;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------------------
|
||||
** Arithmetic with overflow checking
|
||||
** ------------------------------------------------------------
|
||||
|
@ -537,7 +251,6 @@ static inline mpd_size_t
|
|||
mul_size_t(mpd_size_t a, mpd_size_t b)
|
||||
{
|
||||
mpd_uint_t hi, lo;
|
||||
|
||||
_mpd_mul_words(&hi, &lo, (mpd_uint_t)a, (mpd_uint_t)b);
|
||||
if (hi) {
|
||||
mpd_err_fatal("mul_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */
|
||||
|
@ -549,7 +262,6 @@ static inline mpd_size_t
|
|||
add_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow)
|
||||
{
|
||||
mpd_size_t ret;
|
||||
|
||||
*overflow = 0;
|
||||
ret = a + b;
|
||||
if (ret < a) *overflow = 1;
|
||||
|
@ -560,7 +272,6 @@ static inline mpd_size_t
|
|||
mul_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow)
|
||||
{
|
||||
mpd_uint_t lo;
|
||||
|
||||
_mpd_mul_words((mpd_uint_t *)overflow, &lo, (mpd_uint_t)a,
|
||||
(mpd_uint_t)b);
|
||||
return lo;
|
||||
|
@ -578,15 +289,9 @@ mulmod_size_t(mpd_size_t a, mpd_size_t b, mpd_size_t m)
|
|||
{
|
||||
mpd_uint_t hi, lo;
|
||||
mpd_uint_t q, r;
|
||||
|
||||
_mpd_mul_words(&hi, &lo, (mpd_uint_t)a, (mpd_uint_t)b);
|
||||
_mpd_div_words(&q, &r, hi, lo, (mpd_uint_t)m);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
#endif /* TYPEARITH_H */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
#ifndef UMODARITH_H
|
||||
#define UMODARITH_H
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/constants.h"
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
|
||||
#include "third_party/python/Modules/_decimal/libmpdec/typearith.h"
|
||||
/* clang-format off */
|
||||
|
||||
|
||||
/* Bignum: Low level routines for unsigned modular arithmetic. These are
|
||||
used in the fast convolution functions for very large coefficients. */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* ANSI modular arithmetic */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* Restrictions: a < m and b < m
|
||||
* ACL2 proof: umodarith.lisp: addmod-correct
|
||||
|
@ -23,11 +17,9 @@ static inline mpd_uint_t
|
|||
addmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
|
||||
{
|
||||
mpd_uint_t s;
|
||||
|
||||
s = a + b;
|
||||
s = (s < a) ? s - m : s;
|
||||
s = (s >= m) ? s - m : s;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -39,10 +31,8 @@ static inline mpd_uint_t
|
|||
submod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
|
||||
{
|
||||
mpd_uint_t d;
|
||||
|
||||
d = a - b;
|
||||
d = (a < b) ? d + m : d;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
@ -54,13 +44,10 @@ static inline mpd_uint_t
|
|||
ext_submod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
|
||||
{
|
||||
mpd_uint_t d;
|
||||
|
||||
a = (a >= m) ? a - m : a;
|
||||
b = (b >= m) ? b - m : b;
|
||||
|
||||
d = a - b;
|
||||
d = (a < b) ? d + m : d;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
@ -73,10 +60,8 @@ static inline mpd_uint_t
|
|||
dw_reduce(mpd_uint_t hi, mpd_uint_t lo, mpd_uint_t m)
|
||||
{
|
||||
mpd_uint_t r1, r2, w;
|
||||
|
||||
_mpd_div_word(&w, &r1, hi, m);
|
||||
_mpd_div_words(&w, &r2, r1, lo, m);
|
||||
|
||||
return r2;
|
||||
}
|
||||
|
||||
|
@ -89,142 +74,213 @@ static inline mpd_uint_t
|
|||
dw_submod(mpd_uint_t a, mpd_uint_t hi, mpd_uint_t lo, mpd_uint_t m)
|
||||
{
|
||||
mpd_uint_t d, r;
|
||||
|
||||
r = dw_reduce(hi, lo, m);
|
||||
d = a - r;
|
||||
d = (a < r) ? d + m : d;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64
|
||||
|
||||
/**************************************************************************/
|
||||
/* 64-bit modular arithmetic */
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* A proof of the algorithm is in literature/mulmod-64.txt. An ACL2
|
||||
* proof is in umodarith.lisp: section "Fast modular reduction".
|
||||
/**
|
||||
* Calculates (a × b) % 𝑝 where 𝑝 is special
|
||||
*
|
||||
* Algorithm: calculate (a * b) % p:
|
||||
* In the whole comment, "⩭" stands for "is congruent with".
|
||||
*
|
||||
* a) hi, lo <- a * b # Calculate a * b.
|
||||
* Result of a × b in terms of high/low words:
|
||||
*
|
||||
* b) hi, lo <- R(hi, lo) # Reduce modulo p.
|
||||
* (1) hi × 2⁶⁴ + lo = a × b
|
||||
*
|
||||
* c) Repeat step b) until 0 <= hi * 2**64 + lo < 2*p.
|
||||
* Special primes:
|
||||
*
|
||||
* d) If the result is less than p, return lo. Otherwise return lo - p.
|
||||
* (2) 𝑝 = 2⁶⁴ - z + 1, where z = 2ⁿ
|
||||
*
|
||||
* i.e. 0xfffffffffffffc01
|
||||
* 0xfffffffffffff001
|
||||
* 0xffffffffff000001
|
||||
* 0xffffffff00000001
|
||||
* 0xfffffffc00000001
|
||||
* 0xffffff0000000001
|
||||
* 0xffffff0000000001
|
||||
*
|
||||
* Single step modular reduction:
|
||||
*
|
||||
* (3) R(hi, lo) = hi × z - hi + lo
|
||||
*
|
||||
*
|
||||
* Strategy
|
||||
* --------
|
||||
*
|
||||
* a) Set (hi, lo) to the result of a × b.
|
||||
*
|
||||
* b) Set (hi′, lo′) to the result of R(hi, lo).
|
||||
*
|
||||
* c) Repeat step b) until 0 ≤ hi′ × 2⁶⁴ + lo′ < 𝟸×𝑝.
|
||||
*
|
||||
* d) If the result is less than 𝑝, return lo′. Otherwise return lo′ - 𝑝.
|
||||
*
|
||||
*
|
||||
* The reduction step b) preserves congruence
|
||||
* ------------------------------------------
|
||||
*
|
||||
* hi × 2⁶⁴ + lo ⩭ hi × z - hi + lo (mod 𝑝)
|
||||
*
|
||||
* Proof:
|
||||
* ~~~~~~
|
||||
*
|
||||
* hi × 2⁶⁴ + lo = (2⁶⁴ - z + 1) × hi + z × hi - hi + lo
|
||||
*
|
||||
* = 𝑝 × hi + z × hi - hi + lo
|
||||
*
|
||||
* ⩭ z × hi - hi + lo (mod 𝑝)
|
||||
*
|
||||
*
|
||||
* Maximum numbers of step b)
|
||||
* --------------------------
|
||||
*
|
||||
* To avoid unnecessary formalism, define:
|
||||
*
|
||||
* def R(hi, lo, z):
|
||||
* return divmod(hi * z - hi + lo, 2**64)
|
||||
*
|
||||
* For simplicity, assume hi=2⁶⁴-1, lo=2⁶⁴-1 after the
|
||||
* initial multiplication a × b. This is of course impossible
|
||||
* but certainly covers all cases.
|
||||
*
|
||||
* Then, for p1:
|
||||
*
|
||||
* z = 2³²
|
||||
* hi = 2⁶⁴-1
|
||||
* lo = 2⁶⁴-1
|
||||
* p1 = 2⁶⁴ - z + 1
|
||||
* hi, lo = R(hi, lo, z) # First reduction
|
||||
* hi, lo = R(hi, lo, z) # Second reduction
|
||||
* hi × 2⁶⁴ + lo < 2 × p1 # True
|
||||
*
|
||||
* For p2:
|
||||
*
|
||||
* z = 2³⁴
|
||||
* hi = 2⁶⁴-1
|
||||
* lo = 2⁶⁴-1
|
||||
* p2 = 2⁶⁴ - z + 1
|
||||
* hi, lo = R(hi, lo, z) # First reduction
|
||||
* hi, lo = R(hi, lo, z) # Second reduction
|
||||
* hi, lo = R(hi, lo, z) # Third reduction
|
||||
* hi × 2⁶⁴ + lo < 2 × p2 # True
|
||||
*
|
||||
* For p3:
|
||||
*
|
||||
* z = 2⁴⁰
|
||||
* hi = 2⁶⁴-1
|
||||
* lo = 2⁶⁴-1
|
||||
* p3 = 2⁶⁴ - z + 1
|
||||
* hi, lo = R(hi, lo, z) # First reduction
|
||||
* hi, lo = R(hi, lo, z) # Second reduction
|
||||
* hi, lo = R(hi, lo, z) # Third reduction
|
||||
* hi × 2⁶⁴ + lo < 2 × p3 # True
|
||||
*
|
||||
* Step d) preserves congruence and yields a result < 𝑝
|
||||
* ----------------------------------------------------
|
||||
*
|
||||
* Case hi = 0:
|
||||
*
|
||||
* Case lo < 𝑝: trivial.
|
||||
*
|
||||
* Case lo ≥ 𝑝:
|
||||
*
|
||||
* lo ⩭ lo - 𝑝 (mod 𝑝) # result is congruent
|
||||
*
|
||||
* 𝑝 ≤ lo < 𝟸×𝑝 → 0 ≤ lo - 𝑝 < 𝑝 # result is in the correct range
|
||||
*
|
||||
* Case hi = 1:
|
||||
*
|
||||
* 𝑝 < 2⁶⁴ Λ 2⁶⁴ + lo < 𝟸×𝑝 → lo < 𝑝 # lo is always less than 𝑝
|
||||
*
|
||||
* 2⁶⁴ + lo ⩭ 2⁶⁴ + (lo - 𝑝) (mod 𝑝) # result is congruent
|
||||
*
|
||||
* = lo - 𝑝 # exactly the same value as the previous RHS
|
||||
* # in uint64_t arithmetic.
|
||||
*
|
||||
* 𝑝 < 2⁶⁴ + lo < 𝟸×𝑝 → 0 < 2⁶⁴ + (lo - 𝑝) < 𝑝 # correct range
|
||||
*
|
||||
*
|
||||
* [1] http://www.apfloat.org/apfloat/2.40/apfloat.pdf
|
||||
*/
|
||||
|
||||
static inline mpd_uint_t
|
||||
x64_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
|
||||
{
|
||||
mpd_uint_t hi, lo, x, y;
|
||||
|
||||
|
||||
_mpd_mul_words(&hi, &lo, a, b);
|
||||
|
||||
if (m & (1ULL<<32)) { /* P1 */
|
||||
|
||||
/* first reduction */
|
||||
x = y = hi;
|
||||
hi >>= 32;
|
||||
|
||||
x = lo - x;
|
||||
if (x > lo) hi--;
|
||||
|
||||
y <<= 32;
|
||||
lo = y + x;
|
||||
if (lo < y) hi++;
|
||||
|
||||
/* second reduction */
|
||||
x = y = hi;
|
||||
hi >>= 32;
|
||||
|
||||
x = lo - x;
|
||||
if (x > lo) hi--;
|
||||
|
||||
y <<= 32;
|
||||
lo = y + x;
|
||||
if (lo < y) hi++;
|
||||
|
||||
return (hi || lo >= m ? lo - m : lo);
|
||||
return hi || lo >= m ? lo - m : lo;
|
||||
}
|
||||
else if (m & (1ULL<<34)) { /* P2 */
|
||||
|
||||
/* first reduction */
|
||||
x = y = hi;
|
||||
hi >>= 30;
|
||||
|
||||
x = lo - x;
|
||||
if (x > lo) hi--;
|
||||
|
||||
y <<= 34;
|
||||
lo = y + x;
|
||||
if (lo < y) hi++;
|
||||
|
||||
/* second reduction */
|
||||
x = y = hi;
|
||||
hi >>= 30;
|
||||
|
||||
x = lo - x;
|
||||
if (x > lo) hi--;
|
||||
|
||||
y <<= 34;
|
||||
lo = y + x;
|
||||
if (lo < y) hi++;
|
||||
|
||||
/* third reduction */
|
||||
x = y = hi;
|
||||
hi >>= 30;
|
||||
|
||||
x = lo - x;
|
||||
if (x > lo) hi--;
|
||||
|
||||
y <<= 34;
|
||||
lo = y + x;
|
||||
if (lo < y) hi++;
|
||||
|
||||
return (hi || lo >= m ? lo - m : lo);
|
||||
return hi || lo >= m ? lo - m : lo;
|
||||
}
|
||||
else { /* P3 */
|
||||
|
||||
/* first reduction */
|
||||
x = y = hi;
|
||||
hi >>= 24;
|
||||
|
||||
x = lo - x;
|
||||
if (x > lo) hi--;
|
||||
|
||||
y <<= 40;
|
||||
lo = y + x;
|
||||
if (lo < y) hi++;
|
||||
|
||||
/* second reduction */
|
||||
x = y = hi;
|
||||
hi >>= 24;
|
||||
|
||||
x = lo - x;
|
||||
if (x > lo) hi--;
|
||||
|
||||
y <<= 40;
|
||||
lo = y + x;
|
||||
if (lo < y) hi++;
|
||||
|
||||
/* third reduction */
|
||||
x = y = hi;
|
||||
hi >>= 24;
|
||||
|
||||
x = lo - x;
|
||||
if (x > lo) hi--;
|
||||
|
||||
y <<= 40;
|
||||
lo = y + x;
|
||||
if (lo < y) hi++;
|
||||
|
||||
return (hi || lo >= m ? lo - m : lo);
|
||||
return hi || lo >= m ? lo - m : lo;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,375 +303,13 @@ static inline mpd_uint_t
|
|||
x64_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod)
|
||||
{
|
||||
mpd_uint_t r = 1;
|
||||
|
||||
while (exp > 0) {
|
||||
if (exp & 1)
|
||||
r = x64_mulmod(r, base, umod);
|
||||
base = x64_mulmod(base, base, umod);
|
||||
exp >>= 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* END CONFIG_64 */
|
||||
#else /* CONFIG_32 */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* 32-bit modular arithmetic */
|
||||
/**************************************************************************/
|
||||
|
||||
#if defined(ANSI)
|
||||
#if !defined(LEGACY_COMPILER)
|
||||
/* HAVE_UINT64_T */
|
||||
static inline mpd_uint_t
|
||||
std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
|
||||
{
|
||||
return ((mpd_uuint_t) a * b) % m;
|
||||
}
|
||||
|
||||
static inline void
|
||||
std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m)
|
||||
{
|
||||
*a = ((mpd_uuint_t) *a * w) % m;
|
||||
*b = ((mpd_uuint_t) *b * w) % m;
|
||||
}
|
||||
|
||||
static inline void
|
||||
std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1,
|
||||
mpd_uint_t m)
|
||||
{
|
||||
*a0 = ((mpd_uuint_t) *a0 * b0) % m;
|
||||
*a1 = ((mpd_uuint_t) *a1 * b1) % m;
|
||||
}
|
||||
/* END HAVE_UINT64_T */
|
||||
#else
|
||||
/* LEGACY_COMPILER */
|
||||
static inline mpd_uint_t
|
||||
std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
|
||||
{
|
||||
mpd_uint_t hi, lo, q, r;
|
||||
_mpd_mul_words(&hi, &lo, a, b);
|
||||
_mpd_div_words(&q, &r, hi, lo, m);
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline void
|
||||
std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m)
|
||||
{
|
||||
*a = std_mulmod(*a, w, m);
|
||||
*b = std_mulmod(*b, w, m);
|
||||
}
|
||||
|
||||
static inline void
|
||||
std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1,
|
||||
mpd_uint_t m)
|
||||
{
|
||||
*a0 = std_mulmod(*a0, b0, m);
|
||||
*a1 = std_mulmod(*a1, b1, m);
|
||||
}
|
||||
/* END LEGACY_COMPILER */
|
||||
#endif
|
||||
|
||||
static inline mpd_uint_t
|
||||
std_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod)
|
||||
{
|
||||
mpd_uint_t r = 1;
|
||||
|
||||
while (exp > 0) {
|
||||
if (exp & 1)
|
||||
r = std_mulmod(r, base, umod);
|
||||
base = std_mulmod(base, base, umod);
|
||||
exp >>= 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif /* ANSI CONFIG_32 */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* Pentium Pro modular arithmetic */
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* A proof of the algorithm is in literature/mulmod-ppro.txt. The FPU
|
||||
* control word must be set to 64-bit precision and truncation mode
|
||||
* prior to using these functions.
|
||||
*
|
||||
* Algorithm: calculate (a * b) % p:
|
||||
*
|
||||
* p := prime < 2**31
|
||||
* pinv := (long double)1.0 / p (precalculated)
|
||||
*
|
||||
* a) n = a * b # Calculate exact product.
|
||||
* b) qest = n * pinv # Calculate estimate for q = n / p.
|
||||
* c) q = (qest+2**63)-2**63 # Truncate qest to the exact quotient.
|
||||
* d) r = n - q * p # Calculate remainder.
|
||||
*
|
||||
* Remarks:
|
||||
*
|
||||
* - p = dmod and pinv = dinvmod.
|
||||
* - dinvmod points to an array of three uint32_t, which is interpreted
|
||||
* as an 80 bit long double by fldt.
|
||||
* - Intel compilers prior to version 11 do not seem to handle the
|
||||
* __GNUC__ inline assembly correctly.
|
||||
* - random tests are provided in tests/extended/ppro_mulmod.c
|
||||
*/
|
||||
|
||||
#if defined(PPRO)
|
||||
#if defined(ASM)
|
||||
|
||||
/* Return (a * b) % dmod */
|
||||
static inline mpd_uint_t
|
||||
ppro_mulmod(mpd_uint_t a, mpd_uint_t b, double *dmod, uint32_t *dinvmod)
|
||||
{
|
||||
mpd_uint_t retval;
|
||||
|
||||
__asm__ (
|
||||
"fildl %2\n\t"
|
||||
"fildl %1\n\t"
|
||||
"fmulp %%st, %%st(1)\n\t"
|
||||
"fldt (%4)\n\t"
|
||||
"fmul %%st(1), %%st\n\t"
|
||||
"flds %5\n\t"
|
||||
"fadd %%st, %%st(1)\n\t"
|
||||
"fsubrp %%st, %%st(1)\n\t"
|
||||
"fldl (%3)\n\t"
|
||||
"fmulp %%st, %%st(1)\n\t"
|
||||
"fsubrp %%st, %%st(1)\n\t"
|
||||
"fistpl %0\n\t"
|
||||
: "=m" (retval)
|
||||
: "m" (a), "m" (b), "r" (dmod), "r" (dinvmod), "m" (MPD_TWO63)
|
||||
: "st", "memory"
|
||||
);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Two modular multiplications in parallel:
|
||||
* *a0 = (*a0 * w) % dmod
|
||||
* *a1 = (*a1 * w) % dmod
|
||||
*/
|
||||
static inline void
|
||||
ppro_mulmod2c(mpd_uint_t *a0, mpd_uint_t *a1, mpd_uint_t w,
|
||||
double *dmod, uint32_t *dinvmod)
|
||||
{
|
||||
__asm__ (
|
||||
"fildl %2\n\t"
|
||||
"fildl (%1)\n\t"
|
||||
"fmul %%st(1), %%st\n\t"
|
||||
"fxch %%st(1)\n\t"
|
||||
"fildl (%0)\n\t"
|
||||
"fmulp %%st, %%st(1) \n\t"
|
||||
"fldt (%4)\n\t"
|
||||
"flds %5\n\t"
|
||||
"fld %%st(2)\n\t"
|
||||
"fmul %%st(2)\n\t"
|
||||
"fadd %%st(1)\n\t"
|
||||
"fsub %%st(1)\n\t"
|
||||
"fmull (%3)\n\t"
|
||||
"fsubrp %%st, %%st(3)\n\t"
|
||||
"fxch %%st(2)\n\t"
|
||||
"fistpl (%0)\n\t"
|
||||
"fmul %%st(2)\n\t"
|
||||
"fadd %%st(1)\n\t"
|
||||
"fsubp %%st, %%st(1)\n\t"
|
||||
"fmull (%3)\n\t"
|
||||
"fsubrp %%st, %%st(1)\n\t"
|
||||
"fistpl (%1)\n\t"
|
||||
: : "r" (a0), "r" (a1), "m" (w),
|
||||
"r" (dmod), "r" (dinvmod),
|
||||
"m" (MPD_TWO63)
|
||||
: "st", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Two modular multiplications in parallel:
|
||||
* *a0 = (*a0 * b0) % dmod
|
||||
* *a1 = (*a1 * b1) % dmod
|
||||
*/
|
||||
static inline void
|
||||
ppro_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1,
|
||||
double *dmod, uint32_t *dinvmod)
|
||||
{
|
||||
__asm__ (
|
||||
"fildl %3\n\t"
|
||||
"fildl (%2)\n\t"
|
||||
"fmulp %%st, %%st(1)\n\t"
|
||||
"fildl %1\n\t"
|
||||
"fildl (%0)\n\t"
|
||||
"fmulp %%st, %%st(1)\n\t"
|
||||
"fldt (%5)\n\t"
|
||||
"fld %%st(2)\n\t"
|
||||
"fmul %%st(1), %%st\n\t"
|
||||
"fxch %%st(1)\n\t"
|
||||
"fmul %%st(2), %%st\n\t"
|
||||
"flds %6\n\t"
|
||||
"fldl (%4)\n\t"
|
||||
"fxch %%st(3)\n\t"
|
||||
"fadd %%st(1), %%st\n\t"
|
||||
"fxch %%st(2)\n\t"
|
||||
"fadd %%st(1), %%st\n\t"
|
||||
"fxch %%st(2)\n\t"
|
||||
"fsub %%st(1), %%st\n\t"
|
||||
"fxch %%st(2)\n\t"
|
||||
"fsubp %%st, %%st(1)\n\t"
|
||||
"fxch %%st(1)\n\t"
|
||||
"fmul %%st(2), %%st\n\t"
|
||||
"fxch %%st(1)\n\t"
|
||||
"fmulp %%st, %%st(2)\n\t"
|
||||
"fsubrp %%st, %%st(3)\n\t"
|
||||
"fsubrp %%st, %%st(1)\n\t"
|
||||
"fxch %%st(1)\n\t"
|
||||
"fistpl (%2)\n\t"
|
||||
"fistpl (%0)\n\t"
|
||||
: : "r" (a0), "m" (b0), "r" (a1), "m" (b1),
|
||||
"r" (dmod), "r" (dinvmod),
|
||||
"m" (MPD_TWO63)
|
||||
: "st", "memory"
|
||||
);
|
||||
}
|
||||
/* END PPRO GCC ASM */
|
||||
#elif defined(MASM)
|
||||
|
||||
/* Return (a * b) % dmod */
|
||||
static inline mpd_uint_t __cdecl
|
||||
ppro_mulmod(mpd_uint_t a, mpd_uint_t b, double *dmod, uint32_t *dinvmod)
|
||||
{
|
||||
mpd_uint_t retval;
|
||||
|
||||
__asm {
|
||||
mov eax, dinvmod
|
||||
mov edx, dmod
|
||||
fild b
|
||||
fild a
|
||||
fmulp st(1), st
|
||||
fld TBYTE PTR [eax]
|
||||
fmul st, st(1)
|
||||
fld MPD_TWO63
|
||||
fadd st(1), st
|
||||
fsubp st(1), st
|
||||
fld QWORD PTR [edx]
|
||||
fmulp st(1), st
|
||||
fsubp st(1), st
|
||||
fistp retval
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Two modular multiplications in parallel:
|
||||
* *a0 = (*a0 * w) % dmod
|
||||
* *a1 = (*a1 * w) % dmod
|
||||
*/
|
||||
static inline mpd_uint_t __cdecl
|
||||
ppro_mulmod2c(mpd_uint_t *a0, mpd_uint_t *a1, mpd_uint_t w,
|
||||
double *dmod, uint32_t *dinvmod)
|
||||
{
|
||||
__asm {
|
||||
mov ecx, dmod
|
||||
mov edx, a1
|
||||
mov ebx, dinvmod
|
||||
mov eax, a0
|
||||
fild w
|
||||
fild DWORD PTR [edx]
|
||||
fmul st, st(1)
|
||||
fxch st(1)
|
||||
fild DWORD PTR [eax]
|
||||
fmulp st(1), st
|
||||
fld TBYTE PTR [ebx]
|
||||
fld MPD_TWO63
|
||||
fld st(2)
|
||||
fmul st, st(2)
|
||||
fadd st, st(1)
|
||||
fsub st, st(1)
|
||||
fmul QWORD PTR [ecx]
|
||||
fsubp st(3), st
|
||||
fxch st(2)
|
||||
fistp DWORD PTR [eax]
|
||||
fmul st, st(2)
|
||||
fadd st, st(1)
|
||||
fsubrp st(1), st
|
||||
fmul QWORD PTR [ecx]
|
||||
fsubp st(1), st
|
||||
fistp DWORD PTR [edx]
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Two modular multiplications in parallel:
|
||||
* *a0 = (*a0 * b0) % dmod
|
||||
* *a1 = (*a1 * b1) % dmod
|
||||
*/
|
||||
static inline void __cdecl
|
||||
ppro_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1,
|
||||
double *dmod, uint32_t *dinvmod)
|
||||
{
|
||||
__asm {
|
||||
mov ecx, dmod
|
||||
mov edx, a1
|
||||
mov ebx, dinvmod
|
||||
mov eax, a0
|
||||
fild b1
|
||||
fild DWORD PTR [edx]
|
||||
fmulp st(1), st
|
||||
fild b0
|
||||
fild DWORD PTR [eax]
|
||||
fmulp st(1), st
|
||||
fld TBYTE PTR [ebx]
|
||||
fld st(2)
|
||||
fmul st, st(1)
|
||||
fxch st(1)
|
||||
fmul st, st(2)
|
||||
fld DWORD PTR MPD_TWO63
|
||||
fld QWORD PTR [ecx]
|
||||
fxch st(3)
|
||||
fadd st, st(1)
|
||||
fxch st(2)
|
||||
fadd st, st(1)
|
||||
fxch st(2)
|
||||
fsub st, st(1)
|
||||
fxch st(2)
|
||||
fsubrp st(1), st
|
||||
fxch st(1)
|
||||
fmul st, st(2)
|
||||
fxch st(1)
|
||||
fmulp st(2), st
|
||||
fsubp st(3), st
|
||||
fsubp st(1), st
|
||||
fxch st(1)
|
||||
fistp DWORD PTR [edx]
|
||||
fistp DWORD PTR [eax]
|
||||
}
|
||||
}
|
||||
#endif /* PPRO MASM (_MSC_VER) */
|
||||
|
||||
|
||||
/* Return (base ** exp) % dmod */
|
||||
static inline mpd_uint_t
|
||||
ppro_powmod(mpd_uint_t base, mpd_uint_t exp, double *dmod, uint32_t *dinvmod)
|
||||
{
|
||||
mpd_uint_t r = 1;
|
||||
|
||||
while (exp > 0) {
|
||||
if (exp & 1)
|
||||
r = ppro_mulmod(r, base, dmod, dinvmod);
|
||||
base = ppro_mulmod(base, base, dmod, dinvmod);
|
||||
exp >>= 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif /* PPRO */
|
||||
#endif /* CONFIG_32 */
|
||||
|
||||
|
||||
#endif /* UMODARITH_H */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1301,3 +1301,8 @@ PyInit__functools(void)
|
|||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__functools = {
|
||||
"_functools",
|
||||
PyInit__functools,
|
||||
};
|
||||
|
|
696
third_party/python/Modules/_hashmbedtls.c
vendored
696
third_party/python/Modules/_hashmbedtls.c
vendored
|
@ -1,18 +1,36 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Copying of this file is authorized only if (1) you are Justine Tunney, │
|
||||
│ or (2) you make absolutely no changes to your copy. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/log/backtrace.internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/mbedtls/error.h"
|
||||
#include "third_party/mbedtls/md.h"
|
||||
#include "third_party/mbedtls/pkcs5.h"
|
||||
#include "third_party/python/Include/Python.h"
|
||||
#include "third_party/python/Include/ezprint.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pystrhex.h"
|
||||
#include "third_party/python/Include/structmember.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
|
@ -27,6 +45,7 @@ PYTHON_PROVIDE("_hashlib.__name__");
|
|||
PYTHON_PROVIDE("_hashlib.__package__");
|
||||
PYTHON_PROVIDE("_hashlib.__spec__");
|
||||
PYTHON_PROVIDE("_hashlib.new");
|
||||
PYTHON_PROVIDE("_hashlib.pbkdf2_hmac");
|
||||
PYTHON_PROVIDE("_hashlib.mbedtls_md5");
|
||||
PYTHON_PROVIDE("_hashlib.mbedtls_md_meth_names");
|
||||
PYTHON_PROVIDE("_hashlib.mbedtls_sha1");
|
||||
|
@ -35,52 +54,39 @@ PYTHON_PROVIDE("_hashlib.mbedtls_sha256");
|
|||
PYTHON_PROVIDE("_hashlib.mbedtls_sha384");
|
||||
PYTHON_PROVIDE("_hashlib.mbedtls_sha512");
|
||||
|
||||
#include "third_party/python/Modules/clinic/_hashmbedtls.inc"
|
||||
|
||||
/*[clinic input]
|
||||
module _hashlib
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c2b4ff081bac4be1]*/
|
||||
|
||||
#define MUNCH_SIZE 65536
|
||||
|
||||
#ifndef HASH_OBJ_CONSTRUCTOR
|
||||
#define HASH_OBJ_CONSTRUCTOR 0
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
struct Hasher {
|
||||
PyObject_HEAD
|
||||
PyObject *name;
|
||||
mbedtls_md_context_t ctx;
|
||||
#ifdef WITH_THREAD
|
||||
PyThread_type_lock lock;
|
||||
#endif
|
||||
} EVPobject;
|
||||
};
|
||||
|
||||
static PyTypeObject EVPtype;
|
||||
|
||||
static PyObject *CONST_MD5_name_obj;
|
||||
static PyObject *CONST_SHA1_name_obj;
|
||||
static PyObject *CONST_SHA224_name_obj;
|
||||
static PyObject *CONST_SHA256_name_obj;
|
||||
static PyObject *CONST_SHA384_name_obj;
|
||||
static PyObject *CONST_SHA512_name_obj;
|
||||
static PyObject *CONST_BLAKE2B256_name_obj;
|
||||
static PyTypeObject hasher_type;
|
||||
static const PyObject *CONST_MD5_name_obj;
|
||||
static const PyObject *CONST_SHA1_name_obj;
|
||||
static const PyObject *CONST_SHA224_name_obj;
|
||||
static const PyObject *CONST_SHA256_name_obj;
|
||||
static const PyObject *CONST_SHA384_name_obj;
|
||||
static const PyObject *CONST_SHA512_name_obj;
|
||||
static const PyObject *CONST_BLAKE2B256_name_obj;
|
||||
|
||||
static PyObject *
|
||||
SetMbedtlsError(PyObject *exc, int rc)
|
||||
{
|
||||
char b[128];
|
||||
mbedtls_strerror(rc, b, sizeof(b));
|
||||
stpcpy(b, "MBEDTLS - ");
|
||||
mbedtls_strerror(rc, b + 10, sizeof(b) - 10);
|
||||
PyErr_SetString(exc, b);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static EVPobject *
|
||||
newEVPobject(PyObject *name)
|
||||
static struct Hasher *
|
||||
hasher_new(PyObject *name)
|
||||
{
|
||||
EVPobject *self;
|
||||
if ((self = PyObject_New(EVPobject, &EVPtype))) {
|
||||
struct Hasher *self;
|
||||
if ((self = PyObject_New(struct Hasher, &hasher_type))) {
|
||||
mbedtls_md_init(&self->ctx);
|
||||
Py_INCREF(name);
|
||||
self->name = name;
|
||||
|
@ -92,28 +98,13 @@ newEVPobject(PyObject *name)
|
|||
}
|
||||
|
||||
static int
|
||||
EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
|
||||
hasher_hash(struct Hasher *self, const void *p, Py_ssize_t n)
|
||||
{
|
||||
int rc;
|
||||
unsigned int process;
|
||||
const unsigned char *cp;
|
||||
for (cp = vp; 0 < len; len -= process, cp += process) {
|
||||
if (len > MUNCH_SIZE) {
|
||||
process = MUNCH_SIZE;
|
||||
} else {
|
||||
process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
|
||||
}
|
||||
if ((rc = mbedtls_md_update(&self->ctx, cp, process)) < 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return mbedtls_md_update(&self->ctx, p, n);
|
||||
}
|
||||
|
||||
/* Internal methods for a hash object */
|
||||
|
||||
static void
|
||||
EVP_dealloc(EVPobject *self)
|
||||
hasher_dealloc(struct Hasher *self)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
if (self->lock)
|
||||
|
@ -125,7 +116,7 @@ EVP_dealloc(EVPobject *self)
|
|||
}
|
||||
|
||||
static int
|
||||
locked_mbedtls_md_clone(mbedtls_md_context_t *new_ctx_p, EVPobject *self)
|
||||
mbedtls_md_clone_locked(mbedtls_md_context_t *new_ctx_p, struct Hasher *self)
|
||||
{
|
||||
int rc;
|
||||
ENTER_HASHLIB(self);
|
||||
|
@ -136,29 +127,34 @@ locked_mbedtls_md_clone(mbedtls_md_context_t *new_ctx_p, EVPobject *self)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* External methods for a hash object */
|
||||
|
||||
PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object.");
|
||||
PyDoc_STRVAR(hashlib_copy__doc__, "\
|
||||
copy($self, /)\n\
|
||||
--\n\
|
||||
\n\
|
||||
Return a copy of the hash object.");
|
||||
|
||||
static PyObject *
|
||||
EVP_copy(EVPobject *self, PyObject *unused)
|
||||
hashlib_copy(struct Hasher *self, PyObject *unused)
|
||||
{
|
||||
int rc;
|
||||
EVPobject *newobj;
|
||||
if ((newobj = newEVPobject(self->name))) {
|
||||
if ((rc = locked_mbedtls_md_clone(&newobj->ctx, self))) {
|
||||
EVP_dealloc(newobj);
|
||||
struct Hasher *newobj;
|
||||
if ((newobj = hasher_new(self->name))) {
|
||||
if ((rc = mbedtls_md_clone_locked(&newobj->ctx, self))) {
|
||||
hasher_dealloc(newobj);
|
||||
return SetMbedtlsError(PyExc_ValueError, rc);
|
||||
}
|
||||
}
|
||||
return (PyObject *)newobj;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(EVP_digest__doc__,
|
||||
"Return the digest value as a bytes object.");
|
||||
PyDoc_STRVAR(hashlib_digest__doc__, "\
|
||||
digest($self, /)\n\
|
||||
--\n\
|
||||
\n\
|
||||
Return the digest value as a bytes object.");
|
||||
|
||||
static PyObject *
|
||||
EVP_digest(EVPobject *self, PyObject *unused)
|
||||
hashlib_digest(struct Hasher *self, PyObject *unused)
|
||||
{
|
||||
int rc;
|
||||
PyObject *retval;
|
||||
|
@ -166,7 +162,7 @@ EVP_digest(EVPobject *self, PyObject *unused)
|
|||
mbedtls_md_context_t temp_ctx;
|
||||
unsigned char digest[MBEDTLS_MD_MAX_SIZE];
|
||||
mbedtls_md_init(&temp_ctx);
|
||||
if (!(rc = locked_mbedtls_md_clone(&temp_ctx, self))) {
|
||||
if (!(rc = mbedtls_md_clone_locked(&temp_ctx, self))) {
|
||||
digest_size = mbedtls_md_get_size(temp_ctx.md_info);
|
||||
if (!(rc = mbedtls_md_finish(&temp_ctx, digest))) {
|
||||
retval = PyBytes_FromStringAndSize((const char *)digest, digest_size);
|
||||
|
@ -180,11 +176,14 @@ EVP_digest(EVPobject *self, PyObject *unused)
|
|||
return retval;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(EVP_hexdigest__doc__,
|
||||
"Return the digest value as a string of hexadecimal digits.");
|
||||
PyDoc_STRVAR(hashlib_hexdigest__doc__, "\
|
||||
hexdigest($self, /)\n\
|
||||
--\n\
|
||||
\n\
|
||||
Return the digest value as a string of hexadecimal digits.");
|
||||
|
||||
static PyObject *
|
||||
EVP_hexdigest(EVPobject *self, PyObject *unused)
|
||||
hashlib_hexdigest(struct Hasher *self, PyObject *unused)
|
||||
{
|
||||
int rc;
|
||||
PyObject *retval;
|
||||
|
@ -192,7 +191,7 @@ EVP_hexdigest(EVPobject *self, PyObject *unused)
|
|||
mbedtls_md_context_t temp_ctx;
|
||||
unsigned char digest[MBEDTLS_MD_MAX_SIZE];
|
||||
mbedtls_md_init(&temp_ctx);
|
||||
if (!(rc = locked_mbedtls_md_clone(&temp_ctx, self))) {
|
||||
if (!(rc = mbedtls_md_clone_locked(&temp_ctx, self))) {
|
||||
digest_size = mbedtls_md_get_size(temp_ctx.md_info);
|
||||
if (!(rc = mbedtls_md_finish(&temp_ctx, digest))) {
|
||||
retval = _Py_strhex((const char *)digest, digest_size);
|
||||
|
@ -206,338 +205,210 @@ EVP_hexdigest(EVPobject *self, PyObject *unused)
|
|||
return retval;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(EVP_update__doc__,
|
||||
"Update this hash object's state with the provided string.");
|
||||
PyDoc_STRVAR(hashlib_update__doc__, "\
|
||||
update($self, bytes, /)\n\
|
||||
--\n\
|
||||
\n\
|
||||
Update this hash object's state with the provided string.");
|
||||
|
||||
static PyObject *
|
||||
EVP_update(EVPobject *self, PyObject *args)
|
||||
hashlib_update(struct Hasher *self, PyObject *args)
|
||||
{
|
||||
PyObject *obj;
|
||||
Py_buffer view;
|
||||
if (!PyArg_ParseTuple(args, "O:update", &obj)) return 0;
|
||||
GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
|
||||
EVP_hash(self, view.buf, view.len);
|
||||
PyBuffer_Release(&view);
|
||||
Py_buffer data;
|
||||
if (!PyArg_ParseTuple(args, "y*:update", &data)) return 0;
|
||||
hasher_hash(self, data.buf, data.len);
|
||||
PyBuffer_Release(&data);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef EVP_methods[] = {
|
||||
{"update", (PyCFunction)EVP_update, METH_VARARGS, EVP_update__doc__},
|
||||
{"digest", (PyCFunction)EVP_digest, METH_NOARGS, EVP_digest__doc__},
|
||||
{"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS, EVP_hexdigest__doc__},
|
||||
{"copy", (PyCFunction)EVP_copy, METH_NOARGS, EVP_copy__doc__},
|
||||
{NULL, NULL} /* sentinel */
|
||||
static PyMethodDef hashlib_methods[] = {
|
||||
{"update", (PyCFunction)hashlib_update, METH_VARARGS, hashlib_update__doc__},
|
||||
{"digest", (PyCFunction)hashlib_digest, METH_NOARGS, hashlib_digest__doc__},
|
||||
{"hexdigest", (PyCFunction)hashlib_hexdigest, METH_NOARGS, hashlib_hexdigest__doc__},
|
||||
{"copy", (PyCFunction)hashlib_copy, METH_NOARGS, hashlib_copy__doc__},
|
||||
{0}
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
EVP_get_block_size(EVPobject *self, void *closure)
|
||||
hashlib_get_block_size(struct Hasher *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(mbedtls_md_get_block_size(self->ctx.md_info));
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
EVP_get_digest_size(EVPobject *self, void *closure)
|
||||
hashlib_get_digest_size(struct Hasher *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(mbedtls_md_get_size(self->ctx.md_info));
|
||||
}
|
||||
|
||||
static PyMemberDef EVP_members[] = {
|
||||
{"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")},
|
||||
{NULL}
|
||||
static PyMemberDef hashlib_members[] = {
|
||||
{"name", T_OBJECT, offsetof(struct Hasher, name), READONLY, PyDoc_STR("algorithm name.")},
|
||||
{0}
|
||||
};
|
||||
|
||||
static PyGetSetDef EVP_getseters[] = {
|
||||
{"digest_size", (getter)EVP_get_digest_size, NULL, NULL, NULL},
|
||||
{"block_size", (getter)EVP_get_block_size, NULL, NULL, NULL},
|
||||
{NULL}
|
||||
static PyGetSetDef hashlib_getseters[] = {
|
||||
{"digest_size", (getter)hashlib_get_digest_size, NULL, NULL, NULL},
|
||||
{"block_size", (getter)hashlib_get_block_size, NULL, NULL, NULL},
|
||||
{0}
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
EVP_repr(EVPobject *self)
|
||||
hasher_repr(struct Hasher *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("<%U HASH object @ %p>", self->name, self);
|
||||
}
|
||||
|
||||
#if HASH_OBJ_CONSTRUCTOR
|
||||
#error wut
|
||||
static int
|
||||
EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"name", "string", NULL};
|
||||
PyObject *name_obj = NULL;
|
||||
PyObject *data_obj = NULL;
|
||||
Py_buffer view;
|
||||
char *nameStr;
|
||||
const mbedtls_md_info_t *digest;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:HASH", kwlist,
|
||||
&name_obj, &data_obj)) {
|
||||
return -1;
|
||||
}
|
||||
if (data_obj)
|
||||
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
|
||||
if (!PyArg_Parse(name_obj, "s", &nameStr)) {
|
||||
PyErr_SetString(PyExc_TypeError, "name must be a string");
|
||||
if (data_obj)
|
||||
PyBuffer_Release(&view);
|
||||
return -1;
|
||||
}
|
||||
digest = mbedtls_md_info_from_string(nameStr);
|
||||
if (!digest) {
|
||||
PyErr_SetString(PyExc_ValueError, "unknown hash function");
|
||||
if (data_obj)
|
||||
PyBuffer_Release(&view);
|
||||
return -1;
|
||||
}
|
||||
if (!EVP_DigestInit(self->ctx, digest)) {
|
||||
SetMbedtlsError(PyExc_ValueError);
|
||||
if (data_obj)
|
||||
PyBuffer_Release(&view);
|
||||
return -1;
|
||||
}
|
||||
Py_INCREF(name_obj);
|
||||
Py_XSETREF(self->name, name_obj);
|
||||
if (data_obj) {
|
||||
if (view.len >= HASHLIB_GIL_MINSIZE) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
EVP_hash(self, view.buf, view.len);
|
||||
Py_END_ALLOW_THREADS
|
||||
} else {
|
||||
EVP_hash(self, view.buf, view.len);
|
||||
}
|
||||
PyBuffer_Release(&view);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
PyDoc_STRVAR(hashtype_doc,
|
||||
"A hash represents the object used to calculate a checksum of a\n\
|
||||
string of information.\n\
|
||||
\n\
|
||||
Methods:\n\
|
||||
\n\
|
||||
update() -- updates the current digest with an additional string\n\
|
||||
digest() -- return the current digest value\n\
|
||||
hexdigest() -- return the current digest as a string of hexadecimal digits\n\
|
||||
copy() -- return a copy of the current hash object\n\
|
||||
\n\
|
||||
Attributes:\n\
|
||||
\n\
|
||||
name -- the hash algorithm being used by this object\n\
|
||||
digest_size -- number of bytes in this hashes output\n");
|
||||
|
||||
static PyTypeObject EVPtype = {
|
||||
static PyTypeObject hasher_type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"_hashlib.HASH", /*tp_name*/
|
||||
sizeof(EVPobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)EVP_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_reserved*/
|
||||
(reprfunc)EVP_repr, /*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 | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
hashtype_doc, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
EVP_methods, /* tp_methods */
|
||||
EVP_members, /* tp_members */
|
||||
EVP_getseters, /* tp_getset */
|
||||
#if 1
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
#endif
|
||||
#if HASH_OBJ_CONSTRUCTOR
|
||||
(initproc)EVP_tp_init, /* tp_init */
|
||||
#endif
|
||||
/*tp_name*/ "_hashlib.HASH",
|
||||
/*tp_basicsize*/ sizeof(struct Hasher),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)hasher_dealloc,
|
||||
/*tp_print*/ 0,
|
||||
/*tp_getattr*/ 0,
|
||||
/*tp_setattr*/ 0,
|
||||
/*tp_reserved*/ 0,
|
||||
/*tp_repr*/ (reprfunc)hasher_repr,
|
||||
/*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*/ 0,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ hashtype_doc,
|
||||
/*tp_traverse*/ 0,
|
||||
/*tp_clear*/ 0,
|
||||
/*tp_richcompare*/ 0,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ 0,
|
||||
/*tp_iternext*/ 0,
|
||||
/*tp_methods*/ hashlib_methods,
|
||||
/*tp_members*/ hashlib_members,
|
||||
/*tp_getset*/ hashlib_getseters,
|
||||
/*tp_base*/ 0,
|
||||
/*tp_dict*/ 0,
|
||||
/*tp_descr_get*/ 0,
|
||||
/*tp_descr_set*/ 0,
|
||||
/*tp_dictoffset*/ 0,
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
EVPnew(PyObject *name_obj,
|
||||
const mbedtls_md_info_t *digest,
|
||||
const unsigned char *cp, Py_ssize_t len)
|
||||
NewHasher(PyObject *name_obj,
|
||||
const mbedtls_md_info_t *digest,
|
||||
void *p, Py_ssize_t n)
|
||||
{
|
||||
int rc;
|
||||
EVPobject *self;
|
||||
struct Hasher *self;
|
||||
if (!digest) {
|
||||
PyErr_SetString(PyExc_ValueError, "unsupported hash type");
|
||||
return NULL;
|
||||
}
|
||||
if ((self = newEVPobject(name_obj)) == NULL)
|
||||
return NULL;
|
||||
if ((rc = mbedtls_md_setup(&self->ctx, digest, 0))) {
|
||||
if (!(self = hasher_new(name_obj))) return 0;
|
||||
if ((rc = mbedtls_md_setup(&self->ctx, digest, 0)) ||
|
||||
(rc = mbedtls_md_starts(&self->ctx))) {
|
||||
SetMbedtlsError(PyExc_ValueError, rc);
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
if (cp && len) {
|
||||
if (len >= HASHLIB_GIL_MINSIZE) {
|
||||
if (n) {
|
||||
if (n >= HASHLIB_GIL_MINSIZE) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
EVP_hash(self, cp, len);
|
||||
hasher_hash(self, p, n);
|
||||
Py_END_ALLOW_THREADS
|
||||
} else {
|
||||
EVP_hash(self, cp, len);
|
||||
hasher_hash(self, p, n);
|
||||
}
|
||||
}
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
|
||||
/* The module-level function: new() */
|
||||
|
||||
PyDoc_STRVAR(EVP_new__doc__,
|
||||
"Return a new hash object using the named algorithm.\n\
|
||||
PyDoc_STRVAR(hashlib_new__doc__,
|
||||
"new($module, name, string=b'')\n\
|
||||
--\n\
|
||||
\n\
|
||||
Return a new hash object using the named algorithm.\n\
|
||||
An optional string argument may be provided and will be\n\
|
||||
automatically hashed.\n\
|
||||
\n\
|
||||
The MD5 and SHA1 algorithms are always supported.\n");
|
||||
|
||||
static PyObject *
|
||||
EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
|
||||
hashlib_new(PyObject *self, PyObject *args, PyObject *kwdict)
|
||||
{
|
||||
static char *kwlist[] = {"name", "string", NULL};
|
||||
PyObject *name_obj = NULL;
|
||||
PyObject *data_obj = NULL;
|
||||
Py_buffer view = { 0 };
|
||||
PyObject *ret_obj;
|
||||
char *name;
|
||||
const mbedtls_md_info_t *digest;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|O:new", kwlist,
|
||||
&name_obj, &data_obj)) {
|
||||
PyObject *res;
|
||||
Py_buffer data = {0};
|
||||
PyObject *name_obj = 0;
|
||||
static char *kwlist[] = {"name", "string", NULL};
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|y*:new", kwlist,
|
||||
&name_obj, &data)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_Parse(name_obj, "s", &name)) {
|
||||
PyErr_SetString(PyExc_TypeError, "name must be a string");
|
||||
PyBuffer_Release(&data);
|
||||
return NULL;
|
||||
}
|
||||
if (data_obj)
|
||||
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
|
||||
digest = mbedtls_md_info_from_string(name);
|
||||
ret_obj = EVPnew(name_obj, digest, (unsigned char*)view.buf, view.len);
|
||||
if (data_obj)
|
||||
PyBuffer_Release(&view);
|
||||
return ret_obj;
|
||||
res = NewHasher(name_obj, mbedtls_md_info_from_string(name),
|
||||
data.buf, data.len);
|
||||
PyBuffer_Release(&data);
|
||||
return res;
|
||||
}
|
||||
|
||||
#if (MBEDTLS_VERSION_NUMBER >= 0x10000000 && !defined(MBEDTLS_NO_HMAC) \
|
||||
&& !defined(MBEDTLS_NO_SHA))
|
||||
#define PY_PBKDF2_HMAC 1
|
||||
#if !HAS_FAST_PKCS5_PBKDF2_HMAC
|
||||
/* Improved implementation of PKCS5_PBKDF2_HMAC()
|
||||
*
|
||||
* PKCS5_PBKDF2_HMAC_fast() hashes the password exactly one time instead of
|
||||
* `iter` times. Today (2013) the iteration count is typically 100,000 or
|
||||
* more. The improved algorithm is not subject to a Denial-of-Service
|
||||
* vulnerability with overly large passwords.
|
||||
*
|
||||
* Also Mbedtls < 1.0 don't provide PKCS5_PBKDF2_HMAC(), only
|
||||
* PKCS5_PBKDF2_SHA1.
|
||||
*/
|
||||
static int
|
||||
PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen,
|
||||
const unsigned char *salt, int saltlen,
|
||||
int iter, const mbedtls_md_info_t *digest,
|
||||
int keylen, unsigned char *out)
|
||||
pbkdf2(const mbedtls_md_info_t *digest,
|
||||
const void *pass, size_t passlen,
|
||||
const void *salt, size_t saltlen,
|
||||
size_t c, size_t dklen, void *dk)
|
||||
{
|
||||
unsigned char digtmp[MBEDTLS_MD_MAX_SIZE], *p, itmp[4];
|
||||
int cplen, j, k, tkeylen, mdlen;
|
||||
unsigned long i = 1;
|
||||
HMAC_CTX hctx_tpl, hctx;
|
||||
mdlen = mbedtls_md_get_size(digest);
|
||||
if (mdlen < 0)
|
||||
return 0;
|
||||
HMAC_CTX_init(&hctx_tpl);
|
||||
HMAC_CTX_init(&hctx);
|
||||
p = out;
|
||||
tkeylen = keylen;
|
||||
if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) {
|
||||
HMAC_CTX_cleanup(&hctx_tpl);
|
||||
return 0;
|
||||
int rc;
|
||||
mbedtls_md_context_t ctx;
|
||||
mbedtls_md_init(&ctx);
|
||||
if (!(rc = mbedtls_md_setup(&ctx, digest, 1))) {
|
||||
rc = mbedtls_pkcs5_pbkdf2_hmac(
|
||||
&ctx, pass, passlen, salt, saltlen, c, dklen, dk);
|
||||
}
|
||||
while (tkeylen) {
|
||||
if (tkeylen > mdlen)
|
||||
cplen = mdlen;
|
||||
else
|
||||
cplen = tkeylen;
|
||||
/* We are unlikely to ever use more than 256 blocks (5120 bits!)
|
||||
* but just in case...
|
||||
*/
|
||||
itmp[0] = (unsigned char)((i >> 24) & 0xff);
|
||||
itmp[1] = (unsigned char)((i >> 16) & 0xff);
|
||||
itmp[2] = (unsigned char)((i >> 8) & 0xff);
|
||||
itmp[3] = (unsigned char)(i & 0xff);
|
||||
if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
|
||||
HMAC_CTX_cleanup(&hctx_tpl);
|
||||
return 0;
|
||||
}
|
||||
if (!HMAC_Update(&hctx, salt, saltlen)
|
||||
|| !HMAC_Update(&hctx, itmp, 4)
|
||||
|| !HMAC_Final(&hctx, digtmp, NULL)) {
|
||||
HMAC_CTX_cleanup(&hctx_tpl);
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
return 0;
|
||||
}
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
memcpy(p, digtmp, cplen);
|
||||
for (j = 1; j < iter; j++) {
|
||||
if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
|
||||
HMAC_CTX_cleanup(&hctx_tpl);
|
||||
return 0;
|
||||
}
|
||||
if (!HMAC_Update(&hctx, digtmp, mdlen)
|
||||
|| !HMAC_Final(&hctx, digtmp, NULL)) {
|
||||
HMAC_CTX_cleanup(&hctx_tpl);
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
return 0;
|
||||
}
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
for (k = 0; k < cplen; k++) {
|
||||
p[k] ^= digtmp[k];
|
||||
}
|
||||
}
|
||||
tkeylen-= cplen;
|
||||
i++;
|
||||
p+= cplen;
|
||||
}
|
||||
HMAC_CTX_cleanup(&hctx_tpl);
|
||||
return 1;
|
||||
mbedtls_md_free(&ctx);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
PyDoc_STRVAR(pbkdf2_hmac__doc__,
|
||||
"pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key\n\
|
||||
"pbkdf2_hmac($module, hash_name, password, salt, iterations, dklen=None)\n\
|
||||
--\n\
|
||||
\n\
|
||||
Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as\n\
|
||||
Password based key derivation function 2 (PKCS #5 v2.o) with HMAC as\n\
|
||||
pseudorandom function.");
|
||||
|
||||
static PyObject *
|
||||
pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
|
||||
{
|
||||
static char *kwlist[] = {"hash_name", "password", "salt", "iterations",
|
||||
"dklen", NULL};
|
||||
PyObject *key_obj = NULL, *dklen_obj = Py_None;
|
||||
static char *kwlist[] = {
|
||||
"hash_name",
|
||||
"password",
|
||||
"salt",
|
||||
"iterations",
|
||||
"dklen",
|
||||
NULL,
|
||||
};
|
||||
int rc;
|
||||
char *name, *key;
|
||||
Py_buffer password, salt;
|
||||
long iterations, dklen;
|
||||
int retval;
|
||||
PyObject *key_obj = NULL;
|
||||
PyObject *dklen_obj = Py_None;
|
||||
const mbedtls_md_info_t *digest;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "sy*y*l|O:pbkdf2_hmac",
|
||||
kwlist, &name, &password, &salt,
|
||||
|
@ -594,21 +465,12 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
|
|||
}
|
||||
key = PyBytes_AS_STRING(key_obj);
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
#if HAS_FAST_PKCS5_PBKDF2_HMAC
|
||||
retval = PKCS5_PBKDF2_HMAC((char*)password.buf, (int)password.len,
|
||||
(unsigned char *)salt.buf, (int)salt.len,
|
||||
iterations, digest, dklen,
|
||||
(unsigned char *)key);
|
||||
#else
|
||||
retval = PKCS5_PBKDF2_HMAC_fast((char*)password.buf, (int)password.len,
|
||||
(unsigned char *)salt.buf, (int)salt.len,
|
||||
iterations, digest, dklen,
|
||||
(unsigned char *)key);
|
||||
#endif
|
||||
rc = pbkdf2(digest, password.buf, password.len,
|
||||
salt.buf, salt.len, iterations, dklen, key);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (retval) {
|
||||
if (rc) {
|
||||
Py_CLEAR(key_obj);
|
||||
SetMbedtlsError(PyExc_ValueError, retval);
|
||||
SetMbedtlsError(PyExc_ValueError, rc);
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
|
@ -616,120 +478,6 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
|
|||
PyBuffer_Release(&salt);
|
||||
return key_obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER > 0x10100000L && !defined(MBEDTLS_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#define PY_SCRYPT 1
|
||||
/* XXX: Parameters salt, n, r and p should be required keyword-only parameters.
|
||||
They are optional in the Argument Clinic declaration only due to a
|
||||
limitation of PyArg_ParseTupleAndKeywords. */
|
||||
|
||||
/*[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) {
|
||||
/* Mbedtls 1.1.0 restricts maxmem to 32MB. It may change in the
|
||||
future. The maxmem constant is private to Mbedtls. */
|
||||
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 Mbedtls 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);
|
||||
SetMbedtlsError(PyExc_ValueError);
|
||||
return NULL;
|
||||
}
|
||||
return key_obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
GenerateHashNameList(void)
|
||||
|
@ -751,40 +499,26 @@ GenerateHashNameList(void)
|
|||
return set;
|
||||
}
|
||||
|
||||
/*
|
||||
* This macro generates constructor function definitions for specific
|
||||
* hash algorithms. These constructors are much faster than calling
|
||||
* the generic one passing it a python string and are noticeably
|
||||
* faster than calling a python new() wrapper. That is important for
|
||||
* code that wants to make hashes of a bunch of small strings.
|
||||
* The first call will lazy-initialize, which reports an exception
|
||||
* if initialization fails.
|
||||
*/
|
||||
#define GEN_CONSTRUCTOR(NAME, STRNAME) \
|
||||
static PyObject * \
|
||||
EVP_new_ ## NAME (PyObject *self, PyObject *args) \
|
||||
{ \
|
||||
PyObject *ret; \
|
||||
PyObject *data = 0; \
|
||||
Py_buffer view = { 0 }; \
|
||||
if (!PyArg_ParseTuple(args, "|O:" STRNAME , &data)) return 0; \
|
||||
if (data) GET_BUFFER_VIEW_OR_ERROUT(data, &view); \
|
||||
ret = EVPnew(CONST_ ## NAME ## _name_obj, \
|
||||
mbedtls_md_info_from_type(MBEDTLS_MD_ ## NAME), \
|
||||
(unsigned char *)view.buf, view.len); \
|
||||
if (data) PyBuffer_Release(&view); \
|
||||
return ret; \
|
||||
}
|
||||
static PyObject * \
|
||||
hashlib_new_ ## NAME (PyObject *self, PyObject *args) \
|
||||
{ \
|
||||
PyObject *ret; \
|
||||
Py_buffer data = {0}; \
|
||||
if (!PyArg_ParseTuple(args, "|y*:" STRNAME, &data)) return 0; \
|
||||
ret = NewHasher(CONST_ ## NAME ## _name_obj, \
|
||||
mbedtls_md_info_from_type(MBEDTLS_MD_ ## NAME), \
|
||||
data.buf, data.len); \
|
||||
PyBuffer_Release(&data); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
/* a PyMethodDef structure for the constructor */
|
||||
#define CONSTRUCTOR_METH_DEF(NAME, STRNAME) \
|
||||
{"mbedtls_" STRNAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \
|
||||
PyDoc_STR("Returns a " STRNAME \
|
||||
" hash object; optionally initialized with a string") \
|
||||
}
|
||||
#define CONSTRUCTOR_METH_DEF(NAME, STRNAME) \
|
||||
{"mbedtls_" STRNAME, (PyCFunction)hashlib_new_ ## NAME, METH_VARARGS,\
|
||||
PyDoc_STR("mbedtls_" STRNAME "($module, string=b'')\n--\n\n" \
|
||||
"Returns a " STRNAME " hash object; optionally " \
|
||||
"initialized with a string")}
|
||||
|
||||
/* used in the init function to setup a constructor: initialize Mbedtls
|
||||
constructor constants if they haven't been initialized already. */
|
||||
#define INIT_CONSTRUCTOR_CONSTANTS(NAME, STRNAME) \
|
||||
if (CONST_ ## NAME ## _name_obj == NULL) { \
|
||||
CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \
|
||||
|
@ -798,15 +532,9 @@ GEN_CONSTRUCTOR(SHA384, "sha384")
|
|||
GEN_CONSTRUCTOR(SHA512, "sha512")
|
||||
GEN_CONSTRUCTOR(BLAKE2B256, "blake2b256")
|
||||
|
||||
/* List of functions exported by this module */
|
||||
|
||||
static struct PyMethodDef EVP_functions[] = {
|
||||
{"new", (PyCFunction)EVP_new, METH_VARARGS|METH_KEYWORDS, EVP_new__doc__},
|
||||
#ifdef PY_PBKDF2_HMAC
|
||||
{"pbkdf2_hmac", (PyCFunction)pbkdf2_hmac, METH_VARARGS|METH_KEYWORDS,
|
||||
pbkdf2_hmac__doc__},
|
||||
#endif
|
||||
_HASHLIB_SCRYPT_METHODDEF
|
||||
static struct PyMethodDef hashlib_functions[] = {
|
||||
{"new", (PyCFunction)hashlib_new, METH_VARARGS|METH_KEYWORDS, hashlib_new__doc__},
|
||||
{"pbkdf2_hmac", (PyCFunction)pbkdf2_hmac, METH_VARARGS|METH_KEYWORDS, pbkdf2_hmac__doc__},
|
||||
CONSTRUCTOR_METH_DEF(MD5, "md5"),
|
||||
CONSTRUCTOR_METH_DEF(SHA1, "sha1"),
|
||||
CONSTRUCTOR_METH_DEF(SHA224, "sha224"),
|
||||
|
@ -814,7 +542,7 @@ static struct PyMethodDef EVP_functions[] = {
|
|||
CONSTRUCTOR_METH_DEF(SHA384, "sha384"),
|
||||
CONSTRUCTOR_METH_DEF(SHA512, "sha512"),
|
||||
CONSTRUCTOR_METH_DEF(BLAKE2B256, "blake2b256"),
|
||||
{NULL}
|
||||
{0}
|
||||
};
|
||||
|
||||
static struct PyModuleDef _hashlibmodule = {
|
||||
|
@ -822,7 +550,7 @@ static struct PyModuleDef _hashlibmodule = {
|
|||
"_hashlib",
|
||||
NULL,
|
||||
-1,
|
||||
EVP_functions,
|
||||
hashlib_functions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -833,11 +561,9 @@ PyMODINIT_FUNC
|
|||
PyInit__hashlib(void)
|
||||
{
|
||||
PyObject *m, *mbedtls_md_meth_names;
|
||||
Py_TYPE(&EVPtype) = &PyType_Type;
|
||||
if (PyType_Ready(&EVPtype) < 0)
|
||||
return NULL;
|
||||
if (!(m = PyModule_Create(&_hashlibmodule)))
|
||||
return NULL;
|
||||
Py_TYPE(&hasher_type) = &PyType_Type;
|
||||
if (PyType_Ready(&hasher_type) < 0) return 0;
|
||||
if (!(m = PyModule_Create(&_hashlibmodule))) return 0;
|
||||
if (!(mbedtls_md_meth_names = GenerateHashNameList())) {
|
||||
Py_DECREF(m);
|
||||
return NULL;
|
||||
|
@ -846,8 +572,8 @@ PyInit__hashlib(void)
|
|||
Py_DECREF(m);
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF((PyObject *)&EVPtype);
|
||||
PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
|
||||
Py_INCREF((PyObject *)&hasher_type);
|
||||
PyModule_AddObject(m, "HASH", (PyObject *)&hasher_type);
|
||||
INIT_CONSTRUCTOR_CONSTANTS(MD5, "md5")
|
||||
INIT_CONSTRUCTOR_CONSTANTS(SHA1, "sha1")
|
||||
INIT_CONSTRUCTOR_CONSTANTS(SHA224, "sha224")
|
||||
|
|
108
third_party/python/Modules/_heapqmodule.c
vendored
108
third_party/python/Modules/_heapqmodule.c
vendored
|
@ -28,7 +28,6 @@ PYTHON_PROVIDE("_heapq.heapreplace");
|
|||
C implementation derived directly from heapq.py in Py2.3
|
||||
which was written by Kevin O'Connor, augmented by Tim Peters,
|
||||
annotated by François Pinard, and converted to C by Raymond Hettinger.
|
||||
|
||||
*/
|
||||
|
||||
static int
|
||||
|
@ -37,14 +36,12 @@ siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
|
|||
PyObject *newitem, *parent, **arr;
|
||||
Py_ssize_t parentpos, size;
|
||||
int cmp;
|
||||
|
||||
assert(PyList_Check(heap));
|
||||
size = PyList_GET_SIZE(heap);
|
||||
if (pos >= size) {
|
||||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Follow the path to the root, moving parents down until finding
|
||||
a place newitem fits. */
|
||||
arr = _PyList_ITEMS(heap);
|
||||
|
@ -82,7 +79,6 @@ siftup(PyListObject *heap, Py_ssize_t pos)
|
|||
Py_ssize_t startpos, endpos, childpos, limit;
|
||||
PyObject *tmp1, *tmp2, **arr;
|
||||
int cmp;
|
||||
|
||||
assert(PyList_Check(heap));
|
||||
endpos = PyList_GET_SIZE(heap);
|
||||
startpos = pos;
|
||||
|
@ -90,7 +86,6 @@ siftup(PyListObject *heap, Py_ssize_t pos)
|
|||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Bubble up the smaller child until hitting a leaf. */
|
||||
arr = _PyList_ITEMS(heap);
|
||||
limit = endpos >> 1; /* smallest pos that has no child */
|
||||
|
@ -130,18 +125,14 @@ static PyObject *
|
|||
heappush(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *heap, *item;
|
||||
|
||||
if (!PyArg_UnpackTuple(args, "heappush", 2, 2, &heap, &item))
|
||||
return NULL;
|
||||
|
||||
if (!PyList_Check(heap)) {
|
||||
PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyList_Append(heap, item))
|
||||
return NULL;
|
||||
|
||||
if (siftdown((PyListObject *)heap, 0, PyList_GET_SIZE(heap)-1))
|
||||
return NULL;
|
||||
Py_RETURN_NONE;
|
||||
|
@ -155,19 +146,16 @@ heappop_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t))
|
|||
{
|
||||
PyObject *lastelt, *returnitem;
|
||||
Py_ssize_t n;
|
||||
|
||||
if (!PyList_Check(heap)) {
|
||||
PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* raises IndexError if the heap is empty */
|
||||
n = PyList_GET_SIZE(heap);
|
||||
if (n == 0) {
|
||||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lastelt = PyList_GET_ITEM(heap, n-1) ;
|
||||
Py_INCREF(lastelt);
|
||||
if (PyList_SetSlice(heap, n-1, n, NULL)) {
|
||||
|
@ -175,7 +163,6 @@ heappop_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t))
|
|||
return NULL;
|
||||
}
|
||||
n--;
|
||||
|
||||
if (!n)
|
||||
return lastelt;
|
||||
returnitem = PyList_GET_ITEM(heap, 0);
|
||||
|
@ -200,20 +187,16 @@ static PyObject *
|
|||
heapreplace_internal(PyObject *args, int siftup_func(PyListObject *, Py_ssize_t))
|
||||
{
|
||||
PyObject *heap, *item, *returnitem;
|
||||
|
||||
if (!PyArg_UnpackTuple(args, "heapreplace", 2, 2, &heap, &item))
|
||||
return NULL;
|
||||
|
||||
if (!PyList_Check(heap)) {
|
||||
PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyList_GET_SIZE(heap) == 0) {
|
||||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
returnitem = PyList_GET_ITEM(heap, 0);
|
||||
Py_INCREF(item);
|
||||
PyList_SET_ITEM(heap, 0, item);
|
||||
|
@ -243,23 +226,19 @@ this routine unless written as part of a conditional replacement:\n\n\
|
|||
static PyObject *
|
||||
heappushpop(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *heap, *item, *returnitem;
|
||||
int cmp;
|
||||
|
||||
PyObject *top, *heap, *item, *returnitem;
|
||||
if (!PyArg_UnpackTuple(args, "heappushpop", 2, 2, &heap, &item))
|
||||
return NULL;
|
||||
|
||||
if (!PyList_Check(heap)) {
|
||||
PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyList_GET_SIZE(heap) == 0) {
|
||||
Py_INCREF(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
PyObject* top = PyList_GET_ITEM(heap, 0);
|
||||
top = PyList_GET_ITEM(heap, 0);
|
||||
Py_INCREF(top);
|
||||
cmp = PyObject_RichCompareBool(top, item, Py_LT);
|
||||
Py_DECREF(top);
|
||||
|
@ -269,12 +248,10 @@ heappushpop(PyObject *self, PyObject *args)
|
|||
Py_INCREF(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
if (PyList_GET_SIZE(heap) == 0) {
|
||||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
returnitem = PyList_GET_ITEM(heap, 0);
|
||||
Py_INCREF(item);
|
||||
PyList_SET_ITEM(heap, 0, item);
|
||||
|
@ -290,16 +267,27 @@ PyDoc_STRVAR(heappushpop_doc,
|
|||
from the heap. The combined action runs more efficiently than\n\
|
||||
heappush() followed by a separate call to heappop().");
|
||||
|
||||
static Py_ssize_t
|
||||
static inline Py_ssize_t
|
||||
keep_top_bit(Py_ssize_t n)
|
||||
{
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
/* [jart] constant-time bitscan */
|
||||
if (n > 0) {
|
||||
return (Py_ssize_t)1 << (__builtin_clzll(n) ^
|
||||
(sizeof(long long) * CHAR_BIT - 1));
|
||||
} else if (n < 0) {
|
||||
return n;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int i = 0;
|
||||
|
||||
while (n > 1) {
|
||||
n >>= 1;
|
||||
i++;
|
||||
}
|
||||
return n << i;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Cache friendly version of heapify()
|
||||
|
@ -326,11 +314,9 @@ static PyObject *
|
|||
cache_friendly_heapify(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t))
|
||||
{
|
||||
Py_ssize_t i, j, m, mhalf, leftmost;
|
||||
|
||||
m = PyList_GET_SIZE(heap) >> 1; /* index of first childless node */
|
||||
leftmost = keep_top_bit(m + 1) - 1; /* leftmost node in row of m */
|
||||
mhalf = m >> 1; /* parent of first childless node */
|
||||
|
||||
for (i = leftmost - 1 ; i >= mhalf ; i--) {
|
||||
j = i;
|
||||
while (1) {
|
||||
|
@ -341,7 +327,6 @@ cache_friendly_heapify(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_
|
|||
j >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = m - 1 ; i >= leftmost ; i--) {
|
||||
j = i;
|
||||
while (1) {
|
||||
|
@ -359,12 +344,10 @@ static PyObject *
|
|||
heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t))
|
||||
{
|
||||
Py_ssize_t i, n;
|
||||
|
||||
if (!PyList_Check(heap)) {
|
||||
PyErr_SetString(PyExc_TypeError, "heap argument must be a list");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* For heaps likely to be bigger than L1 cache, we use the cache
|
||||
friendly heapify function. For smaller heaps that fit entirely
|
||||
in cache, we prefer the simpler algorithm with less branching.
|
||||
|
@ -372,7 +355,6 @@ heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t))
|
|||
n = PyList_GET_SIZE(heap);
|
||||
if (n > 2500)
|
||||
return cache_friendly_heapify(heap, siftup_func);
|
||||
|
||||
/* Transform bottom-up. The largest index there's any point to
|
||||
looking at is the largest with a child index in-range, so must
|
||||
have 2*i + 1 < n, or i < (n-1)/2. If n is even = 2*j, this is
|
||||
|
@ -401,14 +383,12 @@ siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
|
|||
PyObject *newitem, *parent, **arr;
|
||||
Py_ssize_t parentpos, size;
|
||||
int cmp;
|
||||
|
||||
assert(PyList_Check(heap));
|
||||
size = PyList_GET_SIZE(heap);
|
||||
if (pos >= size) {
|
||||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Follow the path to the root, moving parents down until finding
|
||||
a place newitem fits. */
|
||||
arr = _PyList_ITEMS(heap);
|
||||
|
@ -446,7 +426,6 @@ siftup_max(PyListObject *heap, Py_ssize_t pos)
|
|||
Py_ssize_t startpos, endpos, childpos, limit;
|
||||
PyObject *tmp1, *tmp2, **arr;
|
||||
int cmp;
|
||||
|
||||
assert(PyList_Check(heap));
|
||||
endpos = PyList_GET_SIZE(heap);
|
||||
startpos = pos;
|
||||
|
@ -454,7 +433,6 @@ siftup_max(PyListObject *heap, Py_ssize_t pos)
|
|||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Bubble up the smaller child until hitting a leaf. */
|
||||
arr = _PyList_ITEMS(heap);
|
||||
limit = endpos >> 1; /* smallest pos that has no child */
|
||||
|
@ -515,23 +493,39 @@ heapify_max(PyObject *self, PyObject *heap)
|
|||
PyDoc_STRVAR(heapify_max_doc, "Maxheap variant of heapify.");
|
||||
|
||||
static PyMethodDef heapq_methods[] = {
|
||||
{"heappush", (PyCFunction)heappush,
|
||||
METH_VARARGS, heappush_doc},
|
||||
{"heappushpop", (PyCFunction)heappushpop,
|
||||
METH_VARARGS, heappushpop_doc},
|
||||
{"heappop", (PyCFunction)heappop,
|
||||
METH_O, heappop_doc},
|
||||
{"heapreplace", (PyCFunction)heapreplace,
|
||||
METH_VARARGS, heapreplace_doc},
|
||||
{"heapify", (PyCFunction)heapify,
|
||||
METH_O, heapify_doc},
|
||||
{"_heappop_max", (PyCFunction)heappop_max,
|
||||
METH_O, heappop_max_doc},
|
||||
{"_heapreplace_max",(PyCFunction)heapreplace_max,
|
||||
METH_VARARGS, heapreplace_max_doc},
|
||||
{"_heapify_max", (PyCFunction)heapify_max,
|
||||
METH_O, heapify_max_doc},
|
||||
{NULL, NULL} /* sentinel */
|
||||
{"heappush",
|
||||
(PyCFunction)heappush,
|
||||
METH_VARARGS,
|
||||
heappush_doc},
|
||||
{"heappushpop",
|
||||
(PyCFunction)heappushpop,
|
||||
METH_VARARGS,
|
||||
heappushpop_doc},
|
||||
{"heappop",
|
||||
(PyCFunction)heappop,
|
||||
METH_O,
|
||||
heappop_doc},
|
||||
{"heapreplace",
|
||||
(PyCFunction)heapreplace,
|
||||
METH_VARARGS,
|
||||
heapreplace_doc},
|
||||
{"heapify",
|
||||
(PyCFunction)heapify,
|
||||
METH_O,
|
||||
heapify_doc},
|
||||
{"_heappop_max",
|
||||
(PyCFunction)heappop_max,
|
||||
METH_O,
|
||||
heappop_max_doc},
|
||||
{"_heapreplace_max",
|
||||
(PyCFunction)heapreplace_max,
|
||||
METH_VARARGS,
|
||||
heapreplace_max_doc},
|
||||
{"_heapify_max",
|
||||
(PyCFunction)heapify_max,
|
||||
METH_O,
|
||||
heapify_max_doc},
|
||||
{0}
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(module_doc,
|
||||
|
@ -676,7 +670,6 @@ PyMODINIT_FUNC
|
|||
PyInit__heapq(void)
|
||||
{
|
||||
PyObject *m, *about;
|
||||
|
||||
m = PyModule_Create(&_heapqmodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
@ -684,3 +677,8 @@ PyInit__heapq(void)
|
|||
PyModule_AddObject(m, "__about__", about);
|
||||
return m;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__heapq = {
|
||||
"_heapq",
|
||||
PyInit__heapq,
|
||||
};
|
||||
|
|
4
third_party/python/Modules/_io/bytesio.c
vendored
4
third_party/python/Modules/_io/bytesio.c
vendored
|
@ -206,8 +206,8 @@ write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
|
|||
| | <--to pad-->|<---to write---> |
|
||||
0 buf position
|
||||
*/
|
||||
memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
|
||||
(self->pos - self->string_size) * sizeof(char));
|
||||
bzero(PyBytes_AS_STRING(self->buf) + self->string_size,
|
||||
(self->pos - self->string_size) * sizeof(char));
|
||||
}
|
||||
|
||||
/* Copy the data to the internal buffer, overwriting some of the existing
|
||||
|
|
4
third_party/python/Modules/_io/stringio.c
vendored
4
third_party/python/Modules/_io/stringio.c
vendored
|
@ -257,8 +257,8 @@ write_str(stringio *self, PyObject *obj)
|
|||
0 buf position
|
||||
|
||||
*/
|
||||
memset(self->buf + self->string_size, '\0',
|
||||
(self->pos - self->string_size) * sizeof(Py_UCS4));
|
||||
bzero(self->buf + self->string_size,
|
||||
(self->pos - self->string_size) * sizeof(Py_UCS4));
|
||||
}
|
||||
|
||||
/* Copy the data to the internal buffer, overwriting some of the
|
||||
|
|
|
@ -559,7 +559,6 @@ read_console_w(HANDLE handle, DWORD maxlen, DWORD *readlen) {
|
|||
|
||||
*readlen = 0;
|
||||
|
||||
//DebugBreak();
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
DWORD off = 0;
|
||||
while (off < maxlen) {
|
||||
|
|
5
third_party/python/Modules/_localemodule.c
vendored
5
third_party/python/Modules/_localemodule.c
vendored
|
@ -775,3 +775,8 @@ c-basic-offset: 4
|
|||
indent-tabs-mode: nil
|
||||
End:
|
||||
*/
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__locale = {
|
||||
"_locale",
|
||||
PyInit__locale,
|
||||
};
|
||||
|
|
|
@ -31,11 +31,6 @@ PYTHON_PROVIDE("_sha3.sha3_512");
|
|||
PYTHON_PROVIDE("_sha3.shake_128");
|
||||
PYTHON_PROVIDE("_sha3.shake_256");
|
||||
|
||||
/*
|
||||
Ran preprocessor on working build, because spaghetti structure of
|
||||
upstream Python 3.6 source code was unnaceptably incomprehensible
|
||||
*/
|
||||
|
||||
typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn;
|
||||
|
||||
typedef struct KeccakWidth1600_SpongeInstanceStruct {
|
28
third_party/python/Modules/_lsprof.c
vendored
28
third_party/python/Modules/_lsprof.c
vendored
|
@ -1,3 +1,9 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
|
@ -509,21 +515,21 @@ pending_exception(ProfilerObject *pObj)
|
|||
/************************************************************/
|
||||
|
||||
static PyStructSequence_Field profiler_entry_fields[] = {
|
||||
{"code", "code object or built-in function name"},
|
||||
{"callcount", "how many times this was called"},
|
||||
{"reccallcount", "how many times called recursively"},
|
||||
{"totaltime", "total time in this entry"},
|
||||
{"inlinetime", "inline time in this entry (not in subcalls)"},
|
||||
{"calls", "details of the calls"},
|
||||
{"code", PyDoc_STR("code object or built-in function name")},
|
||||
{"callcount", PyDoc_STR("how many times this was called")},
|
||||
{"reccallcount", PyDoc_STR("how many times called recursively")},
|
||||
{"totaltime", PyDoc_STR("total time in this entry")},
|
||||
{"inlinetime", PyDoc_STR("inline time in this entry (not in subcalls)")},
|
||||
{"calls", PyDoc_STR("details of the calls")},
|
||||
{0}
|
||||
};
|
||||
|
||||
static PyStructSequence_Field profiler_subentry_fields[] = {
|
||||
{"code", "called code object or built-in function name"},
|
||||
{"callcount", "how many times this is called"},
|
||||
{"reccallcount", "how many times this is called recursively"},
|
||||
{"totaltime", "total time spent in this call"},
|
||||
{"inlinetime", "inline time (not in further subcalls)"},
|
||||
{"code", PyDoc_STR("called code object or built-in function name")},
|
||||
{"callcount", PyDoc_STR("how many times this is called")},
|
||||
{"reccallcount", PyDoc_STR("how many times this is called recursively")},
|
||||
{"totaltime", PyDoc_STR("total time spent in this call")},
|
||||
{"inlinetime", PyDoc_STR("inline time (not in further subcalls)")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
9
third_party/python/Modules/_operator.c
vendored
9
third_party/python/Modules/_operator.c
vendored
|
@ -1286,25 +1286,26 @@ PyMODINIT_FUNC
|
|||
PyInit__operator(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
/* Create the module and add the functions */
|
||||
m = PyModule_Create(&operatormodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
if (PyType_Ready(&itemgetter_type) < 0)
|
||||
return NULL;
|
||||
Py_INCREF(&itemgetter_type);
|
||||
PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type);
|
||||
|
||||
if (PyType_Ready(&attrgetter_type) < 0)
|
||||
return NULL;
|
||||
Py_INCREF(&attrgetter_type);
|
||||
PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
|
||||
|
||||
if (PyType_Ready(&methodcaller_type) < 0)
|
||||
return NULL;
|
||||
Py_INCREF(&methodcaller_type);
|
||||
PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type);
|
||||
return m;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__operator = {
|
||||
"_operator",
|
||||
PyInit__operator,
|
||||
};
|
||||
|
|
20
third_party/python/Modules/_randommodule.c
vendored
20
third_party/python/Modules/_randommodule.c
vendored
|
@ -4,7 +4,12 @@
|
|||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
#include "third_party/python/Include/floatobject.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/longobject.h"
|
||||
|
@ -22,6 +27,11 @@
|
|||
PYTHON_PROVIDE("_random");
|
||||
PYTHON_PROVIDE("_random.Random");
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
mt19937 (BSD-3)\\n\
|
||||
Copyright 1997-2004 Makoto Matsumoto and Takuji Nishimura\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
The code in this module was based on a download from:
|
||||
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
|
||||
|
@ -166,7 +176,6 @@ init_genrand(RandomObject *self, uint32_t s)
|
|||
{
|
||||
int mti;
|
||||
uint32_t *mt;
|
||||
|
||||
mt = self->state;
|
||||
mt[0]= s;
|
||||
for (mti=1; mti<N; mti++) {
|
||||
|
@ -189,7 +198,6 @@ 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 */
|
||||
uint32_t *mt;
|
||||
|
||||
mt = self->state;
|
||||
init_genrand(self, 19650218U);
|
||||
i=1; j=0;
|
||||
|
@ -207,7 +215,6 @@ init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length)
|
|||
i++;
|
||||
if (i>=N) { mt[0] = mt[N-1]; i=1; }
|
||||
}
|
||||
|
||||
mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
|
||||
}
|
||||
|
||||
|
@ -220,9 +227,8 @@ static int
|
|||
random_seed_urandom(RandomObject *self)
|
||||
{
|
||||
PY_UINT32_T key[N];
|
||||
|
||||
if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) {
|
||||
return -1;
|
||||
abort();
|
||||
}
|
||||
init_by_array(self, key, Py_ARRAY_LENGTH(key));
|
||||
return 0;
|
||||
|
@ -233,17 +239,13 @@ 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/pythread.h"
|
||||
#include "third_party/python/Include/structmember.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/Modules/_sqlite/cache.h"
|
||||
#include "third_party/python/Modules/_sqlite/connection.h"
|
||||
#include "third_party/python/Modules/_sqlite/cursor.h"
|
||||
|
@ -33,6 +34,8 @@
|
|||
#include "third_party/python/Modules/_sqlite/statement.h"
|
||||
#include "third_party/python/Modules/_sqlite/util.h"
|
||||
|
||||
PYTHON_YOINK("sqlite3.dump");
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
pysqlite (zlib license)\\n\
|
||||
Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>\"");
|
||||
|
|
49
third_party/python/Modules/_sre.c
vendored
49
third_party/python/Modules/_sre.c
vendored
|
@ -4,6 +4,7 @@
|
|||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/boolobject.h"
|
||||
#include "third_party/python/Include/bytesobject.h"
|
||||
|
@ -36,10 +37,15 @@ PYTHON_PROVIDE("_sre.__name__");
|
|||
PYTHON_PROVIDE("_sre.__package__");
|
||||
PYTHON_PROVIDE("_sre.__spec__");
|
||||
PYTHON_PROVIDE("_sre.compile");
|
||||
PYTHON_PROVIDE("_sre.copyright");
|
||||
PYTHON_PROVIDE("_sre.getcodesize");
|
||||
PYTHON_PROVIDE("_sre.getlower");
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
SRE 2.2.2 (Python license)\\n\
|
||||
Copyright 1997-2002 Secret Labs AB\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* Secret Labs' Regular Expression Engine
|
||||
*
|
||||
|
@ -77,11 +83,6 @@ PYTHON_PROVIDE("_sre.getlower");
|
|||
* other compatibility work.
|
||||
*/
|
||||
|
||||
static const char copyright[] =
|
||||
" SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB ";
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
|
||||
#define SRE_CODE_BITS (8 * sizeof(SRE_CODE))
|
||||
|
||||
/* name of this module, minus the leading underscore */
|
||||
|
@ -148,17 +149,25 @@ static unsigned int sre_upper(unsigned int ch)
|
|||
/* locale-specific character predicates */
|
||||
/* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
|
||||
* warnings when c's type supports only numbers < N+1 */
|
||||
#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0)
|
||||
#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? Py_ISALNUM((ch)) : 0)
|
||||
#define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_')
|
||||
|
||||
static unsigned int sre_lower_locale(unsigned int ch)
|
||||
static inline unsigned int sre_lower_locale(unsigned int ch)
|
||||
{
|
||||
#ifdef __COSMOPOLITAN__
|
||||
return sre_lower(ch);
|
||||
#else
|
||||
return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned int sre_upper_locale(unsigned int ch)
|
||||
static inline unsigned int sre_upper_locale(unsigned int ch)
|
||||
{
|
||||
#ifdef __COSMOPOLITAN__
|
||||
return sre_upper(ch);
|
||||
#else
|
||||
return ((ch) < 256 ? (unsigned int)toupper((ch)) : ch);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* unicode-specific character predicates */
|
||||
|
@ -199,12 +208,10 @@ sre_category(SRE_CODE category, unsigned int ch)
|
|||
return SRE_IS_LINEBREAK(ch);
|
||||
case SRE_CATEGORY_NOT_LINEBREAK:
|
||||
return !SRE_IS_LINEBREAK(ch);
|
||||
|
||||
case SRE_CATEGORY_LOC_WORD:
|
||||
return SRE_LOC_IS_WORD(ch);
|
||||
case SRE_CATEGORY_LOC_NOT_WORD:
|
||||
return !SRE_LOC_IS_WORD(ch);
|
||||
|
||||
case SRE_CATEGORY_UNI_DIGIT:
|
||||
return SRE_UNI_IS_DIGIT(ch);
|
||||
case SRE_CATEGORY_UNI_NOT_DIGIT:
|
||||
|
@ -225,8 +232,6 @@ sre_category(SRE_CODE category, unsigned int ch)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* helpers */
|
||||
|
||||
static void
|
||||
data_stack_dealloc(SRE_STATE* state)
|
||||
{
|
||||
|
@ -2734,8 +2739,8 @@ pattern_richcompare(PyObject *lefto, PyObject *righto, int op)
|
|||
produce different codes depending on the locale used to compile the
|
||||
pattern when the re.LOCALE flag is used. Don't compare groups,
|
||||
indexgroup nor groupindex: they are derivated from the pattern. */
|
||||
cmp = (memcmp(left->code, right->code,
|
||||
sizeof(left->code[0]) * left->codesize) == 0);
|
||||
cmp = !bcmp(left->code, right->code,
|
||||
sizeof(left->code[0]) * left->codesize);
|
||||
}
|
||||
if (cmp) {
|
||||
cmp = PyObject_RichCompareBool(left->pattern, right->pattern,
|
||||
|
@ -2948,7 +2953,8 @@ static struct PyModuleDef sremodule = {
|
|||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit__sre(void)
|
||||
PyMODINIT_FUNC
|
||||
PyInit__sre(void)
|
||||
{
|
||||
PyObject* m;
|
||||
PyObject* d;
|
||||
|
@ -2988,13 +2994,10 @@ PyMODINIT_FUNC PyInit__sre(void)
|
|||
Py_DECREF(x);
|
||||
}
|
||||
|
||||
x = PyUnicode_FromString(copyright);
|
||||
if (x) {
|
||||
PyDict_SetItemString(d, "copyright", x);
|
||||
Py_DECREF(x);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/* vim:ts=4:sw=4:et
|
||||
*/
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__sre = {
|
||||
"_sre",
|
||||
PyInit__sre,
|
||||
};
|
||||
|
|
3
third_party/python/Modules/_struct.c
vendored
3
third_party/python/Modules/_struct.c
vendored
|
@ -1786,8 +1786,7 @@ s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
|
|||
/* XXX(nnorwitz): why does i need to be a local? can we use
|
||||
the offset parameter or do we need the wider width? */
|
||||
Py_ssize_t i;
|
||||
|
||||
memset(buf, '\0', soself->s_size);
|
||||
bzero(buf, soself->s_size);
|
||||
i = offset;
|
||||
for (code = soself->s_codes; code->fmtdef != NULL; code++) {
|
||||
const formatdef *e = code->fmtdef;
|
||||
|
|
2
third_party/python/Modules/_testbuffer.c
vendored
2
third_party/python/Modules/_testbuffer.c
vendored
|
@ -2605,7 +2605,7 @@ cmp_contig(PyObject *self, PyObject *args)
|
|||
goto result;
|
||||
}
|
||||
|
||||
if (memcmp((char *)v1.buf, (char *)v2.buf, v1.len) != 0) {
|
||||
if (bcmp((char *)v1.buf, (char *)v2.buf, v1.len)) {
|
||||
goto result;
|
||||
}
|
||||
|
||||
|
|
8
third_party/python/Modules/arraymodule.c
vendored
8
third_party/python/Modules/arraymodule.c
vendored
|
@ -1816,9 +1816,9 @@ typecode_to_mformat_code(char typecode)
|
|||
case 'f':
|
||||
if (sizeof(float) == 4) {
|
||||
const float y = 16711938.0;
|
||||
if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
|
||||
if (!bcmp(&y, "\x4b\x7f\x01\x02", 4))
|
||||
return IEEE_754_FLOAT_BE;
|
||||
if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
|
||||
if (!bcmp(&y, "\x02\x01\x7f\x4b", 4))
|
||||
return IEEE_754_FLOAT_LE;
|
||||
}
|
||||
return UNKNOWN_FORMAT;
|
||||
|
@ -1826,9 +1826,9 @@ typecode_to_mformat_code(char typecode)
|
|||
case 'd':
|
||||
if (sizeof(double) == 8) {
|
||||
const double x = 9006104071832581.0;
|
||||
if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
|
||||
if (!bcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8))
|
||||
return IEEE_754_DOUBLE_BE;
|
||||
if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
|
||||
if (!bcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8))
|
||||
return IEEE_754_DOUBLE_LE;
|
||||
}
|
||||
return UNKNOWN_FORMAT;
|
||||
|
|
324
third_party/python/Modules/audioop.c
vendored
324
third_party/python/Modules/audioop.c
vendored
|
@ -5,6 +5,7 @@
|
|||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "dsp/core/core.h"
|
||||
#include "libc/math.h"
|
||||
#include "third_party/python/Include/dictobject.h"
|
||||
#include "third_party/python/Include/floatobject.h"
|
||||
|
@ -71,256 +72,12 @@ fbound(double val, double minval, double maxval)
|
|||
else if (val < minval + 1.0) {
|
||||
val = minval;
|
||||
}
|
||||
|
||||
/* Round towards minus infinity (-inf) */
|
||||
val = floor(val);
|
||||
|
||||
/* Cast double to integer: round towards zero */
|
||||
return (int)val;
|
||||
}
|
||||
|
||||
|
||||
/* Code shamelessly stolen from sox, 12.17.7, g711.c
|
||||
** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
|
||||
|
||||
/* From g711.c:
|
||||
*
|
||||
* December 30, 1994:
|
||||
* Functions linear2alaw, linear2ulaw have been updated to correctly
|
||||
* convert unquantized 16 bit values.
|
||||
* Tables for direct u- to A-law and A- to u-law conversions have been
|
||||
* corrected.
|
||||
* Borge Lindberg, Center for PersonKommunikation, Aalborg University.
|
||||
* bli@cpk.auc.dk
|
||||
*
|
||||
*/
|
||||
#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
|
||||
#define CLIP 32635
|
||||
#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
|
||||
#define QUANT_MASK (0xf) /* Quantization field mask. */
|
||||
#define SEG_SHIFT (4) /* Left shift for segment number. */
|
||||
#define SEG_MASK (0x70) /* Segment field mask. */
|
||||
|
||||
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 int16_t
|
||||
search(int16_t val, const int16_t *table, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (val <= *table++)
|
||||
return (i);
|
||||
}
|
||||
return (size);
|
||||
}
|
||||
#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
|
||||
#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
|
||||
|
||||
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,
|
||||
-13436, -12924, -12412, -11900, -11388, -10876, -10364,
|
||||
-9852, -9340, -8828, -8316, -7932, -7676, -7420,
|
||||
-7164, -6908, -6652, -6396, -6140, -5884, -5628,
|
||||
-5372, -5116, -4860, -4604, -4348, -4092, -3900,
|
||||
-3772, -3644, -3516, -3388, -3260, -3132, -3004,
|
||||
-2876, -2748, -2620, -2492, -2364, -2236, -2108,
|
||||
-1980, -1884, -1820, -1756, -1692, -1628, -1564,
|
||||
-1500, -1436, -1372, -1308, -1244, -1180, -1116,
|
||||
-1052, -988, -924, -876, -844, -812, -780,
|
||||
-748, -716, -684, -652, -620, -588, -556,
|
||||
-524, -492, -460, -428, -396, -372, -356,
|
||||
-340, -324, -308, -292, -276, -260, -244,
|
||||
-228, -212, -196, -180, -164, -148, -132,
|
||||
-120, -112, -104, -96, -88, -80, -72,
|
||||
-64, -56, -48, -40, -32, -24, -16,
|
||||
-8, 0, 32124, 31100, 30076, 29052, 28028,
|
||||
27004, 25980, 24956, 23932, 22908, 21884, 20860,
|
||||
19836, 18812, 17788, 16764, 15996, 15484, 14972,
|
||||
14460, 13948, 13436, 12924, 12412, 11900, 11388,
|
||||
10876, 10364, 9852, 9340, 8828, 8316, 7932,
|
||||
7676, 7420, 7164, 6908, 6652, 6396, 6140,
|
||||
5884, 5628, 5372, 5116, 4860, 4604, 4348,
|
||||
4092, 3900, 3772, 3644, 3516, 3388, 3260,
|
||||
3132, 3004, 2876, 2748, 2620, 2492, 2364,
|
||||
2236, 2108, 1980, 1884, 1820, 1756, 1692,
|
||||
1628, 1564, 1500, 1436, 1372, 1308, 1244,
|
||||
1180, 1116, 1052, 988, 924, 876, 844,
|
||||
812, 780, 748, 716, 684, 652, 620,
|
||||
588, 556, 524, 492, 460, 428, 396,
|
||||
372, 356, 340, 324, 308, 292, 276,
|
||||
260, 244, 228, 212, 196, 180, 164,
|
||||
148, 132, 120, 112, 104, 96, 88,
|
||||
80, 72, 64, 56, 48, 40, 32,
|
||||
24, 16, 8, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
|
||||
* stored in an unsigned char. This function should only be called with
|
||||
* the data shifted such that it only contains information in the lower
|
||||
* 14-bits.
|
||||
*
|
||||
* In order to simplify the encoding process, the original linear magnitude
|
||||
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
|
||||
* (33 - 8191). The result can be seen in the following encoding table:
|
||||
*
|
||||
* Biased Linear Input Code Compressed Code
|
||||
* ------------------------ ---------------
|
||||
* 00000001wxyza 000wxyz
|
||||
* 0000001wxyzab 001wxyz
|
||||
* 000001wxyzabc 010wxyz
|
||||
* 00001wxyzabcd 011wxyz
|
||||
* 0001wxyzabcde 100wxyz
|
||||
* 001wxyzabcdef 101wxyz
|
||||
* 01wxyzabcdefg 110wxyz
|
||||
* 1wxyzabcdefgh 111wxyz
|
||||
*
|
||||
* Each biased linear code has a leading 1 which identifies the segment
|
||||
* number. The value of the segment number is equal to 7 minus the number
|
||||
* of leading 0's. The quantization interval is directly available as the
|
||||
* four bits wxyz. * The trailing bits (a - h) are ignored.
|
||||
*
|
||||
* Ordinarily the complement of the resulting code word is used for
|
||||
* transmission, and so the code word is complemented before it is returned.
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
static unsigned char
|
||||
st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */
|
||||
{
|
||||
int16_t mask;
|
||||
int16_t seg;
|
||||
unsigned char uval;
|
||||
|
||||
/* u-law inverts all bits */
|
||||
/* Get the sign and the magnitude of the value. */
|
||||
if (pcm_val < 0) {
|
||||
pcm_val = -pcm_val;
|
||||
mask = 0x7F;
|
||||
} else {
|
||||
mask = 0xFF;
|
||||
}
|
||||
if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
|
||||
pcm_val += (BIAS >> 2);
|
||||
|
||||
/* Convert the scaled magnitude to segment number. */
|
||||
seg = search(pcm_val, seg_uend, 8);
|
||||
|
||||
/*
|
||||
* Combine the sign, segment, quantization bits;
|
||||
* and complement the code word.
|
||||
*/
|
||||
if (seg >= 8) /* out of range, return maximum value. */
|
||||
return (unsigned char) (0x7F ^ mask);
|
||||
else {
|
||||
uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
|
||||
return (uval ^ mask);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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,
|
||||
-2112, -2496, -2368, -3776, -3648, -4032, -3904,
|
||||
-3264, -3136, -3520, -3392, -22016, -20992, -24064,
|
||||
-23040, -17920, -16896, -19968, -18944, -30208, -29184,
|
||||
-32256, -31232, -26112, -25088, -28160, -27136, -11008,
|
||||
-10496, -12032, -11520, -8960, -8448, -9984, -9472,
|
||||
-15104, -14592, -16128, -15616, -13056, -12544, -14080,
|
||||
-13568, -344, -328, -376, -360, -280, -264,
|
||||
-312, -296, -472, -456, -504, -488, -408,
|
||||
-392, -440, -424, -88, -72, -120, -104,
|
||||
-24, -8, -56, -40, -216, -200, -248,
|
||||
-232, -152, -136, -184, -168, -1376, -1312,
|
||||
-1504, -1440, -1120, -1056, -1248, -1184, -1888,
|
||||
-1824, -2016, -1952, -1632, -1568, -1760, -1696,
|
||||
-688, -656, -752, -720, -560, -528, -624,
|
||||
-592, -944, -912, -1008, -976, -816, -784,
|
||||
-880, -848, 5504, 5248, 6016, 5760, 4480,
|
||||
4224, 4992, 4736, 7552, 7296, 8064, 7808,
|
||||
6528, 6272, 7040, 6784, 2752, 2624, 3008,
|
||||
2880, 2240, 2112, 2496, 2368, 3776, 3648,
|
||||
4032, 3904, 3264, 3136, 3520, 3392, 22016,
|
||||
20992, 24064, 23040, 17920, 16896, 19968, 18944,
|
||||
30208, 29184, 32256, 31232, 26112, 25088, 28160,
|
||||
27136, 11008, 10496, 12032, 11520, 8960, 8448,
|
||||
9984, 9472, 15104, 14592, 16128, 15616, 13056,
|
||||
12544, 14080, 13568, 344, 328, 376, 360,
|
||||
280, 264, 312, 296, 472, 456, 504,
|
||||
488, 408, 392, 440, 424, 88, 72,
|
||||
120, 104, 24, 8, 56, 40, 216,
|
||||
200, 248, 232, 152, 136, 184, 168,
|
||||
1376, 1312, 1504, 1440, 1120, 1056, 1248,
|
||||
1184, 1888, 1824, 2016, 1952, 1632, 1568,
|
||||
1760, 1696, 688, 656, 752, 720, 560,
|
||||
528, 624, 592, 944, 912, 1008, 976,
|
||||
816, 784, 880, 848
|
||||
};
|
||||
|
||||
/*
|
||||
* linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data
|
||||
* stored in an unsigned char. This function should only be called with
|
||||
* the data shifted such that it only contains information in the lower
|
||||
* 13-bits.
|
||||
*
|
||||
* Linear Input Code Compressed Code
|
||||
* ------------------------ ---------------
|
||||
* 0000000wxyza 000wxyz
|
||||
* 0000001wxyza 001wxyz
|
||||
* 000001wxyzab 010wxyz
|
||||
* 00001wxyzabc 011wxyz
|
||||
* 0001wxyzabcd 100wxyz
|
||||
* 001wxyzabcde 101wxyz
|
||||
* 01wxyzabcdef 110wxyz
|
||||
* 1wxyzabcdefg 111wxyz
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
static unsigned char
|
||||
st_linear2alaw(int16_t pcm_val) /* 2's complement (13-bit range) */
|
||||
{
|
||||
int16_t mask;
|
||||
int16_t seg;
|
||||
unsigned char aval;
|
||||
|
||||
/* A-law using even bit inversion */
|
||||
if (pcm_val >= 0) {
|
||||
mask = 0xD5; /* sign (7th) bit = 1 */
|
||||
} else {
|
||||
mask = 0x55; /* sign bit = 0 */
|
||||
pcm_val = -pcm_val - 1;
|
||||
}
|
||||
|
||||
/* Convert the scaled magnitude to segment number. */
|
||||
seg = search(pcm_val, seg_aend, 8);
|
||||
|
||||
/* Combine the sign, segment, and quantization bits. */
|
||||
|
||||
if (seg >= 8) /* out of range, return maximum value. */
|
||||
return (unsigned char) (0x7F ^ mask);
|
||||
else {
|
||||
aval = (unsigned char) seg << SEG_SHIFT;
|
||||
if (seg < 2)
|
||||
aval |= (pcm_val >> 1) & QUANT_MASK;
|
||||
else
|
||||
aval |= (pcm_val >> seg) & QUANT_MASK;
|
||||
return (aval ^ mask);
|
||||
}
|
||||
}
|
||||
/* End of code taken from sox */
|
||||
|
||||
/* Intel ADPCM step variation table */
|
||||
static const int indexTable[16] = {
|
||||
-1, -1, -1, -1, 2, 4, 6, 8,
|
||||
|
@ -344,7 +101,6 @@ static const int stepsizeTable[89] = {
|
|||
*(T *)((unsigned char *)(cp) + (i)) = (T)(val); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define GETINT8(cp, i) GETINTX(signed char, (cp), (i))
|
||||
#define GETINT16(cp, i) GETINTX(int16_t, (cp), (i))
|
||||
#define GETINT32(cp, i) GETINTX(int32_t, (cp), (i))
|
||||
|
@ -361,7 +117,6 @@ static const int stepsizeTable[89] = {
|
|||
(((signed char *)(cp) + (i))[2] << 16) )
|
||||
#endif
|
||||
|
||||
|
||||
#define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val))
|
||||
#define SETINT16(cp, i, val) SETINTX(int16_t, (cp), (i), (val))
|
||||
#define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val))
|
||||
|
@ -380,7 +135,6 @@ static const int stepsizeTable[89] = {
|
|||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
#define GETRAWSAMPLE(size, cp, i) ( \
|
||||
(size == 1) ? (int)GETINT8((cp), (i)) : \
|
||||
(size == 2) ? (int)GETINT16((cp), (i)) : \
|
||||
|
@ -398,7 +152,6 @@ static const int stepsizeTable[89] = {
|
|||
SETINT32((cp), (i), (val)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define GETSAMPLE32(size, cp, i) ( \
|
||||
(size == 1) ? (int)GETINT8((cp), (i)) << 24 : \
|
||||
(size == 2) ? (int)GETINT16((cp), (i)) << 16 : \
|
||||
|
@ -416,7 +169,6 @@ static const int stepsizeTable[89] = {
|
|||
SETINT32((cp), (i), (val)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
static PyObject *AudioopError;
|
||||
|
||||
static int
|
||||
|
@ -426,8 +178,7 @@ audioop_check_size(int size)
|
|||
PyErr_SetString(AudioopError, "Size should be 1, 2, 3 or 4");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -464,7 +215,6 @@ audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
|
|||
/*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/
|
||||
{
|
||||
int val;
|
||||
|
||||
if (!audioop_check_parameters(fragment->len, width))
|
||||
return NULL;
|
||||
if (index < 0 || index >= fragment->len/width) {
|
||||
|
@ -491,7 +241,6 @@ audioop_max_impl(PyObject *module, Py_buffer *fragment, int width)
|
|||
{
|
||||
Py_ssize_t i;
|
||||
unsigned int absval, max = 0;
|
||||
|
||||
if (!audioop_check_parameters(fragment->len, width))
|
||||
return NULL;
|
||||
for (i = 0; i < fragment->len; i += width) {
|
||||
|
@ -657,7 +406,6 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
|
|||
Py_ssize_t j, best_j;
|
||||
double aj_m1, aj_lm1;
|
||||
double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
|
||||
|
||||
if (fragment->len & 1 || reference->len & 1) {
|
||||
PyErr_SetString(AudioopError, "Strings should be even-sized");
|
||||
return NULL;
|
||||
|
@ -666,7 +414,6 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
|
|||
len1 = fragment->len >> 1;
|
||||
cp2 = (const int16_t *)reference->buf;
|
||||
len2 = reference->len >> 1;
|
||||
|
||||
if (len1 < len2) {
|
||||
PyErr_SetString(AudioopError, "First sample should be longer");
|
||||
return NULL;
|
||||
|
@ -674,31 +421,22 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
|
|||
sum_ri_2 = _sum2(cp2, cp2, len2);
|
||||
sum_aij_2 = _sum2(cp1, cp1, len2);
|
||||
sum_aij_ri = _sum2(cp1, cp2, len2);
|
||||
|
||||
result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2;
|
||||
|
||||
best_result = result;
|
||||
best_j = 0;
|
||||
|
||||
for ( j=1; j<=len1-len2; j++) {
|
||||
aj_m1 = (double)cp1[j-1];
|
||||
aj_lm1 = (double)cp1[j+len2-1];
|
||||
|
||||
sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1;
|
||||
sum_aij_ri = _sum2(cp1+j, cp2, len2);
|
||||
|
||||
result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri)
|
||||
/ sum_aij_2;
|
||||
|
||||
if ( result < best_result ) {
|
||||
best_result = result;
|
||||
best_j = j;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2;
|
||||
|
||||
return Py_BuildValue("(nf)", best_j, factor);
|
||||
}
|
||||
|
||||
|
@ -821,7 +559,6 @@ audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width)
|
|||
double sum = 0.0;
|
||||
unsigned int avg;
|
||||
int diff, prevdiff, nextreme = 0;
|
||||
|
||||
if (!audioop_check_parameters(fragment->len, width))
|
||||
return NULL;
|
||||
if (fragment->len <= width)
|
||||
|
@ -1100,26 +837,21 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
|
|||
Py_ssize_t i;
|
||||
int minval, maxval, newval;
|
||||
PyObject *rv;
|
||||
|
||||
if (!audioop_check_parameters(fragment1->len, width))
|
||||
return NULL;
|
||||
if (fragment1->len != fragment2->len) {
|
||||
PyErr_SetString(AudioopError, "Lengths should be the same");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
maxval = maxvals[width];
|
||||
minval = minvals[width];
|
||||
|
||||
rv = PyBytes_FromStringAndSize(NULL, fragment1->len);
|
||||
if (rv == NULL)
|
||||
return NULL;
|
||||
ncp = (signed char *)PyBytes_AsString(rv);
|
||||
|
||||
for (i = 0; i < fragment1->len; i += width) {
|
||||
int val1 = GETRAWSAMPLE(width, fragment1->buf, i);
|
||||
int val2 = GETRAWSAMPLE(width, fragment2->buf, i);
|
||||
|
||||
if (width < 4) {
|
||||
newval = val1 + val2;
|
||||
/* truncate in case of overflow */
|
||||
|
@ -1133,7 +865,6 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
|
|||
/* truncate in case of overflow */
|
||||
newval = fbound(fval, minval, maxval);
|
||||
}
|
||||
|
||||
SETRAWSAMPLE(width, ncp, i, newval);
|
||||
}
|
||||
return rv;
|
||||
|
@ -1158,17 +889,13 @@ audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias)
|
|||
Py_ssize_t i;
|
||||
unsigned int val = 0, mask;
|
||||
PyObject *rv;
|
||||
|
||||
if (!audioop_check_parameters(fragment->len, width))
|
||||
return NULL;
|
||||
|
||||
rv = PyBytes_FromStringAndSize(NULL, fragment->len);
|
||||
if (rv == NULL)
|
||||
return NULL;
|
||||
ncp = (signed char *)PyBytes_AsString(rv);
|
||||
|
||||
mask = masks[width];
|
||||
|
||||
for (i = 0; i < fragment->len; i += width) {
|
||||
if (width == 1)
|
||||
val = GETINTX(unsigned char, fragment->buf, i);
|
||||
|
@ -1180,11 +907,9 @@ audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias)
|
|||
assert(width == 4);
|
||||
val = GETINTX(uint32_t, fragment->buf, i);
|
||||
}
|
||||
|
||||
val += (unsigned int)bias;
|
||||
/* wrap around in case of overflow */
|
||||
val &= mask;
|
||||
|
||||
if (width == 1)
|
||||
SETINTX(unsigned char, ncp, i, val);
|
||||
else if (width == 2)
|
||||
|
@ -1216,15 +941,12 @@ audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width)
|
|||
unsigned char *ncp;
|
||||
Py_ssize_t i;
|
||||
PyObject *rv;
|
||||
|
||||
if (!audioop_check_parameters(fragment->len, width))
|
||||
return NULL;
|
||||
|
||||
rv = PyBytes_FromStringAndSize(NULL, fragment->len);
|
||||
if (rv == NULL)
|
||||
return NULL;
|
||||
ncp = (unsigned char *)PyBytes_AsString(rv);
|
||||
|
||||
for (i = 0; i < fragment->len; i += width) {
|
||||
int val = GETRAWSAMPLE(width, fragment->buf, i);
|
||||
SETRAWSAMPLE(width, ncp, fragment->len - i - width, val);
|
||||
|
@ -1246,22 +968,20 @@ static PyObject *
|
|||
audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width)
|
||||
/*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/
|
||||
{
|
||||
unsigned char *ncp;
|
||||
int j;
|
||||
Py_ssize_t i;
|
||||
PyObject *rv;
|
||||
|
||||
unsigned char *ncp;
|
||||
if (!audioop_check_parameters(fragment->len, width))
|
||||
return NULL;
|
||||
|
||||
rv = PyBytes_FromStringAndSize(NULL, fragment->len);
|
||||
if (rv == NULL)
|
||||
return NULL;
|
||||
ncp = (unsigned char *)PyBytes_AsString(rv);
|
||||
|
||||
for (i = 0; i < fragment->len; i += width) {
|
||||
int j;
|
||||
for (j = 0; j < width; j++)
|
||||
for (j = 0; j < width; j++) {
|
||||
ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j];
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -1533,18 +1253,17 @@ audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
|
|||
unsigned char *ncp;
|
||||
Py_ssize_t i;
|
||||
PyObject *rv;
|
||||
|
||||
if (!audioop_check_parameters(fragment->len, width))
|
||||
return NULL;
|
||||
|
||||
rv = PyBytes_FromStringAndSize(NULL, fragment->len/width);
|
||||
if (rv == NULL)
|
||||
return NULL;
|
||||
ncp = (unsigned char *)PyBytes_AsString(rv);
|
||||
|
||||
for (i = 0; i < fragment->len; i += width) {
|
||||
int val = GETSAMPLE32(width, fragment->buf, i);
|
||||
*ncp++ = st_14linear2ulaw(val >> 18);
|
||||
*ncp++ = mulaw(val >> 16);
|
||||
/* [jart] 2x slower, bloated, and off by one 0.7% of the time */
|
||||
/* *ncp++ = st_14linear2ulaw(val >> 18); */
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -1567,10 +1286,8 @@ audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
|
|||
signed char *ncp;
|
||||
Py_ssize_t i;
|
||||
PyObject *rv;
|
||||
|
||||
if (!audioop_check_size(width))
|
||||
return NULL;
|
||||
|
||||
if (fragment->len > PY_SSIZE_T_MAX/width) {
|
||||
PyErr_SetString(PyExc_MemoryError,
|
||||
"not enough memory for output buffer");
|
||||
|
@ -1580,10 +1297,12 @@ audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
|
|||
if (rv == NULL)
|
||||
return NULL;
|
||||
ncp = (signed char *)PyBytes_AsString(rv);
|
||||
|
||||
cp = fragment->buf;
|
||||
for (i = 0; i < fragment->len*width; i += width) {
|
||||
int val = st_ulaw2linear16(*cp++) << 16;
|
||||
/*
|
||||
* [jart] fixed left shift undefined behavior
|
||||
*/
|
||||
int val = (unsigned)unmulaw(*cp++) << 16;
|
||||
SETSAMPLE32(width, ncp, i, val);
|
||||
}
|
||||
return rv;
|
||||
|
@ -1617,7 +1336,8 @@ audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width)
|
|||
|
||||
for (i = 0; i < fragment->len; i += width) {
|
||||
int val = GETSAMPLE32(width, fragment->buf, i);
|
||||
*ncp++ = st_linear2alaw(val >> 19);
|
||||
*ncp++ = alaw(val >> 16);
|
||||
/* *ncp++ = st_linear2alaw(val >> 19); */
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -1636,15 +1356,13 @@ static PyObject *
|
|||
audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
|
||||
/*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/
|
||||
{
|
||||
unsigned char *cp;
|
||||
signed char *ncp;
|
||||
Py_ssize_t i;
|
||||
int val;
|
||||
PyObject *rv;
|
||||
|
||||
Py_ssize_t i;
|
||||
signed char *ncp;
|
||||
unsigned char *cp;
|
||||
if (!audioop_check_size(width))
|
||||
return NULL;
|
||||
|
||||
if (fragment->len > PY_SSIZE_T_MAX/width) {
|
||||
PyErr_SetString(PyExc_MemoryError,
|
||||
"not enough memory for output buffer");
|
||||
|
@ -1655,9 +1373,11 @@ audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width)
|
|||
return NULL;
|
||||
ncp = (signed char *)PyBytes_AsString(rv);
|
||||
cp = fragment->buf;
|
||||
|
||||
for (i = 0; i < fragment->len*width; i += width) {
|
||||
val = st_alaw2linear16(*cp++) << 16;
|
||||
/*
|
||||
* [jart] fixed undefined behavior
|
||||
*/
|
||||
val = (unsigned)unalaw(*cp++) << 16;
|
||||
SETSAMPLE32(width, ncp, i, val);
|
||||
}
|
||||
return rv;
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/* clang-format off */
|
||||
/*[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_FASTCALL, _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, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
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_ParseStack(args, nargs, kwnames, &_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=118cd7036fa0fb52 input=a9049054013a1b77]*/
|
|
@ -843,19 +843,15 @@ audioop_alaw2lin(PyObject *module, PyObject *args)
|
|||
PyObject *return_value = NULL;
|
||||
Py_buffer fragment = {NULL, NULL};
|
||||
int width;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "y*i:alaw2lin",
|
||||
&fragment, &width)) {
|
||||
if (!PyArg_ParseTuple(args, "y*i:alaw2lin", &fragment, &width)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = audioop_alaw2lin_impl(module, &fragment, width);
|
||||
|
||||
exit:
|
||||
/* Cleanup for fragment */
|
||||
if (fragment.obj) {
|
||||
PyBuffer_Release(&fragment);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
|
98
third_party/python/Modules/clinic/md5module.inc
vendored
98
third_party/python/Modules/clinic/md5module.inc
vendored
|
@ -1,98 +0,0 @@
|
|||
/* clang-format off */
|
||||
/*[clinic input]
|
||||
preserve
|
||||
[clinic start generated code]*/
|
||||
|
||||
PyDoc_STRVAR(MD5Type_copy__doc__,
|
||||
"copy($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a copy of the hash object.");
|
||||
|
||||
#define MD5TYPE_COPY_METHODDEF \
|
||||
{"copy", (PyCFunction)MD5Type_copy, METH_NOARGS, MD5Type_copy__doc__},
|
||||
|
||||
static PyObject *
|
||||
MD5Type_copy_impl(MD5object *self);
|
||||
|
||||
static PyObject *
|
||||
MD5Type_copy(MD5object *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return MD5Type_copy_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(MD5Type_digest__doc__,
|
||||
"digest($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the digest value as a bytes object.");
|
||||
|
||||
#define MD5TYPE_DIGEST_METHODDEF \
|
||||
{"digest", (PyCFunction)MD5Type_digest, METH_NOARGS, MD5Type_digest__doc__},
|
||||
|
||||
static PyObject *
|
||||
MD5Type_digest_impl(MD5object *self);
|
||||
|
||||
static PyObject *
|
||||
MD5Type_digest(MD5object *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return MD5Type_digest_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(MD5Type_hexdigest__doc__,
|
||||
"hexdigest($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the digest value as a string of hexadecimal digits.");
|
||||
|
||||
#define MD5TYPE_HEXDIGEST_METHODDEF \
|
||||
{"hexdigest", (PyCFunction)MD5Type_hexdigest, METH_NOARGS, MD5Type_hexdigest__doc__},
|
||||
|
||||
static PyObject *
|
||||
MD5Type_hexdigest_impl(MD5object *self);
|
||||
|
||||
static PyObject *
|
||||
MD5Type_hexdigest(MD5object *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return MD5Type_hexdigest_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(MD5Type_update__doc__,
|
||||
"update($self, obj, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Update this hash object\'s state with the provided string.");
|
||||
|
||||
#define MD5TYPE_UPDATE_METHODDEF \
|
||||
{"update", (PyCFunction)MD5Type_update, METH_O, MD5Type_update__doc__},
|
||||
|
||||
PyDoc_STRVAR(_md5_md5__doc__,
|
||||
"md5($module, /, string=b\'\')\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a new MD5 hash object; optionally initialized with a string.");
|
||||
|
||||
#define _MD5_MD5_METHODDEF \
|
||||
{"md5", (PyCFunction)_md5_md5, METH_FASTCALL, _md5_md5__doc__},
|
||||
|
||||
static PyObject *
|
||||
_md5_md5_impl(PyObject *module, PyObject *string);
|
||||
|
||||
static PyObject *
|
||||
_md5_md5(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"string", NULL};
|
||||
static _PyArg_Parser _parser = {"|O:md5", _keywords, 0};
|
||||
PyObject *string = NULL;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser,
|
||||
&string)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _md5_md5_impl(module, string);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=1761d10cec19a4c2 input=a9049054013a1b77]*/
|
|
@ -967,8 +967,6 @@ exit:
|
|||
|
||||
#endif /* defined(MS_WINDOWS) */
|
||||
|
||||
#if defined(MS_WINDOWS)
|
||||
|
||||
PyDoc_STRVAR(os__getfinalpathname__doc__,
|
||||
"_getfinalpathname($module, path, /)\n"
|
||||
"--\n"
|
||||
|
@ -986,18 +984,14 @@ os__getfinalpathname(PyObject *module, PyObject *arg)
|
|||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyObject *path;
|
||||
|
||||
if (!PyArg_Parse(arg, "U:_getfinalpathname", &path)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = os__getfinalpathname_impl(module, path);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
#endif /* defined(MS_WINDOWS) */
|
||||
|
||||
#if defined(MS_WINDOWS)
|
||||
|
||||
PyDoc_STRVAR(os__isdir__doc__,
|
||||
|
@ -1017,23 +1011,18 @@ 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)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = os__isdir_impl(module, &path);
|
||||
|
||||
exit:
|
||||
/* Cleanup for path */
|
||||
path_cleanup(&path);
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
#endif /* defined(MS_WINDOWS) */
|
||||
|
||||
#if defined(MS_WINDOWS)
|
||||
|
||||
PyDoc_STRVAR(os__getvolumepathname__doc__,
|
||||
"_getvolumepathname($module, /, path)\n"
|
||||
"--\n"
|
||||
|
@ -1053,19 +1042,15 @@ os__getvolumepathname(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObj
|
|||
static const char * const _keywords[] = {"path", NULL};
|
||||
static _PyArg_Parser _parser = {"U:_getvolumepathname", _keywords, 0};
|
||||
PyObject *path;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser,
|
||||
&path)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = os__getvolumepathname_impl(module, path);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
#endif /* defined(MS_WINDOWS) */
|
||||
|
||||
PyDoc_STRVAR(os_mkdir__doc__,
|
||||
"mkdir($module, /, path, mode=511, *, dir_fd=None)\n"
|
||||
"--\n"
|
||||
|
|
98
third_party/python/Modules/clinic/sha1module.inc
vendored
98
third_party/python/Modules/clinic/sha1module.inc
vendored
|
@ -1,98 +0,0 @@
|
|||
/* clang-format off */
|
||||
/*[clinic input]
|
||||
preserve
|
||||
[clinic start generated code]*/
|
||||
|
||||
PyDoc_STRVAR(SHA1Type_copy__doc__,
|
||||
"copy($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a copy of the hash object.");
|
||||
|
||||
#define SHA1TYPE_COPY_METHODDEF \
|
||||
{"copy", (PyCFunction)SHA1Type_copy, METH_NOARGS, SHA1Type_copy__doc__},
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_copy_impl(SHA1object *self);
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_copy(SHA1object *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return SHA1Type_copy_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(SHA1Type_digest__doc__,
|
||||
"digest($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the digest value as a bytes object.");
|
||||
|
||||
#define SHA1TYPE_DIGEST_METHODDEF \
|
||||
{"digest", (PyCFunction)SHA1Type_digest, METH_NOARGS, SHA1Type_digest__doc__},
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_digest_impl(SHA1object *self);
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_digest(SHA1object *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return SHA1Type_digest_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(SHA1Type_hexdigest__doc__,
|
||||
"hexdigest($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the digest value as a string of hexadecimal digits.");
|
||||
|
||||
#define SHA1TYPE_HEXDIGEST_METHODDEF \
|
||||
{"hexdigest", (PyCFunction)SHA1Type_hexdigest, METH_NOARGS, SHA1Type_hexdigest__doc__},
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_hexdigest_impl(SHA1object *self);
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_hexdigest(SHA1object *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return SHA1Type_hexdigest_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(SHA1Type_update__doc__,
|
||||
"update($self, obj, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Update this hash object\'s state with the provided string.");
|
||||
|
||||
#define SHA1TYPE_UPDATE_METHODDEF \
|
||||
{"update", (PyCFunction)SHA1Type_update, METH_O, SHA1Type_update__doc__},
|
||||
|
||||
PyDoc_STRVAR(_sha1_sha1__doc__,
|
||||
"sha1($module, /, string=b\'\')\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a new SHA1 hash object; optionally initialized with a string.");
|
||||
|
||||
#define _SHA1_SHA1_METHODDEF \
|
||||
{"sha1", (PyCFunction)_sha1_sha1, METH_FASTCALL, _sha1_sha1__doc__},
|
||||
|
||||
static PyObject *
|
||||
_sha1_sha1_impl(PyObject *module, PyObject *string);
|
||||
|
||||
static PyObject *
|
||||
_sha1_sha1(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"string", NULL};
|
||||
static _PyArg_Parser _parser = {"|O:sha1", _keywords, 0};
|
||||
PyObject *string = NULL;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser,
|
||||
&string)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _sha1_sha1_impl(module, string);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=34e9cee5761f2a36 input=a9049054013a1b77]*/
|
128
third_party/python/Modules/clinic/sha256module.inc
vendored
128
third_party/python/Modules/clinic/sha256module.inc
vendored
|
@ -1,128 +0,0 @@
|
|||
/* clang-format off */
|
||||
/*[clinic input]
|
||||
preserve
|
||||
[clinic start generated code]*/
|
||||
|
||||
PyDoc_STRVAR(SHA256Type_copy__doc__,
|
||||
"copy($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a copy of the hash object.");
|
||||
|
||||
#define SHA256TYPE_COPY_METHODDEF \
|
||||
{"copy", (PyCFunction)SHA256Type_copy, METH_NOARGS, SHA256Type_copy__doc__},
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_copy_impl(SHAobject *self);
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return SHA256Type_copy_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(SHA256Type_digest__doc__,
|
||||
"digest($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the digest value as a bytes object.");
|
||||
|
||||
#define SHA256TYPE_DIGEST_METHODDEF \
|
||||
{"digest", (PyCFunction)SHA256Type_digest, METH_NOARGS, SHA256Type_digest__doc__},
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_digest_impl(SHAobject *self);
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return SHA256Type_digest_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(SHA256Type_hexdigest__doc__,
|
||||
"hexdigest($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the digest value as a string of hexadecimal digits.");
|
||||
|
||||
#define SHA256TYPE_HEXDIGEST_METHODDEF \
|
||||
{"hexdigest", (PyCFunction)SHA256Type_hexdigest, METH_NOARGS, SHA256Type_hexdigest__doc__},
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_hexdigest_impl(SHAobject *self);
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return SHA256Type_hexdigest_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(SHA256Type_update__doc__,
|
||||
"update($self, obj, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Update this hash object\'s state with the provided string.");
|
||||
|
||||
#define SHA256TYPE_UPDATE_METHODDEF \
|
||||
{"update", (PyCFunction)SHA256Type_update, METH_O, SHA256Type_update__doc__},
|
||||
|
||||
PyDoc_STRVAR(_sha256_sha256__doc__,
|
||||
"sha256($module, /, string=b\'\')\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a new SHA-256 hash object; optionally initialized with a string.");
|
||||
|
||||
#define _SHA256_SHA256_METHODDEF \
|
||||
{"sha256", (PyCFunction)_sha256_sha256, METH_FASTCALL, _sha256_sha256__doc__},
|
||||
|
||||
static PyObject *
|
||||
_sha256_sha256_impl(PyObject *module, PyObject *string);
|
||||
|
||||
static PyObject *
|
||||
_sha256_sha256(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"string", NULL};
|
||||
static _PyArg_Parser _parser = {"|O:sha256", _keywords, 0};
|
||||
PyObject *string = NULL;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser,
|
||||
&string)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _sha256_sha256_impl(module, string);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(_sha256_sha224__doc__,
|
||||
"sha224($module, /, string=b\'\')\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a new SHA-224 hash object; optionally initialized with a string.");
|
||||
|
||||
#define _SHA256_SHA224_METHODDEF \
|
||||
{"sha224", (PyCFunction)_sha256_sha224, METH_FASTCALL, _sha256_sha224__doc__},
|
||||
|
||||
static PyObject *
|
||||
_sha256_sha224_impl(PyObject *module, PyObject *string);
|
||||
|
||||
static PyObject *
|
||||
_sha256_sha224(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"string", NULL};
|
||||
static _PyArg_Parser _parser = {"|O:sha224", _keywords, 0};
|
||||
PyObject *string = NULL;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser,
|
||||
&string)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _sha256_sha224_impl(module, string);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=3babbe1e753c1a38 input=a9049054013a1b77]*/
|
128
third_party/python/Modules/clinic/sha512module.inc
vendored
128
third_party/python/Modules/clinic/sha512module.inc
vendored
|
@ -1,128 +0,0 @@
|
|||
/* clang-format off */
|
||||
/*[clinic input]
|
||||
preserve
|
||||
[clinic start generated code]*/
|
||||
|
||||
PyDoc_STRVAR(SHA512Type_copy__doc__,
|
||||
"copy($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a copy of the hash object.");
|
||||
|
||||
#define SHA512TYPE_COPY_METHODDEF \
|
||||
{"copy", (PyCFunction)SHA512Type_copy, METH_NOARGS, SHA512Type_copy__doc__},
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_copy_impl(SHAobject *self);
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return SHA512Type_copy_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(SHA512Type_digest__doc__,
|
||||
"digest($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the digest value as a bytes object.");
|
||||
|
||||
#define SHA512TYPE_DIGEST_METHODDEF \
|
||||
{"digest", (PyCFunction)SHA512Type_digest, METH_NOARGS, SHA512Type_digest__doc__},
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_digest_impl(SHAobject *self);
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return SHA512Type_digest_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(SHA512Type_hexdigest__doc__,
|
||||
"hexdigest($self, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the digest value as a string of hexadecimal digits.");
|
||||
|
||||
#define SHA512TYPE_HEXDIGEST_METHODDEF \
|
||||
{"hexdigest", (PyCFunction)SHA512Type_hexdigest, METH_NOARGS, SHA512Type_hexdigest__doc__},
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_hexdigest_impl(SHAobject *self);
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return SHA512Type_hexdigest_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(SHA512Type_update__doc__,
|
||||
"update($self, obj, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Update this hash object\'s state with the provided string.");
|
||||
|
||||
#define SHA512TYPE_UPDATE_METHODDEF \
|
||||
{"update", (PyCFunction)SHA512Type_update, METH_O, SHA512Type_update__doc__},
|
||||
|
||||
PyDoc_STRVAR(_sha512_sha512__doc__,
|
||||
"sha512($module, /, string=b\'\')\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a new SHA-512 hash object; optionally initialized with a string.");
|
||||
|
||||
#define _SHA512_SHA512_METHODDEF \
|
||||
{"sha512", (PyCFunction)_sha512_sha512, METH_FASTCALL, _sha512_sha512__doc__},
|
||||
|
||||
static PyObject *
|
||||
_sha512_sha512_impl(PyObject *module, PyObject *string);
|
||||
|
||||
static PyObject *
|
||||
_sha512_sha512(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"string", NULL};
|
||||
static _PyArg_Parser _parser = {"|O:sha512", _keywords, 0};
|
||||
PyObject *string = NULL;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser,
|
||||
&string)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _sha512_sha512_impl(module, string);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(_sha512_sha384__doc__,
|
||||
"sha384($module, /, string=b\'\')\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return a new SHA-384 hash object; optionally initialized with a string.");
|
||||
|
||||
#define _SHA512_SHA384_METHODDEF \
|
||||
{"sha384", (PyCFunction)_sha512_sha384, METH_FASTCALL, _sha512_sha384__doc__},
|
||||
|
||||
static PyObject *
|
||||
_sha512_sha384_impl(PyObject *module, PyObject *string);
|
||||
|
||||
static PyObject *
|
||||
_sha512_sha384(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"string", NULL};
|
||||
static _PyArg_Parser _parser = {"|O:sha384", _keywords, 0};
|
||||
PyObject *string = NULL;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser,
|
||||
&string)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _sha512_sha384_impl(module, string);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=59a43fa6eb3b5f4f input=a9049054013a1b77]*/
|
|
@ -111,7 +111,8 @@ PyDoc_STRVAR(zlib_compressobj__doc__,
|
|||
" usage, faster compression, and smaller output.\n"
|
||||
" strategy\n"
|
||||
" Used to tune the compression algorithm. Possible values are\n"
|
||||
" Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n"
|
||||
" Z_DEFAULT_STRATEGY, Z_RLE, Z_HUFFMAN_ONLY, Z_FILTERED, and\n"
|
||||
" Z_FIXED.\n"
|
||||
" zdict\n"
|
||||
" The predefined compression dictionary - a sequence of bytes\n"
|
||||
" containing subsequences that are likely to occur in the input data.");
|
||||
|
|
95
third_party/python/Modules/config.c
vendored
95
third_party/python/Modules/config.c
vendored
|
@ -4,110 +4,35 @@
|
|||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/Python.h"
|
||||
#include "third_party/python/Include/cosmo.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/pyport.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
/* clang-format off */
|
||||
|
||||
PyObject *PyInit__ast(void);
|
||||
PyObject *PyInit__bisect(void);
|
||||
PyObject *PyInit__bz2(void);
|
||||
PyObject *PyInit__codecs(void);
|
||||
PyObject *PyInit__codecs_cn(void);
|
||||
PyObject *PyInit__codecs_hk(void);
|
||||
PyObject *PyInit__codecs_iso2022(void);
|
||||
PyObject *PyInit__codecs_jp(void);
|
||||
PyObject *PyInit__codecs_kr(void);
|
||||
PyObject *PyInit__codecs_tw(void);
|
||||
PyObject *PyInit__collections(void);
|
||||
PyObject *PyInit__csv(void);
|
||||
PyObject *PyInit__datetime(void);
|
||||
PyObject *PyInit__decimal(void);
|
||||
PyObject *PyInit__elementtree(void);
|
||||
PyObject *PyInit__functools(void);
|
||||
PyObject *PyInit__heapq(void);
|
||||
PyObject *PyInit__io(void);
|
||||
PyObject *PyInit__json(void);
|
||||
PyObject *PyInit__locale(void);
|
||||
PyObject *PyInit__lsprof(void);
|
||||
PyObject *PyInit__md5(void);
|
||||
PyObject *PyInit__multibytecodec(void);
|
||||
PyObject *PyInit__multiprocessing(void);
|
||||
PyObject *PyInit__opcode(void);
|
||||
PyObject *PyInit__operator(void);
|
||||
PyObject *PyInit__pickle(void);
|
||||
PyObject *PyInit__posixsubprocess(void);
|
||||
PyObject *PyInit__random(void);
|
||||
PyObject *PyInit__sha1(void);
|
||||
PyObject *PyInit__sha256(void);
|
||||
PyObject *PyInit__sha3(void);
|
||||
PyObject *PyInit__sha512(void);
|
||||
PyObject *PyInit__signal(void);
|
||||
PyObject *PyInit__socket(void);
|
||||
PyObject *PyInit__sqlite3(void);
|
||||
PyObject *PyInit__sre(void);
|
||||
PyObject *PyInit__stat(void);
|
||||
PyObject *PyInit__string(void);
|
||||
PyObject *PyInit__struct(void);
|
||||
PyObject *PyInit__symtable(void);
|
||||
PyObject *PyInit__testcapi(void);
|
||||
PyObject *PyInit__tracemalloc(void);
|
||||
PyObject *PyInit__weakref(void);
|
||||
PyObject *PyInit_array(void);
|
||||
PyObject *PyInit_atexit(void);
|
||||
PyObject *PyInit_audioop(void);
|
||||
PyObject *PyInit_binascii(void);
|
||||
PyObject *PyInit_cmath(void);
|
||||
PyObject *PyInit_cosmo(void);
|
||||
PyObject *PyInit_errno(void);
|
||||
PyObject *PyInit_faulthandler(void);
|
||||
PyObject *PyInit_fcntl(void);
|
||||
PyObject *PyInit_fpectl(void);
|
||||
PyObject *PyInit_gc(void);
|
||||
PyObject *PyInit_grp(void);
|
||||
PyObject *PyInit_imp(void);
|
||||
PyObject *PyInit_itertools(void);
|
||||
PyObject *PyInit_math(void);
|
||||
PyObject *PyInit_mmap(void);
|
||||
PyObject *PyInit_parser(void);
|
||||
PyObject *PyInit_posix(void);
|
||||
PyObject *PyInit_pwd(void);
|
||||
PyObject *PyInit_pyexpat(void);
|
||||
PyObject *PyInit_resource(void);
|
||||
PyObject *PyInit_select(void);
|
||||
PyObject *PyInit_syslog(void);
|
||||
PyObject *PyInit_termios(void);
|
||||
PyObject *PyInit_time(void);
|
||||
PyObject *PyInit_unicodedata(void);
|
||||
PyObject *PyInit_zipimport(void);
|
||||
PyObject *PyInit_zlib(void);
|
||||
PyObject *PyInit__codecs(void);
|
||||
PyObject *PyInit_itertools(void);
|
||||
PyObject *PyInit__io(void);
|
||||
PyObject *PyInit__weakref(void);
|
||||
PyObject *PyMarshal_Init(void);
|
||||
PyObject *PyInit__ast(void);
|
||||
PyObject *PyInit_gc(void);
|
||||
PyObject *_PyWarnings_Init(void);
|
||||
PyObject *PyInit__string(void);
|
||||
|
||||
_Alignas(16) _Section(".rodata.pytab.0") const struct _inittab _PyImport_Inittab[0];
|
||||
_Alignas(16) _Section(".rodata.pytab.2") const struct _inittab _PyImport_Inittab2[] = {
|
||||
{"posix", PyInit_posix},
|
||||
{"errno", PyInit_errno},
|
||||
{"_sre", PyInit__sre},
|
||||
{"_codecs", PyInit__codecs},
|
||||
{"_functools", PyInit__functools},
|
||||
{"_operator", PyInit__operator},
|
||||
{"_collections", PyInit__collections},
|
||||
{"itertools", PyInit_itertools},
|
||||
{"_signal", PyInit__signal},
|
||||
{"_locale", PyInit__locale},
|
||||
{"_io", PyInit__io},
|
||||
{"_weakref", PyInit__weakref},
|
||||
{"_heapq", PyInit__heapq},
|
||||
{"marshal", PyMarshal_Init},
|
||||
{"_imp", PyInit_imp},
|
||||
{"_cosmo", PyInit_cosmo},
|
||||
{"_ast", PyInit__ast},
|
||||
{"builtins", NULL},
|
||||
{"sys", NULL},
|
||||
{"gc", PyInit_gc},
|
||||
{"_warnings", _PyWarnings_Init},
|
||||
{"_warnings", _PyWarnings_Init},
|
||||
{"_string", PyInit__string},
|
||||
{0, 0}
|
||||
{0}
|
||||
};
|
||||
|
|
59
third_party/python/Modules/config.c.in
vendored
59
third_party/python/Modules/config.c.in
vendored
|
@ -1,59 +0,0 @@
|
|||
/* clang-format off */
|
||||
/* -*- C -*- ***********************************************
|
||||
Copyright (c) 2000, BeOpen.com.
|
||||
Copyright (c) 1995-2000, Corporation for National Research Initiatives.
|
||||
Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
|
||||
All rights reserved.
|
||||
|
||||
See the file "Misc/COPYRIGHT" for information on usage and
|
||||
redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
******************************************************************/
|
||||
|
||||
/* Module configuration */
|
||||
|
||||
/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */
|
||||
|
||||
/* This file contains the table of built-in modules.
|
||||
See create_builtin() in import.c. */
|
||||
|
||||
#include "third_party/python/Include/Python.h"
|
||||
|
||||
/* -- ADDMODULE MARKER 1 -- */
|
||||
|
||||
extern PyObject* PyMarshal_Init(void);
|
||||
extern PyObject* PyInit_imp(void);
|
||||
extern PyObject* PyInit_gc(void);
|
||||
extern PyObject* PyInit__ast(void);
|
||||
extern PyObject* _PyWarnings_Init(void);
|
||||
extern PyObject* PyInit__string(void);
|
||||
|
||||
struct _inittab _PyImport_Inittab[] = {
|
||||
|
||||
/* -- ADDMODULE MARKER 2 -- */
|
||||
|
||||
/* This module lives in marshal.c */
|
||||
{"marshal", PyMarshal_Init},
|
||||
|
||||
/* This lives in import.c */
|
||||
{"_imp", PyInit_imp},
|
||||
|
||||
/* This lives in Python/Python-ast.c */
|
||||
{"_ast", PyInit__ast},
|
||||
|
||||
/* These entries are here for sys.builtin_module_names */
|
||||
{"builtins", NULL},
|
||||
{"sys", NULL},
|
||||
|
||||
/* This lives in gcmodule.c */
|
||||
{"gc", PyInit_gc},
|
||||
|
||||
/* This lives in _warnings.c */
|
||||
{"_warnings", _PyWarnings_Init},
|
||||
|
||||
/* This lives in Objects/unicodeobject.c */
|
||||
{"_string", PyInit__string},
|
||||
|
||||
/* Sentinel */
|
||||
{0, 0}
|
||||
};
|
||||
|
5
third_party/python/Modules/errnomodule.c
vendored
5
third_party/python/Modules/errnomodule.c
vendored
|
@ -399,3 +399,8 @@ PyInit_errno(void)
|
|||
Py_DECREF(de);
|
||||
return m;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab_errno = {
|
||||
"errno",
|
||||
PyInit_errno,
|
||||
};
|
||||
|
|
28
third_party/python/Modules/expat/xmlparse.c
vendored
28
third_party/python/Modules/expat/xmlparse.c
vendored
|
@ -1,8 +1,11 @@
|
|||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
@ -593,11 +596,30 @@ static unsigned long get_hash_secret_salt(XML_Parser parser) {
|
|||
return parser->m_hash_secret_salt;
|
||||
}
|
||||
|
||||
static uint64_t getsome(void) {
|
||||
int i;
|
||||
char cf;
|
||||
uint64_t x;
|
||||
if (X86_HAVE(RDRND)) {
|
||||
for (i = 0; i < 10; ++i) {
|
||||
asm volatile(CFLAG_ASM("rdrand\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) return x;
|
||||
asm volatile("pause");
|
||||
}
|
||||
}
|
||||
if (getrandom(&x, 8, 0) != 8) abort();
|
||||
return x;
|
||||
}
|
||||
|
||||
static XML_Bool /* only valid for root parser */
|
||||
startParsing(XML_Parser parser) {
|
||||
/* hash functions must be initialized before setContext() is called */
|
||||
if (parser->m_hash_secret_salt == 0)
|
||||
parser->m_hash_secret_salt = rand64();
|
||||
if (!parser->m_hash_secret_salt) {
|
||||
parser->m_hash_secret_salt = getsome();
|
||||
}
|
||||
if (parser->m_ns) {
|
||||
/* implicit context only set for root parser, since child
|
||||
parsers (i.e. external entity parsers) will inherit it
|
||||
|
@ -2421,7 +2443,7 @@ static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
|
|||
rawName = s + enc->minBytesPerChar * 2;
|
||||
len = XmlNameLength(enc, rawName);
|
||||
if (len != tag->rawNameLength ||
|
||||
memcmp(tag->rawName, rawName, len) != 0) {
|
||||
bcmp(tag->rawName, rawName, len)) {
|
||||
*eventPP = rawName;
|
||||
return XML_ERROR_TAG_MISMATCH;
|
||||
}
|
||||
|
|
14
third_party/python/Modules/fcntlmodule.c
vendored
14
third_party/python/Modules/fcntlmodule.c
vendored
|
@ -23,6 +23,7 @@
|
|||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/pyconfig.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("fcntl");
|
||||
|
@ -74,7 +75,6 @@ static int
|
|||
conv_descriptor(PyObject *object, int *target)
|
||||
{
|
||||
int fd = PyObject_AsFileDescriptor(object);
|
||||
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
*target = fd;
|
||||
|
@ -337,7 +337,6 @@ fcntl_flock_impl(PyObject *module, int fd, int code)
|
|||
{
|
||||
int ret;
|
||||
int async_err = 0;
|
||||
|
||||
#ifdef HAVE_FLOCK
|
||||
do {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
|
@ -345,13 +344,6 @@ fcntl_flock_impl(PyObject *module, int fd, int code)
|
|||
Py_END_ALLOW_THREADS
|
||||
} while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||
#else
|
||||
|
||||
#ifndef LOCK_SH
|
||||
#define LOCK_SH 1 /* shared lock */
|
||||
#define LOCK_EX 2 /* exclusive lock */
|
||||
#define LOCK_NB 4 /* don't block when locking */
|
||||
#define LOCK_UN 8 /* unlock */
|
||||
#endif
|
||||
{
|
||||
struct flock l;
|
||||
if (code == LOCK_UN)
|
||||
|
@ -674,7 +666,6 @@ all_ins(PyObject* m)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct PyModuleDef fcntlmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"fcntl",
|
||||
|
@ -691,16 +682,13 @@ PyMODINIT_FUNC
|
|||
PyInit_fcntl(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
/* Create the module and add the functions and documentation */
|
||||
m = PyModule_Create(&fcntlmodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Add some symbolic constants to the module */
|
||||
if (all_ins(m) < 0)
|
||||
return NULL;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
|
17
third_party/python/Modules/gcmodule.c
vendored
17
third_party/python/Modules/gcmodule.c
vendored
|
@ -1728,14 +1728,6 @@ _PyGC_Dump(PyGC_Head *g)
|
|||
_PyObject_Dump(FROM_GC(g));
|
||||
}
|
||||
|
||||
/* extension modules might be compiled with GC support so these
|
||||
functions must always be available */
|
||||
|
||||
#undef PyObject_GC_Track
|
||||
#undef PyObject_GC_UnTrack
|
||||
#undef PyObject_GC_Del
|
||||
#undef _PyObject_GC_Malloc
|
||||
|
||||
void
|
||||
PyObject_GC_Track(void *op)
|
||||
{
|
||||
|
@ -1743,7 +1735,7 @@ PyObject_GC_Track(void *op)
|
|||
}
|
||||
|
||||
void
|
||||
PyObject_GC_UnTrack(void *op)
|
||||
(PyObject_GC_UnTrack)(void *op)
|
||||
{
|
||||
/* Obscure: the Py_TRASHCAN mechanism requires that we be able to
|
||||
* call PyObject_GC_UnTrack twice on an object.
|
||||
|
@ -1752,7 +1744,7 @@ PyObject_GC_UnTrack(void *op)
|
|||
_PyObject_GC_UNTRACK(op);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyObject *
|
||||
_PyObject_GC_Alloc(int use_calloc, size_t basicsize)
|
||||
{
|
||||
PyObject *op;
|
||||
|
@ -1784,13 +1776,13 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize)
|
|||
}
|
||||
|
||||
PyObject *
|
||||
_PyObject_GC_Malloc(size_t basicsize)
|
||||
(_PyObject_GC_Malloc)(size_t basicsize)
|
||||
{
|
||||
return _PyObject_GC_Alloc(0, basicsize);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_PyObject_GC_Calloc(size_t basicsize)
|
||||
(_PyObject_GC_Calloc)(size_t basicsize)
|
||||
{
|
||||
return _PyObject_GC_Alloc(1, basicsize);
|
||||
}
|
||||
|
@ -1809,7 +1801,6 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
|
|||
{
|
||||
size_t size;
|
||||
PyVarObject *op;
|
||||
|
||||
if (nitems < 0) {
|
||||
PyErr_BadInternalCall();
|
||||
return NULL;
|
||||
|
|
27
third_party/python/Modules/getbuildinfo.c
vendored
27
third_party/python/Modules/getbuildinfo.c
vendored
|
@ -8,33 +8,6 @@
|
|||
#include "third_party/python/Include/pylifecycle.h"
|
||||
/* clang-format off */
|
||||
|
||||
#ifndef DATE
|
||||
#ifdef __DATE__
|
||||
#define DATE __DATE__
|
||||
#else
|
||||
#define DATE "xx/xx/xx"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef TIME
|
||||
#ifdef __TIME__
|
||||
#define TIME __TIME__
|
||||
#else
|
||||
#define TIME "xx:xx:xx"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* XXX Only unix build process has been tested */
|
||||
#ifndef GITVERSION
|
||||
#define GITVERSION ""
|
||||
#endif
|
||||
#ifndef GITTAG
|
||||
#define GITTAG ""
|
||||
#endif
|
||||
#ifndef GITBRANCH
|
||||
#define GITBRANCH ""
|
||||
#endif
|
||||
|
||||
const char *
|
||||
Py_GetBuildInfo(void)
|
||||
{
|
||||
|
|
10
third_party/python/Modules/grpmodule.c
vendored
10
third_party/python/Modules/grpmodule.c
vendored
|
@ -36,11 +36,11 @@ module grp
|
|||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cade63f2ed1bd9f8]*/
|
||||
|
||||
static PyStructSequence_Field struct_group_type_fields[] = {
|
||||
{"gr_name", "group name"},
|
||||
{"gr_passwd", "password"},
|
||||
{"gr_gid", "group id"},
|
||||
{"gr_mem", "group members"},
|
||||
{0}
|
||||
{"gr_name", PyDoc_STR("group name")},
|
||||
{"gr_passwd", PyDoc_STR("password")},
|
||||
{"gr_gid", PyDoc_STR("group id")},
|
||||
{"gr_mem", PyDoc_STR("group members")},
|
||||
{0}
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(struct_group__doc__,
|
||||
|
|
2
third_party/python/Modules/hashtable.c
vendored
2
third_party/python/Modules/hashtable.c
vendored
|
@ -132,7 +132,7 @@ _Py_hashtable_compare_direct(_Py_hashtable_t *ht, const void *pkey,
|
|||
const _Py_hashtable_entry_t *entry)
|
||||
{
|
||||
const void *pkey2 = _Py_HASHTABLE_ENTRY_PKEY(entry);
|
||||
return (memcmp(pkey, pkey2, ht->key_size) == 0);
|
||||
return !bcmp(pkey, pkey2, ht->key_size);
|
||||
}
|
||||
|
||||
|
||||
|
|
100
third_party/python/Modules/main.c
vendored
100
third_party/python/Modules/main.c
vendored
|
@ -5,6 +5,7 @@
|
|||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/unicode/locale.h"
|
||||
|
@ -24,12 +25,12 @@
|
|||
#include "third_party/python/Include/pythonrun.h"
|
||||
#include "third_party/python/Include/sysmodule.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/pyconfig.h"
|
||||
/* clang-format off */
|
||||
|
||||
STATIC_YOINK("PyInit__codecs"); // for pylifecycle.o
|
||||
STATIC_YOINK("PyInit__collections"); // for pylifecycle.o
|
||||
STATIC_YOINK("PyInit__functools"); // for pylifecycle.o
|
||||
STATIC_YOINK("PyInit__heapq"); // for pylifecycle.o
|
||||
STATIC_YOINK("PyInit__locale"); // for pylifecycle.o
|
||||
STATIC_YOINK("PyInit__operator"); // for pylifecycle.o
|
||||
STATIC_YOINK("PyInit__signal"); // for pylifecycle.o
|
||||
|
@ -50,7 +51,7 @@ PYTHON_YOINK("site");
|
|||
PYTHON_YOINK("_sysconfigdata_m_cosmo_x86_64_cosmo");
|
||||
|
||||
PYTHON_YOINK("_bootlocale");
|
||||
PYTHON_YOINK("warnings");
|
||||
PYTHON_YOINK("_warnings");
|
||||
PYTHON_YOINK("_locale");
|
||||
PYTHON_YOINK("locale");
|
||||
PYTHON_YOINK("runpy");
|
||||
|
@ -655,7 +656,7 @@ Py_Main(int argc, wchar_t **argv)
|
|||
_setmode(fileno(stderr), O_BINARY);
|
||||
#endif
|
||||
|
||||
if (1 || Py_UnbufferedStdioFlag) {
|
||||
if (Py_UnbufferedStdioFlag) {
|
||||
#ifdef HAVE_SETVBUF
|
||||
setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
|
||||
setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
|
||||
|
@ -680,57 +681,52 @@ Py_Main(int argc, wchar_t **argv)
|
|||
/* Leave stderr alone - it should be unbuffered anyway. */
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* On MacOS X, when the Python interpreter is embedded in an
|
||||
application bundle, it gets executed by a bootstrapping script
|
||||
that does os.execve() with an argv[0] that's different from the
|
||||
actual Python executable. This is needed to keep the Finder happy,
|
||||
or rather, to work around Apple's overly strict requirements of
|
||||
the process name. However, we still need a usable sys.executable,
|
||||
so the actual executable path is passed in an environment variable.
|
||||
See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
|
||||
script. */
|
||||
if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
|
||||
wchar_t* buffer;
|
||||
size_t len = strlen(p) + 1;
|
||||
|
||||
buffer = PyMem_RawMalloc(len * sizeof(wchar_t));
|
||||
if (buffer == NULL) {
|
||||
Py_FatalError(
|
||||
"not enough memory to copy PYTHONEXECUTABLE");
|
||||
}
|
||||
|
||||
mbstowcs(buffer, p, len);
|
||||
Py_SetProgramName(buffer);
|
||||
/* buffer is now handed off - do not free */
|
||||
} else {
|
||||
#ifdef WITH_NEXT_FRAMEWORK
|
||||
char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
|
||||
|
||||
if (pyvenv_launcher && *pyvenv_launcher) {
|
||||
/* Used by Mac/Tools/pythonw.c to forward
|
||||
* the argv0 of the stub executable
|
||||
*/
|
||||
wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, NULL);
|
||||
|
||||
if (wbuf == NULL) {
|
||||
Py_FatalError("Cannot decode __PYVENV_LAUNCHER__");
|
||||
}
|
||||
Py_SetProgramName(wbuf);
|
||||
|
||||
/* Don't free wbuf, the argument to Py_SetProgramName
|
||||
* must remain valid until Py_FinalizeEx is called.
|
||||
*/
|
||||
} else {
|
||||
Py_SetProgramName(argv[0]);
|
||||
}
|
||||
#else
|
||||
if (!IsXnu()) {
|
||||
Py_SetProgramName(argv[0]);
|
||||
#endif
|
||||
} else {
|
||||
/* On MacOS X, when the Python interpreter is embedded in an
|
||||
application bundle, it gets executed by a bootstrapping script
|
||||
that does os.execve() with an argv[0] that's different from the
|
||||
actual Python executable. This is needed to keep the Finder happy,
|
||||
or rather, to work around Apple's overly strict requirements of
|
||||
the process name. However, we still need a usable sys.executable,
|
||||
so the actual executable path is passed in an environment variable.
|
||||
See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
|
||||
script. */
|
||||
if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
|
||||
wchar_t* buffer;
|
||||
size_t len = strlen(p) + 1;
|
||||
buffer = PyMem_RawMalloc(len * sizeof(wchar_t));
|
||||
if (buffer == NULL) {
|
||||
Py_FatalError(
|
||||
"not enough memory to copy PYTHONEXECUTABLE");
|
||||
}
|
||||
mbstowcs(buffer, p, len);
|
||||
Py_SetProgramName(buffer);
|
||||
/* buffer is now handed off - do not free */
|
||||
} else {
|
||||
#ifdef WITH_NEXT_FRAMEWORK
|
||||
char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
|
||||
if (pyvenv_launcher && *pyvenv_launcher) {
|
||||
/* Used by Mac/Tools/pythonw.c to forward
|
||||
* the argv0 of the stub executable
|
||||
*/
|
||||
wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, NULL);
|
||||
if (wbuf == NULL) {
|
||||
Py_FatalError("Cannot decode __PYVENV_LAUNCHER__");
|
||||
}
|
||||
Py_SetProgramName(wbuf);
|
||||
/* Don't free wbuf, the argument to Py_SetProgramName
|
||||
* must remain valid until Py_FinalizeEx is called.
|
||||
*/
|
||||
} else {
|
||||
Py_SetProgramName(argv[0]);
|
||||
}
|
||||
#else /* WITH_NEXT_FRAMEWORK */
|
||||
Py_SetProgramName(argv[0]);
|
||||
#endif /* WITH_NEXT_FRAMEWORK */
|
||||
}
|
||||
}
|
||||
#else
|
||||
Py_SetProgramName(argv[0]);
|
||||
#endif
|
||||
Py_Initialize();
|
||||
Py_XDECREF(warning_options);
|
||||
|
||||
|
|
604
third_party/python/Modules/md5module.c
vendored
604
third_party/python/Modules/md5module.c
vendored
|
@ -1,604 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/bytesobject.h"
|
||||
#include "third_party/python/Include/descrobject.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/longobject.h"
|
||||
#include "third_party/python/Include/modsupport.h"
|
||||
#include "third_party/python/Include/objimpl.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
#include "third_party/python/Include/pystrhex.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/Modules/hashlib.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("_md5");
|
||||
PYTHON_PROVIDE("_md5.MD5Type");
|
||||
PYTHON_PROVIDE("_md5.md5");
|
||||
|
||||
/* 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)
|
||||
|
||||
Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org)
|
||||
Licensed to PSF under a Contributor Agreement.
|
||||
|
||||
*/
|
||||
|
||||
/*[clinic input]
|
||||
module _md5
|
||||
class MD5Type "MD5object *" "&PyType_Type"
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6e5261719957a912]*/
|
||||
|
||||
/* Some useful types */
|
||||
|
||||
#if SIZEOF_INT == 4
|
||||
typedef unsigned int MD5_INT32; /* 32-bit integer */
|
||||
typedef long long MD5_INT64; /* 64-bit integer */
|
||||
#else
|
||||
/* not defined. compilation will die. */
|
||||
#endif
|
||||
|
||||
/* The MD5 block size and message digest sizes, in bytes */
|
||||
|
||||
#define MD5_BLOCKSIZE 64
|
||||
#define MD5_DIGESTSIZE 16
|
||||
|
||||
/* The structure for storing MD5 info */
|
||||
|
||||
struct md5_state {
|
||||
MD5_INT64 length;
|
||||
MD5_INT32 state[4], curlen;
|
||||
unsigned char buf[MD5_BLOCKSIZE];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
struct md5_state hash_state;
|
||||
} MD5object;
|
||||
|
||||
#include "third_party/python/Modules/clinic/md5module.inc"
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
*
|
||||
* This code for the MD5 algorithm was noted as public domain. The
|
||||
* original headers are pasted below.
|
||||
*
|
||||
* Several changes have been made to make it more compatible with the
|
||||
* Python environment and desired interface.
|
||||
*
|
||||
*/
|
||||
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
|
||||
/* rotate the hard way (platform optimizations could be done) */
|
||||
#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
|
||||
/* Endian Neutral macros that work on all platforms */
|
||||
|
||||
#define STORE32L(x, y) \
|
||||
{ (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32L(x, y) \
|
||||
{ x = ((unsigned long)((y)[3] & 255)<<24) | \
|
||||
((unsigned long)((y)[2] & 255)<<16) | \
|
||||
((unsigned long)((y)[1] & 255)<<8) | \
|
||||
((unsigned long)((y)[0] & 255)); }
|
||||
|
||||
#define STORE64L(x, y) \
|
||||
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
|
||||
/* MD5 macros */
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define G(x,y,z) (y ^ (z & (y ^ x)))
|
||||
#define H(x,y,z) (x^y^z)
|
||||
#define I(x,y,z) (y^(x|(~z)))
|
||||
|
||||
#define FF(a,b,c,d,M,s,t) \
|
||||
a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
|
||||
|
||||
#define GG(a,b,c,d,M,s,t) \
|
||||
a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
|
||||
|
||||
#define HH(a,b,c,d,M,s,t) \
|
||||
a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
|
||||
|
||||
#define II(a,b,c,d,M,s,t) \
|
||||
a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
|
||||
|
||||
|
||||
static void md5_compress(struct md5_state *md5, unsigned char *buf)
|
||||
{
|
||||
MD5_INT32 i, W[16], a, b, c, d;
|
||||
|
||||
assert(md5 != NULL);
|
||||
assert(buf != NULL);
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32L(W[i], buf + (4*i));
|
||||
}
|
||||
|
||||
/* copy state */
|
||||
a = md5->state[0];
|
||||
b = md5->state[1];
|
||||
c = md5->state[2];
|
||||
d = md5->state[3];
|
||||
|
||||
FF(a,b,c,d,W[0],7,0xd76aa478UL)
|
||||
FF(d,a,b,c,W[1],12,0xe8c7b756UL)
|
||||
FF(c,d,a,b,W[2],17,0x242070dbUL)
|
||||
FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
|
||||
FF(a,b,c,d,W[4],7,0xf57c0fafUL)
|
||||
FF(d,a,b,c,W[5],12,0x4787c62aUL)
|
||||
FF(c,d,a,b,W[6],17,0xa8304613UL)
|
||||
FF(b,c,d,a,W[7],22,0xfd469501UL)
|
||||
FF(a,b,c,d,W[8],7,0x698098d8UL)
|
||||
FF(d,a,b,c,W[9],12,0x8b44f7afUL)
|
||||
FF(c,d,a,b,W[10],17,0xffff5bb1UL)
|
||||
FF(b,c,d,a,W[11],22,0x895cd7beUL)
|
||||
FF(a,b,c,d,W[12],7,0x6b901122UL)
|
||||
FF(d,a,b,c,W[13],12,0xfd987193UL)
|
||||
FF(c,d,a,b,W[14],17,0xa679438eUL)
|
||||
FF(b,c,d,a,W[15],22,0x49b40821UL)
|
||||
GG(a,b,c,d,W[1],5,0xf61e2562UL)
|
||||
GG(d,a,b,c,W[6],9,0xc040b340UL)
|
||||
GG(c,d,a,b,W[11],14,0x265e5a51UL)
|
||||
GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
|
||||
GG(a,b,c,d,W[5],5,0xd62f105dUL)
|
||||
GG(d,a,b,c,W[10],9,0x02441453UL)
|
||||
GG(c,d,a,b,W[15],14,0xd8a1e681UL)
|
||||
GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
|
||||
GG(a,b,c,d,W[9],5,0x21e1cde6UL)
|
||||
GG(d,a,b,c,W[14],9,0xc33707d6UL)
|
||||
GG(c,d,a,b,W[3],14,0xf4d50d87UL)
|
||||
GG(b,c,d,a,W[8],20,0x455a14edUL)
|
||||
GG(a,b,c,d,W[13],5,0xa9e3e905UL)
|
||||
GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
|
||||
GG(c,d,a,b,W[7],14,0x676f02d9UL)
|
||||
GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
|
||||
HH(a,b,c,d,W[5],4,0xfffa3942UL)
|
||||
HH(d,a,b,c,W[8],11,0x8771f681UL)
|
||||
HH(c,d,a,b,W[11],16,0x6d9d6122UL)
|
||||
HH(b,c,d,a,W[14],23,0xfde5380cUL)
|
||||
HH(a,b,c,d,W[1],4,0xa4beea44UL)
|
||||
HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
|
||||
HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
|
||||
HH(b,c,d,a,W[10],23,0xbebfbc70UL)
|
||||
HH(a,b,c,d,W[13],4,0x289b7ec6UL)
|
||||
HH(d,a,b,c,W[0],11,0xeaa127faUL)
|
||||
HH(c,d,a,b,W[3],16,0xd4ef3085UL)
|
||||
HH(b,c,d,a,W[6],23,0x04881d05UL)
|
||||
HH(a,b,c,d,W[9],4,0xd9d4d039UL)
|
||||
HH(d,a,b,c,W[12],11,0xe6db99e5UL)
|
||||
HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
|
||||
HH(b,c,d,a,W[2],23,0xc4ac5665UL)
|
||||
II(a,b,c,d,W[0],6,0xf4292244UL)
|
||||
II(d,a,b,c,W[7],10,0x432aff97UL)
|
||||
II(c,d,a,b,W[14],15,0xab9423a7UL)
|
||||
II(b,c,d,a,W[5],21,0xfc93a039UL)
|
||||
II(a,b,c,d,W[12],6,0x655b59c3UL)
|
||||
II(d,a,b,c,W[3],10,0x8f0ccc92UL)
|
||||
II(c,d,a,b,W[10],15,0xffeff47dUL)
|
||||
II(b,c,d,a,W[1],21,0x85845dd1UL)
|
||||
II(a,b,c,d,W[8],6,0x6fa87e4fUL)
|
||||
II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
|
||||
II(c,d,a,b,W[6],15,0xa3014314UL)
|
||||
II(b,c,d,a,W[13],21,0x4e0811a1UL)
|
||||
II(a,b,c,d,W[4],6,0xf7537e82UL)
|
||||
II(d,a,b,c,W[11],10,0xbd3af235UL)
|
||||
II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
|
||||
II(b,c,d,a,W[9],21,0xeb86d391UL)
|
||||
|
||||
md5->state[0] = md5->state[0] + a;
|
||||
md5->state[1] = md5->state[1] + b;
|
||||
md5->state[2] = md5->state[2] + c;
|
||||
md5->state[3] = md5->state[3] + d;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize the hash state
|
||||
@param sha1 The hash state you wish to initialize
|
||||
*/
|
||||
static void
|
||||
md5_init(struct md5_state *md5)
|
||||
{
|
||||
assert(md5 != NULL);
|
||||
md5->state[0] = 0x67452301UL;
|
||||
md5->state[1] = 0xefcdab89UL;
|
||||
md5->state[2] = 0x98badcfeUL;
|
||||
md5->state[3] = 0x10325476UL;
|
||||
md5->curlen = 0;
|
||||
md5->length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Process a block of memory though the hash
|
||||
@param sha1 The hash state
|
||||
@param in The data to hash
|
||||
@param inlen The length of the data (octets)
|
||||
*/
|
||||
static void
|
||||
md5_process(struct md5_state *md5, const unsigned char *in, Py_ssize_t inlen)
|
||||
{
|
||||
Py_ssize_t n;
|
||||
|
||||
assert(md5 != NULL);
|
||||
assert(in != NULL);
|
||||
assert(md5->curlen <= sizeof(md5->buf));
|
||||
|
||||
while (inlen > 0) {
|
||||
if (md5->curlen == 0 && inlen >= MD5_BLOCKSIZE) {
|
||||
md5_compress(md5, (unsigned char *)in);
|
||||
md5->length += MD5_BLOCKSIZE * 8;
|
||||
in += MD5_BLOCKSIZE;
|
||||
inlen -= MD5_BLOCKSIZE;
|
||||
} else {
|
||||
n = Py_MIN(inlen, (Py_ssize_t)(MD5_BLOCKSIZE - md5->curlen));
|
||||
memcpy(md5->buf + md5->curlen, in, (size_t)n);
|
||||
md5->curlen += (MD5_INT32)n;
|
||||
in += n;
|
||||
inlen -= n;
|
||||
if (md5->curlen == MD5_BLOCKSIZE) {
|
||||
md5_compress(md5, md5->buf);
|
||||
md5->length += 8*MD5_BLOCKSIZE;
|
||||
md5->curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
@param sha1 The hash state
|
||||
@param out [out] The destination of the hash (16 bytes)
|
||||
*/
|
||||
static void
|
||||
md5_done(struct md5_state *md5, unsigned char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(md5 != NULL);
|
||||
assert(out != NULL);
|
||||
assert(md5->curlen < sizeof(md5->buf));
|
||||
|
||||
/* increase the length of the message */
|
||||
md5->length += md5->curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md5->buf[md5->curlen++] = (unsigned char)0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md5->curlen > 56) {
|
||||
while (md5->curlen < 64) {
|
||||
md5->buf[md5->curlen++] = (unsigned char)0;
|
||||
}
|
||||
md5_compress(md5, md5->buf);
|
||||
md5->curlen = 0;
|
||||
}
|
||||
|
||||
/* pad up to 56 bytes of zeroes */
|
||||
while (md5->curlen < 56) {
|
||||
md5->buf[md5->curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64L(md5->length, md5->buf+56);
|
||||
md5_compress(md5, md5->buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 4; i++) {
|
||||
STORE32L(md5->state[i], out+(4*i));
|
||||
}
|
||||
}
|
||||
|
||||
/* .Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */
|
||||
/* .Revision: 1.10 $ */
|
||||
/* .Date: 2007/05/12 14:25:28 $ */
|
||||
|
||||
/*
|
||||
* End of copied MD5 code.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static PyTypeObject MD5type;
|
||||
|
||||
|
||||
static MD5object *
|
||||
newMD5object(void)
|
||||
{
|
||||
return (MD5object *)PyObject_New(MD5object, &MD5type);
|
||||
}
|
||||
|
||||
|
||||
/* Internal methods for a hash object */
|
||||
|
||||
static void
|
||||
MD5_dealloc(PyObject *ptr)
|
||||
{
|
||||
PyObject_Del(ptr);
|
||||
}
|
||||
|
||||
|
||||
/* External methods for a hash object */
|
||||
|
||||
/*[clinic input]
|
||||
MD5Type.copy
|
||||
|
||||
Return a copy of the hash object.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
MD5Type_copy_impl(MD5object *self)
|
||||
/*[clinic end generated code: output=596eb36852f02071 input=2c09e6d2493f3079]*/
|
||||
{
|
||||
MD5object *newobj;
|
||||
|
||||
if ((newobj = newMD5object())==NULL)
|
||||
return NULL;
|
||||
|
||||
newobj->hash_state = self->hash_state;
|
||||
return (PyObject *)newobj;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
MD5Type.digest
|
||||
|
||||
Return the digest value as a bytes object.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
MD5Type_digest_impl(MD5object *self)
|
||||
/*[clinic end generated code: output=eb691dc4190a07ec input=bc0c4397c2994be6]*/
|
||||
{
|
||||
unsigned char digest[MD5_DIGESTSIZE];
|
||||
struct md5_state temp;
|
||||
|
||||
temp = self->hash_state;
|
||||
md5_done(&temp, digest);
|
||||
return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
MD5Type.hexdigest
|
||||
|
||||
Return the digest value as a string of hexadecimal digits.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
MD5Type_hexdigest_impl(MD5object *self)
|
||||
/*[clinic end generated code: output=17badced1f3ac932 input=b60b19de644798dd]*/
|
||||
{
|
||||
unsigned char digest[MD5_DIGESTSIZE];
|
||||
struct md5_state temp;
|
||||
|
||||
/* Get the raw (binary) digest value */
|
||||
temp = self->hash_state;
|
||||
md5_done(&temp, digest);
|
||||
|
||||
return _Py_strhex((const char*)digest, MD5_DIGESTSIZE);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
MD5Type.update
|
||||
|
||||
obj: object
|
||||
/
|
||||
|
||||
Update this hash object's state with the provided string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
MD5Type_update(MD5object *self, PyObject *obj)
|
||||
/*[clinic end generated code: output=f6ad168416338423 input=6e1efcd9ecf17032]*/
|
||||
{
|
||||
Py_buffer buf;
|
||||
|
||||
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
|
||||
|
||||
md5_process(&self->hash_state, buf.buf, buf.len);
|
||||
|
||||
PyBuffer_Release(&buf);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyMethodDef MD5_methods[] = {
|
||||
MD5TYPE_COPY_METHODDEF
|
||||
MD5TYPE_DIGEST_METHODDEF
|
||||
MD5TYPE_HEXDIGEST_METHODDEF
|
||||
MD5TYPE_UPDATE_METHODDEF
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
MD5_get_block_size(PyObject *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(MD5_BLOCKSIZE);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
MD5_get_name(PyObject *self, void *closure)
|
||||
{
|
||||
return PyUnicode_FromStringAndSize("md5", 3);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
md5_get_digest_size(PyObject *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(MD5_DIGESTSIZE);
|
||||
}
|
||||
|
||||
|
||||
static PyGetSetDef MD5_getseters[] = {
|
||||
{"block_size",
|
||||
(getter)MD5_get_block_size, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{"name",
|
||||
(getter)MD5_get_name, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{"digest_size",
|
||||
(getter)md5_get_digest_size, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject MD5type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"_md5.md5", /*tp_name*/
|
||||
sizeof(MD5object), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
MD5_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*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
MD5_methods, /* tp_methods */
|
||||
NULL, /* tp_members */
|
||||
MD5_getseters, /* tp_getset */
|
||||
};
|
||||
|
||||
|
||||
/* The single module-level function: new() */
|
||||
|
||||
/*[clinic input]
|
||||
_md5.md5
|
||||
|
||||
string: object(c_default="NULL") = b''
|
||||
|
||||
Return a new MD5 hash object; optionally initialized with a string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_md5_md5_impl(PyObject *module, PyObject *string)
|
||||
/*[clinic end generated code: output=2cfd0f8c091b97e6 input=d12ef8f72d684f7b]*/
|
||||
{
|
||||
MD5object *new;
|
||||
Py_buffer buf;
|
||||
|
||||
if (string)
|
||||
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
|
||||
|
||||
if ((new = newMD5object()) == NULL) {
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
md5_init(&new->hash_state);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(new);
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
if (string) {
|
||||
md5_process(&new->hash_state, buf.buf, buf.len);
|
||||
PyBuffer_Release(&buf);
|
||||
}
|
||||
|
||||
return (PyObject *)new;
|
||||
}
|
||||
|
||||
|
||||
/* List of functions exported by this module */
|
||||
|
||||
static struct PyMethodDef MD5_functions[] = {
|
||||
_MD5_MD5_METHODDEF
|
||||
{NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
/* Initialize this module. */
|
||||
|
||||
#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
|
||||
|
||||
|
||||
static struct PyModuleDef _md5module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_md5",
|
||||
NULL,
|
||||
-1,
|
||||
MD5_functions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit__md5(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
Py_TYPE(&MD5type) = &PyType_Type;
|
||||
if (PyType_Ready(&MD5type) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&_md5module);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF((PyObject *)&MD5type);
|
||||
PyModule_AddObject(m, "MD5Type", (PyObject *)&MD5type);
|
||||
return m;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__md5 = {
|
||||
"_md5",
|
||||
PyInit__md5,
|
||||
};
|
38
third_party/python/Modules/parsermodule.c
vendored
38
third_party/python/Modules/parsermodule.c
vendored
|
@ -41,6 +41,18 @@ PYTHON_PROVIDE("parser.st2tuple");
|
|||
PYTHON_PROVIDE("parser.suite");
|
||||
PYTHON_PROVIDE("parser.tuple2st");
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
parsermodule (Python license)\\n\
|
||||
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\
|
||||
Centrum, Amsterdam, The Netherlands.\"");
|
||||
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\
|
||||
Centrum, Amsterdam, The Netherlands.";
|
||||
|
||||
/* parsermodule.c
|
||||
*
|
||||
* Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
|
||||
|
@ -77,22 +89,11 @@ extern grammar _PyParser_Grammar; /* From graminit.c */
|
|||
|
||||
#define NOTE(x)
|
||||
|
||||
/* String constants used to initialize module attributes.
|
||||
*
|
||||
*/
|
||||
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\
|
||||
Centrum, Amsterdam, The Netherlands.";
|
||||
|
||||
|
||||
PyDoc_STRVAR(parser_doc_string,
|
||||
"This is an interface to Python's internal parser.");
|
||||
|
||||
static const char parser_version_string[] = "0.5";
|
||||
|
||||
|
||||
typedef PyObject* (*SeqMaker) (Py_ssize_t length);
|
||||
typedef int (*SeqInserter) (PyObject* sequence,
|
||||
Py_ssize_t index,
|
||||
|
@ -106,8 +107,6 @@ typedef int (*SeqInserter) (PyObject* sequence,
|
|||
* new naming conventions. Added arguments to provide support for creating
|
||||
* lists as well as tuples, and optionally including the line numbers.
|
||||
*/
|
||||
|
||||
|
||||
static PyObject*
|
||||
node2tuple(node *n, /* node to convert */
|
||||
SeqMaker mkseq, /* create sequence */
|
||||
|
@ -116,31 +115,25 @@ node2tuple(node *n, /* node to convert */
|
|||
int col_offset) /* include column offsets? */
|
||||
{
|
||||
PyObject *result = NULL, *w;
|
||||
|
||||
if (n == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
if (ISNONTERMINAL(TYPE(n))) {
|
||||
int i;
|
||||
|
||||
result = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl));
|
||||
if (result == NULL)
|
||||
goto error;
|
||||
|
||||
w = PyLong_FromLong(TYPE(n));
|
||||
if (w == NULL)
|
||||
goto error;
|
||||
(void) addelem(result, 0, w);
|
||||
|
||||
for (i = 0; i < NCH(n); i++) {
|
||||
w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset);
|
||||
if (w == NULL)
|
||||
goto error;
|
||||
(void) addelem(result, i+1, w);
|
||||
}
|
||||
|
||||
if (TYPE(n) == encoding_decl) {
|
||||
w = PyUnicode_FromString(STR(n));
|
||||
if (w == NULL)
|
||||
|
@ -152,24 +145,20 @@ node2tuple(node *n, /* node to convert */
|
|||
result = mkseq(2 + lineno + col_offset);
|
||||
if (result == NULL)
|
||||
goto error;
|
||||
|
||||
w = PyLong_FromLong(TYPE(n));
|
||||
if (w == NULL)
|
||||
goto error;
|
||||
(void) addelem(result, 0, w);
|
||||
|
||||
w = PyUnicode_FromString(STR(n));
|
||||
if (w == NULL)
|
||||
goto error;
|
||||
(void) addelem(result, 1, w);
|
||||
|
||||
if (lineno) {
|
||||
w = PyLong_FromLong(n->n_lineno);
|
||||
if (w == NULL)
|
||||
goto error;
|
||||
(void) addelem(result, 2, w);
|
||||
}
|
||||
|
||||
if (col_offset) {
|
||||
w = PyLong_FromLong(n->n_col_offset);
|
||||
if (w == NULL)
|
||||
|
@ -183,7 +172,6 @@ node2tuple(node *n, /* node to convert */
|
|||
return ((PyObject*) NULL);
|
||||
}
|
||||
return result;
|
||||
|
||||
error:
|
||||
Py_XDECREF(result);
|
||||
return NULL;
|
||||
|
@ -1171,8 +1159,6 @@ static PyMethodDef parser_functions[] = {
|
|||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct PyModuleDef parsermodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"parser",
|
||||
|
|
473
third_party/python/Modules/posixmodule.c
vendored
473
third_party/python/Modules/posixmodule.c
vendored
|
@ -19,9 +19,15 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/dll.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/sw.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/dlfcn.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/sysconf.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
@ -41,6 +47,7 @@
|
|||
#include "libc/sysv/consts/waitid.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/musl/passwd.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/boolobject.h"
|
||||
|
@ -64,11 +71,13 @@
|
|||
#include "third_party/python/Include/structseq.h"
|
||||
#include "third_party/python/Include/warnings.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/Modules/_multiprocessing/multiprocessing.h"
|
||||
#include "third_party/python/Modules/posixmodule.h"
|
||||
#include "third_party/python/pyconfig.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("posix");
|
||||
PYTHON_PROVIDE("posix._getfinalpathname");
|
||||
|
||||
/* POSIX module implementation */
|
||||
|
||||
|
@ -156,7 +165,7 @@ module os
|
|||
/* defined in fileutils.c */
|
||||
void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
|
||||
void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
|
||||
ULONG, struct _Py_stat_struct *);
|
||||
ULONG, struct _Py_stat_struct *);
|
||||
#endif
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
@ -938,14 +947,12 @@ PyLong_FromPy_off_t(Py_off_t offset)
|
|||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
||||
static int
|
||||
win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
|
||||
{
|
||||
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(
|
||||
reparse_point_handle,
|
||||
FSCTL_GET_REPARSE_POINT,
|
||||
|
@ -954,13 +961,10 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
|
|||
&n_bytes_returned,
|
||||
NULL)) /* we're not using OVERLAPPED_IO */
|
||||
return FALSE;
|
||||
|
||||
if (reparse_tag)
|
||||
*reparse_tag = rdb->ReparseTag;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
static PyObject *
|
||||
|
@ -972,7 +976,6 @@ convertenviron(void)
|
|||
#else
|
||||
char **e;
|
||||
#endif
|
||||
|
||||
d = PyDict_New();
|
||||
if (d == NULL)
|
||||
return NULL;
|
||||
|
@ -1051,7 +1054,6 @@ posix_error(void)
|
|||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
static PyObject *
|
||||
win32_error(const char* function, const char* filename)
|
||||
{
|
||||
|
@ -1081,8 +1083,6 @@ win32_error_object(const char* function, PyObject* filename)
|
|||
return PyErr_SetFromWindowsErr(errno);
|
||||
}
|
||||
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
static PyObject *
|
||||
posix_path_object_error(PyObject *path)
|
||||
{
|
||||
|
@ -1255,8 +1255,7 @@ get_target_path(HANDLE hdl, wchar_t **target_path)
|
|||
|
||||
/* We have a good handle to the target, use it to determine
|
||||
the target path name (then we'll call lstat on it). */
|
||||
buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
|
||||
VOLUME_NAME_DOS);
|
||||
buf_size = GetFinalPathNameByHandle(hdl, 0, 0, kNtVolumeNameDos);
|
||||
if(!buf_size)
|
||||
return FALSE;
|
||||
|
||||
|
@ -1423,43 +1422,43 @@ or st_flags, they are available as attributes only.\n\
|
|||
See os.stat for more information.");
|
||||
|
||||
static PyStructSequence_Field stat_result_fields[] = {
|
||||
{"st_mode", "protection bits"},
|
||||
{"st_ino", "inode"},
|
||||
{"st_dev", "device"},
|
||||
{"st_nlink", "number of hard links"},
|
||||
{"st_uid", "user ID of owner"},
|
||||
{"st_gid", "group ID of owner"},
|
||||
{"st_size", "total size, in bytes"},
|
||||
{"st_mode", PyDoc_STR("protection bits")},
|
||||
{"st_ino", PyDoc_STR("inode")},
|
||||
{"st_dev", PyDoc_STR("device")},
|
||||
{"st_nlink", PyDoc_STR("number of hard links")},
|
||||
{"st_uid", PyDoc_STR("user ID of owner")},
|
||||
{"st_gid", PyDoc_STR("group ID of owner")},
|
||||
{"st_size", PyDoc_STR("total size, in bytes")},
|
||||
/* The NULL is replaced with PyStructSequence_UnnamedField later. */
|
||||
{NULL, "integer time of last access"},
|
||||
{NULL, "integer time of last modification"},
|
||||
{NULL, "integer time of last change"},
|
||||
{"st_atime", "time of last access"},
|
||||
{"st_mtime", "time of last modification"},
|
||||
{"st_ctime", "time of last change"},
|
||||
{"st_atime_ns", "time of last access in nanoseconds"},
|
||||
{"st_mtime_ns", "time of last modification in nanoseconds"},
|
||||
{"st_ctime_ns", "time of last change in nanoseconds"},
|
||||
{NULL, PyDoc_STR("integer time of last access")},
|
||||
{NULL, PyDoc_STR("integer time of last modification")},
|
||||
{NULL, PyDoc_STR("integer time of last change")},
|
||||
{"st_atime", PyDoc_STR("time of last access")},
|
||||
{"st_mtime", PyDoc_STR("time of last modification")},
|
||||
{"st_ctime", PyDoc_STR("time of last change")},
|
||||
{"st_atime_ns", PyDoc_STR("time of last access in nanoseconds")},
|
||||
{"st_mtime_ns", PyDoc_STR("time of last modification in nanoseconds")},
|
||||
{"st_ctime_ns", PyDoc_STR("time of last change in nanoseconds")},
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
{"st_blksize", "blocksize for filesystem I/O"},
|
||||
{"st_blksize", PyDoc_STR("blocksize for filesystem I/O")},
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
||||
{"st_blocks", "number of blocks allocated"},
|
||||
{"st_blocks", PyDoc_STR("number of blocks allocated")},
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_RDEV
|
||||
{"st_rdev", "device type (if inode device)"},
|
||||
{"st_rdev", PyDoc_STR("device type (if inode device)")},
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
|
||||
{"st_flags", "user defined flags for file"},
|
||||
{"st_flags", PyDoc_STR("user defined flags for file")},
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_GEN
|
||||
{"st_gen", "generation number"},
|
||||
{"st_gen", PyDoc_STR("generation number")},
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||
{"st_birthtime", "time of creation"},
|
||||
{"st_birthtime", PyDoc_STR("time of creation")},
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
|
||||
{"st_file_attributes", "Windows file attribute bits"},
|
||||
{"st_file_attributes", PyDoc_STR("Windows file attribute bits")},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
@ -1777,9 +1776,6 @@ _pystat_fromstructstat(STRUCT_STAT *st)
|
|||
return v;
|
||||
}
|
||||
|
||||
/* POSIX methods */
|
||||
|
||||
|
||||
static PyObject *
|
||||
posix_do_stat(const char *function_name, path_t *path,
|
||||
int dir_fd, int follow_symlinks)
|
||||
|
@ -3368,6 +3364,79 @@ os_listdir_impl(PyObject *module, path_t *path)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
os._getfinalpathname
|
||||
|
||||
path: unicode
|
||||
/
|
||||
|
||||
A helper function for samepath on windows.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os__getfinalpathname_impl(PyObject *module, PyObject *path)
|
||||
/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
|
||||
{
|
||||
char *final8;
|
||||
int64_t hFile;
|
||||
size_t final8z;
|
||||
PyObject *path_utf8;
|
||||
char16_t *path_utf16;
|
||||
char16_t buf[PATH_MAX], *target_path = buf;
|
||||
int buf_size = Py_ARRAY_LENGTH(buf);
|
||||
int result_length;
|
||||
PyObject *result;
|
||||
if (!(path_utf8 = PyUnicode_AsUTF8String(path))) return 0;
|
||||
path_utf16 = gc(utf8toutf16(PyBytes_AS_STRING(path_utf8), PyBytes_GET_SIZE(path_utf8), 0));
|
||||
Py_DECREF(path_utf8);
|
||||
if (!path_utf16) return PyErr_NoMemory();
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
hFile = CreateFile(
|
||||
path_utf16,
|
||||
0, /* desired access */
|
||||
0, /* share mode */
|
||||
NULL, /* security attributes */
|
||||
kNtOpenExisting,
|
||||
/* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
|
||||
kNtFileFlagBackupSemantics,
|
||||
0);
|
||||
Py_END_ALLOW_THREADS
|
||||
if(hFile == kNtInvalidHandleValue)
|
||||
return win32_error_object("CreateFile", path);
|
||||
/* We have a good handle to the target, use it to determine the
|
||||
target path name. */
|
||||
while (1) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
result_length = GetFinalPathNameByHandle(hFile, target_path,
|
||||
buf_size, kNtVolumeNameDos);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (!result_length) {
|
||||
result = win32_error_object("GetFinalPathNameByHandle", path);
|
||||
goto cleanup;
|
||||
}
|
||||
if (result_length < buf_size) {
|
||||
break;
|
||||
}
|
||||
char16_t *tmp;
|
||||
tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
|
||||
result_length * sizeof(*tmp));
|
||||
if (!tmp) {
|
||||
result = PyErr_NoMemory();
|
||||
goto cleanup;
|
||||
}
|
||||
buf_size = result_length;
|
||||
target_path = tmp;
|
||||
}
|
||||
final8 = gc(utf16toutf8(target_path, result_length, &final8z));
|
||||
result = PyUnicode_FromStringAndSize(final8, final8z);
|
||||
cleanup:
|
||||
if (target_path != buf) {
|
||||
PyMem_Free(target_path);
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/* A helper function for abspath on win32 */
|
||||
/*[clinic input]
|
||||
|
@ -3407,85 +3476,6 @@ os__getfullpathname_impl(PyObject *module, path_t *path)
|
|||
return v;
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
os._getfinalpathname
|
||||
|
||||
path: unicode
|
||||
/
|
||||
|
||||
A helper function for samepath on windows.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os__getfinalpathname_impl(PyObject *module, PyObject *path)
|
||||
/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
|
||||
{
|
||||
HANDLE hFile;
|
||||
wchar_t buf[MAXPATHLEN], *target_path = buf;
|
||||
int buf_size = Py_ARRAY_LENGTH(buf);
|
||||
int result_length;
|
||||
PyObject *result;
|
||||
const wchar_t *path_wchar;
|
||||
|
||||
path_wchar = _PyUnicode_AsUnicode(path);
|
||||
if (path_wchar == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
hFile = CreateFileW(
|
||||
path_wchar,
|
||||
0, /* desired access */
|
||||
0, /* share mode */
|
||||
NULL, /* security attributes */
|
||||
OPEN_EXISTING,
|
||||
/* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
return win32_error_object("CreateFileW", path);
|
||||
|
||||
/* We have a good handle to the target, use it to determine the
|
||||
target path name. */
|
||||
while (1) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
result_length = GetFinalPathNameByHandleW(hFile, target_path,
|
||||
buf_size, VOLUME_NAME_DOS);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (!result_length) {
|
||||
result = win32_error_object("GetFinalPathNameByHandleW", path);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (result_length < buf_size) {
|
||||
break;
|
||||
}
|
||||
|
||||
wchar_t *tmp;
|
||||
tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
|
||||
result_length * sizeof(*tmp));
|
||||
if (!tmp) {
|
||||
result = PyErr_NoMemory();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
buf_size = result_length;
|
||||
target_path = tmp;
|
||||
}
|
||||
|
||||
result = PyUnicode_FromWideChar(target_path, result_length);
|
||||
|
||||
cleanup:
|
||||
if (target_path != buf) {
|
||||
PyMem_Free(target_path);
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
os._isdir
|
||||
|
||||
|
@ -3504,10 +3494,8 @@ os__isdir_impl(PyObject *module, path_t *path)
|
|||
Py_BEGIN_ALLOW_THREADS
|
||||
attributes = GetFileAttributesW(path->wide);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (attributes == INVALID_FILE_ATTRIBUTES)
|
||||
Py_RETURN_FALSE;
|
||||
|
||||
if (attributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
|
@ -3515,6 +3503,8 @@ os__isdir_impl(PyObject *module, path_t *path)
|
|||
}
|
||||
|
||||
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
/*[clinic input]
|
||||
os._getvolumepathname
|
||||
|
||||
|
@ -3528,46 +3518,75 @@ os__getvolumepathname_impl(PyObject *module, PyObject *path)
|
|||
/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
|
||||
{
|
||||
PyObject *result;
|
||||
const wchar_t *path_wchar;
|
||||
wchar_t *mountpath=NULL;
|
||||
PyObject *path_utf8;
|
||||
char16_t *path_utf16;
|
||||
char16_t *mountpath;
|
||||
char *mountpath8;
|
||||
size_t buflen;
|
||||
BOOL ret;
|
||||
|
||||
path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
|
||||
if (path_wchar == NULL)
|
||||
return NULL;
|
||||
bool32 ret;
|
||||
if (!(path_utf8 = PyUnicode_AsUTF8String(path))) return 0;
|
||||
path_utf16 = gc(utf8toutf16(PyBytes_AS_STRING(path_utf8), PyBytes_GET_SIZE(path_utf8), &buflen));
|
||||
Py_DECREF(path_utf8);
|
||||
if (!path_utf16) return PyErr_NoMemory();
|
||||
buflen += 1;
|
||||
|
||||
/* Volume path should be shorter than entire path */
|
||||
buflen = Py_MAX(buflen, MAX_PATH);
|
||||
|
||||
buflen = Py_MAX(buflen, PATH_MAX);
|
||||
if (buflen > DWORD_MAX) {
|
||||
PyErr_SetString(PyExc_OverflowError, "path too long");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mountpath = PyMem_New(wchar_t, buflen);
|
||||
if (mountpath == NULL)
|
||||
if (!(mountpath = PyMem_New(char16_t, buflen)))
|
||||
return PyErr_NoMemory();
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
ret = GetVolumePathNameW(path_wchar, mountpath,
|
||||
Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
|
||||
ret = GetVolumePathName(path_utf16, mountpath,
|
||||
Py_SAFE_DOWNCAST(buflen, size_t, uint32_t));
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (!ret) {
|
||||
if (ret) {
|
||||
mountpath8 = gc(utf16toutf8(mountpath, -1, &buflen));
|
||||
result = PyUnicode_FromStringAndSize(mountpath8, buflen);
|
||||
} else {
|
||||
result = win32_error_object("_getvolumepathname", path);
|
||||
goto exit;
|
||||
}
|
||||
result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
|
||||
|
||||
exit:
|
||||
PyMem_Free(mountpath);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
/* static PyObject * */
|
||||
/* os__getvolumepathname_impl(PyObject *module, PyObject *path) */
|
||||
/* /\*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*\/ */
|
||||
/* { */
|
||||
/* PyObject *result; */
|
||||
/* const utf8_t *path_utf8; */
|
||||
/* const wchar_t *path_wchar; */
|
||||
/* char16_t *mountpath=NULL; */
|
||||
/* size_t buflen; */
|
||||
/* bool32 ret; */
|
||||
/* path_wchar = PyUnicode_AsUTF8String(path, &buflen); */
|
||||
/* if (path_wchar == NULL) */
|
||||
/* return NULL; */
|
||||
/* buflen += 1; */
|
||||
/* /\* Volume path should be shorter than entire path *\/ */
|
||||
/* buflen = Py_MAX(buflen, MAX_PATH); */
|
||||
/* if (buflen > DWORD_MAX) { */
|
||||
/* PyErr_SetString(PyExc_OverflowError, "path too long"); */
|
||||
/* return NULL; */
|
||||
/* } */
|
||||
/* mountpath = PyMem_New(char16_t, buflen); */
|
||||
/* if (mountpath == NULL) */
|
||||
/* return PyErr_NoMemory(); */
|
||||
/* Py_BEGIN_ALLOW_THREADS */
|
||||
/* ret = GetVolumePathNameW(path_wchar, mountpath, */
|
||||
/* Py_SAFE_DOWNCAST(buflen, size_t, uint32_t)); */
|
||||
/* Py_END_ALLOW_THREADS */
|
||||
/* if (!ret) { */
|
||||
/* result = win32_error_object("_getvolumepathname", path); */
|
||||
/* goto exit; */
|
||||
/* } */
|
||||
/* result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); */
|
||||
/* exit: */
|
||||
/* PyMem_Free(mountpath); */
|
||||
/* return result; */
|
||||
/* } */
|
||||
|
||||
/*[clinic input]
|
||||
os.mkdir
|
||||
|
@ -3922,45 +3941,6 @@ os_umask_impl(PyObject *module, int mask)
|
|||
return PyLong_FromLong((long)i);
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
||||
/* override the default DeleteFileW behavior so that directory
|
||||
symlinks can be removed with this function, the same as with
|
||||
Unix symlinks */
|
||||
BOOL WINAPI Py_DeleteFileW(const char16_t * lpFileName)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA info;
|
||||
WIN32_FIND_DATAW find_data;
|
||||
HANDLE find_data_handle;
|
||||
int is_directory = 0;
|
||||
int is_link = 0;
|
||||
|
||||
if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
|
||||
is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||
|
||||
/* Get WIN32_FIND_DATA structure for the path to determine if
|
||||
it is a symlink */
|
||||
if(is_directory &&
|
||||
info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
find_data_handle = FindFirstFileW(lpFileName, &find_data);
|
||||
|
||||
if(find_data_handle != INVALID_HANDLE_VALUE) {
|
||||
/* IO_REPARSE_TAG_SYMLINK if it is a symlink and
|
||||
IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
|
||||
is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
|
||||
find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
|
||||
FindClose(find_data_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_directory && is_link)
|
||||
return RemoveDirectoryW(lpFileName);
|
||||
|
||||
return DeleteFileW(lpFileName);
|
||||
}
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
os.unlink
|
||||
|
@ -4025,13 +4005,12 @@ os_remove_impl(PyObject *module, path_t *path, int dir_fd)
|
|||
return os_unlink_impl(module, path, dir_fd);
|
||||
}
|
||||
|
||||
|
||||
static PyStructSequence_Field uname_result_fields[] = {
|
||||
{"sysname", "operating system name"},
|
||||
{"nodename", "name of machine on network (implementation-defined)"},
|
||||
{"release", "operating system release"},
|
||||
{"version", "operating system version"},
|
||||
{"machine", "hardware identifier"},
|
||||
{"sysname", PyDoc_STR("operating system name")},
|
||||
{"nodename", PyDoc_STR("name of machine on network (implementation-defined)")},
|
||||
{"release", PyDoc_STR("operating system release")},
|
||||
{"version", PyDoc_STR("operating system version")},
|
||||
{"machine", PyDoc_STR("hardware identifier")},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -5170,7 +5149,7 @@ os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
|
|||
PyDoc_VAR(os_sched_param__doc__);
|
||||
|
||||
static PyStructSequence_Field sched_param_fields[] = {
|
||||
{"sched_priority", "the scheduling priority"},
|
||||
{"sched_priority", PyDoc_STR("the scheduling priority")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -5650,7 +5629,6 @@ os_forkpty_impl(PyObject *module)
|
|||
}
|
||||
#endif /* HAVE_FORKPTY */
|
||||
|
||||
|
||||
#ifdef HAVE_GETEGID
|
||||
/*[clinic input]
|
||||
os.getegid
|
||||
|
@ -6918,15 +6896,12 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
|
|||
}
|
||||
#endif /* HAVE_SYMLINK */
|
||||
|
||||
|
||||
|
||||
|
||||
static PyStructSequence_Field times_result_fields[] = {
|
||||
{"user", "user time"},
|
||||
{"system", "system time"},
|
||||
{"children_user", "user time of children"},
|
||||
{"children_system", "system time of children"},
|
||||
{"elapsed", "elapsed time since an arbitrary point in the past"},
|
||||
{"user", PyDoc_STR("user time")},
|
||||
{"system", PyDoc_STR("system time")},
|
||||
{"children_user", PyDoc_STR("user time of children")},
|
||||
{"children_system", PyDoc_STR("system time of children")},
|
||||
{"elapsed", PyDoc_STR("elapsed time since an arbitrary point in the past")},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -8745,46 +8720,34 @@ os_WSTOPSIG_impl(PyObject *module, int status)
|
|||
#define _SVID3
|
||||
#endif
|
||||
|
||||
static PyObject*
|
||||
static PyObject *
|
||||
_pystatvfs_fromstructstatvfs(struct statvfs st) {
|
||||
PyObject *v = PyStructSequence_New(&StatVFSResultType);
|
||||
if (v == NULL)
|
||||
return NULL;
|
||||
|
||||
#if !defined(HAVE_LARGEFILE_SUPPORT)
|
||||
PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
|
||||
PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
|
||||
#if !defined(HAVE_LARGEFILE_SUPPORT)
|
||||
PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
|
||||
PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
|
||||
PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
|
||||
PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
|
||||
PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
|
||||
PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((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));
|
||||
#else
|
||||
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((long long) st.f_blocks));
|
||||
PyStructSequence_SET_ITEM(v, 3,
|
||||
PyLong_FromLongLong((long long) st.f_bfree));
|
||||
PyStructSequence_SET_ITEM(v, 4,
|
||||
PyLong_FromLongLong((long long) st.f_bavail));
|
||||
PyStructSequence_SET_ITEM(v, 5,
|
||||
PyLong_FromLongLong((long long) st.f_files));
|
||||
PyStructSequence_SET_ITEM(v, 6,
|
||||
PyLong_FromLongLong((long long) st.f_ffree));
|
||||
PyStructSequence_SET_ITEM(v, 7,
|
||||
PyLong_FromLongLong((long long) st.f_favail));
|
||||
PyStructSequence_SET_ITEM(v, 2, PyLong_FromLongLong((long long) st.f_blocks));
|
||||
PyStructSequence_SET_ITEM(v, 3, PyLong_FromLongLong((long long) st.f_bfree));
|
||||
PyStructSequence_SET_ITEM(v, 4, PyLong_FromLongLong((long long) st.f_bavail));
|
||||
PyStructSequence_SET_ITEM(v, 5, PyLong_FromLongLong((long long) st.f_files));
|
||||
PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong((long long) st.f_ffree));
|
||||
PyStructSequence_SET_ITEM(v, 7, PyLong_FromLongLong((long long) st.f_favail));
|
||||
#endif
|
||||
PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
|
||||
PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
|
||||
#endif
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(v);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -10461,8 +10424,8 @@ PyDoc_STRVAR(TerminalSize_docstring,
|
|||
"A tuple of (columns, lines) for holding terminal window size");
|
||||
|
||||
static PyStructSequence_Field TerminalSize_fields[] = {
|
||||
{"columns", "width of the terminal window in characters"},
|
||||
{"lines", "height of the terminal window in characters"},
|
||||
{"columns", PyDoc_STR("width of the terminal window in characters")},
|
||||
{"lines", PyDoc_STR("height of the terminal window in characters")},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -10982,31 +10945,25 @@ DirEntry_fspath(DirEntry *self)
|
|||
|
||||
static PyMemberDef DirEntry_members[] = {
|
||||
{"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
|
||||
"the entry's base filename, relative to scandir() \"path\" argument"},
|
||||
PyDoc_STR("the entry's base filename, relative to scandir() \"path\" argument")},
|
||||
{"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
|
||||
"the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
|
||||
PyDoc_STR("the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)")},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static PyMethodDef DirEntry_methods[] = {
|
||||
{"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
|
||||
"return True if the entry is a directory; cached per entry"
|
||||
},
|
||||
PyDoc_STR("is_dir($self)\n--\n\nreturn True if entry is a directory; cached per entry")},
|
||||
{"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
|
||||
"return True if the entry is a file; cached per entry"
|
||||
},
|
||||
PyDoc_STR("is_file($self)\n--\n\nreturn True if the entry is a file; cached per entry")},
|
||||
{"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
|
||||
"return True if the entry is a symbolic link; cached per entry"
|
||||
},
|
||||
PyDoc_STR("is_symlink($self)\n--\n\nreturn True if the entry is a symbolic link; cached per entry")},
|
||||
{"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
|
||||
"return stat_result object for the entry; cached per entry"
|
||||
},
|
||||
PyDoc_STR("is_stat($self)\n--\n\nreturn stat_result object for the entry; cached per entry")},
|
||||
{"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
|
||||
"return inode of the entry; cached per entry",
|
||||
},
|
||||
PyDoc_STR("inode($self)\n--\n\nreturn inode of the entry; cached per entry")},
|
||||
{"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
|
||||
"returns the path for the entry",
|
||||
},
|
||||
PyDoc_STR("__fspath__($self)\n--\n\nreturns the path for the entry")},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -11599,9 +11556,7 @@ dump buffer
|
|||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
|
||||
|
||||
|
||||
static PyMethodDef posix_methods[] = {
|
||||
|
||||
OS_STAT_METHODDEF
|
||||
OS_ACCESS_METHODDEF
|
||||
OS_TTYNAME_METHODDEF
|
||||
|
@ -11844,6 +11799,8 @@ all_ins(PyObject *m)
|
|||
if (O_NOFOLLOW_ANY && PyModule_AddIntMacro(m, O_NOFOLLOW_ANY)) return -1;
|
||||
if (O_NOATIME && PyModule_AddIntMacro(m, O_NOATIME)) return -1;
|
||||
if (O_VERIFY && PyModule_AddIntMacro(m, O_VERIFY)) return -1;
|
||||
if (IsWindows() && PyModule_AddIntConstant(m, "O_SHORT_LIVED", kNtFileAttributeTemporary)) return -1;
|
||||
if (IsWindows() && PyModule_AddIntConstant(m, "O_TEMPORARY", kNtFileFlagDeleteOnClose)) return -1;
|
||||
#ifdef O_BINARY
|
||||
if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
|
||||
#endif
|
||||
|
@ -11856,12 +11813,6 @@ all_ins(PyObject *m)
|
|||
#ifdef O_NOINHERIT
|
||||
if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
|
||||
#endif
|
||||
#ifdef _O_SHORT_LIVED
|
||||
if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
|
||||
#endif
|
||||
#ifdef O_TEMPORARY
|
||||
if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
|
||||
#endif
|
||||
|
||||
if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
|
||||
if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
|
||||
|
@ -12012,13 +11963,10 @@ all_ins(PyObject *m)
|
|||
|
||||
if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
|
||||
if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
|
||||
if (PyModule_AddIntMacro(m, GRND_NORDRND)) return -1;
|
||||
if (PyModule_AddIntMacro(m, GRND_NOSYSTEM)) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct PyModuleDef posixmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
MODNAME,
|
||||
|
@ -12031,133 +11979,100 @@ static struct PyModuleDef posixmodule = {
|
|||
NULL
|
||||
};
|
||||
|
||||
|
||||
static const char * const have_functions[] = {
|
||||
|
||||
#ifdef HAVE_FACCESSAT
|
||||
"HAVE_FACCESSAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCHDIR
|
||||
"HAVE_FCHDIR",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCHMOD
|
||||
"HAVE_FCHMOD",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCHMODAT
|
||||
"HAVE_FCHMODAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCHOWN
|
||||
"HAVE_FCHOWN",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCHOWNAT
|
||||
"HAVE_FCHOWNAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FEXECVE
|
||||
"HAVE_FEXECVE",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FDOPENDIR
|
||||
"HAVE_FDOPENDIR",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FPATHCONF
|
||||
"HAVE_FPATHCONF",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FSTATAT
|
||||
"HAVE_FSTATAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FSTATVFS
|
||||
"HAVE_FSTATVFS",
|
||||
#endif
|
||||
|
||||
#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
|
||||
"HAVE_FTRUNCATE",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FUTIMENS
|
||||
"HAVE_FUTIMENS",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FUTIMES
|
||||
"HAVE_FUTIMES",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FUTIMESAT
|
||||
"HAVE_FUTIMESAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINKAT
|
||||
"HAVE_LINKAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LCHFLAGS
|
||||
"HAVE_LCHFLAGS",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LCHMOD
|
||||
"HAVE_LCHMOD",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LCHOWN
|
||||
"HAVE_LCHOWN",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LSTAT
|
||||
"HAVE_LSTAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LUTIMES
|
||||
"HAVE_LUTIMES",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MKDIRAT
|
||||
"HAVE_MKDIRAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MKFIFOAT
|
||||
"HAVE_MKFIFOAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MKNODAT
|
||||
"HAVE_MKNODAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENAT
|
||||
"HAVE_OPENAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_READLINKAT
|
||||
"HAVE_READLINKAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RENAMEAT
|
||||
"HAVE_RENAMEAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYMLINKAT
|
||||
"HAVE_SYMLINKAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNLINKAT
|
||||
"HAVE_UNLINKAT",
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
"HAVE_UTIMENSAT",
|
||||
#endif
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
"MS_WINDOWS",
|
||||
#endif
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
8
third_party/python/Modules/posixmodule.h
vendored
8
third_party/python/Modules/posixmodule.h
vendored
|
@ -13,13 +13,5 @@ int _Py_Gid_Converter(PyObject *, void *);
|
|||
#endif /* MS_WINDOWS */
|
||||
#endif
|
||||
|
||||
#undef HAVE_SETGROUPS
|
||||
#undef HAVE_FORKPTY
|
||||
#undef HAVE_SCHED_SETPARAM
|
||||
#undef HAVE_SCHED_SETSCHEDULER
|
||||
#undef HAVE_FCHMODAT
|
||||
#undef HAVE_LINKAT
|
||||
#undef HAVE_READLINKAT
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !Py_POSIXMODULE_H */
|
||||
|
|
14
third_party/python/Modules/pwdmodule.c
vendored
14
third_party/python/Modules/pwdmodule.c
vendored
|
@ -33,13 +33,13 @@ module pwd
|
|||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=60f628ef356b97b6]*/
|
||||
|
||||
static PyStructSequence_Field struct_pwd_type_fields[] = {
|
||||
{"pw_name", "user name"},
|
||||
{"pw_passwd", "password"},
|
||||
{"pw_uid", "user id"},
|
||||
{"pw_gid", "group id"},
|
||||
{"pw_gecos", "real name"},
|
||||
{"pw_dir", "home directory"},
|
||||
{"pw_shell", "shell program"},
|
||||
{"pw_name", PyDoc_STR("user name")},
|
||||
{"pw_passwd", PyDoc_STR("password")},
|
||||
{"pw_uid", PyDoc_STR("user id")},
|
||||
{"pw_gid", PyDoc_STR("group id")},
|
||||
{"pw_gecos", PyDoc_STR("real name")},
|
||||
{"pw_dir", PyDoc_STR("home directory")},
|
||||
{"pw_shell", PyDoc_STR("shell program")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
103
third_party/python/Modules/resource.c
vendored
103
third_party/python/Modules/resource.c
vendored
|
@ -70,22 +70,22 @@ PyDoc_STRVAR(struct_rusage__doc__,
|
|||
"or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.");
|
||||
|
||||
static PyStructSequence_Field struct_rusage_fields[] = {
|
||||
{"ru_utime", "user time used"},
|
||||
{"ru_stime", "system time used"},
|
||||
{"ru_maxrss", "max. resident set size"},
|
||||
{"ru_ixrss", "shared memory size"},
|
||||
{"ru_idrss", "unshared data size"},
|
||||
{"ru_isrss", "unshared stack size"},
|
||||
{"ru_minflt", "page faults not requiring I/O"},
|
||||
{"ru_majflt", "page faults requiring I/O"},
|
||||
{"ru_nswap", "number of swap outs"},
|
||||
{"ru_inblock", "block input operations"},
|
||||
{"ru_oublock", "block output operations"},
|
||||
{"ru_msgsnd", "IPC messages sent"},
|
||||
{"ru_msgrcv", "IPC messages received"},
|
||||
{"ru_nsignals", "signals received"},
|
||||
{"ru_nvcsw", "voluntary context switches"},
|
||||
{"ru_nivcsw", "involuntary context switches"},
|
||||
{"ru_utime", PyDoc_STR("user time used")},
|
||||
{"ru_stime", PyDoc_STR("system time used")},
|
||||
{"ru_maxrss", PyDoc_STR("max. resident set size")},
|
||||
{"ru_ixrss", PyDoc_STR("shared memory size")},
|
||||
{"ru_idrss", PyDoc_STR("unshared data size")},
|
||||
{"ru_isrss", PyDoc_STR("unshared stack size")},
|
||||
{"ru_minflt", PyDoc_STR("page faults not requiring I/O")},
|
||||
{"ru_majflt", PyDoc_STR("page faults requiring I/O")},
|
||||
{"ru_nswap", PyDoc_STR("number of swap outs")},
|
||||
{"ru_inblock", PyDoc_STR("block input operations")},
|
||||
{"ru_oublock", PyDoc_STR("block output operations")},
|
||||
{"ru_msgsnd", PyDoc_STR("IPC messages sent")},
|
||||
{"ru_msgrcv", PyDoc_STR("IPC messages received")},
|
||||
{"ru_nsignals", PyDoc_STR("signals received")},
|
||||
{"ru_nvcsw", PyDoc_STR("voluntary context switches")},
|
||||
{"ru_nivcsw", PyDoc_STR("involuntary context switches")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -104,11 +104,9 @@ resource_getrusage(PyObject *self, PyObject *args)
|
|||
{
|
||||
int who;
|
||||
struct rusage ru;
|
||||
PyObject *result;
|
||||
|
||||
PyObject *r;
|
||||
if (!PyArg_ParseTuple(args, "i:getrusage", &who))
|
||||
return NULL;
|
||||
|
||||
if (getrusage(who, &ru) == -1) {
|
||||
if (errno == EINVAL) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
|
@ -118,36 +116,30 @@ resource_getrusage(PyObject *self, PyObject *args)
|
|||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = PyStructSequence_New(&StructRUsageType);
|
||||
if (!result)
|
||||
r = PyStructSequence_New(&StructRUsageType);
|
||||
if (!r)
|
||||
return NULL;
|
||||
|
||||
PyStructSequence_SET_ITEM(result, 0,
|
||||
PyFloat_FromDouble(doubletime(ru.ru_utime)));
|
||||
PyStructSequence_SET_ITEM(result, 1,
|
||||
PyFloat_FromDouble(doubletime(ru.ru_stime)));
|
||||
PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(ru.ru_maxrss));
|
||||
PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(ru.ru_ixrss));
|
||||
PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(ru.ru_idrss));
|
||||
PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(ru.ru_isrss));
|
||||
PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(ru.ru_minflt));
|
||||
PyStructSequence_SET_ITEM(result, 7, PyLong_FromLong(ru.ru_majflt));
|
||||
PyStructSequence_SET_ITEM(result, 8, PyLong_FromLong(ru.ru_nswap));
|
||||
PyStructSequence_SET_ITEM(result, 9, PyLong_FromLong(ru.ru_inblock));
|
||||
PyStructSequence_SET_ITEM(result, 10, PyLong_FromLong(ru.ru_oublock));
|
||||
PyStructSequence_SET_ITEM(result, 11, PyLong_FromLong(ru.ru_msgsnd));
|
||||
PyStructSequence_SET_ITEM(result, 12, PyLong_FromLong(ru.ru_msgrcv));
|
||||
PyStructSequence_SET_ITEM(result, 13, PyLong_FromLong(ru.ru_nsignals));
|
||||
PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(ru.ru_nvcsw));
|
||||
PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(ru.ru_nivcsw));
|
||||
|
||||
PyStructSequence_SET_ITEM(r, 0, PyFloat_FromDouble(doubletime(ru.ru_utime)));
|
||||
PyStructSequence_SET_ITEM(r, 1, PyFloat_FromDouble(doubletime(ru.ru_stime)));
|
||||
PyStructSequence_SET_ITEM(r, 2, PyLong_FromLong(ru.ru_maxrss));
|
||||
PyStructSequence_SET_ITEM(r, 3, PyLong_FromLong(ru.ru_ixrss));
|
||||
PyStructSequence_SET_ITEM(r, 4, PyLong_FromLong(ru.ru_idrss));
|
||||
PyStructSequence_SET_ITEM(r, 5, PyLong_FromLong(ru.ru_isrss));
|
||||
PyStructSequence_SET_ITEM(r, 6, PyLong_FromLong(ru.ru_minflt));
|
||||
PyStructSequence_SET_ITEM(r, 7, PyLong_FromLong(ru.ru_majflt));
|
||||
PyStructSequence_SET_ITEM(r, 8, PyLong_FromLong(ru.ru_nswap));
|
||||
PyStructSequence_SET_ITEM(r, 9, PyLong_FromLong(ru.ru_inblock));
|
||||
PyStructSequence_SET_ITEM(r, 10, PyLong_FromLong(ru.ru_oublock));
|
||||
PyStructSequence_SET_ITEM(r, 11, PyLong_FromLong(ru.ru_msgsnd));
|
||||
PyStructSequence_SET_ITEM(r, 12, PyLong_FromLong(ru.ru_msgrcv));
|
||||
PyStructSequence_SET_ITEM(r, 13, PyLong_FromLong(ru.ru_nsignals));
|
||||
PyStructSequence_SET_ITEM(r, 14, PyLong_FromLong(ru.ru_nvcsw));
|
||||
PyStructSequence_SET_ITEM(r, 15, PyLong_FromLong(ru.ru_nivcsw));
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(result);
|
||||
Py_DECREF(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -158,7 +150,6 @@ py2rlimit(PyObject *limits, struct rlimit *rl_out)
|
|||
if (!limits)
|
||||
/* Here limits is a borrowed reference */
|
||||
return -1;
|
||||
|
||||
if (PyTuple_GET_SIZE(limits) != 2) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"expected a tuple of 2 integers");
|
||||
|
@ -182,12 +173,10 @@ py2rlimit(PyObject *limits, struct rlimit *rl_out)
|
|||
if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred())
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
Py_DECREF(limits);
|
||||
rl_out->rlim_cur = rl_out->rlim_cur & RLIM_INFINITY;
|
||||
rl_out->rlim_max = rl_out->rlim_max & RLIM_INFINITY;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
Py_DECREF(limits);
|
||||
return -1;
|
||||
|
@ -209,16 +198,13 @@ resource_getrlimit(PyObject *self, PyObject *args)
|
|||
{
|
||||
struct rlimit rl;
|
||||
int resource;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i:getrlimit", &resource))
|
||||
return NULL;
|
||||
|
||||
if (resource < 0 || resource >= RLIM_NLIMITS) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"invalid resource specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (getrlimit(resource, &rl) == -1) {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return NULL;
|
||||
|
@ -232,20 +218,16 @@ resource_setrlimit(PyObject *self, PyObject *args)
|
|||
struct rlimit rl;
|
||||
int resource;
|
||||
PyObject *limits;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iO:setrlimit", &resource, &limits))
|
||||
return NULL;
|
||||
|
||||
if (resource < 0 || resource >= RLIM_NLIMITS) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"invalid resource specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (py2rlimit(limits, &rl) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (setrlimit(resource, &rl) == -1) {
|
||||
if (errno == EINVAL)
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
|
@ -268,17 +250,14 @@ resource_prlimit(PyObject *self, PyObject *args)
|
|||
int resource, retval;
|
||||
pid_t pid;
|
||||
PyObject *limits = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i|O:prlimit",
|
||||
&pid, &resource, &limits))
|
||||
return NULL;
|
||||
|
||||
if (resource < 0 || resource >= RLIM_NLIMITS) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"invalid resource specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (limits != NULL) {
|
||||
if (py2rlimit(limits, &new_limit) < 0) {
|
||||
return NULL;
|
||||
|
@ -288,7 +267,6 @@ resource_prlimit(PyObject *self, PyObject *args)
|
|||
else {
|
||||
retval = prlimit(pid, resource, NULL, &old_limit);
|
||||
}
|
||||
|
||||
if (retval == -1) {
|
||||
if (errno == EINVAL) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
|
@ -317,11 +295,8 @@ resource_getpagesize(PyObject *self, PyObject *unused)
|
|||
#endif
|
||||
#endif
|
||||
return Py_BuildValue("i", pagesize);
|
||||
|
||||
}
|
||||
|
||||
/* List of functions */
|
||||
|
||||
static struct PyMethodDef
|
||||
resource_methods[] = {
|
||||
{"getrusage", resource_getrusage, METH_VARARGS},
|
||||
|
@ -334,10 +309,6 @@ resource_methods[] = {
|
|||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
/* Module initialization */
|
||||
|
||||
|
||||
static struct PyModuleDef resourcemodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"resource",
|
||||
|
|
2
third_party/python/Modules/selectmodule.c
vendored
2
third_party/python/Modules/selectmodule.c
vendored
|
@ -1187,9 +1187,7 @@ static int select_have_broken_poll(void)
|
|||
{
|
||||
int poll_test;
|
||||
int filedes[2];
|
||||
|
||||
struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
|
||||
|
||||
/* Create a file descriptor to make invalid */
|
||||
if (pipe(filedes) < 0) {
|
||||
return 1;
|
||||
|
|
587
third_party/python/Modules/sha1module.c
vendored
587
third_party/python/Modules/sha1module.c
vendored
|
@ -1,587 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/bytesobject.h"
|
||||
#include "third_party/python/Include/descrobject.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/longobject.h"
|
||||
#include "third_party/python/Include/modsupport.h"
|
||||
#include "third_party/python/Include/objimpl.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
#include "third_party/python/Include/pystrhex.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/Modules/hashlib.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("_sha1");
|
||||
PYTHON_PROVIDE("_sha1.SHA1Type");
|
||||
PYTHON_PROVIDE("_sha1.sha1");
|
||||
|
||||
/* SHA1 module */
|
||||
|
||||
/* This module provides an interface to the SHA1 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)
|
||||
|
||||
Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org)
|
||||
Licensed to PSF under a Contributor Agreement.
|
||||
|
||||
*/
|
||||
|
||||
/* SHA1 objects */
|
||||
|
||||
/*[clinic input]
|
||||
module _sha1
|
||||
class SHA1Type "SHA1object *" "&PyType_Type"
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3dc9a20d1becb759]*/
|
||||
|
||||
/* Some useful types */
|
||||
|
||||
#if SIZEOF_INT == 4
|
||||
typedef unsigned int SHA1_INT32; /* 32-bit integer */
|
||||
typedef long long SHA1_INT64; /* 64-bit integer */
|
||||
#else
|
||||
/* not defined. compilation will die. */
|
||||
#endif
|
||||
|
||||
/* The SHA1 block size and message digest sizes, in bytes */
|
||||
|
||||
#define SHA1_BLOCKSIZE 64
|
||||
#define SHA1_DIGESTSIZE 20
|
||||
|
||||
/* The structure for storing SHA1 info */
|
||||
|
||||
struct sha1_state {
|
||||
SHA1_INT64 length;
|
||||
SHA1_INT32 state[5], curlen;
|
||||
unsigned char buf[SHA1_BLOCKSIZE];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
struct sha1_state hash_state;
|
||||
} SHA1object;
|
||||
|
||||
#include "third_party/python/Modules/clinic/sha1module.inc"
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
*
|
||||
* This code for the SHA1 algorithm was noted as public domain. The
|
||||
* original headers are pasted below.
|
||||
*
|
||||
* Several changes have been made to make it more compatible with the
|
||||
* Python environment and desired interface.
|
||||
*
|
||||
*/
|
||||
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
|
||||
/* rotate the hard way (platform optimizations could be done) */
|
||||
#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
|
||||
/* Endian Neutral macros that work on all platforms */
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
{ x = ((unsigned long)((y)[0] & 255)<<24) | \
|
||||
((unsigned long)((y)[1] & 255)<<16) | \
|
||||
((unsigned long)((y)[2] & 255)<<8) | \
|
||||
((unsigned long)((y)[3] & 255)); }
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
|
||||
|
||||
|
||||
/* SHA1 macros */
|
||||
|
||||
#define F0(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define F1(x,y,z) (x ^ y ^ z)
|
||||
#define F2(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F3(x,y,z) (x ^ y ^ z)
|
||||
|
||||
static void sha1_compress(struct sha1_state *sha1, unsigned char *buf)
|
||||
{
|
||||
SHA1_INT32 a,b,c,d,e,W[80],i;
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32H(W[i], buf + (4*i));
|
||||
}
|
||||
|
||||
/* copy state */
|
||||
a = sha1->state[0];
|
||||
b = sha1->state[1];
|
||||
c = sha1->state[2];
|
||||
d = sha1->state[3];
|
||||
e = sha1->state[4];
|
||||
|
||||
/* expand it */
|
||||
for (i = 16; i < 80; i++) {
|
||||
W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
|
||||
}
|
||||
|
||||
/* compress */
|
||||
/* round one */
|
||||
#define FF_0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
|
||||
#define FF_1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
|
||||
#define FF_2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
|
||||
#define FF_3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
|
||||
|
||||
for (i = 0; i < 20; ) {
|
||||
FF_0(a,b,c,d,e,i++);
|
||||
FF_0(e,a,b,c,d,i++);
|
||||
FF_0(d,e,a,b,c,i++);
|
||||
FF_0(c,d,e,a,b,i++);
|
||||
FF_0(b,c,d,e,a,i++);
|
||||
}
|
||||
|
||||
/* round two */
|
||||
for (; i < 40; ) {
|
||||
FF_1(a,b,c,d,e,i++);
|
||||
FF_1(e,a,b,c,d,i++);
|
||||
FF_1(d,e,a,b,c,i++);
|
||||
FF_1(c,d,e,a,b,i++);
|
||||
FF_1(b,c,d,e,a,i++);
|
||||
}
|
||||
|
||||
/* round three */
|
||||
for (; i < 60; ) {
|
||||
FF_2(a,b,c,d,e,i++);
|
||||
FF_2(e,a,b,c,d,i++);
|
||||
FF_2(d,e,a,b,c,i++);
|
||||
FF_2(c,d,e,a,b,i++);
|
||||
FF_2(b,c,d,e,a,i++);
|
||||
}
|
||||
|
||||
/* round four */
|
||||
for (; i < 80; ) {
|
||||
FF_3(a,b,c,d,e,i++);
|
||||
FF_3(e,a,b,c,d,i++);
|
||||
FF_3(d,e,a,b,c,i++);
|
||||
FF_3(c,d,e,a,b,i++);
|
||||
FF_3(b,c,d,e,a,i++);
|
||||
}
|
||||
|
||||
#undef FF_0
|
||||
#undef FF_1
|
||||
#undef FF_2
|
||||
#undef FF_3
|
||||
|
||||
/* store */
|
||||
sha1->state[0] = sha1->state[0] + a;
|
||||
sha1->state[1] = sha1->state[1] + b;
|
||||
sha1->state[2] = sha1->state[2] + c;
|
||||
sha1->state[3] = sha1->state[3] + d;
|
||||
sha1->state[4] = sha1->state[4] + e;
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize the hash state
|
||||
@param sha1 The hash state you wish to initialize
|
||||
*/
|
||||
static void
|
||||
sha1_init(struct sha1_state *sha1)
|
||||
{
|
||||
assert(sha1 != NULL);
|
||||
sha1->state[0] = 0x67452301UL;
|
||||
sha1->state[1] = 0xefcdab89UL;
|
||||
sha1->state[2] = 0x98badcfeUL;
|
||||
sha1->state[3] = 0x10325476UL;
|
||||
sha1->state[4] = 0xc3d2e1f0UL;
|
||||
sha1->curlen = 0;
|
||||
sha1->length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Process a block of memory though the hash
|
||||
@param sha1 The hash state
|
||||
@param in The data to hash
|
||||
@param inlen The length of the data (octets)
|
||||
*/
|
||||
static void
|
||||
sha1_process(struct sha1_state *sha1,
|
||||
const unsigned char *in, Py_ssize_t inlen)
|
||||
{
|
||||
Py_ssize_t n;
|
||||
|
||||
assert(sha1 != NULL);
|
||||
assert(in != NULL);
|
||||
assert(sha1->curlen <= sizeof(sha1->buf));
|
||||
|
||||
while (inlen > 0) {
|
||||
if (sha1->curlen == 0 && inlen >= SHA1_BLOCKSIZE) {
|
||||
sha1_compress(sha1, (unsigned char *)in);
|
||||
sha1->length += SHA1_BLOCKSIZE * 8;
|
||||
in += SHA1_BLOCKSIZE;
|
||||
inlen -= SHA1_BLOCKSIZE;
|
||||
} else {
|
||||
n = Py_MIN(inlen, (Py_ssize_t)(SHA1_BLOCKSIZE - sha1->curlen));
|
||||
memcpy(sha1->buf + sha1->curlen, in, (size_t)n);
|
||||
sha1->curlen += (SHA1_INT32)n;
|
||||
in += n;
|
||||
inlen -= n;
|
||||
if (sha1->curlen == SHA1_BLOCKSIZE) {
|
||||
sha1_compress(sha1, sha1->buf);
|
||||
sha1->length += 8*SHA1_BLOCKSIZE;
|
||||
sha1->curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
@param sha1 The hash state
|
||||
@param out [out] The destination of the hash (20 bytes)
|
||||
*/
|
||||
static void
|
||||
sha1_done(struct sha1_state *sha1, unsigned char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(sha1 != NULL);
|
||||
assert(out != NULL);
|
||||
assert(sha1->curlen < sizeof(sha1->buf));
|
||||
|
||||
/* increase the length of the message */
|
||||
sha1->length += sha1->curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
sha1->buf[sha1->curlen++] = (unsigned char)0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (sha1->curlen > 56) {
|
||||
while (sha1->curlen < 64) {
|
||||
sha1->buf[sha1->curlen++] = (unsigned char)0;
|
||||
}
|
||||
sha1_compress(sha1, sha1->buf);
|
||||
sha1->curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (sha1->curlen < 56) {
|
||||
sha1->buf[sha1->curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64H(sha1->length, sha1->buf+56);
|
||||
sha1_compress(sha1, sha1->buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 5; i++) {
|
||||
STORE32H(sha1->state[i], out+(4*i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* .Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */
|
||||
/* .Revision: 1.10 $ */
|
||||
/* .Date: 2007/05/12 14:25:28 $ */
|
||||
|
||||
/*
|
||||
* End of copied SHA1 code.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static PyTypeObject SHA1type;
|
||||
|
||||
|
||||
static SHA1object *
|
||||
newSHA1object(void)
|
||||
{
|
||||
return (SHA1object *)PyObject_New(SHA1object, &SHA1type);
|
||||
}
|
||||
|
||||
|
||||
/* Internal methods for a hash object */
|
||||
|
||||
static void
|
||||
SHA1_dealloc(PyObject *ptr)
|
||||
{
|
||||
PyObject_Del(ptr);
|
||||
}
|
||||
|
||||
|
||||
/* External methods for a hash object */
|
||||
|
||||
/*[clinic input]
|
||||
SHA1Type.copy
|
||||
|
||||
Return a copy of the hash object.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_copy_impl(SHA1object *self)
|
||||
/*[clinic end generated code: output=b4e001264620f02a input=b7eae10df6f89b36]*/
|
||||
{
|
||||
SHA1object *newobj;
|
||||
|
||||
if ((newobj = newSHA1object()) == NULL)
|
||||
return NULL;
|
||||
|
||||
newobj->hash_state = self->hash_state;
|
||||
return (PyObject *)newobj;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
SHA1Type.digest
|
||||
|
||||
Return the digest value as a bytes object.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_digest_impl(SHA1object *self)
|
||||
/*[clinic end generated code: output=2f05302a7aa2b5cb input=13824b35407444bd]*/
|
||||
{
|
||||
unsigned char digest[SHA1_DIGESTSIZE];
|
||||
struct sha1_state temp;
|
||||
|
||||
temp = self->hash_state;
|
||||
sha1_done(&temp, digest);
|
||||
return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
SHA1Type.hexdigest
|
||||
|
||||
Return the digest value as a string of hexadecimal digits.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_hexdigest_impl(SHA1object *self)
|
||||
/*[clinic end generated code: output=4161fd71e68c6659 input=97691055c0c74ab0]*/
|
||||
{
|
||||
unsigned char digest[SHA1_DIGESTSIZE];
|
||||
struct sha1_state temp;
|
||||
|
||||
/* Get the raw (binary) digest value */
|
||||
temp = self->hash_state;
|
||||
sha1_done(&temp, digest);
|
||||
|
||||
return _Py_strhex((const char *)digest, SHA1_DIGESTSIZE);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
SHA1Type.update
|
||||
|
||||
obj: object
|
||||
/
|
||||
|
||||
Update this hash object's state with the provided string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA1Type_update(SHA1object *self, PyObject *obj)
|
||||
/*[clinic end generated code: output=d9902f0e5015e9ae input=aad8e07812edbba3]*/
|
||||
{
|
||||
Py_buffer buf;
|
||||
|
||||
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
|
||||
|
||||
sha1_process(&self->hash_state, buf.buf, buf.len);
|
||||
|
||||
PyBuffer_Release(&buf);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyMethodDef SHA1_methods[] = {
|
||||
SHA1TYPE_COPY_METHODDEF
|
||||
SHA1TYPE_DIGEST_METHODDEF
|
||||
SHA1TYPE_HEXDIGEST_METHODDEF
|
||||
SHA1TYPE_UPDATE_METHODDEF
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
SHA1_get_block_size(PyObject *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(SHA1_BLOCKSIZE);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
SHA1_get_name(PyObject *self, void *closure)
|
||||
{
|
||||
return PyUnicode_FromStringAndSize("sha1", 4);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sha1_get_digest_size(PyObject *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(SHA1_DIGESTSIZE);
|
||||
}
|
||||
|
||||
|
||||
static PyGetSetDef SHA1_getseters[] = {
|
||||
{"block_size",
|
||||
(getter)SHA1_get_block_size, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{"name",
|
||||
(getter)SHA1_get_name, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{"digest_size",
|
||||
(getter)sha1_get_digest_size, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject SHA1type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"_sha1.sha1", /*tp_name*/
|
||||
sizeof(SHA1object), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
SHA1_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*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
SHA1_methods, /* tp_methods */
|
||||
NULL, /* tp_members */
|
||||
SHA1_getseters, /* tp_getset */
|
||||
};
|
||||
|
||||
|
||||
/* The single module-level function: new() */
|
||||
|
||||
/*[clinic input]
|
||||
_sha1.sha1
|
||||
|
||||
string: object(c_default="NULL") = b''
|
||||
|
||||
Return a new SHA1 hash object; optionally initialized with a string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_sha1_sha1_impl(PyObject *module, PyObject *string)
|
||||
/*[clinic end generated code: output=e5982830d1dece51 input=27ea54281d995ec2]*/
|
||||
{
|
||||
SHA1object *new;
|
||||
Py_buffer buf;
|
||||
|
||||
if (string)
|
||||
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
|
||||
|
||||
if ((new = newSHA1object()) == NULL) {
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sha1_init(&new->hash_state);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(new);
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
if (string) {
|
||||
sha1_process(&new->hash_state, buf.buf, buf.len);
|
||||
PyBuffer_Release(&buf);
|
||||
}
|
||||
|
||||
return (PyObject *)new;
|
||||
}
|
||||
|
||||
|
||||
/* List of functions exported by this module */
|
||||
|
||||
static struct PyMethodDef SHA1_functions[] = {
|
||||
_SHA1_SHA1_METHODDEF
|
||||
{NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
/* Initialize this module. */
|
||||
|
||||
#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
|
||||
|
||||
|
||||
static struct PyModuleDef _sha1module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_sha1",
|
||||
NULL,
|
||||
-1,
|
||||
SHA1_functions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit__sha1(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
Py_TYPE(&SHA1type) = &PyType_Type;
|
||||
if (PyType_Ready(&SHA1type) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&_sha1module);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF((PyObject *)&SHA1type);
|
||||
PyModule_AddObject(m, "SHA1Type", (PyObject *)&SHA1type);
|
||||
return m;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__sha1 = {
|
||||
"_sha1",
|
||||
PyInit__sha1,
|
||||
};
|
752
third_party/python/Modules/sha256module.c
vendored
752
third_party/python/Modules/sha256module.c
vendored
|
@ -1,752 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/bytesobject.h"
|
||||
#include "third_party/python/Include/descrobject.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/longobject.h"
|
||||
#include "third_party/python/Include/modsupport.h"
|
||||
#include "third_party/python/Include/objimpl.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
#include "third_party/python/Include/pystrhex.h"
|
||||
#include "third_party/python/Include/structmember.h"
|
||||
#include "third_party/python/Include/unicodeobject.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/Modules/hashlib.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("_sha256");
|
||||
PYTHON_PROVIDE("_sha256.SHA224Type");
|
||||
PYTHON_PROVIDE("_sha256.SHA256Type");
|
||||
PYTHON_PROVIDE("_sha256.sha224");
|
||||
PYTHON_PROVIDE("_sha256.sha256");
|
||||
|
||||
/* This module provides an interface to NIST's SHA-256 and SHA-224 Algorithms */
|
||||
|
||||
/* 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)
|
||||
|
||||
Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org)
|
||||
Licensed to PSF under a Contributor Agreement.
|
||||
|
||||
*/
|
||||
|
||||
/*[clinic input]
|
||||
module _sha256
|
||||
class SHA256Type "SHAobject *" "&PyType_Type"
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=71a39174d4f0a744]*/
|
||||
|
||||
/* Some useful types */
|
||||
|
||||
typedef unsigned char SHA_BYTE;
|
||||
|
||||
#if SIZEOF_INT == 4
|
||||
typedef unsigned int SHA_INT32; /* 32-bit integer */
|
||||
#else
|
||||
/* not defined. compilation will die. */
|
||||
#endif
|
||||
|
||||
/* The SHA block size and message digest sizes, in bytes */
|
||||
|
||||
#define SHA_BLOCKSIZE 64
|
||||
#define SHA_DIGESTSIZE 32
|
||||
|
||||
/* The structure for storing SHA info */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
SHA_INT32 digest[8]; /* Message digest */
|
||||
SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
|
||||
SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
|
||||
int local; /* unprocessed amount in data */
|
||||
int digestsize;
|
||||
} SHAobject;
|
||||
|
||||
#include "third_party/python/Modules/clinic/sha256module.inc"
|
||||
|
||||
/* When run on a little-endian CPU we need to perform byte reversal on an
|
||||
array of longwords. */
|
||||
|
||||
#if PY_LITTLE_ENDIAN
|
||||
static void longReverse(SHA_INT32 *buffer, int byteCount)
|
||||
{
|
||||
SHA_INT32 value;
|
||||
|
||||
byteCount /= sizeof(*buffer);
|
||||
while (byteCount--) {
|
||||
value = *buffer;
|
||||
value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
|
||||
( ( value & 0x00FF00FFL ) << 8 );
|
||||
*buffer++ = ( value << 16 ) | ( value >> 16 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SHAcopy(SHAobject *src, SHAobject *dest)
|
||||
{
|
||||
dest->local = src->local;
|
||||
dest->digestsize = src->digestsize;
|
||||
dest->count_lo = src->count_lo;
|
||||
dest->count_hi = src->count_hi;
|
||||
memcpy(dest->digest, src->digest, sizeof(src->digest));
|
||||
memcpy(dest->data, src->data, sizeof(src->data));
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
*
|
||||
* This code for the SHA-256 algorithm was noted as public domain. The
|
||||
* original headers are pasted below.
|
||||
*
|
||||
* Several changes have been made to make it more compatible with the
|
||||
* Python environment and desired interface.
|
||||
*
|
||||
*/
|
||||
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@iahu.ca, http://libtom.org
|
||||
*/
|
||||
|
||||
|
||||
/* SHA256 by Tom St Denis */
|
||||
|
||||
/* Various logical functions */
|
||||
#define ROR(x, y)\
|
||||
( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \
|
||||
((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define Maj(x,y,z) (((x | y) & z) | (x & y))
|
||||
#define S(x, n) ROR((x),(n))
|
||||
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
|
||||
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
|
||||
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
|
||||
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
|
||||
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
|
||||
|
||||
|
||||
static void
|
||||
sha_transform(SHAobject *sha_info)
|
||||
{
|
||||
int i;
|
||||
SHA_INT32 S[8], W[64], t0, t1;
|
||||
|
||||
memcpy(W, sha_info->data, sizeof(sha_info->data));
|
||||
#if PY_LITTLE_ENDIAN
|
||||
longReverse(W, (int)sizeof(sha_info->data));
|
||||
#endif
|
||||
|
||||
for (i = 16; i < 64; ++i) {
|
||||
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
for (i = 0; i < 8; ++i) {
|
||||
S[i] = sha_info->digest[i];
|
||||
}
|
||||
|
||||
/* Compress */
|
||||
#define RND(a,b,c,d,e,f,g,h,i,ki) \
|
||||
t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
|
||||
t1 = Sigma0(a) + Maj(a, b, c); \
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
|
||||
|
||||
#undef RND
|
||||
|
||||
/* feedback */
|
||||
for (i = 0; i < 8; i++) {
|
||||
sha_info->digest[i] = sha_info->digest[i] + S[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* initialize the SHA digest */
|
||||
|
||||
static void
|
||||
sha_init(SHAobject *sha_info)
|
||||
{
|
||||
sha_info->digest[0] = 0x6A09E667L;
|
||||
sha_info->digest[1] = 0xBB67AE85L;
|
||||
sha_info->digest[2] = 0x3C6EF372L;
|
||||
sha_info->digest[3] = 0xA54FF53AL;
|
||||
sha_info->digest[4] = 0x510E527FL;
|
||||
sha_info->digest[5] = 0x9B05688CL;
|
||||
sha_info->digest[6] = 0x1F83D9ABL;
|
||||
sha_info->digest[7] = 0x5BE0CD19L;
|
||||
sha_info->count_lo = 0L;
|
||||
sha_info->count_hi = 0L;
|
||||
sha_info->local = 0;
|
||||
sha_info->digestsize = 32;
|
||||
}
|
||||
|
||||
static void
|
||||
sha224_init(SHAobject *sha_info)
|
||||
{
|
||||
sha_info->digest[0] = 0xc1059ed8L;
|
||||
sha_info->digest[1] = 0x367cd507L;
|
||||
sha_info->digest[2] = 0x3070dd17L;
|
||||
sha_info->digest[3] = 0xf70e5939L;
|
||||
sha_info->digest[4] = 0xffc00b31L;
|
||||
sha_info->digest[5] = 0x68581511L;
|
||||
sha_info->digest[6] = 0x64f98fa7L;
|
||||
sha_info->digest[7] = 0xbefa4fa4L;
|
||||
sha_info->count_lo = 0L;
|
||||
sha_info->count_hi = 0L;
|
||||
sha_info->local = 0;
|
||||
sha_info->digestsize = 28;
|
||||
}
|
||||
|
||||
|
||||
/* update the SHA digest */
|
||||
|
||||
static void
|
||||
sha_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
SHA_INT32 clo;
|
||||
|
||||
clo = sha_info->count_lo + ((SHA_INT32) count << 3);
|
||||
if (clo < sha_info->count_lo) {
|
||||
++sha_info->count_hi;
|
||||
}
|
||||
sha_info->count_lo = clo;
|
||||
sha_info->count_hi += (SHA_INT32) count >> 29;
|
||||
if (sha_info->local) {
|
||||
i = SHA_BLOCKSIZE - sha_info->local;
|
||||
if (i > count) {
|
||||
i = count;
|
||||
}
|
||||
memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
|
||||
count -= i;
|
||||
buffer += i;
|
||||
sha_info->local += (int)i;
|
||||
if (sha_info->local == SHA_BLOCKSIZE) {
|
||||
sha_transform(sha_info);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (count >= SHA_BLOCKSIZE) {
|
||||
memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
|
||||
buffer += SHA_BLOCKSIZE;
|
||||
count -= SHA_BLOCKSIZE;
|
||||
sha_transform(sha_info);
|
||||
}
|
||||
memcpy(sha_info->data, buffer, count);
|
||||
sha_info->local = (int)count;
|
||||
}
|
||||
|
||||
/* finish computing the SHA digest */
|
||||
|
||||
static void
|
||||
sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
|
||||
{
|
||||
int count;
|
||||
SHA_INT32 lo_bit_count, hi_bit_count;
|
||||
|
||||
lo_bit_count = sha_info->count_lo;
|
||||
hi_bit_count = sha_info->count_hi;
|
||||
count = (int) ((lo_bit_count >> 3) & 0x3f);
|
||||
((SHA_BYTE *) sha_info->data)[count++] = 0x80;
|
||||
if (count > SHA_BLOCKSIZE - 8) {
|
||||
bzero(((SHA_BYTE *) sha_info->data) + count, SHA_BLOCKSIZE - count);
|
||||
sha_transform(sha_info);
|
||||
bzero((SHA_BYTE *) sha_info->data, SHA_BLOCKSIZE - 8);
|
||||
}
|
||||
else {
|
||||
bzero(((SHA_BYTE *)sha_info->data) + count, SHA_BLOCKSIZE - 8 - count);
|
||||
}
|
||||
|
||||
/* GJS: note that we add the hi/lo in big-endian. sha_transform will
|
||||
swap these values into host-order. */
|
||||
sha_info->data[56] = (hi_bit_count >> 24) & 0xff;
|
||||
sha_info->data[57] = (hi_bit_count >> 16) & 0xff;
|
||||
sha_info->data[58] = (hi_bit_count >> 8) & 0xff;
|
||||
sha_info->data[59] = (hi_bit_count >> 0) & 0xff;
|
||||
sha_info->data[60] = (lo_bit_count >> 24) & 0xff;
|
||||
sha_info->data[61] = (lo_bit_count >> 16) & 0xff;
|
||||
sha_info->data[62] = (lo_bit_count >> 8) & 0xff;
|
||||
sha_info->data[63] = (lo_bit_count >> 0) & 0xff;
|
||||
sha_transform(sha_info);
|
||||
digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
|
||||
digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
|
||||
digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
|
||||
digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
|
||||
digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
|
||||
digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
|
||||
digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
|
||||
digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
|
||||
digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
|
||||
digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
|
||||
digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
|
||||
digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
|
||||
digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
|
||||
digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
|
||||
digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
|
||||
digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
|
||||
digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
|
||||
digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
|
||||
digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
|
||||
digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
|
||||
digest[20] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff);
|
||||
digest[21] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff);
|
||||
digest[22] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff);
|
||||
digest[23] = (unsigned char) ((sha_info->digest[5] ) & 0xff);
|
||||
digest[24] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff);
|
||||
digest[25] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff);
|
||||
digest[26] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff);
|
||||
digest[27] = (unsigned char) ((sha_info->digest[6] ) & 0xff);
|
||||
digest[28] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff);
|
||||
digest[29] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff);
|
||||
digest[30] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff);
|
||||
digest[31] = (unsigned char) ((sha_info->digest[7] ) & 0xff);
|
||||
}
|
||||
|
||||
/*
|
||||
* End of copied SHA code.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static PyTypeObject SHA224type;
|
||||
static PyTypeObject SHA256type;
|
||||
|
||||
|
||||
static SHAobject *
|
||||
newSHA224object(void)
|
||||
{
|
||||
return (SHAobject *)PyObject_New(SHAobject, &SHA224type);
|
||||
}
|
||||
|
||||
static SHAobject *
|
||||
newSHA256object(void)
|
||||
{
|
||||
return (SHAobject *)PyObject_New(SHAobject, &SHA256type);
|
||||
}
|
||||
|
||||
/* Internal methods for a hash object */
|
||||
|
||||
static void
|
||||
SHA_dealloc(PyObject *ptr)
|
||||
{
|
||||
PyObject_Del(ptr);
|
||||
}
|
||||
|
||||
|
||||
/* External methods for a hash object */
|
||||
|
||||
/*[clinic input]
|
||||
SHA256Type.copy
|
||||
|
||||
Return a copy of the hash object.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_copy_impl(SHAobject *self)
|
||||
/*[clinic end generated code: output=1a8bbd66a0c9c168 input=f58840a618d4f2a7]*/
|
||||
{
|
||||
SHAobject *newobj;
|
||||
|
||||
if (Py_TYPE(self) == &SHA256type) {
|
||||
if ( (newobj = newSHA256object())==NULL)
|
||||
return NULL;
|
||||
} else {
|
||||
if ( (newobj = newSHA224object())==NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SHAcopy(self, newobj);
|
||||
return (PyObject *)newobj;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
SHA256Type.digest
|
||||
|
||||
Return the digest value as a bytes object.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_digest_impl(SHAobject *self)
|
||||
/*[clinic end generated code: output=46616a5e909fbc3d input=f1f4cfea5cbde35c]*/
|
||||
{
|
||||
unsigned char digest[SHA_DIGESTSIZE];
|
||||
SHAobject temp;
|
||||
|
||||
SHAcopy(self, &temp);
|
||||
sha_final(digest, &temp);
|
||||
return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
SHA256Type.hexdigest
|
||||
|
||||
Return the digest value as a string of hexadecimal digits.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_hexdigest_impl(SHAobject *self)
|
||||
/*[clinic end generated code: output=725f8a7041ae97f3 input=0cc4c714693010d1]*/
|
||||
{
|
||||
unsigned char digest[SHA_DIGESTSIZE];
|
||||
SHAobject temp;
|
||||
|
||||
/* Get the raw (binary) digest value */
|
||||
SHAcopy(self, &temp);
|
||||
sha_final(digest, &temp);
|
||||
|
||||
return _Py_strhex((const char *)digest, self->digestsize);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
SHA256Type.update
|
||||
|
||||
obj: object
|
||||
/
|
||||
|
||||
Update this hash object's state with the provided string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA256Type_update(SHAobject *self, PyObject *obj)
|
||||
/*[clinic end generated code: output=0967fb2860c66af7 input=b2d449d5b30f0f5a]*/
|
||||
{
|
||||
Py_buffer buf;
|
||||
|
||||
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
|
||||
|
||||
sha_update(self, buf.buf, buf.len);
|
||||
|
||||
PyBuffer_Release(&buf);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyMethodDef SHA_methods[] = {
|
||||
SHA256TYPE_COPY_METHODDEF
|
||||
SHA256TYPE_DIGEST_METHODDEF
|
||||
SHA256TYPE_HEXDIGEST_METHODDEF
|
||||
SHA256TYPE_UPDATE_METHODDEF
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
SHA256_get_block_size(PyObject *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(SHA_BLOCKSIZE);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
SHA256_get_name(PyObject *self, void *closure)
|
||||
{
|
||||
if (((SHAobject *)self)->digestsize == 32)
|
||||
return PyUnicode_FromStringAndSize("sha256", 6);
|
||||
else
|
||||
return PyUnicode_FromStringAndSize("sha224", 6);
|
||||
}
|
||||
|
||||
static PyGetSetDef SHA_getseters[] = {
|
||||
{"block_size",
|
||||
(getter)SHA256_get_block_size, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{"name",
|
||||
(getter)SHA256_get_name, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyMemberDef SHA_members[] = {
|
||||
{"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject SHA224type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"_sha256.sha224", /*tp_name*/
|
||||
sizeof(SHAobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
SHA_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*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
SHA_methods, /* tp_methods */
|
||||
SHA_members, /* tp_members */
|
||||
SHA_getseters, /* tp_getset */
|
||||
};
|
||||
|
||||
static PyTypeObject SHA256type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"_sha256.sha256", /*tp_name*/
|
||||
sizeof(SHAobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
SHA_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*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
SHA_methods, /* tp_methods */
|
||||
SHA_members, /* tp_members */
|
||||
SHA_getseters, /* tp_getset */
|
||||
};
|
||||
|
||||
|
||||
/* The single module-level function: new() */
|
||||
|
||||
/*[clinic input]
|
||||
_sha256.sha256
|
||||
|
||||
string: object(c_default="NULL") = b''
|
||||
|
||||
Return a new SHA-256 hash object; optionally initialized with a string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_sha256_sha256_impl(PyObject *module, PyObject *string)
|
||||
/*[clinic end generated code: output=fa644436dcea5c31 input=09cce3fb855056b2]*/
|
||||
{
|
||||
SHAobject *new;
|
||||
Py_buffer buf;
|
||||
|
||||
if (string)
|
||||
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
|
||||
|
||||
if ((new = newSHA256object()) == NULL) {
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sha_init(new);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(new);
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
if (string) {
|
||||
sha_update(new, buf.buf, buf.len);
|
||||
PyBuffer_Release(&buf);
|
||||
}
|
||||
|
||||
return (PyObject *)new;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
_sha256.sha224
|
||||
|
||||
string: object(c_default="NULL") = b''
|
||||
|
||||
Return a new SHA-224 hash object; optionally initialized with a string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_sha256_sha224_impl(PyObject *module, PyObject *string)
|
||||
/*[clinic end generated code: output=21e3ba22c3404f93 input=27a04ba24c353a73]*/
|
||||
{
|
||||
SHAobject *new;
|
||||
Py_buffer buf;
|
||||
|
||||
if (string)
|
||||
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
|
||||
|
||||
if ((new = newSHA224object()) == NULL) {
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sha224_init(new);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(new);
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
if (string) {
|
||||
sha_update(new, buf.buf, buf.len);
|
||||
PyBuffer_Release(&buf);
|
||||
}
|
||||
|
||||
return (PyObject *)new;
|
||||
}
|
||||
|
||||
|
||||
/* List of functions exported by this module */
|
||||
|
||||
static struct PyMethodDef SHA_functions[] = {
|
||||
_SHA256_SHA256_METHODDEF
|
||||
_SHA256_SHA224_METHODDEF
|
||||
{NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
/* Initialize this module. */
|
||||
|
||||
#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
|
||||
|
||||
|
||||
static struct PyModuleDef _sha256module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_sha256",
|
||||
NULL,
|
||||
-1,
|
||||
SHA_functions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit__sha256(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
Py_TYPE(&SHA224type) = &PyType_Type;
|
||||
if (PyType_Ready(&SHA224type) < 0)
|
||||
return NULL;
|
||||
Py_TYPE(&SHA256type) = &PyType_Type;
|
||||
if (PyType_Ready(&SHA256type) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&_sha256module);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF((PyObject *)&SHA224type);
|
||||
PyModule_AddObject(m, "SHA224Type", (PyObject *)&SHA224type);
|
||||
Py_INCREF((PyObject *)&SHA256type);
|
||||
PyModule_AddObject(m, "SHA256Type", (PyObject *)&SHA256type);
|
||||
return m;
|
||||
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__sha256 = {
|
||||
"_sha256",
|
||||
PyInit__sha256,
|
||||
};
|
826
third_party/python/Modules/sha512module.c
vendored
826
third_party/python/Modules/sha512module.c
vendored
|
@ -1,826 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/bytesobject.h"
|
||||
#include "third_party/python/Include/descrobject.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/longobject.h"
|
||||
#include "third_party/python/Include/modsupport.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Include/objimpl.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
#include "third_party/python/Include/pystrhex.h"
|
||||
#include "third_party/python/Include/structmember.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/Modules/hashlib.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("_sha512");
|
||||
PYTHON_PROVIDE("_sha512.SHA384Type");
|
||||
PYTHON_PROVIDE("_sha512.SHA512Type");
|
||||
PYTHON_PROVIDE("_sha512.sha384");
|
||||
PYTHON_PROVIDE("_sha512.sha512");
|
||||
|
||||
/* This module provides an interface to NIST's SHA-512 and SHA-384 Algorithms */
|
||||
|
||||
/* 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)
|
||||
|
||||
Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org)
|
||||
Licensed to PSF under a Contributor Agreement.
|
||||
|
||||
*/
|
||||
|
||||
/* SHA objects */
|
||||
|
||||
/*[clinic input]
|
||||
module _sha512
|
||||
class SHA512Type "SHAobject *" "&PyType_Type"
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81a3ccde92bcfe8d]*/
|
||||
|
||||
/* Some useful types */
|
||||
|
||||
typedef unsigned char SHA_BYTE;
|
||||
|
||||
#if SIZEOF_INT == 4
|
||||
typedef unsigned int SHA_INT32; /* 32-bit integer */
|
||||
typedef unsigned long long SHA_INT64; /* 64-bit integer */
|
||||
#else
|
||||
/* not defined. compilation will die. */
|
||||
#endif
|
||||
|
||||
/* The SHA block size and message digest sizes, in bytes */
|
||||
|
||||
#define SHA_BLOCKSIZE 128
|
||||
#define SHA_DIGESTSIZE 64
|
||||
|
||||
/* The structure for storing SHA info */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
SHA_INT64 digest[8]; /* Message digest */
|
||||
SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
|
||||
SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
|
||||
int local; /* unprocessed amount in data */
|
||||
int digestsize;
|
||||
} SHAobject;
|
||||
|
||||
#include "third_party/python/Modules/clinic/sha512module.inc"
|
||||
|
||||
/* When run on a little-endian CPU we need to perform byte reversal on an
|
||||
array of longwords. */
|
||||
|
||||
#if PY_LITTLE_ENDIAN
|
||||
static void longReverse(SHA_INT64 *buffer, int byteCount)
|
||||
{
|
||||
SHA_INT64 value;
|
||||
|
||||
byteCount /= sizeof(*buffer);
|
||||
while (byteCount--) {
|
||||
value = *buffer;
|
||||
|
||||
((unsigned char*)buffer)[0] = (unsigned char)(value >> 56) & 0xff;
|
||||
((unsigned char*)buffer)[1] = (unsigned char)(value >> 48) & 0xff;
|
||||
((unsigned char*)buffer)[2] = (unsigned char)(value >> 40) & 0xff;
|
||||
((unsigned char*)buffer)[3] = (unsigned char)(value >> 32) & 0xff;
|
||||
((unsigned char*)buffer)[4] = (unsigned char)(value >> 24) & 0xff;
|
||||
((unsigned char*)buffer)[5] = (unsigned char)(value >> 16) & 0xff;
|
||||
((unsigned char*)buffer)[6] = (unsigned char)(value >> 8) & 0xff;
|
||||
((unsigned char*)buffer)[7] = (unsigned char)(value ) & 0xff;
|
||||
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SHAcopy(SHAobject *src, SHAobject *dest)
|
||||
{
|
||||
dest->local = src->local;
|
||||
dest->digestsize = src->digestsize;
|
||||
dest->count_lo = src->count_lo;
|
||||
dest->count_hi = src->count_hi;
|
||||
memcpy(dest->digest, src->digest, sizeof(src->digest));
|
||||
memcpy(dest->data, src->data, sizeof(src->data));
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
*
|
||||
* This code for the SHA-512 algorithm was noted as public domain. The
|
||||
* original headers are pasted below.
|
||||
*
|
||||
* Several changes have been made to make it more compatible with the
|
||||
* Python environment and desired interface.
|
||||
*
|
||||
*/
|
||||
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@iahu.ca, http://libtom.org
|
||||
*/
|
||||
|
||||
|
||||
/* SHA512 by Tom St Denis */
|
||||
|
||||
/* Various logical functions */
|
||||
#define ROR64(x, y) \
|
||||
( ((((x) & 0xFFFFFFFFFFFFFFFFULL)>>((unsigned long long)(y) & 63)) | \
|
||||
((x)<<((unsigned long long)(64-((y) & 63))))) & 0xFFFFFFFFFFFFFFFFULL)
|
||||
#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) & 0xFFFFFFFFFFFFFFFFULL) >> ((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))
|
||||
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
|
||||
|
||||
|
||||
static void
|
||||
sha512_transform(SHAobject *sha_info)
|
||||
{
|
||||
int i;
|
||||
SHA_INT64 S[8], W[80], t0, t1;
|
||||
|
||||
memcpy(W, sha_info->data, sizeof(sha_info->data));
|
||||
#if PY_LITTLE_ENDIAN
|
||||
longReverse(W, (int)sizeof(sha_info->data));
|
||||
#endif
|
||||
|
||||
for (i = 16; i < 80; ++i) {
|
||||
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
for (i = 0; i < 8; ++i) {
|
||||
S[i] = sha_info->digest[i];
|
||||
}
|
||||
|
||||
/* Compress */
|
||||
#define RND(a,b,c,d,e,f,g,h,i,ki) \
|
||||
t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
|
||||
t1 = Sigma0(a) + Maj(a, b, c); \
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98d728ae22ULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x7137449123ef65cdULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcfec4d3b2fULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba58189dbbcULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25bf348b538ULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1b605d019ULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4af194f9bULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5da6d8118ULL);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98a3030242ULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b0145706fbeULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be4ee4b28cULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3d5ffb4e2ULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74f27b896fULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe3b1696b1ULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a725c71235ULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174cf692694ULL);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c19ef14ad2ULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786384f25e3ULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc68b8cd5b5ULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc77ac9c65ULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f592b0275ULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa6ea6e483ULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dcbd41fbd4ULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da831153b5ULL);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152ee66dfabULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d2db43210ULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c898fb213fULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7beef0ee4ULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf33da88fc2ULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147930aa725ULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351e003826fULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x142929670a0e6e70ULL);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a8546d22ffcULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b21385c26c926ULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc5ac42aedULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d139d95b3dfULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a73548baf63deULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb3c77b2a8ULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e47edaee6ULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c851482353bULL);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a14cf10364ULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664bbc423001ULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70d0f89791ULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a30654be30ULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819d6ef5218ULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd69906245565a910ULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e35855771202aULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa07032bbd1b8ULL);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116b8d2d0c8ULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c085141ab53ULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774cdf8eeb99ULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5e19b48a8ULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3c5c95a63ULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4ae3418acbULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f7763e373ULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3d6b2b8a3ULL);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee5defb2fcULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f43172f60ULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814a1f0ab72ULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc702081a6439ecULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa23631e28ULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506cebde82bde9ULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7b2c67915ULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2e372532bULL);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,0xca273eceea26619cULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,0xd186b8c721c0c207ULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,0xeada7dd6cde0eb1eULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,0xf57d4f7fee6ed178ULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,0x06f067aa72176fbaULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,0x0a637dc5a2c898a6ULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,0x113f9804bef90daeULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,0x1b710b35131c471bULL);
|
||||
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,0x28db77f523047d84ULL);
|
||||
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,0x32caab7b40c72493ULL);
|
||||
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,0x3c9ebe0a15c9bebcULL);
|
||||
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,0x431d67c49c100d4cULL);
|
||||
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,0x4cc5d4becb3e42b6ULL);
|
||||
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,0x597f299cfc657e2aULL);
|
||||
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,0x5fcb6fab3ad6faecULL);
|
||||
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,0x6c44198c4a475817ULL);
|
||||
|
||||
#undef RND
|
||||
|
||||
/* feedback */
|
||||
for (i = 0; i < 8; i++) {
|
||||
sha_info->digest[i] = sha_info->digest[i] + S[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* initialize the SHA digest */
|
||||
|
||||
static void
|
||||
sha512_init(SHAobject *sha_info)
|
||||
{
|
||||
sha_info->digest[0] = Py_ULL(0x6a09e667f3bcc908);
|
||||
sha_info->digest[1] = Py_ULL(0xbb67ae8584caa73b);
|
||||
sha_info->digest[2] = Py_ULL(0x3c6ef372fe94f82b);
|
||||
sha_info->digest[3] = Py_ULL(0xa54ff53a5f1d36f1);
|
||||
sha_info->digest[4] = Py_ULL(0x510e527fade682d1);
|
||||
sha_info->digest[5] = Py_ULL(0x9b05688c2b3e6c1f);
|
||||
sha_info->digest[6] = Py_ULL(0x1f83d9abfb41bd6b);
|
||||
sha_info->digest[7] = Py_ULL(0x5be0cd19137e2179);
|
||||
sha_info->count_lo = 0L;
|
||||
sha_info->count_hi = 0L;
|
||||
sha_info->local = 0;
|
||||
sha_info->digestsize = 64;
|
||||
}
|
||||
|
||||
static void
|
||||
sha384_init(SHAobject *sha_info)
|
||||
{
|
||||
sha_info->digest[0] = Py_ULL(0xcbbb9d5dc1059ed8);
|
||||
sha_info->digest[1] = Py_ULL(0x629a292a367cd507);
|
||||
sha_info->digest[2] = Py_ULL(0x9159015a3070dd17);
|
||||
sha_info->digest[3] = Py_ULL(0x152fecd8f70e5939);
|
||||
sha_info->digest[4] = Py_ULL(0x67332667ffc00b31);
|
||||
sha_info->digest[5] = Py_ULL(0x8eb44a8768581511);
|
||||
sha_info->digest[6] = Py_ULL(0xdb0c2e0d64f98fa7);
|
||||
sha_info->digest[7] = Py_ULL(0x47b5481dbefa4fa4);
|
||||
sha_info->count_lo = 0L;
|
||||
sha_info->count_hi = 0L;
|
||||
sha_info->local = 0;
|
||||
sha_info->digestsize = 48;
|
||||
}
|
||||
|
||||
|
||||
/* update the SHA digest */
|
||||
|
||||
static void
|
||||
sha512_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
SHA_INT32 clo;
|
||||
|
||||
clo = sha_info->count_lo + ((SHA_INT32) count << 3);
|
||||
if (clo < sha_info->count_lo) {
|
||||
++sha_info->count_hi;
|
||||
}
|
||||
sha_info->count_lo = clo;
|
||||
sha_info->count_hi += (SHA_INT32) count >> 29;
|
||||
if (sha_info->local) {
|
||||
i = SHA_BLOCKSIZE - sha_info->local;
|
||||
if (i > count) {
|
||||
i = count;
|
||||
}
|
||||
memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
|
||||
count -= i;
|
||||
buffer += i;
|
||||
sha_info->local += (int)i;
|
||||
if (sha_info->local == SHA_BLOCKSIZE) {
|
||||
sha512_transform(sha_info);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (count >= SHA_BLOCKSIZE) {
|
||||
memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
|
||||
buffer += SHA_BLOCKSIZE;
|
||||
count -= SHA_BLOCKSIZE;
|
||||
sha512_transform(sha_info);
|
||||
}
|
||||
memcpy(sha_info->data, buffer, count);
|
||||
sha_info->local = (int)count;
|
||||
}
|
||||
|
||||
/* finish computing the SHA digest */
|
||||
|
||||
static void
|
||||
sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
|
||||
{
|
||||
int count;
|
||||
SHA_INT32 lo_bit_count, hi_bit_count;
|
||||
|
||||
lo_bit_count = sha_info->count_lo;
|
||||
hi_bit_count = sha_info->count_hi;
|
||||
count = (int) ((lo_bit_count >> 3) & 0x7f);
|
||||
((SHA_BYTE *) sha_info->data)[count++] = 0x80;
|
||||
if (count > SHA_BLOCKSIZE - 16) {
|
||||
bzero(((SHA_BYTE *) sha_info->data) + count, SHA_BLOCKSIZE - count);
|
||||
sha512_transform(sha_info);
|
||||
bzero((SHA_BYTE *) sha_info->data, SHA_BLOCKSIZE - 16);
|
||||
}
|
||||
else {
|
||||
bzero(((SHA_BYTE *)sha_info->data) + count, SHA_BLOCKSIZE - 16 - count);
|
||||
}
|
||||
|
||||
/* GJS: note that we add the hi/lo in big-endian. sha512_transform will
|
||||
swap these values into host-order. */
|
||||
sha_info->data[112] = 0;
|
||||
sha_info->data[113] = 0;
|
||||
sha_info->data[114] = 0;
|
||||
sha_info->data[115] = 0;
|
||||
sha_info->data[116] = 0;
|
||||
sha_info->data[117] = 0;
|
||||
sha_info->data[118] = 0;
|
||||
sha_info->data[119] = 0;
|
||||
sha_info->data[120] = (hi_bit_count >> 24) & 0xff;
|
||||
sha_info->data[121] = (hi_bit_count >> 16) & 0xff;
|
||||
sha_info->data[122] = (hi_bit_count >> 8) & 0xff;
|
||||
sha_info->data[123] = (hi_bit_count >> 0) & 0xff;
|
||||
sha_info->data[124] = (lo_bit_count >> 24) & 0xff;
|
||||
sha_info->data[125] = (lo_bit_count >> 16) & 0xff;
|
||||
sha_info->data[126] = (lo_bit_count >> 8) & 0xff;
|
||||
sha_info->data[127] = (lo_bit_count >> 0) & 0xff;
|
||||
sha512_transform(sha_info);
|
||||
digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 56) & 0xff);
|
||||
digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 48) & 0xff);
|
||||
digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 40) & 0xff);
|
||||
digest[ 3] = (unsigned char) ((sha_info->digest[0] >> 32) & 0xff);
|
||||
digest[ 4] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
|
||||
digest[ 5] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
|
||||
digest[ 6] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
|
||||
digest[ 7] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
|
||||
digest[ 8] = (unsigned char) ((sha_info->digest[1] >> 56) & 0xff);
|
||||
digest[ 9] = (unsigned char) ((sha_info->digest[1] >> 48) & 0xff);
|
||||
digest[10] = (unsigned char) ((sha_info->digest[1] >> 40) & 0xff);
|
||||
digest[11] = (unsigned char) ((sha_info->digest[1] >> 32) & 0xff);
|
||||
digest[12] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
|
||||
digest[13] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
|
||||
digest[14] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
|
||||
digest[15] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
|
||||
digest[16] = (unsigned char) ((sha_info->digest[2] >> 56) & 0xff);
|
||||
digest[17] = (unsigned char) ((sha_info->digest[2] >> 48) & 0xff);
|
||||
digest[18] = (unsigned char) ((sha_info->digest[2] >> 40) & 0xff);
|
||||
digest[19] = (unsigned char) ((sha_info->digest[2] >> 32) & 0xff);
|
||||
digest[20] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
|
||||
digest[21] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
|
||||
digest[22] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
|
||||
digest[23] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
|
||||
digest[24] = (unsigned char) ((sha_info->digest[3] >> 56) & 0xff);
|
||||
digest[25] = (unsigned char) ((sha_info->digest[3] >> 48) & 0xff);
|
||||
digest[26] = (unsigned char) ((sha_info->digest[3] >> 40) & 0xff);
|
||||
digest[27] = (unsigned char) ((sha_info->digest[3] >> 32) & 0xff);
|
||||
digest[28] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
|
||||
digest[29] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
|
||||
digest[30] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
|
||||
digest[31] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
|
||||
digest[32] = (unsigned char) ((sha_info->digest[4] >> 56) & 0xff);
|
||||
digest[33] = (unsigned char) ((sha_info->digest[4] >> 48) & 0xff);
|
||||
digest[34] = (unsigned char) ((sha_info->digest[4] >> 40) & 0xff);
|
||||
digest[35] = (unsigned char) ((sha_info->digest[4] >> 32) & 0xff);
|
||||
digest[36] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
|
||||
digest[37] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
|
||||
digest[38] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
|
||||
digest[39] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
|
||||
digest[40] = (unsigned char) ((sha_info->digest[5] >> 56) & 0xff);
|
||||
digest[41] = (unsigned char) ((sha_info->digest[5] >> 48) & 0xff);
|
||||
digest[42] = (unsigned char) ((sha_info->digest[5] >> 40) & 0xff);
|
||||
digest[43] = (unsigned char) ((sha_info->digest[5] >> 32) & 0xff);
|
||||
digest[44] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff);
|
||||
digest[45] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff);
|
||||
digest[46] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff);
|
||||
digest[47] = (unsigned char) ((sha_info->digest[5] ) & 0xff);
|
||||
digest[48] = (unsigned char) ((sha_info->digest[6] >> 56) & 0xff);
|
||||
digest[49] = (unsigned char) ((sha_info->digest[6] >> 48) & 0xff);
|
||||
digest[50] = (unsigned char) ((sha_info->digest[6] >> 40) & 0xff);
|
||||
digest[51] = (unsigned char) ((sha_info->digest[6] >> 32) & 0xff);
|
||||
digest[52] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff);
|
||||
digest[53] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff);
|
||||
digest[54] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff);
|
||||
digest[55] = (unsigned char) ((sha_info->digest[6] ) & 0xff);
|
||||
digest[56] = (unsigned char) ((sha_info->digest[7] >> 56) & 0xff);
|
||||
digest[57] = (unsigned char) ((sha_info->digest[7] >> 48) & 0xff);
|
||||
digest[58] = (unsigned char) ((sha_info->digest[7] >> 40) & 0xff);
|
||||
digest[59] = (unsigned char) ((sha_info->digest[7] >> 32) & 0xff);
|
||||
digest[60] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff);
|
||||
digest[61] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff);
|
||||
digest[62] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff);
|
||||
digest[63] = (unsigned char) ((sha_info->digest[7] ) & 0xff);
|
||||
}
|
||||
|
||||
/*
|
||||
* End of copied SHA code.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static PyTypeObject SHA384type;
|
||||
static PyTypeObject SHA512type;
|
||||
|
||||
|
||||
static SHAobject *
|
||||
newSHA384object(void)
|
||||
{
|
||||
return (SHAobject *)PyObject_New(SHAobject, &SHA384type);
|
||||
}
|
||||
|
||||
static SHAobject *
|
||||
newSHA512object(void)
|
||||
{
|
||||
return (SHAobject *)PyObject_New(SHAobject, &SHA512type);
|
||||
}
|
||||
|
||||
/* Internal methods for a hash object */
|
||||
|
||||
static void
|
||||
SHA512_dealloc(PyObject *ptr)
|
||||
{
|
||||
PyObject_Del(ptr);
|
||||
}
|
||||
|
||||
|
||||
/* External methods for a hash object */
|
||||
|
||||
/*[clinic input]
|
||||
SHA512Type.copy
|
||||
|
||||
Return a copy of the hash object.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_copy_impl(SHAobject *self)
|
||||
/*[clinic end generated code: output=adea896ed3164821 input=9f5f31e6c457776a]*/
|
||||
{
|
||||
SHAobject *newobj;
|
||||
|
||||
if (((PyObject*)self)->ob_type == &SHA512type) {
|
||||
if ( (newobj = newSHA512object())==NULL)
|
||||
return NULL;
|
||||
} else {
|
||||
if ( (newobj = newSHA384object())==NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SHAcopy(self, newobj);
|
||||
return (PyObject *)newobj;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
SHA512Type.digest
|
||||
|
||||
Return the digest value as a bytes object.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_digest_impl(SHAobject *self)
|
||||
/*[clinic end generated code: output=1080bbeeef7dde1b input=f6470dd359071f4b]*/
|
||||
{
|
||||
unsigned char digest[SHA_DIGESTSIZE];
|
||||
SHAobject temp;
|
||||
|
||||
SHAcopy(self, &temp);
|
||||
sha512_final(digest, &temp);
|
||||
return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
SHA512Type.hexdigest
|
||||
|
||||
Return the digest value as a string of hexadecimal digits.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_hexdigest_impl(SHAobject *self)
|
||||
/*[clinic end generated code: output=7373305b8601e18b input=498b877b25cbe0a2]*/
|
||||
{
|
||||
unsigned char digest[SHA_DIGESTSIZE];
|
||||
SHAobject temp;
|
||||
|
||||
/* Get the raw (binary) digest value */
|
||||
SHAcopy(self, &temp);
|
||||
sha512_final(digest, &temp);
|
||||
|
||||
return _Py_strhex((const char *)digest, self->digestsize);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
SHA512Type.update
|
||||
|
||||
obj: object
|
||||
/
|
||||
|
||||
Update this hash object's state with the provided string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
SHA512Type_update(SHAobject *self, PyObject *obj)
|
||||
/*[clinic end generated code: output=1cf333e73995a79e input=ded2b46656566283]*/
|
||||
{
|
||||
Py_buffer buf;
|
||||
|
||||
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
|
||||
|
||||
sha512_update(self, buf.buf, buf.len);
|
||||
|
||||
PyBuffer_Release(&buf);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
/*[clinic input]
|
||||
dump buffer
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
|
||||
|
||||
static PyMethodDef SHA_methods[] = {
|
||||
SHA512TYPE_COPY_METHODDEF
|
||||
SHA512TYPE_DIGEST_METHODDEF
|
||||
SHA512TYPE_HEXDIGEST_METHODDEF
|
||||
SHA512TYPE_UPDATE_METHODDEF
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
SHA512_get_block_size(PyObject *self, void *closure)
|
||||
{
|
||||
return PyLong_FromLong(SHA_BLOCKSIZE);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
SHA512_get_name(PyObject *self, void *closure)
|
||||
{
|
||||
if (((SHAobject *)self)->digestsize == 64)
|
||||
return PyUnicode_FromStringAndSize("sha512", 6);
|
||||
else
|
||||
return PyUnicode_FromStringAndSize("sha384", 6);
|
||||
}
|
||||
|
||||
static PyGetSetDef SHA_getseters[] = {
|
||||
{"block_size",
|
||||
(getter)SHA512_get_block_size, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{"name",
|
||||
(getter)SHA512_get_name, NULL,
|
||||
NULL,
|
||||
NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyMemberDef SHA_members[] = {
|
||||
{"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyTypeObject SHA384type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"_sha512.sha384", /*tp_name*/
|
||||
sizeof(SHAobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
SHA512_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*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
SHA_methods, /* tp_methods */
|
||||
SHA_members, /* tp_members */
|
||||
SHA_getseters, /* tp_getset */
|
||||
};
|
||||
|
||||
static PyTypeObject SHA512type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"_sha512.sha512", /*tp_name*/
|
||||
sizeof(SHAobject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
SHA512_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*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
SHA_methods, /* tp_methods */
|
||||
SHA_members, /* tp_members */
|
||||
SHA_getseters, /* tp_getset */
|
||||
};
|
||||
|
||||
|
||||
/* The single module-level function: new() */
|
||||
|
||||
/*[clinic input]
|
||||
_sha512.sha512
|
||||
|
||||
string: object(c_default="NULL") = b''
|
||||
|
||||
Return a new SHA-512 hash object; optionally initialized with a string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_sha512_sha512_impl(PyObject *module, PyObject *string)
|
||||
/*[clinic end generated code: output=8b865a2df73bd387 input=e69bad9ae9b6a308]*/
|
||||
{
|
||||
SHAobject *new;
|
||||
Py_buffer buf;
|
||||
|
||||
if (string)
|
||||
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
|
||||
|
||||
if ((new = newSHA512object()) == NULL) {
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sha512_init(new);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(new);
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
if (string) {
|
||||
sha512_update(new, buf.buf, buf.len);
|
||||
PyBuffer_Release(&buf);
|
||||
}
|
||||
|
||||
return (PyObject *)new;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
_sha512.sha384
|
||||
|
||||
string: object(c_default="NULL") = b''
|
||||
|
||||
Return a new SHA-384 hash object; optionally initialized with a string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_sha512_sha384_impl(PyObject *module, PyObject *string)
|
||||
/*[clinic end generated code: output=ae4b2e26decf81e8 input=c9327788d4ea4545]*/
|
||||
{
|
||||
SHAobject *new;
|
||||
Py_buffer buf;
|
||||
|
||||
if (string)
|
||||
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
|
||||
|
||||
if ((new = newSHA384object()) == NULL) {
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sha384_init(new);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(new);
|
||||
if (string)
|
||||
PyBuffer_Release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
if (string) {
|
||||
sha512_update(new, buf.buf, buf.len);
|
||||
PyBuffer_Release(&buf);
|
||||
}
|
||||
|
||||
return (PyObject *)new;
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
dump buffer
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
|
||||
|
||||
/* List of functions exported by this module */
|
||||
|
||||
static struct PyMethodDef SHA_functions[] = {
|
||||
_SHA512_SHA512_METHODDEF
|
||||
_SHA512_SHA384_METHODDEF
|
||||
{NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
/* Initialize this module. */
|
||||
|
||||
#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
|
||||
|
||||
|
||||
static struct PyModuleDef _sha512module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_sha512",
|
||||
NULL,
|
||||
-1,
|
||||
SHA_functions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit__sha512(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
Py_TYPE(&SHA384type) = &PyType_Type;
|
||||
if (PyType_Ready(&SHA384type) < 0)
|
||||
return NULL;
|
||||
Py_TYPE(&SHA512type) = &PyType_Type;
|
||||
if (PyType_Ready(&SHA512type) < 0)
|
||||
return NULL;
|
||||
|
||||
m = PyModule_Create(&_sha512module);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_INCREF((PyObject *)&SHA384type);
|
||||
PyModule_AddObject(m, "SHA384Type", (PyObject *)&SHA384type);
|
||||
Py_INCREF((PyObject *)&SHA512type);
|
||||
PyModule_AddObject(m, "SHA512Type", (PyObject *)&SHA512type);
|
||||
return m;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__sha512 = {
|
||||
"_sha512",
|
||||
PyInit__sha512,
|
||||
};
|
19
third_party/python/Modules/signalmodule.c
vendored
19
third_party/python/Modules/signalmodule.c
vendored
|
@ -985,13 +985,13 @@ signal_sigwait(PyObject *module, PyObject *sigset)
|
|||
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
|
||||
static int initialized;
|
||||
static PyStructSequence_Field struct_siginfo_fields[] = {
|
||||
{"si_signo", "signal number"},
|
||||
{"si_code", "signal code"},
|
||||
{"si_errno", "errno associated with this signal"},
|
||||
{"si_pid", "sending process ID"},
|
||||
{"si_uid", "real user ID of sending process"},
|
||||
{"si_status", "exit value or signal"},
|
||||
{"si_band", "band event for SIGPOLL"},
|
||||
{"si_signo", PyDoc_STR("signal number")},
|
||||
{"si_code", PyDoc_STR("signal code")},
|
||||
{"si_errno", PyDoc_STR("errno associated with this signal")},
|
||||
{"si_pid", PyDoc_STR("sending process ID")},
|
||||
{"si_uid", PyDoc_STR("real user ID of sending process")},
|
||||
{"si_status", PyDoc_STR("exit value or signal")},
|
||||
{"si_band", PyDoc_STR("band event for SIGPOLL")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -1564,3 +1564,8 @@ void *_PyOS_SigintEvent(void)
|
|||
return sigint_event;
|
||||
}
|
||||
#endif
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab__signal = {
|
||||
"_signal",
|
||||
PyInit__signal,
|
||||
};
|
||||
|
|
13
third_party/python/Modules/socketmodule.c
vendored
13
third_party/python/Modules/socketmodule.c
vendored
|
@ -1027,8 +1027,7 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int
|
|||
{
|
||||
struct addrinfo hints, *res;
|
||||
int error;
|
||||
|
||||
memset((void *) addr_ret, '\0', sizeof(*addr_ret));
|
||||
bzero(addr_ret, sizeof(*addr_ret));
|
||||
if (name[0] == '\0') {
|
||||
int siz;
|
||||
bzero(&hints, sizeof(hints));
|
||||
|
@ -1086,7 +1085,7 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int
|
|||
return -1;
|
||||
}
|
||||
sin = (struct sockaddr_in *)addr_ret;
|
||||
memset((void *) sin, '\0', sizeof(*sin));
|
||||
bzero(sin, sizeof(*sin));
|
||||
sin->sin_family = AF_INET;
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
sin->sin_len = sizeof(*sin);
|
||||
|
@ -5147,7 +5146,7 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
|
|||
#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
|
||||
h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop);
|
||||
#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
|
||||
memset((void *) &data, '\0', sizeof(data));
|
||||
bzero(&data, sizeof(data));
|
||||
result = gethostbyname_r(name, &hp_allocated, &data);
|
||||
h = (result != 0) ? NULL : &hp_allocated;
|
||||
#endif
|
||||
|
@ -5245,7 +5244,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
|
|||
h = gethostbyaddr_r(ap, al, af,
|
||||
&hp_allocated, buf, buf_len, &errnop);
|
||||
#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
|
||||
memset((void *) &data, '\0', sizeof(data));
|
||||
bzero(&data, sizeof(data));
|
||||
result = gethostbyaddr_r(ap, al, af, &hp_allocated, &data);
|
||||
h = (result != 0) ? NULL : &hp_allocated;
|
||||
#endif
|
||||
|
@ -5838,7 +5837,7 @@ socket_inet_ntop(PyObject *self, PyObject *args)
|
|||
#endif
|
||||
|
||||
/* Guarantee NUL-termination for PyUnicode_FromString() below */
|
||||
memset((void *) &ip[0], '\0', sizeof(ip));
|
||||
bzero(&ip[0], sizeof(ip));
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) {
|
||||
return NULL;
|
||||
|
@ -5893,7 +5892,7 @@ socket_inet_ntop(PyObject *self, PyObject *args)
|
|||
#endif
|
||||
|
||||
/* Guarantee NUL-termination for PyUnicode_FromString() below */
|
||||
memset((void *) &ip[0], '\0', sizeof(ip));
|
||||
bzero(&ip[0], sizeof(ip));
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) {
|
||||
return NULL;
|
||||
|
|
24
third_party/python/Modules/spwdmodule.c
vendored
24
third_party/python/Modules/spwdmodule.c
vendored
|
@ -41,17 +41,17 @@ You have to be root to be able to use this module.");
|
|||
#if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT)
|
||||
|
||||
static PyStructSequence_Field struct_spwd_type_fields[] = {
|
||||
{"sp_namp", "login name"},
|
||||
{"sp_pwdp", "encrypted password"},
|
||||
{"sp_lstchg", "date of last change"},
|
||||
{"sp_min", "min #days between changes"},
|
||||
{"sp_max", "max #days between changes"},
|
||||
{"sp_warn", "#days before pw expires to warn user about it"},
|
||||
{"sp_inact", "#days after pw expires until account is disabled"},
|
||||
{"sp_expire", "#days since 1970-01-01 when account expires"},
|
||||
{"sp_flag", "reserved"},
|
||||
{"sp_nam", "login name; deprecated"}, /* Backward compatibility */
|
||||
{"sp_pwd", "encrypted password; deprecated"}, /* Backward compatibility */
|
||||
{"sp_namp", PyDoc_STR("login name")},
|
||||
{"sp_pwdp", PyDoc_STR("encrypted password")},
|
||||
{"sp_lstchg", PyDoc_STR("date of last change")},
|
||||
{"sp_min", PyDoc_STR("min #days between changes")},
|
||||
{"sp_max", PyDoc_STR("max #days between changes")},
|
||||
{"sp_warn", PyDoc_STR("#days before pw expires to warn user about it")},
|
||||
{"sp_inact", PyDoc_STR("#days after pw expires until account is disabled")},
|
||||
{"sp_expire", PyDoc_STR("#days since 1970-01-01 when account expires")},
|
||||
{"sp_flag", PyDoc_STR("reserved")},
|
||||
{"sp_nam", PyDoc_STR("login name; deprecated")}, /* Backward compatibility */
|
||||
{"sp_pwd", PyDoc_STR("encrypted password; deprecated")}, /* Backward compatibility */
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -206,8 +206,6 @@ static PyMethodDef spwd_methods[] = {
|
|||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct PyModuleDef spwdmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"spwd",
|
||||
|
|
2
third_party/python/Modules/sre.h
vendored
2
third_party/python/Modules/sre.h
vendored
|
@ -82,4 +82,4 @@ typedef struct {
|
|||
SRE_STATE state;
|
||||
} ScannerObject;
|
||||
|
||||
#endif
|
||||
#endif /* SRE_INCLUDED */
|
||||
|
|
21
third_party/python/Modules/sre_constants.h
vendored
21
third_party/python/Modules/sre_constants.h
vendored
|
@ -1,15 +1,8 @@
|
|||
/*
|
||||
* Secret Labs' Regular Expression Engine
|
||||
*
|
||||
* regular expression matching engine
|
||||
*
|
||||
* NOTE: This file is generated by sre_constants.py. If you need
|
||||
* to change anything in here, edit sre_constants.py and run it.
|
||||
*
|
||||
* Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved.
|
||||
*
|
||||
* See the _sre.c file for information on usage and redistribution.
|
||||
*/
|
||||
#ifndef COSMOPOLITAN_THIRD_PARTY_PYTHON_MODULES_SRE_CONSTANTS_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_PYTHON_MODULES_SRE_CONSTANTS_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
/* clang-format off */
|
||||
|
||||
#define SRE_MAGIC 20140917
|
||||
#define SRE_OP_FAILURE 0
|
||||
|
@ -87,3 +80,7 @@
|
|||
#define SRE_INFO_PREFIX 1
|
||||
#define SRE_INFO_LITERAL 2
|
||||
#define SRE_INFO_CHARSET 4
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_PYTHON_MODULES_SRE_CONSTANTS_H_ */
|
||||
|
|
52
third_party/python/Modules/timemodule.c
vendored
52
third_party/python/Modules/timemodule.c
vendored
|
@ -274,17 +274,17 @@ Delay execution for a given number of seconds. The argument may be\n\
|
|||
a floating point number for subsecond precision.");
|
||||
|
||||
static PyStructSequence_Field struct_time_type_fields[] = {
|
||||
{"tm_year", "year, for example, 1993"},
|
||||
{"tm_mon", "month of year, range [1, 12]"},
|
||||
{"tm_mday", "day of month, range [1, 31]"},
|
||||
{"tm_hour", "hours, range [0, 23]"},
|
||||
{"tm_min", "minutes, range [0, 59]"},
|
||||
{"tm_sec", "seconds, range [0, 61])"},
|
||||
{"tm_wday", "day of week, range [0, 6], Monday is 0"},
|
||||
{"tm_yday", "day of year, range [1, 366]"},
|
||||
{"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"},
|
||||
{"tm_zone", "abbreviation of timezone name"},
|
||||
{"tm_gmtoff", "offset from UTC in seconds"},
|
||||
{"tm_year", PyDoc_STR("year, for example, 1993")},
|
||||
{"tm_mon", PyDoc_STR("month of year, range [1, 12]")},
|
||||
{"tm_mday", PyDoc_STR("day of month, range [1, 31]")},
|
||||
{"tm_hour", PyDoc_STR("hours, range [0, 23]")},
|
||||
{"tm_min", PyDoc_STR("minutes, range [0, 59]")},
|
||||
{"tm_sec", PyDoc_STR("seconds, range [0, 61])")},
|
||||
{"tm_wday", PyDoc_STR("day of week, range [0, 6], Monday is 0")},
|
||||
{"tm_yday", PyDoc_STR("day of year, range [1, 366]")},
|
||||
{"tm_isdst", PyDoc_STR("1 if summer time is in effect, 0 if not, and -1 if unknown")},
|
||||
{"tm_zone", PyDoc_STR("abbreviation of timezone name")},
|
||||
{"tm_gmtoff", PyDoc_STR("offset from UTC in seconds")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -345,6 +345,14 @@ tmtotuple(struct tm *p
|
|||
return v;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
Time(int64_t *tp) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
if (tp) *tp = ts.tv_sec;
|
||||
return ts.tv_sec;
|
||||
}
|
||||
|
||||
/* Parse arg tuple that can contain an optional float-or-None value;
|
||||
format needs to be "|O:name".
|
||||
Returns non-zero on success (parallels PyArg_ParseTuple).
|
||||
|
@ -357,7 +365,7 @@ parse_time_t_args(PyObject *args, const char *format, time_t *pwhen)
|
|||
if (!PyArg_ParseTuple(args, format, &ot))
|
||||
return 0;
|
||||
if (ot == NULL || ot == Py_None) {
|
||||
whent = time(NULL);
|
||||
whent = Time(NULL);
|
||||
}
|
||||
else {
|
||||
if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1)
|
||||
|
@ -445,7 +453,7 @@ gettmarg(PyObject *args, struct tm *p)
|
|||
{
|
||||
int y;
|
||||
|
||||
memset((void *) p, '\0', sizeof(struct tm));
|
||||
bzero(p, sizeof(struct tm));
|
||||
|
||||
if (!PyTuple_Check(args)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
|
@ -605,7 +613,7 @@ time_strftime(PyObject *self, PyObject *args)
|
|||
size_t i;
|
||||
PyObject *ret = NULL;
|
||||
|
||||
memset((void *) &buf, '\0', sizeof(buf));
|
||||
bzero(&buf, sizeof(buf));
|
||||
|
||||
/* Will always expect a unicode string to be passed as format.
|
||||
Given that there's no str type anymore in py3k this seems safe.
|
||||
|
@ -614,7 +622,7 @@ time_strftime(PyObject *self, PyObject *args)
|
|||
return NULL;
|
||||
|
||||
if (tup == NULL) {
|
||||
time_t tt = time(NULL);
|
||||
time_t tt = Time(NULL);
|
||||
if (_PyTime_localtime(tt, &buf) != 0)
|
||||
return NULL;
|
||||
}
|
||||
|
@ -797,7 +805,7 @@ time_asctime(PyObject *self, PyObject *args)
|
|||
if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
|
||||
return NULL;
|
||||
if (tup == NULL) {
|
||||
time_t tt = time(NULL);
|
||||
time_t tt = Time(NULL);
|
||||
if (_PyTime_localtime(tt, &buf) != 0)
|
||||
return NULL;
|
||||
} else if (!gettmarg(tup, &buf) || !checktm(&buf))
|
||||
|
@ -1217,7 +1225,7 @@ init_timezone(PyObject *m)
|
|||
struct tm p;
|
||||
time_t janzone_t, julyzone_t;
|
||||
char janname[10], julyname[10];
|
||||
t = (time((time_t *)0) / YEAR) * YEAR;
|
||||
t = (Time((time_t *)0) / YEAR) * YEAR;
|
||||
_PyTime_localtime(t, &p);
|
||||
get_zone(janname, 9, &p);
|
||||
janzone_t = -get_gmtoff(t, &p);
|
||||
|
@ -1410,6 +1418,7 @@ pysleep(_PyTime_t secs)
|
|||
_PyTime_t deadline, monotonic;
|
||||
#ifndef MS_WINDOWS
|
||||
struct timeval timeout;
|
||||
struct timespec timeout2;
|
||||
int err = 0;
|
||||
#else
|
||||
_PyTime_t millisecs;
|
||||
|
@ -1422,11 +1431,16 @@ pysleep(_PyTime_t secs)
|
|||
|
||||
do {
|
||||
#ifndef MS_WINDOWS
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
#ifdef __COSMOPOLITAN__
|
||||
if (_PyTime_AsTimespec(secs, &timeout2) < 0)
|
||||
return -1;
|
||||
err = nanosleep(&timeout2, 0);
|
||||
#else /* b/c xnu */
|
||||
if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0)
|
||||
return -1;
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
|
||||
#endif
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (err == 0)
|
||||
|
|
504
third_party/python/Modules/tlsmodule.c
vendored
Normal file
504
third_party/python/Modules/tlsmodule.c
vendored
Normal file
|
@ -0,0 +1,504 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Copying of this file is authorized only if (1) you are Justine Tunney, │
|
||||
│ or (2) you make absolutely no changes to your copy. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "net/https/https.h"
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
#include "third_party/mbedtls/debug.h"
|
||||
#include "third_party/mbedtls/error.h"
|
||||
#include "third_party/mbedtls/ssl.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/longobject.h"
|
||||
#include "third_party/python/Include/modsupport.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Include/objimpl.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
#include "third_party/python/Include/structmember.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
/* clang-format off */
|
||||
|
||||
/**
|
||||
* @fileoverview Enough TLS support for HttpsClient so far.
|
||||
*/
|
||||
|
||||
PYTHON_PROVIDE("tls");
|
||||
|
||||
#if 0
|
||||
#define LOG(...) __printf(__VA_ARGS__)
|
||||
#else
|
||||
#define LOG(...) (void)0
|
||||
#endif
|
||||
|
||||
struct Tls {
|
||||
PyObject_HEAD
|
||||
int fd;
|
||||
PyObject *todo;
|
||||
mbedtls_ssl_config conf;
|
||||
mbedtls_ssl_context ssl;
|
||||
mbedtls_ctr_drbg_context rng;
|
||||
};
|
||||
|
||||
static PyObject *TlsError;
|
||||
static PyTypeObject tls_type;
|
||||
static mbedtls_x509_crt *roots;
|
||||
|
||||
static PyObject *
|
||||
SetTlsError(int rc)
|
||||
{
|
||||
char b[128];
|
||||
mbedtls_strerror(rc, b, sizeof(b));
|
||||
PyErr_SetString(TlsError, b);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
TlsSend(void *c, const unsigned char *p, size_t n)
|
||||
{
|
||||
int rc;
|
||||
struct Tls *self = c;
|
||||
for (;;) {
|
||||
rc = write(self->fd, p, n);
|
||||
if (rc != -1) {
|
||||
return rc;
|
||||
} else if (errno == EINTR) {
|
||||
if (PyErr_CheckSignals()) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
TlsRecv(void *c, unsigned char *p, size_t n, uint32_t t)
|
||||
{
|
||||
int rc;
|
||||
struct Tls *self = c;
|
||||
for (;;) {
|
||||
rc = read(self->fd, p, n);
|
||||
if (rc != -1) {
|
||||
return rc;
|
||||
} else if (errno == EINTR) {
|
||||
if (PyErr_CheckSignals()) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct Tls *
|
||||
tls_new(int fd, const char *host, PyObject *todo)
|
||||
{
|
||||
struct Tls *self;
|
||||
LOG("TLS.new\n");
|
||||
if ((self = PyObject_New(struct Tls, &tls_type))) {
|
||||
self->fd = fd;
|
||||
self->todo = todo;
|
||||
Py_INCREF(todo);
|
||||
InitializeRng(&self->rng);
|
||||
mbedtls_ssl_init(&self->ssl);
|
||||
mbedtls_ssl_config_init(&self->conf);
|
||||
mbedtls_ssl_config_defaults(&self->conf,
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
mbedtls_ssl_conf_rng(&self->conf, mbedtls_ctr_drbg_random, &self->rng);
|
||||
mbedtls_ssl_conf_ca_chain(&self->conf, roots, 0);
|
||||
/* mbedtls_ssl_conf_dbg(&self->conf, TlsDebug, 0); */
|
||||
/* mbedtls_debug_threshold = 5; */
|
||||
if (host && *host) {
|
||||
mbedtls_ssl_conf_authmode(&self->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
mbedtls_ssl_set_hostname(&self->ssl, host);
|
||||
} else {
|
||||
mbedtls_ssl_conf_authmode(&self->conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
}
|
||||
mbedtls_ssl_set_bio(&self->ssl, self, TlsSend, 0, TlsRecv);
|
||||
mbedtls_ssl_setup(&self->ssl, &self->conf);
|
||||
self->conf.disable_compression = true;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
tls_dealloc(struct Tls *self)
|
||||
{
|
||||
LOG("TLS.dealloc\n");
|
||||
if (self->fd != -1) {
|
||||
LOG("TLS CLOSING\n");
|
||||
close(self->fd);
|
||||
}
|
||||
Py_DECREF(self->todo);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
mbedtls_ssl_free(&self->ssl);
|
||||
mbedtls_ctr_drbg_free(&self->rng);
|
||||
mbedtls_ssl_config_free(&self->conf);
|
||||
PyObject_Del(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(tls_send__doc__, "\
|
||||
send($self, bytes, /)\n\
|
||||
--\n\n\
|
||||
Sends bytes as ciphertext to file descriptor, returning number\n\
|
||||
of bytes from buffer transmitted, or raising OSError/TlsError.");
|
||||
|
||||
static PyObject *
|
||||
tls_send(struct Tls *self, PyObject *args)
|
||||
{
|
||||
int rc;
|
||||
PyObject *res;
|
||||
Py_buffer data;
|
||||
LOG("TLS.send\n");
|
||||
if (!PyArg_ParseTuple(args, "y*:send", &data)) return 0;
|
||||
rc = mbedtls_ssl_write(&self->ssl, data.buf, data.len);
|
||||
if (rc != -1) {
|
||||
if (rc >= 0) {
|
||||
res = PyLong_FromLong(rc);
|
||||
} else {
|
||||
SetTlsError(rc);
|
||||
LOG("TLS CLOSING\n");
|
||||
close(self->fd);
|
||||
self->fd = -1;
|
||||
res = 0;
|
||||
}
|
||||
} else {
|
||||
res = 0;
|
||||
}
|
||||
PyBuffer_Release(&data);
|
||||
return res;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(tls_sendall__doc__, "\
|
||||
sendall($self, bytes, /)\n\
|
||||
--\n\n\
|
||||
Sends all bytes to file descriptor as ciphertext, returning number\n\
|
||||
of bytes from buffer transmitted, or raising OSError / TlsError.");
|
||||
|
||||
static PyObject *
|
||||
tls_sendall(struct Tls *self, PyObject *args)
|
||||
{
|
||||
LOG("TLS.sendall\n");
|
||||
int rc;
|
||||
Py_ssize_t i;
|
||||
PyObject *res;
|
||||
Py_buffer data;
|
||||
if (!PyArg_ParseTuple(args, "y*:sendall", &data)) return 0;
|
||||
for (i = 0;;) {
|
||||
rc = mbedtls_ssl_write(&self->ssl, (char *)data.buf + i, data.len - i);
|
||||
if (rc > 0) {
|
||||
if ((i += rc) == data.len) {
|
||||
res = Py_None;
|
||||
Py_INCREF(res);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (rc != -1) {
|
||||
SetTlsError(rc);
|
||||
LOG("TLS CLOSING\n");
|
||||
close(self->fd);
|
||||
self->fd = -1;
|
||||
}
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PyBuffer_Release(&data);
|
||||
return res;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(tls_recv__doc__, "\
|
||||
recv($self, nbytes, /)\n\
|
||||
--\n\n\
|
||||
Receives deciphered bytes from file descriptor, returning bytes\n\
|
||||
or raising OSError / TlsError.");
|
||||
|
||||
static PyObject *
|
||||
tls_recv(struct Tls *self, PyObject *args)
|
||||
{
|
||||
LOG("TLS.recv\n");
|
||||
int rc;
|
||||
Py_ssize_t n;
|
||||
PyObject *res, *buf;
|
||||
if (!PyArg_ParseTuple(args, "n:recv", &n)) return 0;
|
||||
if (n < 0) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"negative buffersize in recv");
|
||||
return NULL;
|
||||
}
|
||||
if (!(buf = PyBytes_FromStringAndSize(0, n))) return 0;
|
||||
rc = mbedtls_ssl_read(&self->ssl, PyBytes_AS_STRING(buf), n);
|
||||
if (rc != -1) {
|
||||
if (rc >= 0) {
|
||||
if (rc != n) {
|
||||
_PyBytes_Resize(&buf, rc);
|
||||
}
|
||||
res = buf;
|
||||
} else {
|
||||
Py_DECREF(buf);
|
||||
SetTlsError(rc);
|
||||
LOG("TLS CLOSING\n");
|
||||
close(self->fd);
|
||||
self->fd = -1;
|
||||
res = 0;
|
||||
}
|
||||
} else {
|
||||
Py_DECREF(buf);
|
||||
res = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(tls_recv_into__doc__, "\
|
||||
recv_into($self, buf, /)\n\
|
||||
--\n\n\
|
||||
Reads into an existing buffer...");
|
||||
|
||||
static PyObject *
|
||||
tls_recv_into(struct Tls *self, PyObject *args)
|
||||
{
|
||||
LOG("TLS.recv_into\n");
|
||||
int rc;
|
||||
Py_ssize_t n;
|
||||
PyObject *res;
|
||||
Py_buffer buf;
|
||||
if (!PyArg_ParseTuple(args, "w*:recv_into", &buf)) return 0;
|
||||
rc = mbedtls_ssl_read(&self->ssl, buf.buf, buf.len);
|
||||
if (rc != -1) {
|
||||
if (rc >= 0) {
|
||||
res = PyLong_FromLong(rc);
|
||||
LOG("got %d\n", rc);
|
||||
} else {
|
||||
SetTlsError(rc);
|
||||
LOG("TLS CLOSING\n");
|
||||
close(self->fd);
|
||||
self->fd = -1;
|
||||
res = 0;
|
||||
}
|
||||
} else {
|
||||
res = 0;
|
||||
}
|
||||
PyBuffer_Release(&buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(tls_fileno__doc__, "\
|
||||
fileno($self, /)\n\
|
||||
--\n\n\
|
||||
Returns file descriptor passed to constructor.");
|
||||
|
||||
static PyObject *
|
||||
tls_fileno(struct Tls *self, PyObject *unused)
|
||||
{
|
||||
LOG("TLS.fileno\n");
|
||||
return PyLong_FromLong(self->fd);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(tls_shutdown__doc__, "\
|
||||
shutdown($self, how, /)\n\
|
||||
--\n\n\
|
||||
Does nothing currently.");
|
||||
|
||||
static PyObject *
|
||||
tls_shutdown(struct Tls *self, PyObject *unused)
|
||||
{
|
||||
LOG("TLS.shutdown\n");
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(tls_close__doc__, "\
|
||||
close($self, /)\n\
|
||||
--\n\n\
|
||||
Closes SSL connection and file descriptor.");
|
||||
|
||||
static PyObject *
|
||||
tls_close(struct Tls *self, PyObject *unused)
|
||||
{
|
||||
int rc, fd;
|
||||
/* TODO(jart): do nothing until we can figure out how to own fd */
|
||||
Py_RETURN_NONE;
|
||||
fd = self->fd;
|
||||
if (fd != -1) {
|
||||
self->fd = -1;
|
||||
rc = mbedtls_ssl_close_notify(&self->ssl);
|
||||
if (rc) {
|
||||
LOG("TLS CLOSING\n");
|
||||
close(fd);
|
||||
if (rc != -1) {
|
||||
SetTlsError(rc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
LOG("TLS CLOSING\n");
|
||||
rc = close(fd);
|
||||
if (rc == -1) {
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(tls_handshake__doc__, "\
|
||||
handshake($self, /)\n\
|
||||
--\n\n\
|
||||
Handshakes SSL connection and file descriptor.");
|
||||
|
||||
static PyObject *
|
||||
tls_handshake(struct Tls *self, PyObject *unused)
|
||||
{
|
||||
int rc;
|
||||
LOG("TLS.handshake\n");
|
||||
rc = mbedtls_ssl_handshake(&self->ssl);
|
||||
if (rc) {
|
||||
LOG("TLS CLOSING\n");
|
||||
close(self->fd);
|
||||
self->fd = -1;
|
||||
if (rc != -1) {
|
||||
if (rc == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
|
||||
PyErr_SetString(TlsError, gc(DescribeSslVerifyFailure(self->ssl.session_negotiate->verify_result)));
|
||||
} else {
|
||||
SetTlsError(rc);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef tls_methods[] = {
|
||||
{"handshake", (PyCFunction)tls_handshake, METH_NOARGS, tls_handshake__doc__},
|
||||
{"recv", (PyCFunction)tls_recv, METH_VARARGS, tls_recv__doc__},
|
||||
{"recv_into", (PyCFunction)tls_recv_into, METH_VARARGS, tls_recv_into__doc__},
|
||||
{"send", (PyCFunction)tls_send, METH_VARARGS, tls_send__doc__},
|
||||
{"sendall", (PyCFunction)tls_sendall, METH_VARARGS, tls_sendall__doc__},
|
||||
{"fileno", (PyCFunction)tls_fileno, METH_NOARGS, tls_fileno__doc__},
|
||||
{"shutdown", (PyCFunction)tls_shutdown, METH_VARARGS, tls_shutdown__doc__},
|
||||
{"close", (PyCFunction)tls_close, METH_NOARGS, tls_close__doc__},
|
||||
{0}
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
tls_repr(struct Tls *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("<TLS object @ %p>", self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(tls_doc,
|
||||
"An MbedTLS object.");
|
||||
|
||||
static PyTypeObject tls_type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
/*tp_name*/ "tls.TLS",
|
||||
/*tp_basicsize*/ sizeof(struct Tls),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)tls_dealloc,
|
||||
/*tp_print*/ 0,
|
||||
/*tp_getattr*/ 0,
|
||||
/*tp_setattr*/ 0,
|
||||
/*tp_reserved*/ 0,
|
||||
/*tp_repr*/ (reprfunc)tls_repr,
|
||||
/*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*/ 0,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ tls_doc,
|
||||
/*tp_traverse*/ 0,
|
||||
/*tp_clear*/ 0,
|
||||
/*tp_richcompare*/ 0,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ 0,
|
||||
/*tp_iternext*/ 0,
|
||||
/*tp_methods*/ tls_methods,
|
||||
/*tp_members*/ 0,
|
||||
/*tp_getset*/ 0,
|
||||
/*tp_base*/ 0,
|
||||
/*tp_dict*/ 0,
|
||||
/*tp_descr_get*/ 0,
|
||||
/*tp_descr_set*/ 0,
|
||||
/*tp_dictoffset*/ 0,
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(newclient__doc__,
|
||||
"newclient($module, fd, host)\n\
|
||||
--\n\n\
|
||||
Creates TLS client.");
|
||||
|
||||
static PyObject *
|
||||
newclient(PyObject *self, PyObject *args)
|
||||
{
|
||||
int rc, fd;
|
||||
PyObject *todo;
|
||||
struct Tls *tls;
|
||||
const char *host;
|
||||
if (!PyArg_ParseTuple(args, "isO:newclient", &fd, &host, &todo)) return 0;
|
||||
tls = tls_new(fd, host, todo);
|
||||
return (PyObject *)tls;
|
||||
}
|
||||
|
||||
static struct PyMethodDef mbedtls_functions[] = {
|
||||
{"newclient", (PyCFunction)newclient, METH_VARARGS, newclient__doc__},
|
||||
{0}
|
||||
};
|
||||
|
||||
static struct PyModuleDef mbedtls_module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"tls",
|
||||
NULL,
|
||||
-1,
|
||||
mbedtls_functions
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_tls(void)
|
||||
{
|
||||
PyObject *m, *mbedtls_md_meth_names;
|
||||
Py_TYPE(&tls_type) = &PyType_Type;
|
||||
if (PyType_Ready(&tls_type) < 0) return 0;
|
||||
if (!(m = PyModule_Create(&mbedtls_module))) return 0;
|
||||
Py_INCREF((PyObject *)&tls_type);
|
||||
PyModule_AddObject(m, "TLS", (PyObject *)&tls_type);
|
||||
TlsError = PyErr_NewException("tls.TlsError", NULL, NULL);
|
||||
Py_INCREF(TlsError);
|
||||
PyModule_AddObject(m, "TlsError", TlsError);
|
||||
roots = GetSslRoots();
|
||||
return m;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab_tls = {
|
||||
"tls",
|
||||
PyInit_tls,
|
||||
};
|
925
third_party/python/Modules/unicodedata.c
vendored
925
third_party/python/Modules/unicodedata.c
vendored
File diff suppressed because it is too large
Load diff
120
third_party/python/Modules/unicodedata.h
vendored
Normal file
120
third_party/python/Modules/unicodedata.h
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_PYTHON_MODULES_UNICODEDATA_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_PYTHON_MODULES_UNICODEDATA_H_
|
||||
#include "libc/assert.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Include/unicodeobject.h"
|
||||
|
||||
#define _Hanghoul_SBase 0xAC00
|
||||
#define _Hanghoul_LBase 0x1100
|
||||
#define _Hanghoul_VBase 0x1161
|
||||
#define _Hanghoul_TBase 0x11A7
|
||||
#define _Hanghoul_LCount 19
|
||||
#define _Hanghoul_VCount 21
|
||||
#define _Hanghoul_TCount 28
|
||||
#define _Hanghoul_NCount (_Hanghoul_VCount * _Hanghoul_TCount)
|
||||
#define _Hanghoul_SCount (_Hanghoul_LCount * _Hanghoul_NCount)
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* [jart] if it adds 1.2megs to each binary then it should have an api
|
||||
* breaking this up into separate files allows ld to do its job
|
||||
*/
|
||||
|
||||
#define UCD_Check(o) (Py_TYPE(o)==&UCD_Type)
|
||||
#define get_old_record(self, v) ((((PreviousDBVersion*)self)->getrecord)(v))
|
||||
|
||||
typedef struct {
|
||||
const unsigned char category; /* index into _PyUnicode_CategoryNames */
|
||||
const unsigned char combining; /* combining class value 0 - 255 */
|
||||
const unsigned char bidirectional; /* index into _PyUnicode_BidirectionalNames */
|
||||
const unsigned char mirrored; /* true if mirrored in bidir mode */
|
||||
const unsigned char east_asian_width; /* index into _PyUnicode_EastAsianWidth */
|
||||
const unsigned char normalization_quick_check; /* see is_normalized() */
|
||||
} _PyUnicode_Record;
|
||||
|
||||
typedef struct {
|
||||
/* sequence of fields should be the same as in merge_old_version */
|
||||
const unsigned char bidir_changed;
|
||||
const unsigned char category_changed;
|
||||
const unsigned char decimal_changed;
|
||||
const unsigned char mirrored_changed;
|
||||
const unsigned char east_asian_width_changed;
|
||||
const double numeric_changed;
|
||||
} _PyUnicode_ChangeRecord;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
const char *name;
|
||||
const _PyUnicode_ChangeRecord *(*getrecord)(Py_UCS4);
|
||||
Py_UCS4 (*normalization)(Py_UCS4);
|
||||
} PreviousDBVersion;
|
||||
|
||||
typedef struct {
|
||||
int start;
|
||||
short count;
|
||||
short index;
|
||||
} _PyUnicode_Reindex;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
These are either deltas to the character or offsets in
|
||||
_PyUnicode_ExtendedCase.
|
||||
*/
|
||||
int upper;
|
||||
int lower;
|
||||
int title;
|
||||
/* Note if more flag space is needed, decimal and digit could be unified. */
|
||||
unsigned char decimal;
|
||||
unsigned char digit;
|
||||
unsigned short flags;
|
||||
} _PyUnicode_TypeRecord;
|
||||
|
||||
/*
|
||||
* In Unicode 6.0.0, the sequences contain at most 4 BMP chars,
|
||||
* so we are using Py_UCS2 seq[4]. This needs to be updated if longer
|
||||
* sequences or sequences with non-BMP chars are added.
|
||||
* unicodedata_lookup should be adapted too.
|
||||
*/
|
||||
typedef struct{
|
||||
int seqlen;
|
||||
Py_UCS2 seq[4];
|
||||
} _PyUnicode_NamedSequence;
|
||||
|
||||
extern PyTypeObject UCD_Type;
|
||||
|
||||
int _PyUnicode_IsUnifiedIdeograph(Py_UCS4);
|
||||
const _PyUnicode_Record *_PyUnicode_GetRecord(Py_UCS4);
|
||||
PyObject *_PyUnicode_NfcNfkc(PyObject *, PyObject *, int);
|
||||
PyObject *_PyUnicode_NfdNfkd(PyObject *, PyObject *, int);
|
||||
int _PyUnicode_IsNormalized(PyObject *, PyObject *, int, int);
|
||||
int _PyUnicode_GetUcName(PyObject *, Py_UCS4, char *, int, int);
|
||||
int _PyUnicode_FindNfcIndex(const _PyUnicode_Reindex *, Py_UCS4);
|
||||
void _PyUnicode_FindSyllable(const char *, int *, int *, int, int);
|
||||
int _PyUnicode_GetCode(PyObject *, const char *, int, Py_UCS4 *, int);
|
||||
void _PyUnicode_GetDecompRecord(PyObject *, Py_UCS4, int *, int *, int *);
|
||||
|
||||
static inline unsigned _PyUnicode_Bextr(const unsigned *p, unsigned i, char b) {
|
||||
size_t j;
|
||||
unsigned k, r, w;
|
||||
w = sizeof(unsigned) * CHAR_BIT;
|
||||
assert(0 <= b && b < w);
|
||||
j = i;
|
||||
j *= b;
|
||||
k = j & (w - 1);
|
||||
j /= w;
|
||||
if (k <= w - b) {
|
||||
return (p[j] >> k) & ((1ul << b) - 1);
|
||||
} else {
|
||||
r = p[j] >> k;
|
||||
r |= p[j + 1] << (w - k);
|
||||
r &= (1ul << b) - 1;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_PYTHON_MODULES_UNICODEDATA_H_ */
|
1872
third_party/python/Modules/unicodedata_3.2.0.c
vendored
Normal file
1872
third_party/python/Modules/unicodedata_3.2.0.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
475
third_party/python/Modules/unicodedata_aliases.c
vendored
Normal file
475
third_party/python/Modules/unicodedata_aliases.c
vendored
Normal file
|
@ -0,0 +1,475 @@
|
|||
#include "libc/nexgen32e/kompressor.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
/* clang-format off */
|
||||
/* GENERATED BY third_party/python/Tools/unicode/makeunicodedata.py 3.2 */
|
||||
|
||||
const unsigned int _PyUnicode_NameAliases[468] = {
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0001,
|
||||
0x0001,
|
||||
0x0002,
|
||||
0x0002,
|
||||
0x0003,
|
||||
0x0003,
|
||||
0x0004,
|
||||
0x0004,
|
||||
0x0005,
|
||||
0x0005,
|
||||
0x0006,
|
||||
0x0006,
|
||||
0x0007,
|
||||
0x0007,
|
||||
0x0008,
|
||||
0x0008,
|
||||
0x0009,
|
||||
0x0009,
|
||||
0x0009,
|
||||
0x0009,
|
||||
0x000A,
|
||||
0x000A,
|
||||
0x000A,
|
||||
0x000A,
|
||||
0x000A,
|
||||
0x000A,
|
||||
0x000B,
|
||||
0x000B,
|
||||
0x000B,
|
||||
0x000C,
|
||||
0x000C,
|
||||
0x000D,
|
||||
0x000D,
|
||||
0x000E,
|
||||
0x000E,
|
||||
0x000E,
|
||||
0x000F,
|
||||
0x000F,
|
||||
0x000F,
|
||||
0x0010,
|
||||
0x0010,
|
||||
0x0011,
|
||||
0x0011,
|
||||
0x0012,
|
||||
0x0012,
|
||||
0x0013,
|
||||
0x0013,
|
||||
0x0014,
|
||||
0x0014,
|
||||
0x0015,
|
||||
0x0015,
|
||||
0x0016,
|
||||
0x0016,
|
||||
0x0017,
|
||||
0x0017,
|
||||
0x0018,
|
||||
0x0018,
|
||||
0x0019,
|
||||
0x0019,
|
||||
0x001A,
|
||||
0x001A,
|
||||
0x001B,
|
||||
0x001B,
|
||||
0x001C,
|
||||
0x001C,
|
||||
0x001C,
|
||||
0x001D,
|
||||
0x001D,
|
||||
0x001D,
|
||||
0x001E,
|
||||
0x001E,
|
||||
0x001E,
|
||||
0x001F,
|
||||
0x001F,
|
||||
0x001F,
|
||||
0x0020,
|
||||
0x007F,
|
||||
0x007F,
|
||||
0x0080,
|
||||
0x0080,
|
||||
0x0081,
|
||||
0x0081,
|
||||
0x0082,
|
||||
0x0082,
|
||||
0x0083,
|
||||
0x0083,
|
||||
0x0084,
|
||||
0x0084,
|
||||
0x0085,
|
||||
0x0085,
|
||||
0x0086,
|
||||
0x0086,
|
||||
0x0087,
|
||||
0x0087,
|
||||
0x0088,
|
||||
0x0088,
|
||||
0x0088,
|
||||
0x0089,
|
||||
0x0089,
|
||||
0x0089,
|
||||
0x008A,
|
||||
0x008A,
|
||||
0x008A,
|
||||
0x008B,
|
||||
0x008B,
|
||||
0x008B,
|
||||
0x008C,
|
||||
0x008C,
|
||||
0x008C,
|
||||
0x008D,
|
||||
0x008D,
|
||||
0x008D,
|
||||
0x008E,
|
||||
0x008E,
|
||||
0x008E,
|
||||
0x008F,
|
||||
0x008F,
|
||||
0x008F,
|
||||
0x0090,
|
||||
0x0090,
|
||||
0x0091,
|
||||
0x0091,
|
||||
0x0091,
|
||||
0x0092,
|
||||
0x0092,
|
||||
0x0092,
|
||||
0x0093,
|
||||
0x0093,
|
||||
0x0094,
|
||||
0x0094,
|
||||
0x0095,
|
||||
0x0095,
|
||||
0x0096,
|
||||
0x0096,
|
||||
0x0096,
|
||||
0x0097,
|
||||
0x0097,
|
||||
0x0097,
|
||||
0x0098,
|
||||
0x0098,
|
||||
0x0099,
|
||||
0x0099,
|
||||
0x009A,
|
||||
0x009A,
|
||||
0x009B,
|
||||
0x009B,
|
||||
0x009C,
|
||||
0x009C,
|
||||
0x009D,
|
||||
0x009D,
|
||||
0x009E,
|
||||
0x009E,
|
||||
0x009F,
|
||||
0x009F,
|
||||
0x00A0,
|
||||
0x00AD,
|
||||
0x01A2,
|
||||
0x01A3,
|
||||
0x034F,
|
||||
0x061C,
|
||||
0x0709,
|
||||
0x0CDE,
|
||||
0x0E9D,
|
||||
0x0E9F,
|
||||
0x0EA3,
|
||||
0x0EA5,
|
||||
0x0FD0,
|
||||
0x11EC,
|
||||
0x11ED,
|
||||
0x11EE,
|
||||
0x11EF,
|
||||
0x180B,
|
||||
0x180C,
|
||||
0x180D,
|
||||
0x180E,
|
||||
0x200B,
|
||||
0x200C,
|
||||
0x200D,
|
||||
0x200E,
|
||||
0x200F,
|
||||
0x202A,
|
||||
0x202B,
|
||||
0x202C,
|
||||
0x202D,
|
||||
0x202E,
|
||||
0x202F,
|
||||
0x205F,
|
||||
0x2060,
|
||||
0x2066,
|
||||
0x2067,
|
||||
0x2068,
|
||||
0x2069,
|
||||
0x2118,
|
||||
0x2448,
|
||||
0x2449,
|
||||
0x2B7A,
|
||||
0x2B7C,
|
||||
0xA015,
|
||||
0xFE00,
|
||||
0xFE01,
|
||||
0xFE02,
|
||||
0xFE03,
|
||||
0xFE04,
|
||||
0xFE05,
|
||||
0xFE06,
|
||||
0xFE07,
|
||||
0xFE08,
|
||||
0xFE09,
|
||||
0xFE0A,
|
||||
0xFE0B,
|
||||
0xFE0C,
|
||||
0xFE0D,
|
||||
0xFE0E,
|
||||
0xFE0F,
|
||||
0xFE18,
|
||||
0xFEFF,
|
||||
0xFEFF,
|
||||
0xFEFF,
|
||||
0x122D4,
|
||||
0x122D5,
|
||||
0x16E56,
|
||||
0x16E57,
|
||||
0x16E76,
|
||||
0x16E77,
|
||||
0x1B001,
|
||||
0x1D0C5,
|
||||
0xE0100,
|
||||
0xE0101,
|
||||
0xE0102,
|
||||
0xE0103,
|
||||
0xE0104,
|
||||
0xE0105,
|
||||
0xE0106,
|
||||
0xE0107,
|
||||
0xE0108,
|
||||
0xE0109,
|
||||
0xE010A,
|
||||
0xE010B,
|
||||
0xE010C,
|
||||
0xE010D,
|
||||
0xE010E,
|
||||
0xE010F,
|
||||
0xE0110,
|
||||
0xE0111,
|
||||
0xE0112,
|
||||
0xE0113,
|
||||
0xE0114,
|
||||
0xE0115,
|
||||
0xE0116,
|
||||
0xE0117,
|
||||
0xE0118,
|
||||
0xE0119,
|
||||
0xE011A,
|
||||
0xE011B,
|
||||
0xE011C,
|
||||
0xE011D,
|
||||
0xE011E,
|
||||
0xE011F,
|
||||
0xE0120,
|
||||
0xE0121,
|
||||
0xE0122,
|
||||
0xE0123,
|
||||
0xE0124,
|
||||
0xE0125,
|
||||
0xE0126,
|
||||
0xE0127,
|
||||
0xE0128,
|
||||
0xE0129,
|
||||
0xE012A,
|
||||
0xE012B,
|
||||
0xE012C,
|
||||
0xE012D,
|
||||
0xE012E,
|
||||
0xE012F,
|
||||
0xE0130,
|
||||
0xE0131,
|
||||
0xE0132,
|
||||
0xE0133,
|
||||
0xE0134,
|
||||
0xE0135,
|
||||
0xE0136,
|
||||
0xE0137,
|
||||
0xE0138,
|
||||
0xE0139,
|
||||
0xE013A,
|
||||
0xE013B,
|
||||
0xE013C,
|
||||
0xE013D,
|
||||
0xE013E,
|
||||
0xE013F,
|
||||
0xE0140,
|
||||
0xE0141,
|
||||
0xE0142,
|
||||
0xE0143,
|
||||
0xE0144,
|
||||
0xE0145,
|
||||
0xE0146,
|
||||
0xE0147,
|
||||
0xE0148,
|
||||
0xE0149,
|
||||
0xE014A,
|
||||
0xE014B,
|
||||
0xE014C,
|
||||
0xE014D,
|
||||
0xE014E,
|
||||
0xE014F,
|
||||
0xE0150,
|
||||
0xE0151,
|
||||
0xE0152,
|
||||
0xE0153,
|
||||
0xE0154,
|
||||
0xE0155,
|
||||
0xE0156,
|
||||
0xE0157,
|
||||
0xE0158,
|
||||
0xE0159,
|
||||
0xE015A,
|
||||
0xE015B,
|
||||
0xE015C,
|
||||
0xE015D,
|
||||
0xE015E,
|
||||
0xE015F,
|
||||
0xE0160,
|
||||
0xE0161,
|
||||
0xE0162,
|
||||
0xE0163,
|
||||
0xE0164,
|
||||
0xE0165,
|
||||
0xE0166,
|
||||
0xE0167,
|
||||
0xE0168,
|
||||
0xE0169,
|
||||
0xE016A,
|
||||
0xE016B,
|
||||
0xE016C,
|
||||
0xE016D,
|
||||
0xE016E,
|
||||
0xE016F,
|
||||
0xE0170,
|
||||
0xE0171,
|
||||
0xE0172,
|
||||
0xE0173,
|
||||
0xE0174,
|
||||
0xE0175,
|
||||
0xE0176,
|
||||
0xE0177,
|
||||
0xE0178,
|
||||
0xE0179,
|
||||
0xE017A,
|
||||
0xE017B,
|
||||
0xE017C,
|
||||
0xE017D,
|
||||
0xE017E,
|
||||
0xE017F,
|
||||
0xE0180,
|
||||
0xE0181,
|
||||
0xE0182,
|
||||
0xE0183,
|
||||
0xE0184,
|
||||
0xE0185,
|
||||
0xE0186,
|
||||
0xE0187,
|
||||
0xE0188,
|
||||
0xE0189,
|
||||
0xE018A,
|
||||
0xE018B,
|
||||
0xE018C,
|
||||
0xE018D,
|
||||
0xE018E,
|
||||
0xE018F,
|
||||
0xE0190,
|
||||
0xE0191,
|
||||
0xE0192,
|
||||
0xE0193,
|
||||
0xE0194,
|
||||
0xE0195,
|
||||
0xE0196,
|
||||
0xE0197,
|
||||
0xE0198,
|
||||
0xE0199,
|
||||
0xE019A,
|
||||
0xE019B,
|
||||
0xE019C,
|
||||
0xE019D,
|
||||
0xE019E,
|
||||
0xE019F,
|
||||
0xE01A0,
|
||||
0xE01A1,
|
||||
0xE01A2,
|
||||
0xE01A3,
|
||||
0xE01A4,
|
||||
0xE01A5,
|
||||
0xE01A6,
|
||||
0xE01A7,
|
||||
0xE01A8,
|
||||
0xE01A9,
|
||||
0xE01AA,
|
||||
0xE01AB,
|
||||
0xE01AC,
|
||||
0xE01AD,
|
||||
0xE01AE,
|
||||
0xE01AF,
|
||||
0xE01B0,
|
||||
0xE01B1,
|
||||
0xE01B2,
|
||||
0xE01B3,
|
||||
0xE01B4,
|
||||
0xE01B5,
|
||||
0xE01B6,
|
||||
0xE01B7,
|
||||
0xE01B8,
|
||||
0xE01B9,
|
||||
0xE01BA,
|
||||
0xE01BB,
|
||||
0xE01BC,
|
||||
0xE01BD,
|
||||
0xE01BE,
|
||||
0xE01BF,
|
||||
0xE01C0,
|
||||
0xE01C1,
|
||||
0xE01C2,
|
||||
0xE01C3,
|
||||
0xE01C4,
|
||||
0xE01C5,
|
||||
0xE01C6,
|
||||
0xE01C7,
|
||||
0xE01C8,
|
||||
0xE01C9,
|
||||
0xE01CA,
|
||||
0xE01CB,
|
||||
0xE01CC,
|
||||
0xE01CD,
|
||||
0xE01CE,
|
||||
0xE01CF,
|
||||
0xE01D0,
|
||||
0xE01D1,
|
||||
0xE01D2,
|
||||
0xE01D3,
|
||||
0xE01D4,
|
||||
0xE01D5,
|
||||
0xE01D6,
|
||||
0xE01D7,
|
||||
0xE01D8,
|
||||
0xE01D9,
|
||||
0xE01DA,
|
||||
0xE01DB,
|
||||
0xE01DC,
|
||||
0xE01DD,
|
||||
0xE01DE,
|
||||
0xE01DF,
|
||||
0xE01E0,
|
||||
0xE01E1,
|
||||
0xE01E2,
|
||||
0xE01E3,
|
||||
0xE01E4,
|
||||
0xE01E5,
|
||||
0xE01E6,
|
||||
0xE01E7,
|
||||
0xE01E8,
|
||||
0xE01E9,
|
||||
0xE01EA,
|
||||
0xE01EB,
|
||||
0xE01EC,
|
||||
0xE01ED,
|
||||
0xE01EE,
|
||||
0xE01EF,
|
||||
};
|
31
third_party/python/Modules/unicodedata_bidirectionalnames.c
vendored
Normal file
31
third_party/python/Modules/unicodedata_bidirectionalnames.c
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "libc/nexgen32e/kompressor.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
/* clang-format off */
|
||||
/* GENERATED BY third_party/python/Tools/unicode/makeunicodedata.py 3.2 */
|
||||
|
||||
const char _PyUnicode_BidirectionalNames[24][4] = {
|
||||
"",
|
||||
"L",
|
||||
"LRE",
|
||||
"LRO",
|
||||
"R",
|
||||
"AL",
|
||||
"RLE",
|
||||
"RLO",
|
||||
"PDF",
|
||||
"EN",
|
||||
"ES",
|
||||
"ET",
|
||||
"AN",
|
||||
"CS",
|
||||
"NSM",
|
||||
"BN",
|
||||
"B",
|
||||
"S",
|
||||
"WS",
|
||||
"ON",
|
||||
"LRI",
|
||||
"RLI",
|
||||
"FSI",
|
||||
"PDI",
|
||||
};
|
38
third_party/python/Modules/unicodedata_categorynames.c
vendored
Normal file
38
third_party/python/Modules/unicodedata_categorynames.c
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include "libc/nexgen32e/kompressor.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
/* clang-format off */
|
||||
/* GENERATED BY third_party/python/Tools/unicode/makeunicodedata.py 3.2 */
|
||||
|
||||
const char _PyUnicode_CategoryNames[31][3] = {
|
||||
"Cn",
|
||||
"Lu",
|
||||
"Ll",
|
||||
"Lt",
|
||||
"Mn",
|
||||
"Mc",
|
||||
"Me",
|
||||
"Nd",
|
||||
"Nl",
|
||||
"No",
|
||||
"Zs",
|
||||
"Zl",
|
||||
"Zp",
|
||||
"Cc",
|
||||
"Cf",
|
||||
"Cs",
|
||||
"Co",
|
||||
"Cn",
|
||||
"Lm",
|
||||
"Lo",
|
||||
"Pc",
|
||||
"Pd",
|
||||
"Ps",
|
||||
"Pe",
|
||||
"Pi",
|
||||
"Pf",
|
||||
"Po",
|
||||
"Sm",
|
||||
"Sc",
|
||||
"Sk",
|
||||
"So",
|
||||
};
|
4913
third_party/python/Modules/unicodedata_codehash.c
vendored
Normal file
4913
third_party/python/Modules/unicodedata_codehash.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
1317
third_party/python/Modules/unicodedata_comp.c
vendored
Normal file
1317
third_party/python/Modules/unicodedata_comp.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
7386
third_party/python/Modules/unicodedata_db.inc
vendored
7386
third_party/python/Modules/unicodedata_db.inc
vendored
File diff suppressed because it is too large
Load diff
2283
third_party/python/Modules/unicodedata_decomp.c
vendored
Normal file
2283
third_party/python/Modules/unicodedata_decomp.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
24
third_party/python/Modules/unicodedata_decompprefix.c
vendored
Normal file
24
third_party/python/Modules/unicodedata_decompprefix.c
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "libc/nexgen32e/kompressor.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
/* clang-format off */
|
||||
/* GENERATED BY third_party/python/Tools/unicode/makeunicodedata.py 3.2 */
|
||||
|
||||
const char *const _PyUnicode_DecompPrefix[17] = {
|
||||
"",
|
||||
"<noBreak>",
|
||||
"<compat>",
|
||||
"<super>",
|
||||
"<fraction>",
|
||||
"<sub>",
|
||||
"<font>",
|
||||
"<circle>",
|
||||
"<wide>",
|
||||
"<vertical>",
|
||||
"<square>",
|
||||
"<isolated>",
|
||||
"<final>",
|
||||
"<initial>",
|
||||
"<medial>",
|
||||
"<small>",
|
||||
"<narrow>",
|
||||
};
|
13
third_party/python/Modules/unicodedata_eastasianwidthnames.c
vendored
Normal file
13
third_party/python/Modules/unicodedata_eastasianwidthnames.c
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include "libc/nexgen32e/kompressor.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
/* clang-format off */
|
||||
/* GENERATED BY third_party/python/Tools/unicode/makeunicodedata.py 3.2 */
|
||||
|
||||
const char _PyUnicode_EastAsianWidthNames[6][3] = {
|
||||
"F",
|
||||
"H",
|
||||
"W",
|
||||
"Na",
|
||||
"A",
|
||||
"N",
|
||||
};
|
1243
third_party/python/Modules/unicodedata_extendedcase.c
vendored
Normal file
1243
third_party/python/Modules/unicodedata_extendedcase.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
24
third_party/python/Modules/unicodedata_findnfcindex.c
vendored
Normal file
24
third_party/python/Modules/unicodedata_findnfcindex.c
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
/* clang-format off */
|
||||
|
||||
int
|
||||
_PyUnicode_FindNfcIndex(const _PyUnicode_Reindex *nfc, Py_UCS4 code)
|
||||
{
|
||||
unsigned int index;
|
||||
for (index = 0; nfc[index].start; index++) {
|
||||
unsigned int start = nfc[index].start;
|
||||
if (code < start)
|
||||
return -1;
|
||||
if (code <= start + nfc[index].count) {
|
||||
unsigned int delta = code - start;
|
||||
return nfc[index].index + delta;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
285
third_party/python/Modules/unicodedata_getcode.c
vendored
Normal file
285
third_party/python/Modules/unicodedata_getcode.c
vendored
Normal file
|
@ -0,0 +1,285 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "third_party/python/Include/pyctype.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
#include "third_party/python/Include/pymem.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
#include "third_party/python/Modules/unicodedata_unidata.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* macros used to determine if the given code point is in the PUA range that
|
||||
* we are using to store aliases and named sequences */
|
||||
#define IS_ALIAS(cp) ((cp >= _PyUnicode_AliasesStart) && \
|
||||
(cp < _PyUnicode_AliasesEnd))
|
||||
#define IS_NAMED_SEQ(cp) ((cp >= _PyUnicode_NamedSequencesStart) && \
|
||||
(cp < _PyUnicode_NamedSequencesEnd))
|
||||
|
||||
static const char * const kHangulSyllables[][3] = {
|
||||
{ "G", "A", "" },
|
||||
{ "GG", "AE", "G" },
|
||||
{ "N", "YA", "GG" },
|
||||
{ "D", "YAE", "GS" },
|
||||
{ "DD", "EO", "N", },
|
||||
{ "R", "E", "NJ" },
|
||||
{ "M", "YEO", "NH" },
|
||||
{ "B", "YE", "D" },
|
||||
{ "BB", "O", "L" },
|
||||
{ "S", "WA", "LG" },
|
||||
{ "SS", "WAE", "LM" },
|
||||
{ "", "OE", "LB" },
|
||||
{ "J", "YO", "LS" },
|
||||
{ "JJ", "U", "LT" },
|
||||
{ "C", "WEO", "LP" },
|
||||
{ "K", "WE", "LH" },
|
||||
{ "T", "WI", "M" },
|
||||
{ "P", "YU", "B" },
|
||||
{ "H", "EU", "BS" },
|
||||
{ 0, "YI", "S" },
|
||||
{ 0, "I", "SS" },
|
||||
{ 0, 0, "NG" },
|
||||
{ 0, 0, "J" },
|
||||
{ 0, 0, "C" },
|
||||
{ 0, 0, "K" },
|
||||
{ 0, 0, "T" },
|
||||
{ 0, 0, "P" },
|
||||
{ 0, 0, "H" }
|
||||
};
|
||||
|
||||
void
|
||||
_PyUnicode_FindSyllable(const char *str, int *len, int *pos,
|
||||
int count, int column)
|
||||
{
|
||||
int i, len1;
|
||||
*len = -1;
|
||||
for (i = 0; i < count; i++) {
|
||||
const char *s = kHangulSyllables[i][column];
|
||||
len1 = Py_SAFE_DOWNCAST(strlen(s), size_t, int);
|
||||
if (len1 <= *len)
|
||||
continue;
|
||||
if (strncmp(str, s, len1) == 0) {
|
||||
*len = len1;
|
||||
*pos = i;
|
||||
}
|
||||
}
|
||||
if (*len == -1) {
|
||||
*len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
_gethash(const char *s, int len, int scale)
|
||||
{
|
||||
int i;
|
||||
unsigned long h = 0;
|
||||
unsigned long ix;
|
||||
for (i = 0; i < len; i++) {
|
||||
h = (h * scale) + (unsigned char) Py_TOUPPER(Py_CHARMASK(s[i]));
|
||||
ix = h & 0xff000000;
|
||||
if (ix)
|
||||
h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
_cmpname(PyObject *self, int code, const char* name, int namelen)
|
||||
{
|
||||
/* check if code corresponds to the given name */
|
||||
int i;
|
||||
char buffer[UNIDATA_NAME_MAXLEN+1];
|
||||
if (!_PyUnicode_GetUcName(self, code, buffer, UNIDATA_NAME_MAXLEN, 1))
|
||||
return 0;
|
||||
for (i = 0; i < namelen; i++) {
|
||||
if (Py_TOUPPER(Py_CHARMASK(name[i])) != buffer[i])
|
||||
return 0;
|
||||
}
|
||||
return buffer[namelen] == '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
_check_alias_and_seq(unsigned int cp, Py_UCS4* code, int with_named_seq)
|
||||
{
|
||||
/* check if named sequences are allowed */
|
||||
if (!with_named_seq && IS_NAMED_SEQ(cp))
|
||||
return 0;
|
||||
/* if the code point is in the PUA range that we use for aliases,
|
||||
* convert it to obtain the right code point */
|
||||
if (IS_ALIAS(cp))
|
||||
*code = _PyUnicode_NameAliases[cp - _PyUnicode_AliasesStart];
|
||||
else
|
||||
*code = cp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
_PyUnicode_GetCode(PyObject *self, const char *name, int namelen, Py_UCS4 *code,
|
||||
int with_named_seq)
|
||||
{
|
||||
/* Return the code point associated with the given name.
|
||||
* Named aliases are resolved too (unless self != NULL (i.e. we are using
|
||||
* 3.2.0)). If with_named_seq is 1, returns the PUA code point that we are
|
||||
* using for the named sequence, and the caller must then convert it. */
|
||||
unsigned int h, v;
|
||||
unsigned int mask = _PyUnicode_CodeSize - 1;
|
||||
unsigned int i, incr;
|
||||
/* Check for hangul syllables. */
|
||||
if (strncmp(name, "HANGUL SYLLABLE ", 16) == 0) {
|
||||
int len, L = -1, V = -1, T = -1;
|
||||
const char *pos = name + 16;
|
||||
_PyUnicode_FindSyllable(pos, &len, &L, _Hanghoul_LCount, 0);
|
||||
pos += len;
|
||||
_PyUnicode_FindSyllable(pos, &len, &V, _Hanghoul_VCount, 1);
|
||||
pos += len;
|
||||
_PyUnicode_FindSyllable(pos, &len, &T, _Hanghoul_TCount, 2);
|
||||
pos += len;
|
||||
if (L != -1 && V != -1 && T != -1 && pos-name == namelen) {
|
||||
*code = _Hanghoul_SBase + (L * _Hanghoul_VCount+V) * _Hanghoul_TCount + T;
|
||||
return 1;
|
||||
}
|
||||
/* Otherwise, it's an illegal syllable name. */
|
||||
return 0;
|
||||
}
|
||||
/* Check for unified ideographs. */
|
||||
if (strncmp(name, "CJK UNIFIED IDEOGRAPH-", 22) == 0) {
|
||||
/* Four or five hexdigits must follow. */
|
||||
v = 0;
|
||||
name += 22;
|
||||
namelen -= 22;
|
||||
if (namelen != 4 && namelen != 5)
|
||||
return 0;
|
||||
while (namelen--) {
|
||||
v *= 16;
|
||||
if (*name >= '0' && *name <= '9')
|
||||
v += *name - '0';
|
||||
else if (*name >= 'A' && *name <= 'F')
|
||||
v += *name - 'A' + 10;
|
||||
else
|
||||
return 0;
|
||||
name++;
|
||||
}
|
||||
if (!_PyUnicode_IsUnifiedIdeograph(v))
|
||||
return 0;
|
||||
*code = v;
|
||||
return 1;
|
||||
}
|
||||
/* the following is the same as python's dictionary lookup, with
|
||||
only minor changes. see the makeunicodedata script for more
|
||||
details */
|
||||
h = (unsigned int)_gethash(name, namelen, _PyUnicode_CodeMagic);
|
||||
i = ~h & mask;
|
||||
v = _PyUnicode_Bextr(_PyUnicode_CodeHash, i, _PyUnicode_CodeHashBits);
|
||||
if (!v)
|
||||
return 0;
|
||||
if (_cmpname(self, v, name, namelen))
|
||||
return _check_alias_and_seq(v, code, with_named_seq);
|
||||
incr = (h ^ (h >> 3)) & mask;
|
||||
if (!incr)
|
||||
incr = mask;
|
||||
for (;;) {
|
||||
i = (i + incr) & mask;
|
||||
v = _PyUnicode_Bextr(_PyUnicode_CodeHash, i, _PyUnicode_CodeHashBits);
|
||||
if (!v)
|
||||
return 0;
|
||||
if (_cmpname(self, v, name, namelen))
|
||||
return _check_alias_and_seq(v, code, with_named_seq);
|
||||
incr = incr << 1;
|
||||
if (incr > mask)
|
||||
incr = incr ^ _PyUnicode_CodePoly;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_PyUnicode_GetUcName(PyObject *self, Py_UCS4 code, char *buffer, int buflen,
|
||||
int with_alias_and_seq)
|
||||
{
|
||||
/* Find the name associated with the given code point.
|
||||
* If with_alias_and_seq is 1, check for names in the Private Use Area 15
|
||||
* that we are using for aliases and named sequences. */
|
||||
char *p;
|
||||
unsigned char *w;
|
||||
int i, word, offset;
|
||||
if (code >= 0x110000)
|
||||
return 0;
|
||||
/* XXX should we just skip all the code points in the PUAs here? */
|
||||
if (!with_alias_and_seq && (IS_ALIAS(code) || IS_NAMED_SEQ(code)))
|
||||
return 0;
|
||||
if (self && UCD_Check(self)) {
|
||||
/* in 3.2.0 there are no aliases and named sequences */
|
||||
const _PyUnicode_ChangeRecord *old;
|
||||
if (IS_ALIAS(code) || IS_NAMED_SEQ(code))
|
||||
return 0;
|
||||
old = get_old_record(self, code);
|
||||
if (!old->category_changed) {
|
||||
/* unassigned */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (_Hanghoul_SBase <= code && code < _Hanghoul_SBase + _Hanghoul_SCount) {
|
||||
/* Hangul syllable. */
|
||||
int SIndex = code - _Hanghoul_SBase;
|
||||
int L = SIndex / _Hanghoul_NCount;
|
||||
int V = (SIndex % _Hanghoul_NCount) / _Hanghoul_TCount;
|
||||
int T = SIndex % _Hanghoul_TCount;
|
||||
if (buflen < 27)
|
||||
/* Worst case: HANGUL SYLLABLE <10chars>. */
|
||||
return 0;
|
||||
p = buffer;
|
||||
p = stpcpy(p, "HANGUL SYLLABLE ");
|
||||
p = stpcpy(p, kHangulSyllables[L][0]);
|
||||
p = stpcpy(p, kHangulSyllables[V][1]);
|
||||
p = stpcpy(p, kHangulSyllables[T][2]);
|
||||
*p = 0;
|
||||
return 1;
|
||||
}
|
||||
if (_PyUnicode_IsUnifiedIdeograph(code)) {
|
||||
if (buflen < 28)
|
||||
/* Worst case: CJK UNIFIED IDEOGRAPH-20000 */
|
||||
return 0;
|
||||
sprintf(buffer, "CJK UNIFIED IDEOGRAPH-%X", code);
|
||||
return 1;
|
||||
}
|
||||
/* get offset into phrasebook */
|
||||
offset = _PyUnicode_PhrasebookOffset1[(code>>_PyUnicode_PhrasebookShift)];
|
||||
offset = _PyUnicode_Bextr(_PyUnicode_PhrasebookOffset2,
|
||||
(offset << _PyUnicode_PhrasebookShift) +
|
||||
(code & ((1 << _PyUnicode_PhrasebookShift) - 1)),
|
||||
_PyUnicode_PhrasebookOffset2Bits);
|
||||
if (!offset)
|
||||
return 0;
|
||||
i = 0;
|
||||
for (;;) {
|
||||
/* get word index */
|
||||
word = _PyUnicode_Phrasebook[offset] - _PyUnicode_PhrasebookShort;
|
||||
if (word >= 0) {
|
||||
word = (word << 8) + _PyUnicode_Phrasebook[offset+1];
|
||||
offset += 2;
|
||||
} else
|
||||
word = _PyUnicode_Phrasebook[offset++];
|
||||
if (i) {
|
||||
if (i > buflen)
|
||||
return 0; /* buffer overflow */
|
||||
buffer[i++] = ' ';
|
||||
}
|
||||
/* copy word string from lexicon. the last character in the
|
||||
word has bit 7 set. the last word in a string ends with
|
||||
0x80 */
|
||||
w = _PyUnicode_Lexicon + _PyUnicode_LexiconOffset[word];
|
||||
while (*w < 128) {
|
||||
if (i >= buflen)
|
||||
return 0; /* buffer overflow */
|
||||
buffer[i++] = *w++;
|
||||
}
|
||||
if (i >= buflen)
|
||||
return 0; /* buffer overflow */
|
||||
buffer[i++] = *w & 127;
|
||||
if (*w == 128)
|
||||
break; /* end of word */
|
||||
}
|
||||
return 1;
|
||||
}
|
37
third_party/python/Modules/unicodedata_getdecomprecord.c
vendored
Normal file
37
third_party/python/Modules/unicodedata_getdecomprecord.c
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
#include "third_party/python/Modules/unicodedata_unidata.h"
|
||||
/* clang-format off */
|
||||
|
||||
void
|
||||
_PyUnicode_GetDecompRecord(PyObject *self,
|
||||
Py_UCS4 code,
|
||||
int *index,
|
||||
int *prefix,
|
||||
int *count)
|
||||
{
|
||||
unsigned decomp;
|
||||
if (code >= 0x110000) {
|
||||
*index = 0;
|
||||
} else if (self && UCD_Check(self) &&
|
||||
get_old_record(self, code)->category_changed==0) {
|
||||
/* unassigned in old version */
|
||||
*index = 0;
|
||||
}
|
||||
else {
|
||||
*index = _PyUnicode_DecompIndex1[(code>>_PyUnicode_DecompShift)];
|
||||
*index = _PyUnicode_DecompIndex2[(*index<<_PyUnicode_DecompShift)+
|
||||
(code&((1<<_PyUnicode_DecompShift)-1))];
|
||||
}
|
||||
/* high byte is number of hex bytes (usually one or two), low byte
|
||||
is prefix code (from*/
|
||||
decomp = _PyUnicode_Bextr(_PyUnicode_Decomp, *index, _PyUnicode_DecompBits);
|
||||
*count = decomp >> 8;
|
||||
*prefix = decomp & 255;
|
||||
(*index)++;
|
||||
}
|
24
third_party/python/Modules/unicodedata_getrecord.c
vendored
Normal file
24
third_party/python/Modules/unicodedata_getrecord.c
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
#include "third_party/python/Modules/unicodedata_unidata.h"
|
||||
/* clang-format off */
|
||||
|
||||
const _PyUnicode_Record *
|
||||
_PyUnicode_GetRecord(Py_UCS4 c)
|
||||
{
|
||||
int k, i;
|
||||
if (c >= 0x110000) {
|
||||
i = 0;
|
||||
} else {
|
||||
k = _PyUnicode_RecordsShift;
|
||||
i = _PyUnicode_RecordsIndex1[(c >> k)];
|
||||
i = _PyUnicode_RecordsIndex2[(i << k) + (c & ((1 << k) - 1))];
|
||||
}
|
||||
return _PyUnicode_Records + i;
|
||||
}
|
26
third_party/python/Modules/unicodedata_islinebreak.c
vendored
Normal file
26
third_party/python/Modules/unicodedata_islinebreak.c
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "libc/nexgen32e/kompressor.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
/* clang-format off */
|
||||
/* GENERATED BY third_party/python/Tools/unicode/makeunicodedata.py 3.2 */
|
||||
|
||||
/* Returns 1 for Unicode characters having the line break
|
||||
* property 'BK', 'CR', 'LF' or 'NL' or having bidirectional
|
||||
* type 'B', 0 otherwise.
|
||||
*/
|
||||
int _PyUnicode_IsLinebreak(Py_UCS4 ch)
|
||||
{
|
||||
switch (ch) {
|
||||
case 0x000A:
|
||||
case 0x000B:
|
||||
case 0x000C:
|
||||
case 0x000D:
|
||||
case 0x001C:
|
||||
case 0x001D:
|
||||
case 0x001E:
|
||||
case 0x0085:
|
||||
case 0x2028:
|
||||
case 0x2029:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue