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