[ismrmrd] 109/177: "fix" my reverted commit to appease C89 Windows compiler

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Wed Jan 14 20:02:08 UTC 2015


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to annotated tag v1.1.0.beta.1
in repository ismrmrd.

commit 91a3db6be2a3c4f0f13ec66fb146be5f3be0e93f
Author: Joseph Naegele <joseph.naegele at gmail.com>
Date:   Sat Sep 27 10:58:35 2014 -0400

    "fix" my reverted commit to appease C89 Windows compiler
---
 include/ismrmrd/dataset.h |   2 +-
 include/ismrmrd/ismrmrd.h |  18 +++-
 libsrc/dataset.c          | 152 +++++++++++----------------
 libsrc/ismrmrd.c          | 260 +++++++++++++++++++++++++++-------------------
 4 files changed, 223 insertions(+), 209 deletions(-)

diff --git a/include/ismrmrd/dataset.h b/include/ismrmrd/dataset.h
index 38faf82..e96b2a8 100644
--- a/include/ismrmrd/dataset.h
+++ b/include/ismrmrd/dataset.h
@@ -8,7 +8,7 @@
 #ifndef ISMRMRD_DATASET_H
 #define ISMRMRD_DATASET_H
 
-#include "ismrmrd.h"
+#include "ismrmrd/ismrmrd.h"
 
 #ifdef __cplusplus
 #include <string>
diff --git a/include/ismrmrd/ismrmrd.h b/include/ismrmrd/ismrmrd.h
index 09c3aaa..49e85bf 100644
--- a/include/ismrmrd/ismrmrd.h
+++ b/include/ismrmrd/ismrmrd.h
@@ -30,6 +30,7 @@ typedef __int64 int64_t;
 typedef unsigned __int64 uint64_t;
 #else /* non MS C or C++ compiler */
 #include <stdint.h>
+#include <stddef.h>     /* for size_t */
 #endif /* _MSC_VER */
 
 /* Complex numbers */
@@ -372,19 +373,26 @@ EXPORTISMRMRD int ismrmrd_clear_all_flags(uint64_t *flags);
 /******************/
 /* Error Handling */
 /******************/
-typedef void (*ismrmrd_error_handler_t)(const char *file, int line, const char *function, int err, char *msg);
-extern ismrmrd_error_handler_t ismrmrd_error_handler;
-#define ISMRMRD_THROW(err, msg) ismrmrd_error_handler(__FILE__, __LINE__, __func__, (err), (msg))
-
 /** @addtogroup capi
  *  @{
  */
+typedef void (*ismrmrd_error_handler_t)(const char *file, int line,
+        const char *function, int code, const char *msg);
+#define ISMRMRD_PUSH_ERR(code, msg) ismrmrd_push_error(__FILE__, __LINE__, \
+        __func__, (code), (msg))
+int ismrmrd_push_error(const char *file, const int line, const char *func,
+        const int code, const char *msg);
 /** Sets a custom error handler */
 EXPORTISMRMRD void ismrmrd_set_error_handler(ismrmrd_error_handler_t);
 /** Returns message for corresponding error code */
-EXPORTISMRMRD char *ismrmrd_strerror(int err);
+EXPORTISMRMRD char *ismrmrd_strerror(int code);
 /** @} */
 
+/** Populates parameters (if non-NULL) with error information
+ * @returns true if there was error information to return, false otherwise */
+bool ismrmrd_pop_error(char **file, int *line, char **func,
+        int *code, char **msg);
+
 /*****************************/
 /* Rotations and Quaternions */
 /*****************************/
diff --git a/libsrc/dataset.c b/libsrc/dataset.c
index 69ad77b..5a4b25a 100644
--- a/libsrc/dataset.c
+++ b/libsrc/dataset.c
@@ -68,7 +68,7 @@ static char * make_path(const ISMRMRD_Dataset *dset, const char * var) {
             size_t len = strlen(dset->groupname) + strlen(var) + 2;
             char *path = (char *) malloc(len);
             if (path == NULL) {
-                ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to malloc path");
+                ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to malloc path");
                 return NULL;
             }
             memset(path, 0, len);
@@ -93,7 +93,7 @@ static char * append_to_path(const ISMRMRD_Dataset *dset, const char * path, con
                 size_t len = strlen(path) + strlen(var) + 2;
                 char *newpath = (char *) malloc(len);
                 if (newpath == NULL) {
-                    ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to realloc newpath");
+                    ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to realloc newpath");
                     return NULL;
                 }
                 memset(newpath, 0, len);
@@ -123,8 +123,7 @@ static int delete_var(const ISMRMRD_Dataset *dset, const char *var) {
         if (link_exists(dset, path)) {
             h5status = H5Ldelete(dset->fileid, path, H5P_DEFAULT);
             if (h5status < 0) {
-                status = ISMRMRD_FILEERROR;
-                ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to delete H5 path");
+                status = ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to delete H5 path");
             }
         }
         free(path);
@@ -196,7 +195,7 @@ static hid_t get_hdf5type_complexfloat(void) {
     h5status = H5Tinsert(datatype, "real", 0, H5T_NATIVE_FLOAT);
     h5status = H5Tinsert(datatype, "imag", sizeof(float), H5T_NATIVE_FLOAT);
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed get complex float data type");
+        ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get complex float data type");
     }
     return datatype;
 }
@@ -208,7 +207,7 @@ static hid_t get_hdf5type_complexdouble(void) {
     h5status = H5Tinsert(datatype, "real", 0, H5T_NATIVE_DOUBLE);
     h5status = H5Tinsert(datatype, "imag", sizeof(double), H5T_NATIVE_DOUBLE);
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed get complex double data type");
+        ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get complex double data type");
     }
     return datatype;
 }
@@ -217,7 +216,7 @@ static hid_t get_hdf5type_xmlheader(void) {
     hid_t datatype = H5Tcopy(H5T_C_S1);
     herr_t h5status = H5Tset_size(datatype, H5T_VARIABLE);
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed get XML header data type");
+        ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get XML header data type");
     }
     return datatype;
 }
@@ -240,7 +239,7 @@ static hid_t get_hdf5type_encoding(void) {
     arraytype = H5Tarray_create2(H5T_NATIVE_UINT16, 1, arraydims);
     h5status = H5Tinsert(datatype, "user", HOFFSET(ISMRMRD_EncodingCounters, user), arraytype);
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed get endoding data type");
+        ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get endoding data type");
     }
     H5Tclose(arraytype);
     return datatype;
@@ -301,7 +300,7 @@ static hid_t get_hdf5type_acquisitionheader(void) {
     H5Tclose(vartype);
     
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed get acquisitionheader data type");
+        ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get acquisitionheader data type");
     }
     
     return datatype;   
@@ -325,7 +324,7 @@ static hid_t get_hdf5type_acquisition(void) {
     H5Tclose(vlvartype);
     
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed get acquisition data type");
+        ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get acquisition data type");
     }
     
     return datatype;
@@ -379,7 +378,7 @@ static hid_t get_hdf5type_imageheader(void) {
     H5Tclose(vartype);
 
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed get imageheader data type");
+        ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get imageheader data type");
     }
     
     return datatype;   
@@ -389,7 +388,7 @@ static hid_t get_hdf5type_image_attribute_string(void) {
     hid_t datatype = H5Tcopy(H5T_C_S1);
     herr_t h5status = H5Tset_size(datatype, H5T_VARIABLE);
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed get image attribute string data type");
+        ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get image attribute string data type");
     }
     return datatype;
 }
@@ -413,7 +412,7 @@ static hid_t get_hdf5type_ndarrayblob(void) {
     H5Tclose(vlvartype);
     
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed get NDArrayBlob data type");
+        ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed get NDArrayBlob data type");
     }
     
     return datatype;
@@ -448,7 +447,7 @@ static hid_t get_hdf5type_ndarray(uint16_t data_type) {
             hdfdatatype = get_hdf5type_complexdouble();
             break;
         default :
-            ISMRMRD_THROW(ISMRMRD_TYPEERROR, "Failed to get HDF5 data type.");
+            ISMRMRD_PUSH_ERR(ISMRMRD_TYPEERROR, "Failed to get HDF5 data type.");
     }
     return hdfdatatype;
 }
@@ -474,7 +473,7 @@ uint32_t get_number_of_elements(const ISMRMRD_Dataset *dset, const char * path)
             h5status = H5Sclose(dataspace);
             h5status= H5Dclose(dataset);
             if (h5status < 0) {
-                ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to get number of elements in vector.");
+                ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to get number of elements in vector.");
             }
         }
         else {
@@ -505,16 +504,14 @@ int append_element(const ISMRMRD_Dataset * dset, const char * path, void * elem,
             dataspace = H5Dget_space(dataset);
             rank = H5Sget_simple_extent_ndims(dataspace);
             if (rank != (ndim+1)) {
-                ISMRMRD_THROW(ISMRMRD_FILEERROR, "Dimensions are incorrect.");
-                return ISMRMRD_FILEERROR;
+                return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Dimensions are incorrect.");
             }
             hdfdims =(hsize_t *) malloc(rank*sizeof(hsize_t));
             maxdims =(hsize_t *) malloc(rank*sizeof(hsize_t));
             h5status = H5Sget_simple_extent_dims(dataspace, hdfdims, maxdims);
             for (n = 0; n<ndim; n++) {
                 if (dims[n] != hdfdims[n+1]) {
-                    ISMRMRD_THROW(ISMRMRD_FILEERROR, "Dimensions are incorrect.");
-                    return ISMRMRD_FILEERROR;
+                    return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Dimensions are incorrect.");
                 }
             }
             /* extend it by one */
@@ -589,8 +586,7 @@ int append_element(const ISMRMRD_Dataset * dset, const char * path, void * elem,
         h5status = H5Dclose(dataset);
 
         if (h5status < 0) {
-            ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to get number of acquisitions.");
-            return ISMRMRD_FILEERROR;
+            return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to get number of acquisitions.");
         }
         
         return ISMRMRD_NOERROR;
@@ -607,15 +603,13 @@ int ismrmrd_init_dataset(ISMRMRD_Dataset *dset, const char *filename, const char
     if (dset) {
         dset->filename = (char *) malloc(strlen(filename) + 1);
         if (dset->filename == NULL) {
-            ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to malloc dataset groupname");
-            return ISMRMRD_MEMORYERROR;
+            return ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to malloc dataset groupname");
         }
         strcpy(dset->filename, filename);
         
         dset->groupname = (char *) malloc(strlen(groupname) + 1);
         if (dset->groupname == NULL) {
-            ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to malloc dataset groupname");
-            return ISMRMRD_MEMORYERROR;
+            return ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to malloc dataset groupname");
         }
         strcpy(dset->groupname, groupname);
         dset->fileid = 0;
@@ -645,8 +639,7 @@ int ismrmrd_open_dataset(ISMRMRD_Dataset *dset, const bool create_if_needed) {
             /* Some sort of error opening the file */
             /* Maybe it doesn't exist? */
             if (create_if_needed == false) {
-            ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to open file.");
-            return ISMRMRD_FILEERROR;
+            return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to open file.");
         }
         else {
             /* Try creating a new file using the default properties. */
@@ -659,8 +652,7 @@ int ismrmrd_open_dataset(ISMRMRD_Dataset *dset, const bool create_if_needed) {
             }
             else {
             /* Error opening the file */
-                ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to open file.");
-                return ISMRMRD_FILEERROR;
+                return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to open file.");
             }
         }
         }
@@ -685,8 +677,7 @@ int ismrmrd_close_dataset(ISMRMRD_Dataset *dset) {
             h5status = H5Fclose (dset->fileid);
             dset->fileid = 0;
             if (h5status < 0) {
-                ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to close dataset.");
-                return ISMRMRD_FILEERROR;
+                return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to close dataset.");
             }
         }
         
@@ -705,13 +696,11 @@ int ismrmrd_write_header(const ISMRMRD_Dataset *dset, const char *xmlstring) {
     char * path;
 
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
     }
 
     if (xmlstring==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "xmlstring should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "xmlstring should not be NULL.");
     }
 
     /* The path to the xml header */
@@ -739,8 +728,7 @@ int ismrmrd_write_header(const ISMRMRD_Dataset *dset, const char *xmlstring) {
     h5status = H5Dclose(dataset);
     
     if (h5status < 0) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to write header.");
-        return ISMRMRD_FILEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to write header.");
     }
         
     return ISMRMRD_NOERROR;
@@ -752,7 +740,7 @@ char * ismrmrd_read_header(const ISMRMRD_Dataset *dset) {
     char * xmlstring, *path;
         
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
         return NULL;
     }
 
@@ -769,7 +757,7 @@ char * ismrmrd_read_header(const ISMRMRD_Dataset *dset) {
         /* Unpack */
         xmlstring = (char *) malloc(strlen(buff[0])+1);
         if (xmlstring == NULL) {
-            ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to malloc xmlstring");
+            ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to malloc xmlstring");
         } else {
             memcpy(xmlstring, buff[0], strlen(buff[0])+1);
         }
@@ -780,7 +768,7 @@ char * ismrmrd_read_header(const ISMRMRD_Dataset *dset) {
         free(path);
         
         if (h5status < 0) {
-            ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to read header.");
+            ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to read header.");
             return NULL;
         }
             
@@ -788,7 +776,7 @@ char * ismrmrd_read_header(const ISMRMRD_Dataset *dset) {
     }
     else {
         // No XML String found
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "No XML Header found.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "No XML Header found.");
         free(path);
         return NULL;
     }
@@ -799,7 +787,7 @@ uint32_t ismrmrd_get_number_of_acquisitions(const ISMRMRD_Dataset *dset) {
     uint32_t numacq;
     
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
         return 0;
     }
     /* The path to the acqusition data */    
@@ -816,12 +804,10 @@ int ismrmrd_append_acquisition(const ISMRMRD_Dataset *dset, const ISMRMRD_Acquis
     HDF5_Acquisition hdf5acq[1];
             
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
     }
     if (acq==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Acquisition pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Acquisition pointer should not be NULL.");
     }
     
     /* The path to the acqusition data */    
@@ -840,8 +826,7 @@ int ismrmrd_append_acquisition(const ISMRMRD_Dataset *dset, const ISMRMRD_Acquis
     /* Write it */
     status = append_element(dset, path, hdf5acq, datatype, 0, NULL);
     if (status != ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to append acquisition.");
-        return ISMRMRD_FILEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to append acquisition.");
     }
 
     /* Clean up */
@@ -862,12 +847,10 @@ int ismrmrd_read_acquisition(const ISMRMRD_Dataset *dset, uint32_t index, ISMRMR
     char *path;        
 
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
     }
     if (acq==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Acquisition pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Acquisition pointer should not be NULL.");
     }
 
     /* The path to the acqusition data */    
@@ -903,20 +886,17 @@ int ismrmrd_read_acquisition(const ISMRMRD_Dataset *dset, uint32_t index, ISMRMR
             h5status = H5Sclose(memspace);
             h5status = H5Dclose(dataset);
             if (h5status < 0) {
-                ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to read acquisition.");
-                return ISMRMRD_FILEERROR;
+                return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to read acquisition.");
             }
         }
         else {
             /* index out of range */
-            ISMRMRD_THROW(ISMRMRD_FILEERROR, "Acquisition index out of range.");
-            return ISMRMRD_FILEERROR;
+            return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Acquisition index out of range.");
         }
     }
     else {
         /* No data */
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Data not found.");
-        return ISMRMRD_FILEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Data not found.");
     }
     
     return ISMRMRD_NOERROR;
@@ -930,16 +910,13 @@ int ismrmrd_append_image(const ISMRMRD_Dataset *dset, const char *varname,
     uint16_t dims[4];
 
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
     }
     if (varname==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
     }
     if (im==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Image pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Image pointer should not be NULL.");
     }
 
     /* The group for this set of images */
@@ -953,8 +930,7 @@ int ismrmrd_append_image(const ISMRMRD_Dataset *dset, const char *varname,
     datatype = get_hdf5type_imageheader();
     status = append_element(dset, headerpath, (void *) &im->head, datatype, 0, NULL);
     if (status != ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to append image header.");
-        return ISMRMRD_FILEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to append image header.");
     }
     free(headerpath);
             
@@ -963,8 +939,7 @@ int ismrmrd_append_image(const ISMRMRD_Dataset *dset, const char *varname,
     datatype = get_hdf5type_image_attribute_string();
     status = append_element(dset, attrpath, (void *) &im->attribute_string, datatype, 0, NULL);
     if (status != ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to append image attribute string.");
-        return ISMRMRD_FILEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to append image attribute string.");
     }
     free(attrpath);
             
@@ -978,8 +953,7 @@ int ismrmrd_append_image(const ISMRMRD_Dataset *dset, const char *varname,
     dims[0] = im->head.channels;
     status = append_element(dset, datapath, im->data, datatype, 4, dims);
     if (status != ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to append image data.");
-        return ISMRMRD_FILEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to append image data.");
     }
     free(datapath);
             
@@ -996,11 +970,11 @@ uint32_t ismrmrd_get_number_of_images(const ISMRMRD_Dataset *dset, const char *v
     uint32_t numimages;
     
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
         return 0;
     }
     if (varname==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
         return 0;
     }
     /* The group for this set of images */
@@ -1023,16 +997,13 @@ int ismrmrd_append_array(const ISMRMRD_Dataset *dset, const char *varname,
     char *path;
     
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
-        return 0;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
     }
     if (varname==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
-        return 0;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
     }
     if (arr==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Array pointer should not be NULL.");
-        return 0;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Array pointer should not be NULL.");
     }
     
     /* The group for this set */
@@ -1049,8 +1020,7 @@ int ismrmrd_append_array(const ISMRMRD_Dataset *dset, const char *varname,
     }
     status = append_element(dset, path, arr->data, datatype, ndim, dims);
     if (status != ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_FILEERROR, "Failed to append array.");
-        return ISMRMRD_FILEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_FILEERROR, "Failed to append array.");
     }
     
     /* Final cleanup */
@@ -1066,11 +1036,11 @@ uint32_t ismrmrd_get_number_of_arrays(const ISMRMRD_Dataset *dset, const char *v
     uint32_t numarrays;
     
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
         return 0;
     }
     if (varname==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
         return 0;
     }
 
@@ -1088,16 +1058,13 @@ uint32_t ismrmrd_get_number_of_arrays(const ISMRMRD_Dataset *dset, const char *v
 int ismrmrd_read_image(const ISMRMRD_Dataset *dset, const char *varname,
                        const uint32_t index, ISMRMRD_Image *im) {
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
-        return 0;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
     }
     if (varname==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
-        return 0;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
     }
     if (im==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Image should not be NULL.");
-        return 0;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Image should not be NULL.");
     }
 
     return ISMRMRD_NOERROR;
@@ -1106,16 +1073,13 @@ int ismrmrd_read_image(const ISMRMRD_Dataset *dset, const char *varname,
 int ismrmrd_read_array(const ISMRMRD_Dataset *dset, const char *varname,
                        const uint32_t index, ISMRMRD_NDArray *arr) {
     if (dset==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
-        return 0;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Dataset pointer should not be NULL.");
     }
     if (varname==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
-        return 0;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Varname should not be NULL.");
     }
     if (arr==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Array pointer should not be NULL.");
-        return 0;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Array pointer should not be NULL.");
     }
 
     return ISMRMRD_NOERROR;
diff --git a/libsrc/ismrmrd.c b/libsrc/ismrmrd.c
index 30c7ff8..f208c2a 100644
--- a/libsrc/ismrmrd.c
+++ b/libsrc/ismrmrd.c
@@ -4,13 +4,11 @@
 /* Language and Cross platform section for defining types */
 #ifdef __cplusplus
 #include <cmath>
-#include <cassert>
 #include <cstdio>
 
 #else
 /* C99 compiler */
 #include <math.h>
-#include <assert.h>
 #include <stdio.h>
 
 #endif /* __cplusplus */
@@ -22,11 +20,26 @@ namespace ISMRMRD {
 extern "C" {
 #endif
 
+/* Error handling prototypes */
+typedef struct ISMRMRD_error_node {
+    struct ISMRMRD_error_node *next;
+    char *file;
+    char *func;
+    char *msg;
+    int line;
+    int code;
+} ISMRMRD_error_node_t;
+
+static void ismrmrd_error_default(const char *file, int line,
+        const char *func, int code, const char *msg);
+static ISMRMRD_error_node_t *error_stack_head = NULL;
+static ismrmrd_error_handler_t ismrmrd_error_handler = ismrmrd_error_default;
+
+
 /* Acquisition functions */
 int ismrmrd_init_acquisition_header(ISMRMRD_AcquisitionHeader *hdr) {
     if (hdr == NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
     }
 
     memset(hdr, 0, sizeof(ISMRMRD_AcquisitionHeader));
@@ -39,8 +52,7 @@ int ismrmrd_init_acquisition_header(ISMRMRD_AcquisitionHeader *hdr) {
 
 int ismrmrd_init_acquisition(ISMRMRD_Acquisition *acq) {
     if (acq == NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
     }
     ismrmrd_init_acquisition_header(&acq->head);
     acq->traj = NULL;
@@ -50,8 +62,7 @@ int ismrmrd_init_acquisition(ISMRMRD_Acquisition *acq) {
 
 int ismrmrd_cleanup_acquisition(ISMRMRD_Acquisition *acq) {
     if (acq == NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
     }
     
     free(acq->data);
@@ -64,12 +75,12 @@ int ismrmrd_cleanup_acquisition(ISMRMRD_Acquisition *acq) {
 ISMRMRD_Acquisition * ismrmrd_create_acquisition() {
     ISMRMRD_Acquisition *acq = (ISMRMRD_Acquisition *) malloc(sizeof(ISMRMRD_Acquisition));
     if (acq == NULL) {
-        ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to malloc new ISMRMRD_Acquistion.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to malloc new ISMRMRD_Acquistion.");
         return NULL;
     }
     if (ismrmrd_init_acquisition(acq) != ISMRMRD_NOERROR)
     {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Failed to initialize acquistion.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Failed to initialize acquistion.");
         return NULL;
     }
     return acq;
@@ -78,13 +89,11 @@ ISMRMRD_Acquisition * ismrmrd_create_acquisition() {
 int ismrmrd_free_acquisition(ISMRMRD_Acquisition *acq) {
 
     if (acq == NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
     }
     
     if (ismrmrd_cleanup_acquisition(acq)!=ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Failed to cleanup acquisition.");
-        return ISMRMRD_RUNTIMEERROR;        
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Failed to cleanup acquisition.");
     }
     free(acq);
     return ISMRMRD_NOERROR;
@@ -93,12 +102,10 @@ int ismrmrd_free_acquisition(ISMRMRD_Acquisition *acq) {
 int ismrmrd_copy_acquisition(ISMRMRD_Acquisition *acqdest, const ISMRMRD_Acquisition *acqsource) {
 
     if (acqsource==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Source pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Source pointer should not NULL.");
     }
     if (acqdest==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Destination pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Destination pointer should not NULL.");
     }
 
     /* Copy the header */
@@ -116,8 +123,7 @@ int ismrmrd_make_consistent_acquisition(ISMRMRD_Acquisition *acq) {
     size_t traj_size, data_size;
         
     if (acq==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
     }
 
     if (acq->head.available_channels < acq->head.active_channels) {
@@ -128,9 +134,8 @@ int ismrmrd_make_consistent_acquisition(ISMRMRD_Acquisition *acq) {
     if (traj_size > 0) {
         acq->traj = (float *)realloc(acq->traj, traj_size);
         if (acq->traj == NULL) {
-            ISMRMRD_THROW(ISMRMRD_MEMORYERROR,
+            return ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR,
                           "Failed to realloc acquisition trajectory array");
-            return ISMRMRD_MEMORYERROR;
         }
     }
         
@@ -138,9 +143,8 @@ int ismrmrd_make_consistent_acquisition(ISMRMRD_Acquisition *acq) {
     if (data_size > 0) {
         acq->data = (complex_float_t *)realloc(acq->data, data_size);
         if (acq->data == NULL) {
-            ISMRMRD_THROW(ISMRMRD_MEMORYERROR,
+            return ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR,
                           "Failed to realloc acquisition data array");
-            return ISMRMRD_MEMORYERROR;
         }
     }
 
@@ -152,7 +156,7 @@ size_t ismrmrd_size_of_acquisition_traj(const ISMRMRD_Acquisition *acq) {
     int num_traj;
     
     if (acq==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
         return 0;
     }
 
@@ -165,7 +169,7 @@ size_t ismrmrd_size_of_acquisition_data(const ISMRMRD_Acquisition *acq) {
     int num_data;
     
     if (acq==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
         return 0;
     }
 
@@ -177,8 +181,7 @@ size_t ismrmrd_size_of_acquisition_data(const ISMRMRD_Acquisition *acq) {
 /* Image functions */
 int ismrmrd_init_image_header(ISMRMRD_ImageHeader *hdr) {
     if (hdr==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
     }
     memset(hdr, 0, sizeof(ISMRMRD_ImageHeader));
     hdr->version = ISMRMRD_VERSION;
@@ -192,13 +195,11 @@ int ismrmrd_init_image_header(ISMRMRD_ImageHeader *hdr) {
 /* ImageHeader functions */
 int ismrmrd_init_image(ISMRMRD_Image *im) {
     if (im==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
     }
 
     if (ismrmrd_init_image_header(&im->head) != ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Failed to initialize image header.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Failed to initialize image header.");
     }
     im->attribute_string = NULL;
     im->data = NULL;
@@ -208,12 +209,12 @@ int ismrmrd_init_image(ISMRMRD_Image *im) {
 ISMRMRD_Image * ismrmrd_create_image() {
     ISMRMRD_Image *im = (ISMRMRD_Image *) malloc(sizeof(ISMRMRD_Image));
     if (im==NULL) {
-        ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to allocate new Image.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to allocate new Image.");
         return NULL;
     }
     
     if (ismrmrd_init_image(im) != ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Failed to initialize image.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Failed to initialize image.");
         return NULL;
     }
     return im;
@@ -221,8 +222,7 @@ ISMRMRD_Image * ismrmrd_create_image() {
 
 int ismrmrd_cleanup_image(ISMRMRD_Image *im) {
     if (im==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
     }
     free(im->attribute_string);
     im->attribute_string = NULL;
@@ -233,12 +233,10 @@ int ismrmrd_cleanup_image(ISMRMRD_Image *im) {
 
 int ismrmrd_free_image(ISMRMRD_Image *im) {
     if (im==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
     }        
     if (ismrmrd_cleanup_image(im) != ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Failed to clean up image.");
-        return ISMRMRD_RUNTIMEERROR;        
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Failed to clean up image.");
     }
     free(im);
     return ISMRMRD_NOERROR;
@@ -246,17 +244,14 @@ int ismrmrd_free_image(ISMRMRD_Image *im) {
 
 int ismrmrd_copy_image(ISMRMRD_Image *imdest, const ISMRMRD_Image *imsource) {
     if (imsource==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Source pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Source pointer should not NULL.");
     }
     if (imdest==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Destination pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Destination pointer should not NULL.");
     }
     memcpy(&imdest->head, &imsource->head, sizeof(ISMRMRD_ImageHeader));
     if (ismrmrd_make_consistent_image(imdest) != ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Failed to make image consistent.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Failed to make image consistent.");
     }
     memcpy(imdest->attribute_string, imsource->attribute_string,
            ismrmrd_size_of_image_attribute_string(imdest));
@@ -267,16 +262,14 @@ int ismrmrd_copy_image(ISMRMRD_Image *imdest, const ISMRMRD_Image *imsource) {
 int ismrmrd_make_consistent_image(ISMRMRD_Image *im) {
     size_t attr_size, data_size;
     if (im==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
     }
    
     attr_size = ismrmrd_size_of_image_attribute_string(im);
     if (attr_size > 0) {
         im->attribute_string = (char *)realloc(im->attribute_string, attr_size);
         if (im->attribute_string == NULL) {
-            ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to realloc image attribute string");
-            return ISMRMRD_MEMORYERROR;
+            return ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to realloc image attribute string");
         }
     }
         
@@ -284,8 +277,7 @@ int ismrmrd_make_consistent_image(ISMRMRD_Image *im) {
     if (data_size > 0) {
         im->data = realloc(im->data, data_size);
         if (im->data == NULL) {
-            ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to realloc image data array");
-            return ISMRMRD_MEMORYERROR;
+            return ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to realloc image data array");
         }
     }
     return ISMRMRD_NOERROR;
@@ -295,7 +287,7 @@ size_t ismrmrd_size_of_image_data(const ISMRMRD_Image *im) {
     size_t data_size = 0;
     int num_data;
     if (im==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not NULL.");
         return 0;
     }
 
@@ -328,7 +320,7 @@ size_t ismrmrd_size_of_image_data(const ISMRMRD_Image *im) {
             data_size = num_data * sizeof(complex_double_t);
             break;
         default:
-            ISMRMRD_THROW(ISMRMRD_TYPEERROR, "Invalid image data type");
+            ISMRMRD_PUSH_ERR(ISMRMRD_TYPEERROR, "Invalid image data type");
             data_size = 0;
     }
     return data_size;
@@ -336,7 +328,7 @@ size_t ismrmrd_size_of_image_data(const ISMRMRD_Image *im) {
 
 size_t ismrmrd_size_of_image_attribute_string(const ISMRMRD_Image *im) {
     if (im==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
         return 0;
     }
     return im->head.attribute_string_len * sizeof(*im->attribute_string);
@@ -347,7 +339,7 @@ int ismrmrd_init_ndarray(ISMRMRD_NDArray *arr) {
     int n;
 
     if (arr==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
         return ISMRMRD_RUNTIMEERROR;
     }
 
@@ -365,12 +357,12 @@ int ismrmrd_init_ndarray(ISMRMRD_NDArray *arr) {
 ISMRMRD_NDArray * ismrmrd_create_ndarray() {
     ISMRMRD_NDArray *arr = (ISMRMRD_NDArray *) malloc(sizeof(ISMRMRD_NDArray));
     if (arr==NULL) {
-        ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to malloc new ISMRMRD_NDArray.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to malloc new ISMRMRD_NDArray.");
         return NULL;
     }
         
     if (ismrmrd_init_ndarray(arr)!=ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Failed to initialize ndarray.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Failed to initialize ndarray.");
         return NULL;
     }
     return arr;
@@ -378,8 +370,7 @@ ISMRMRD_NDArray * ismrmrd_create_ndarray() {
 
 int ismrmrd_cleanup_ndarray(ISMRMRD_NDArray *arr) {
     if (arr==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
     }
 
     free(arr->data);
@@ -389,13 +380,11 @@ int ismrmrd_cleanup_ndarray(ISMRMRD_NDArray *arr) {
 
 int ismrmrd_free_ndarray(ISMRMRD_NDArray *arr) {
     if (arr==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
     }
 
     if (ismrmrd_cleanup_ndarray(arr)!=ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Failed to cleanup ndarray.");
-        return ISMRMRD_RUNTIMEERROR;        
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Failed to cleanup ndarray.");
     }
     free(arr);
     return ISMRMRD_NOERROR;
@@ -405,12 +394,10 @@ int ismrmrd_copy_ndarray(ISMRMRD_NDArray *arrdest, const ISMRMRD_NDArray *arrsou
     int n;
 
     if (arrsource==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Source pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Source pointer should not be NULL.");
     }
     if (arrdest==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Destination pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Destination pointer should not be NULL.");
     }
             
     arrdest->version = arrsource->version;
@@ -421,8 +408,7 @@ int ismrmrd_copy_ndarray(ISMRMRD_NDArray *arrdest, const ISMRMRD_NDArray *arrsou
         arrdest->dims[n] = arrsource->dims[n];
     }
     if (ismrmrd_make_consistent_ndarray(arrdest)!=ISMRMRD_NOERROR) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Failed to make ndarray consistent.");
-        return ISMRMRD_RUNTIMEERROR;        
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Failed to make ndarray consistent.");
     }
     memcpy(arrdest->data, arrsource->data, ismrmrd_size_of_ndarray_data(arrdest));
     return ISMRMRD_NOERROR;
@@ -432,16 +418,14 @@ int ismrmrd_make_consistent_ndarray(ISMRMRD_NDArray *arr) {
     size_t data_size;
     
     if (arr==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
     }
 
     data_size = ismrmrd_size_of_ndarray_data(arr);
     if (data_size > 0) {
         arr->data = realloc(arr->data, data_size);
         if (arr->data == NULL) {
-            ISMRMRD_THROW(ISMRMRD_MEMORYERROR, "Failed to realloc NDArray data array");
-            return ISMRMRD_MEMORYERROR;
+            return ISMRMRD_PUSH_ERR(ISMRMRD_MEMORYERROR, "Failed to realloc NDArray data array");
         }
     }
     return ISMRMRD_NOERROR;
@@ -453,7 +437,7 @@ size_t ismrmrd_size_of_ndarray_data(const ISMRMRD_NDArray *arr) {
     int n;
     
     if (arr==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
+        ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
         return 0;
     }
 
@@ -487,7 +471,7 @@ size_t ismrmrd_size_of_ndarray_data(const ISMRMRD_NDArray *arr) {
             data_size = num_data * sizeof(complex_double_t);
             break;
         default:
-            ISMRMRD_THROW(ISMRMRD_TYPEERROR, "Invalid NDArray data type");
+            ISMRMRD_PUSH_ERR(ISMRMRD_TYPEERROR, "Invalid NDArray data type");
             data_size = 0;
     }
         
@@ -503,8 +487,7 @@ bool ismrmrd_is_flag_set(const uint64_t flags, const uint64_t val) {
 int ismrmrd_set_flag(uint64_t *flags, const uint64_t val) {
     uint64_t bitmask;
     if (flags==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
     }
     bitmask = 1 << (val - 1);
     *flags |= bitmask;
@@ -514,8 +497,7 @@ int ismrmrd_set_flag(uint64_t *flags, const uint64_t val) {
 int ismrmrd_clear_flag(uint64_t *flags, const uint64_t val) {
     uint64_t bitmask;
     if (flags==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
     }
     bitmask = 1 << (val - 1);
     *flags &= ~bitmask;
@@ -524,40 +506,12 @@ int ismrmrd_clear_flag(uint64_t *flags, const uint64_t val) {
 
 int ismrmrd_clear_all_flags(uint64_t *flags) {
     if (flags==NULL) {
-        ISMRMRD_THROW(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
-        return ISMRMRD_RUNTIMEERROR;
+        return ISMRMRD_PUSH_ERR(ISMRMRD_RUNTIMEERROR, "Pointer should not be NULL.");
     }
     *flags = 0;
     return ISMRMRD_NOERROR;
 }
 
-static void ismrmrd_error_default(const char *file, int line, const char *func, int err, char *msg)
-{
-    char *msgtype = ismrmrd_strerror(err);
-    fprintf(stderr, "ERROR: %s in %s, line %d: %s\n", msgtype, file, line, msg);
-}
-
-ismrmrd_error_handler_t ismrmrd_error_handler = ismrmrd_error_default;
-
-void ismrmrd_set_error_handler(ismrmrd_error_handler_t handler) {
-    ismrmrd_error_handler = handler;
-}
-
-char *ismrmrd_strerror(int err) {
-    /* Match the ISMRMRD_ErrorCodes */
-    char *error_messages[] = {
-        "No Error",
-        "Memory Error",
-        "File Error",
-        "Runtime Error"
-    };
-    
-    assert(err > ISMRMRD_BEGINERROR);
-    assert(err < ISMRMRD_ENDERROR);
-    
-    return error_messages[err];
-}
-
 int ismrmrd_sign_of_directions(float read_dir[3], float phase_dir[3], float slice_dir[3]) {
     float r11 = read_dir[0], r12 = phase_dir[0], r13 = slice_dir[0];
     float r21 = read_dir[1], r22 = phase_dir[1], r23 = slice_dir[1];
@@ -665,6 +619,94 @@ void ismrmrd_quaternion_to_directions(float quat[4], float read_dir[3],
     slice_dir[2] = 1.0f - 2.0f * (a * a + b * b);
 }
 
+/**
+ * Saves error information on the error stack
+ * @returns error code
+ */
+int ismrmrd_push_error(const char *file, const int line, const char *func,
+        const int code, const char *msg)
+{
+    ISMRMRD_error_node_t *node = NULL;
+
+    /* Call user-defined error handler if it exists */
+    if (ismrmrd_error_handler != NULL) {
+        ismrmrd_error_handler(file, line, func, code, msg);
+    }
+
+    /* Save error information on error stack */
+    node = (ISMRMRD_error_node_t*)calloc(1, sizeof(*node));
+    if (node == NULL) {
+        /* TODO: how to handle this? */
+        return ISMRMRD_MEMORYERROR;
+    }
+
+    node->next = error_stack_head;
+    error_stack_head = node;
+
+    node->file = (char*)file;
+    node->line = line;
+    node->func = (char*)func;
+    node->code = code;
+    node->msg = (char*)msg;
+
+    return code;
+}
+
+bool ismrmrd_pop_error(char **file, int *line, char **func,
+        int *code, char **msg)
+{
+    ISMRMRD_error_node_t *node = error_stack_head;
+    if (node == NULL) {
+        /* nothing to pop */
+        return false;
+    }
+
+    /* pop head off stack */
+    error_stack_head = node->next;
+
+    if (file != NULL) {
+        *file = node->file;
+    }
+    if (line != NULL) {
+        *line = node->line;
+    }
+    if (func != NULL) {
+        *func = node->func;
+    }
+    if (code != NULL) {
+        *code = node->code;
+    }
+    if (msg != NULL) {
+        *msg = node->msg;
+    }
+
+    free(node);
+    return true;
+}
+
+void ismrmrd_set_error_handler(ismrmrd_error_handler_t handler) {
+    ismrmrd_error_handler = handler;
+}
+
+char *ismrmrd_strerror(int code) {
+    /* Match the ISMRMRD_ErrorCodes */
+    static char * const error_messages []= {
+        "No Error",
+        "Memory Error",
+        "File Error",
+        "Type Error",
+        "Runtime Error"
+    };
+    return error_messages[code];
+}
+
+static void ismrmrd_error_default(const char *file, int line,
+        const char *func, int code, const char *msg)
+{
+    char *msgtype = ismrmrd_strerror(code);
+    fprintf(stderr, "ERROR: %s in %s, line %d: %s\n", msgtype, file, line, msg);
+}
+
 #ifdef __cplusplus
 } // extern "C"
 } // namespace ISMRMRD

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/ismrmrd.git



More information about the debian-science-commits mailing list