You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2016/02/25 00:07:31 UTC

[04/20] lucy-clownfish git commit: Add ParseTuple-compatible converters for numerics.

Add ParseTuple-compatible converters for numerics.

Add some conversion functions which conform to the API specified by
Python's ParseTuple C functionality.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/991e4a57
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/991e4a57
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/991e4a57

Branch: refs/heads/master
Commit: 991e4a576ab7edfd96e285c8493c3bdbd1794d6d
Parents: 9162199
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jan 22 17:14:30 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Feb 23 18:22:02 2016 -0800

----------------------------------------------------------------------
 runtime/python/cfext/CFBind.c | 305 +++++++++++++++++++++++++++++++++++++
 runtime/python/cfext/CFBind.h |  73 +++++++++
 2 files changed, 378 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/991e4a57/runtime/python/cfext/CFBind.c
----------------------------------------------------------------------
diff --git a/runtime/python/cfext/CFBind.c b/runtime/python/cfext/CFBind.c
index 95ae70d..7653325 100644
--- a/runtime/python/cfext/CFBind.c
+++ b/runtime/python/cfext/CFBind.c
@@ -76,6 +76,311 @@ CFBind_reraise_pyerr(cfish_Class *err_klass, cfish_String *mess) {
     cfish_Err_throw_mess(err_klass, new_mess);
 }
 
+static int
+S_convert_sint(PyObject *py_obj, void *ptr, bool nullable, unsigned width) {
+    if (py_obj == Py_None) {
+        if (nullable) {
+            return 1;
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError, "Required argument cannot be None");
+            return 0;
+        }
+    }
+    int overflow = 0;
+    int64_t value = PyLong_AsLongLongAndOverflow(py_obj, &overflow);
+    if (value == -1 && PyErr_Occurred()) {
+        return 0;
+    }
+    switch (width & 0xF) {
+        case 1:
+            if (value < INT8_MIN  || value > INT8_MAX)  { overflow = 1; }
+            break;
+        case 2:
+            if (value < INT16_MIN || value > INT16_MAX) { overflow = 1; }
+            break;
+        case 4:
+            if (value < INT32_MIN || value > INT32_MAX) { overflow = 1; }
+            break;
+        case 8:
+            break;
+    }
+    if (overflow) {
+        PyErr_SetString(PyExc_OverflowError, "Python int out of range");
+        return 0;
+    }
+    switch (width & 0xF) {
+        case 1:
+            *((int8_t*)ptr) = (int8_t)value;
+            break;
+        case 2:
+            *((int16_t*)ptr) = (int16_t)value;
+            break;
+        case 4:
+            *((int32_t*)ptr) = (int32_t)value;
+            break;
+        case 8:
+            *((int64_t*)ptr) = value;
+            break;
+    }
+    return 1;
+}
+
+static int
+S_convert_uint(PyObject *py_obj, void *ptr, bool nullable, unsigned width) {
+    if (py_obj == Py_None) {
+        if (nullable) {
+            return 1;
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError, "Required argument cannot be None");
+            return 0;
+        }
+    }
+    uint64_t value = PyLong_AsUnsignedLongLong(py_obj);
+    if (PyErr_Occurred()) {
+        return 0;
+    }
+    int overflow = 0;
+    switch (width & 0xF) {
+        case 1:
+            if (value > UINT8_MAX)  { overflow = 1; }
+            break;
+        case 2:
+            if (value > UINT16_MAX) { overflow = 1; }
+            break;
+        case 4:
+            if (value > UINT32_MAX) { overflow = 1; }
+            break;
+        case 8:
+            break;
+    }
+    if (overflow) {
+        PyErr_SetString(PyExc_OverflowError, "Python int out of range");
+        return 0;
+    }
+    switch (width & 0xF) {
+        case 1:
+            *((uint8_t*)ptr) = (uint8_t)value;
+            break;
+        case 2:
+            *((uint16_t*)ptr) = (uint16_t)value;
+            break;
+        case 4:
+            *((uint32_t*)ptr) = (uint32_t)value;
+            break;
+        case 8:
+            *((uint64_t*)ptr) = value;
+            break;
+    }
+    return 1;
+}
+
+int
+CFBind_convert_char(PyObject *py_obj, char *ptr) {
+    return S_convert_sint(py_obj, ptr, false, sizeof(char));
+}
+
+int
+CFBind_convert_short(PyObject *py_obj, short *ptr) {
+    return S_convert_sint(py_obj, ptr, false, sizeof(short));
+}
+
+int
+CFBind_convert_int(PyObject *py_obj, int *ptr) {
+    return S_convert_sint(py_obj, ptr, false, sizeof(int));
+}
+
+int
+CFBind_convert_long(PyObject *py_obj, long *ptr) {
+    return S_convert_sint(py_obj, ptr, false, sizeof(long));
+}
+
+int
+CFBind_convert_int8_t(PyObject *py_obj, int8_t *ptr) {
+    return S_convert_sint(py_obj, ptr, false, sizeof(int8_t));
+}
+
+int
+CFBind_convert_int16_t(PyObject *py_obj, int16_t *ptr) {
+    return S_convert_sint(py_obj, ptr, false, sizeof(int16_t));
+}
+
+int
+CFBind_convert_int32_t(PyObject *py_obj, int32_t *ptr) {
+    return S_convert_sint(py_obj, ptr, false, sizeof(int32_t));
+}
+
+int
+CFBind_convert_int64_t(PyObject *py_obj, int64_t *ptr) {
+    return S_convert_sint(py_obj, ptr, false, sizeof(int64_t));
+}
+
+int
+CFBind_convert_uint8_t(PyObject *py_obj, uint8_t *ptr) {
+    return S_convert_uint(py_obj, ptr, false, sizeof(uint8_t));
+}
+
+int
+CFBind_convert_uint16_t(PyObject *py_obj, uint16_t *ptr) {
+    return S_convert_uint(py_obj, ptr, false, sizeof(uint16_t));
+}
+
+int
+CFBind_convert_uint32_t(PyObject *py_obj, uint32_t *ptr) {
+    return S_convert_uint(py_obj, ptr, false, sizeof(uint32_t));
+}
+
+int
+CFBind_convert_uint64_t(PyObject *py_obj, uint64_t *ptr) {
+    return S_convert_uint(py_obj, ptr, false, sizeof(uint64_t));
+}
+
+int
+CFBind_convert_size_t(PyObject *py_obj, size_t *ptr) {
+    return S_convert_uint(py_obj, ptr, false, sizeof(size_t));
+}
+
+int
+CFBind_maybe_convert_char(PyObject *py_obj, char *ptr) {
+    return S_convert_sint(py_obj, ptr, true, sizeof(char));
+}
+
+int
+CFBind_maybe_convert_short(PyObject *py_obj, short *ptr) {
+    return S_convert_sint(py_obj, ptr, true, sizeof(short));
+}
+
+int
+CFBind_maybe_convert_int(PyObject *py_obj, int *ptr) {
+    return S_convert_sint(py_obj, ptr, true, sizeof(int));
+}
+
+int
+CFBind_maybe_convert_long(PyObject *py_obj, long *ptr) {
+    return S_convert_sint(py_obj, ptr, true, sizeof(long));
+}
+
+int
+CFBind_maybe_convert_int8_t(PyObject *py_obj, int8_t *ptr) {
+    return S_convert_sint(py_obj, ptr, true, sizeof(int8_t));
+}
+
+int
+CFBind_maybe_convert_int16_t(PyObject *py_obj, int16_t *ptr) {
+    return S_convert_sint(py_obj, ptr, true, sizeof(int16_t));
+}
+
+int
+CFBind_maybe_convert_int32_t(PyObject *py_obj, int32_t *ptr) {
+    return S_convert_sint(py_obj, ptr, true, sizeof(int32_t));
+}
+
+int
+CFBind_maybe_convert_int64_t(PyObject *py_obj, int64_t *ptr) {
+    return S_convert_sint(py_obj, ptr, true, sizeof(int64_t));
+}
+
+int
+CFBind_maybe_convert_uint8_t(PyObject *py_obj, uint8_t *ptr) {
+    return S_convert_uint(py_obj, ptr, true, sizeof(uint8_t));
+}
+
+int
+CFBind_maybe_convert_uint16_t(PyObject *py_obj, uint16_t *ptr) {
+    return S_convert_uint(py_obj, ptr, true, sizeof(uint16_t));
+}
+
+int
+CFBind_maybe_convert_uint32_t(PyObject *py_obj, uint32_t *ptr) {
+    return S_convert_uint(py_obj, ptr, true, sizeof(uint32_t));
+}
+
+int
+CFBind_maybe_convert_uint64_t(PyObject *py_obj, uint64_t *ptr) {
+    return S_convert_uint(py_obj, ptr, true, sizeof(uint64_t));
+}
+
+int
+CFBind_maybe_convert_size_t(PyObject *py_obj, size_t *ptr) {
+    return S_convert_uint(py_obj, ptr, true, sizeof(size_t));
+}
+
+static int
+S_convert_floating(PyObject *py_obj, void *ptr, bool nullable, int width) {
+    if (py_obj == Py_None) {
+        if (nullable) {
+            return 1;
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError, "Required argument cannot be None");
+            return 0;
+        }
+    }
+    double value = PyFloat_AsDouble(py_obj);
+    if (PyErr_Occurred()) {
+        return 0;
+    }
+    switch (width & 0xF) {
+        case sizeof(float):
+            *((float*)ptr) = (float)value;
+            break;
+        case sizeof(double):
+            *((double*)ptr) = value;
+            break;
+    }
+    return 1;
+}
+
+int
+CFBind_convert_float(PyObject *py_obj, float *ptr) {
+    return S_convert_floating(py_obj, ptr, false, sizeof(float));
+}
+
+int
+CFBind_convert_double(PyObject *py_obj, double *ptr) {
+    return S_convert_floating(py_obj, ptr, false, sizeof(double));
+}
+
+int
+CFBind_maybe_convert_float(PyObject *py_obj, float *ptr) {
+    return S_convert_floating(py_obj, ptr, true, sizeof(float));
+}
+
+int
+CFBind_maybe_convert_double(PyObject *py_obj, double *ptr) {
+    return S_convert_floating(py_obj, ptr, true, sizeof(double));
+}
+
+static int
+S_convert_bool(PyObject *py_obj, bool *ptr, bool nullable) {
+    if (py_obj == Py_None) {
+        if (nullable) {
+            return 1;
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError, "Required argument cannot be None");
+            return 0;
+        }
+    }
+    int truth = PyObject_IsTrue(py_obj);
+    if (truth == -1) {
+        return 0;
+    }
+    *ptr = !!truth;
+    return 1;
+}
+
+int
+CFBind_convert_bool(PyObject *py_obj, bool *ptr) {
+    return S_convert_bool(py_obj, ptr, false);
+}
+
+int
+CFBind_maybe_convert_bool(PyObject *py_obj, bool *ptr) {
+    return S_convert_bool(py_obj, ptr, true);
+}
+
 /**** refcounting **********************************************************/
 
 uint32_t

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/991e4a57/runtime/python/cfext/CFBind.h
----------------------------------------------------------------------
diff --git a/runtime/python/cfext/CFBind.h b/runtime/python/cfext/CFBind.h
index d6a362e..85be7af 100644
--- a/runtime/python/cfext/CFBind.h
+++ b/runtime/python/cfext/CFBind.h
@@ -37,6 +37,79 @@ struct cfish_String;
 void
 CFBind_reraise_pyerr(struct cfish_Class *err_klass, struct cfish_String *mess);
 
+/* ParseTuple conversion routines for primitive numeric types.
+ *
+ * If the value of `input` is out of range for the an integer C type, an
+ * OverflowError will be raised.
+ *
+ * If `input` is `None`, the "maybe_convert" variants will leave `ptr`
+ * untouched, while the "convert" routines will raise a TypeError.
+ */
+int
+CFBind_convert_char(PyObject *input, char *ptr);
+int
+CFBind_convert_short(PyObject *input, short *ptr);
+int
+CFBind_convert_int(PyObject *input, int *ptr);
+int
+CFBind_convert_long(PyObject *input, long *ptr);
+int
+CFBind_convert_int8_t(PyObject *input, int8_t *ptr);
+int
+CFBind_convert_int16_t(PyObject *input, int16_t *ptr);
+int
+CFBind_convert_int32_t(PyObject *input, int32_t *ptr);
+int
+CFBind_convert_int64_t(PyObject *input, int64_t *ptr);
+int
+CFBind_convert_uint8_t(PyObject *input, uint8_t *ptr);
+int
+CFBind_convert_uint16_t(PyObject *input, uint16_t *ptr);
+int
+CFBind_convert_uint32_t(PyObject *input, uint32_t *ptr);
+int
+CFBind_convert_uint64_t(PyObject *input, uint64_t *ptr);
+int
+CFBind_convert_bool(PyObject *input, bool *ptr);
+int
+CFBind_convert_size_t(PyObject *input, size_t *ptr);
+int
+CFBind_convert_float(PyObject *input, float *ptr);
+int
+CFBind_convert_double(PyObject *input, double *ptr);
+int
+CFBind_maybe_convert_char(PyObject *input, char *ptr);
+int
+CFBind_maybe_convert_short(PyObject *input, short *ptr);
+int
+CFBind_maybe_convert_int(PyObject *input, int *ptr);
+int
+CFBind_maybe_convert_long(PyObject *input, long *ptr);
+int
+CFBind_maybe_convert_int8_t(PyObject *input, int8_t *ptr);
+int
+CFBind_maybe_convert_int16_t(PyObject *input, int16_t *ptr);
+int
+CFBind_maybe_convert_int32_t(PyObject *input, int32_t *ptr);
+int
+CFBind_maybe_convert_int64_t(PyObject *input, int64_t *ptr);
+int
+CFBind_maybe_convert_uint8_t(PyObject *input, uint8_t *ptr);
+int
+CFBind_maybe_convert_uint16_t(PyObject *input, uint16_t *ptr);
+int
+CFBind_maybe_convert_uint32_t(PyObject *input, uint32_t *ptr);
+int
+CFBind_maybe_convert_uint64_t(PyObject *input, uint64_t *ptr);
+int
+CFBind_maybe_convert_bool(PyObject *input, bool *ptr);
+int
+CFBind_maybe_convert_size_t(PyObject *input, size_t *ptr);
+int
+CFBind_maybe_convert_float(PyObject *input, float *ptr);
+int
+CFBind_maybe_convert_double(PyObject *input, double *ptr);
+
 #ifdef __cplusplus
 }
 #endif