diff --git a/iio.c b/iio.c index 549791c..7bf03fb 100644 --- a/iio.c +++ b/iio.c @@ -322,8 +322,13 @@ static float xgetenvf(const char *s, float d) const char *v = xgetenv(s); return v ? atof(v) : d; } +static char iio_last_error[2048] = {0}; -static void fail(const char *fmt, ...) __attribute__((noreturn,format(printf,1,2))); +const char *iio_get_last_error(void) { + return iio_last_error; +} + +static void fail(const char *fmt, ...) __attribute__((format(printf,1,2))); static void fail(const char *fmt, ...) { @@ -334,6 +339,10 @@ static void fail(const char *fmt, ...) va_end(argp); fprintf(stderr, "\n\n"); fflush(NULL); + // save clean error message + va_start(argp, fmt); + vsnprintf(iio_last_error, sizeof(iio_last_error), fmt, argp); + va_end(argp); // if (global_hack_to_never_fail) // { // IIO_DEBUG("now wave a dead chicken and press enter\n"); diff --git a/interfaces/python/pypi/iio.py b/interfaces/python/pypi/iio.py index 0d6acb1..a36d508 100644 --- a/interfaces/python/pypi/iio.py +++ b/interfaces/python/pypi/iio.py @@ -11,18 +11,19 @@ # TODO : 5. canvas-based .explore with full cpu features # TODO : 6. allow the canvas-based .explore to ask data from server-side tiff - +import os # globally accessible C functions __libc_free = 0 __iio_read = 0 __iio_write = 0 - +__iio_get_last_error = 0 # internal function to initialize the C interface def __setup_functions(): global __libc_free global __iio_read global __iio_write + global __iio_get_last_error if __libc_free != 0: return from os.path import abspath, dirname @@ -36,7 +37,8 @@ def __setup_functions(): libc.free.argtypes = [c_void_p] libc.free.restype = c_void_p __libc_free = libc.free - + libiio.iio_get_last_error.restype = c_char_p + __iio_get_last_error = libiio.iio_get_last_error R = libiio.iio_read_image_float_vec R.argtypes = [c_char_p, POINTER(c_int), POINTER(c_int), POINTER(c_int)] R.restype = POINTER(c_float) @@ -51,6 +53,8 @@ def __setup_functions(): # API def read(filename): """Read an image file into a numpy array of floats""" + if not os.path.exists(filename): + raise FileNotFoundError(f"[Errno 2] No such file or directory: {filename}") from ctypes import c_int from numpy.ctypeslib import as_array @@ -61,6 +65,14 @@ def read(filename): d = c_int() p = __iio_read(filename.encode('utf-8'), w, h, d) + # display the error message if p is NULL + from ctypes import cast + if not p: + err = __iio_get_last_error() + if err: + raise ValueError(err.decode("utf-8")) + raise ValueError("iio_read returned NULL without error message") + # convert to numpy array and free the C memory x = as_array(p, (h.value, w.value, d.value)).copy() __libc_free(p) return x