.gitignore | 2 +
GNUmakefile | 9 +-
src/bup/test-pyutil.c | 206 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 216 insertions(+), 1 deletion(-)
create mode 100644 src/bup/test-pyutil.c
diff --git a/.gitignore b/.gitignore
index e7917dd1..322e6b88 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,8 @@
/src/bup/compat.[do]
/src/bup/io.[do]
/src/bup/pyutil.[do]
+/src/bup/test-pyutil.[do]
+/test/ext/test-pyutil
/test/int/__init__.pyc
/test/lib/__init__.pyc
/test/lib/buptest/__init__.pyc
diff --git a/GNUmakefile b/GNUmakefile
index 14a433f1..d1d6a0cc 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -300,6 +300,13 @@ generated_dependencies += lib/bup/_helpers.d src/bup/pyutil.d lib/bup/bupsplit.d
lib/bup/_helpers$(soext): lib/bup/_helpers.o src/bup/pyutil.o lib/bup/bupsplit.o lib/bup/_hashsplit.o
$(ld_helpers)
+clean_paths += src/bup/test-pyutil.o test/ext/test-pyutil
+generated_dependencies += src/bup/test-pyutil.d
+src/bup/test-%.o: src/bup/test-%.c
+ $(cc_bin)
+test/ext/test-%: src/bup/test-%.o src/bup/pyutil.o
+ $(ld_bin)
+
test/tmp:
mkdir test/tmp
@@ -332,7 +339,7 @@ define run_check
./pytest $(xdist_opt)
endef
-check_targets := all test/tmp dev/python
+check_targets := all test/tmp dev/python test/ext/test-pyutil
check: $(check_targets)
$(run_check)
diff --git a/src/bup/test-pyutil.c b/src/bup/test-pyutil.c
new file mode 100644
index 00000000..68847580
--- /dev/null
+++ b/src/bup/test-pyutil.c
@@ -0,0 +1,206 @@
+
+#define _LARGEFILE64_SOURCE 1
+#define PY_SSIZE_T_CLEAN 1
+#undef NDEBUG
+#include "../config/config.h"
+
+// According to Python, its header has to go first:
+//
http://docs.python.org/3/c-api/intro.html#include-files
+#include <Python.h>
+
+#include <assert.h>
+#include <limits.h>
+
+#include "bup/pyutil.h"
+
+
+static void
+test_bup_assign_pylong_to_integral(void)
+{
+ PyObject *zero = PyLong_FromLong(0);
+ PyObject *one = PyLong_FromLong(1);
+ PyObject *neg_one = PyLong_FromLong(-1);
+ assert (zero);
+ assert (one);
+ assert (neg_one);
+
+ int overflow;
+ {
+ long long i;
+ PyObject *min = PyLong_FromLongLong(LLONG_MIN);
+ PyObject *max = PyLong_FromLongLong(LLONG_MAX);
+ PyObject *under = PyNumber_Subtract(min, one);
+ PyObject *over = PyNumber_Add(max, one);
+
+ overflow = 0;
+ assert(BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, min, &overflow));
+ assert(i == LLONG_MIN);
+ assert(!overflow);
+ overflow = 0;
+ assert(BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, max, &overflow));
+ assert(i == LLONG_MAX);
+ assert(!overflow);
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, under, &overflow));
+ assert(overflow);
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, over, &overflow));
+ assert(overflow);
+
+ Py_DECREF(max);
+ Py_DECREF(min);
+ Py_DECREF(over);
+ Py_DECREF(under);
+ }
+ {
+ unsigned long long i;
+ PyObject *max = PyLong_FromUnsignedLongLong(ULLONG_MAX);
+ PyObject *over = PyNumber_Add(max, one);
+
+ overflow = 0;
+ assert(BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, zero, &overflow));
+ assert(i == 0);
+ assert(!overflow);
+ overflow = 0;
+ assert(BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, max, &overflow));
+ assert(i == ULLONG_MAX);
+ assert(!overflow);
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, neg_one, &overflow));
+ assert(overflow);
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, over, &overflow));
+ assert(overflow);
+
+ Py_DECREF(over);
+ Py_DECREF(max);
+ }
+ {
+ assert(sizeof(short) < sizeof(long long));
+
+ short i;
+ PyObject *min = PyLong_FromLongLong(SHRT_MIN);
+ PyObject *max = PyLong_FromLongLong(SHRT_MAX);
+ PyObject *under = PyNumber_Subtract(min, one);
+ PyObject *over = PyNumber_Add(max, one);
+
+ overflow = 0;
+ assert(BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, min, &overflow));
+ assert(i == SHRT_MIN);
+ assert(!overflow);
+ overflow = 0;
+ assert(BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, max, &overflow));
+ assert(i == SHRT_MAX);
+ assert(!overflow);
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, under, &overflow));
+ assert(overflow);
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, over, &overflow));
+ assert(overflow);
+
+ Py_DECREF(max);
+ Py_DECREF(min);
+ Py_DECREF(over);
+ Py_DECREF(under);
+ }
+ {
+ assert(sizeof(unsigned short) < sizeof(unsigned long long));
+
+ unsigned short i;
+ PyObject *max = PyLong_FromUnsignedLongLong(USHRT_MAX);
+ PyObject *over = PyNumber_Add(max, one);
+
+ overflow = 0;
+ assert(BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, zero, &overflow));
+ assert(i == 0);
+ assert(!overflow);
+ overflow = 0;
+ assert(BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, max, &overflow));
+ assert(i == USHRT_MAX);
+ assert(!overflow);
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, neg_one, &overflow));
+ assert(overflow);
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, over, &overflow));
+ assert(overflow);
+
+ Py_DECREF(over);
+ Py_DECREF(max);
+ }
+
+ {
+ int i;
+ unsigned u;
+
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&i, Py_None, &overflow));
+ assert(!overflow);
+ assert(PyErr_Occurred());
+ PyErr_Clear();
+ overflow = 0;
+ assert(!BUP_ASSIGN_PYLONG_TO_INTEGRAL(&u, Py_None, &overflow));
+ assert(!overflow);
+ assert(PyErr_Occurred());
+ PyErr_Clear();
+ }
+
+ Py_DECREF(neg_one);
+ Py_DECREF(one);
+ Py_DECREF(zero);
+ fprintf(stderr, "test-pyutil::%s OK\n", __func__);
+}
+
+static PyObject*
+run(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ test_bup_assign_pylong_to_integral();
+
+ fprintf(stderr, "test-pyutil OK\n");
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef test_methods[] = {
+ {"run", run, METH_VARARGS, "Run tests." },
+ {NULL, NULL, 0, NULL}
+};
+
+static int setup_module(PyObject *mod)
+{
+ return 1;
+}
+
+static struct PyModuleDef bup_main_module_def = {
+ .m_base = PyModuleDef_HEAD_INIT,
+ .m_name = "bup_test",
+ .m_doc = "bup test module",
+ .m_size = -1,
+ .m_methods = test_methods
+};
+
+static PyObject *
+PyInit_bup_test(void) {
+ PyObject *mod = PyModule_Create(&bup_main_module_def);
+ if (!setup_module(mod))
+ {
+ Py_DECREF(mod);
+ return NULL;
+ }
+ return mod;
+}
+
+int
+main(int argc, char **argv)
+{
+ assert(argc == 1);
+ if (PyImport_AppendInittab("bup_test", PyInit_bup_test) == -1) {
+ fprintf(stderr, "unable to register bup_test module\n");
+ exit(2);
+ }
+ char *bup_argv[] = { argv[0], "-c", "import bup_test; bup_test.run()"};
+ return Py_BytesMain (3, bup_argv);
+}
--
2.47.3