From 9457a826d2c960da15d394837a05d028b0202fe3 Mon Sep 17 00:00:00 2001 From: q-posev Date: Wed, 22 Sep 2021 14:50:22 +0200 Subject: [PATCH 1/4] return error code from trexio_open [C, Fortran] --- src/templates_front/templator_front.org | 44 +++++++++++++++++-------- tests/io_all.c | 10 +++--- tests/io_dset_float_hdf5.c | 6 ++-- tests/io_dset_float_text.c | 6 ++-- tests/io_dset_int_hdf5.c | 6 ++-- tests/io_dset_int_text.c | 6 ++-- tests/io_dset_str_hdf5.c | 6 ++-- tests/io_dset_str_text.c | 6 ++-- tests/io_num_hdf5.c | 6 ++-- tests/io_num_text.c | 6 ++-- tests/io_safe_dset_float_hdf5.c | 6 ++-- tests/io_safe_dset_float_text.c | 6 ++-- tests/io_str_hdf5.c | 6 ++-- tests/io_str_text.c | 6 ++-- tests/open_hdf5.c | 9 +++-- tests/open_text.c | 9 +++-- tests/overwrite_all_hdf5.c | 4 +-- tests/overwrite_all_text.c | 4 +-- tests/test_f.f90 | 37 +++++++++++++++++++-- 19 files changed, 122 insertions(+), 67 deletions(-) diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org index cc0d2c6..44728df 100644 --- a/src/templates_front/templator_front.org +++ b/src/templates_front/templator_front.org @@ -703,23 +703,33 @@ struct trexio_back_end_s { *** C #+begin_src c :tangle prefix_front.h :exports none -trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t back_end); +trexio_t* trexio_open(const char* file_name, const char mode, + const back_end_t back_end, trexio_exit_code* const rc_open); #+end_src #+begin_src c :tangle prefix_front.c trexio_t* trexio_open(const char* file_name, const char mode, - const back_end_t back_end) + const back_end_t back_end, trexio_exit_code* const rc_open) { - if (file_name == NULL) return NULL; - if (file_name[0] == '\0') return NULL; + if (file_name == NULL || file_name[0] == '\0') { + *rc_open = TREXIO_INVALID_ARG_1; + return NULL; + } /* Check overflow in file_name */ - if (back_end < 0) return NULL; - if (back_end >= TREXIO_INVALID_BACK_END) return NULL; + if (back_end < 0 || back_end >= TREXIO_INVALID_BACK_END) { + *rc_open = TREXIO_INVALID_ARG_3; + return NULL; + } - if (mode != 'r' && mode != 'w') return NULL; + if (mode != 'r' && mode != 'w') { + *rc_open = TREXIO_INVALID_ARG_2; + return NULL; + } + + if (rc_open == NULL) return NULL; trexio_t* result = NULL; void* result_tmp = NULL; @@ -744,17 +754,18 @@ trexio_open(const char* file_name, const char mode, assert (result != NULL); /* TODO: Error handling */ - /* Data for the parent type */ strncpy(result->file_name, file_name, TREXIO_MAX_FILENAME_LENGTH); if (result->file_name[TREXIO_MAX_FILENAME_LENGTH-1] != '\0') { + *rc_open = TREXIO_INVALID_ARG_1; free(result); return NULL; } strncpy(result->version, PACKAGE_VERSION, 16); if (result->version[15] != '\0') { + *rc_open = TREXIO_FAILURE; free(result); return NULL; } @@ -792,12 +803,14 @@ trexio_open(const char* file_name, const char mode, } if (rc != TREXIO_SUCCESS) { + *rc_open = TREXIO_OPEN_ERROR; free(result); return NULL; } rc = trexio_has_metadata_package_version(result); if (rc == TREXIO_FAILURE) { + *rc_open = TREXIO_OPEN_ERROR; free(result); return NULL; } @@ -821,6 +834,7 @@ trexio_open(const char* file_name, const char mode, } if (rc != TREXIO_SUCCESS) { + *rc_open = TREXIO_OPEN_ERROR; free(result); return NULL; } @@ -847,10 +861,12 @@ trexio_open(const char* file_name, const char mode, } if (rc != TREXIO_SUCCESS) { + *rc_open = TREXIO_LOCK_ERROR; free(result); return NULL; } + *rc_open = TREXIO_SUCCESS; return result; } #+end_src @@ -859,12 +875,13 @@ trexio_open(const char* file_name, const char mode, #+begin_src f90 :tangle prefix_fortran.f90 interface - integer(8) function trexio_open_c (filename, mode, backend) bind(C, name="trexio_open") + integer(8) function trexio_open_c (filename, mode, backend, rc_open) bind(C, name="trexio_open") use, intrinsic :: iso_c_binding import character(kind=c_char), dimension(*) :: filename character, intent(in), value :: mode integer(trexio_backend), intent(in), value :: backend + integer(trexio_exit_code), intent(out) :: rc_open end function trexio_open_c end interface #+end_src @@ -3056,18 +3073,19 @@ def has_$group_str$(trexio_file) -> bool: #+begin_src f90 :tangle helper_fortran.f90 contains - integer(8) function trexio_open (filename, mode, backend) + integer(8) function trexio_open (filename, mode, backend, rc_open) use, intrinsic :: iso_c_binding, only : c_null_char implicit none character(len=*), intent(in) :: filename character, intent(in), value :: mode integer(trexio_backend), intent(in), value :: backend + integer(trexio_exit_code), intent(out) :: rc_open character(len=len_trim(filename)+1) :: filename_c - integer :: rc + integer(trexio_exit_code) :: rc filename_c = trim(filename) // c_null_char - trexio_open = trexio_open_c(filename_c, mode, backend) - if (trexio_open == 0_8) then + trexio_open = trexio_open_c(filename_c, mode, backend, rc_open) + if (trexio_open == 0_8 .or. rc_open /= TREXIO_SUCCESS) then return endif rc = trexio_set_one_based(trexio_open) diff --git a/tests/io_all.c b/tests/io_all.c index 4f4709c..81179cf 100644 --- a/tests/io_all.c +++ b/tests/io_all.c @@ -72,7 +72,7 @@ int test_write(const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // check that certain data does not exist in the file @@ -97,7 +97,7 @@ int test_write(const char* file_name, const back_end_t backend) { assert (rc == TREXIO_SUCCESS); // reopen file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // check if the written data exists in the file @@ -125,7 +125,7 @@ int test_write(const char* file_name, const back_end_t backend) { assert (rc == TREXIO_SUCCESS); // open file again in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write some missing blocks (e.g. if forgot last time) @@ -156,7 +156,7 @@ int test_read(const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open existing file on 'read' mode [created by test_write] - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read nucleus_num @@ -211,7 +211,7 @@ int test_read(const char* file_name, const back_end_t backend) { const char* file_name2 = "test_nonexisting"; trexio_t* file2 = NULL; - file2 = trexio_open(file_name2, 'r', backend); + file2 = trexio_open(file_name2, 'r', backend, &rc); assert (file2 == NULL); /*================= END OF TEST =====================*/ diff --git a/tests/io_dset_float_hdf5.c b/tests/io_dset_float_hdf5.c index d645808..90174cd 100644 --- a/tests/io_dset_float_hdf5.c +++ b/tests/io_dset_float_hdf5.c @@ -34,7 +34,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -65,7 +65,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written dataset exists @@ -100,7 +100,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_dset_float_text.c b/tests/io_dset_float_text.c index 4e21d25..f083ce9 100644 --- a/tests/io_dset_float_text.c +++ b/tests/io_dset_float_text.c @@ -34,7 +34,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -65,7 +65,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written dataset exists @@ -100,7 +100,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_dset_int_hdf5.c b/tests/io_dset_int_hdf5.c index 7d9e1a6..49ff5bb 100644 --- a/tests/io_dset_int_hdf5.c +++ b/tests/io_dset_int_hdf5.c @@ -21,7 +21,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -52,7 +52,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written dataset exists @@ -87,7 +87,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_dset_int_text.c b/tests/io_dset_int_text.c index 1544327..ca6ded2 100644 --- a/tests/io_dset_int_text.c +++ b/tests/io_dset_int_text.c @@ -21,7 +21,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -52,7 +52,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written dataset exists @@ -87,7 +87,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_dset_str_hdf5.c b/tests/io_dset_str_hdf5.c index cb97f42..fed85bc 100644 --- a/tests/io_dset_str_hdf5.c +++ b/tests/io_dset_str_hdf5.c @@ -33,7 +33,7 @@ static int test_write_dset_str (const char* file_name, const back_end_t backend) /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -65,7 +65,7 @@ static int test_has_dset_str (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written dataset of strings exists @@ -100,7 +100,7 @@ static int test_read_dset_str (const char* file_name, const back_end_t backend) /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_dset_str_text.c b/tests/io_dset_str_text.c index 1d8e7dd..8917155 100644 --- a/tests/io_dset_str_text.c +++ b/tests/io_dset_str_text.c @@ -33,7 +33,7 @@ static int test_write_dset_str (const char* file_name, const back_end_t backend) /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -65,7 +65,7 @@ static int test_has_dset_str (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written dataset of strings exists @@ -100,7 +100,7 @@ static int test_read_dset_str (const char* file_name, const back_end_t backend) /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_num_hdf5.c b/tests/io_num_hdf5.c index 8cac31c..e057236 100644 --- a/tests/io_num_hdf5.c +++ b/tests/io_num_hdf5.c @@ -20,7 +20,7 @@ static int test_write_num (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -55,7 +55,7 @@ static int test_has_num (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written num variable exists @@ -90,7 +90,7 @@ static int test_read_num (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_num_text.c b/tests/io_num_text.c index 9f779cd..3c299aa 100644 --- a/tests/io_num_text.c +++ b/tests/io_num_text.c @@ -20,7 +20,7 @@ static int test_write_num (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -55,7 +55,7 @@ static int test_has_num (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written num variable exists @@ -90,7 +90,7 @@ static int test_read_num (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_safe_dset_float_hdf5.c b/tests/io_safe_dset_float_hdf5.c index f70fad7..318ed4a 100644 --- a/tests/io_safe_dset_float_hdf5.c +++ b/tests/io_safe_dset_float_hdf5.c @@ -35,7 +35,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -75,7 +75,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written dataset exists @@ -106,7 +106,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_safe_dset_float_text.c b/tests/io_safe_dset_float_text.c index 709abd0..2d339a0 100644 --- a/tests/io_safe_dset_float_text.c +++ b/tests/io_safe_dset_float_text.c @@ -35,7 +35,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write numerical attribute in an empty file @@ -75,7 +75,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written dataset exists @@ -106,7 +106,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read numerical attribute from the file diff --git a/tests/io_str_hdf5.c b/tests/io_str_hdf5.c index 251b5e3..eaafff0 100644 --- a/tests/io_str_hdf5.c +++ b/tests/io_str_hdf5.c @@ -21,7 +21,7 @@ static int test_write_str (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write string attribute in an empty file @@ -49,7 +49,7 @@ static int test_has_str (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written string attribute exists @@ -83,7 +83,7 @@ static int test_read_str (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read string attribute from the file diff --git a/tests/io_str_text.c b/tests/io_str_text.c index d74e7d2..59cfc05 100644 --- a/tests/io_str_text.c +++ b/tests/io_str_text.c @@ -21,7 +21,7 @@ static int test_write_str (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write string attribute in an empty file @@ -49,7 +49,7 @@ static int test_has_str (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // check that the previously written string attribute exists @@ -83,7 +83,7 @@ static int test_read_str (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); // read string attribute from the file diff --git a/tests/open_hdf5.c b/tests/open_hdf5.c index 88ef17f..20289e9 100644 --- a/tests/open_hdf5.c +++ b/tests/open_hdf5.c @@ -19,8 +19,9 @@ static int test_open_w (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); + assert (rc == TREXIO_SUCCESS); // close current session rc = trexio_close(file); @@ -42,8 +43,9 @@ static int test_open_r (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); + assert (rc == TREXIO_SUCCESS); // close current session rc = trexio_close(file); @@ -65,8 +67,9 @@ static int test_open_void (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file == NULL); + fprintf(stderr, "%s \n", trexio_string_of_error(rc)); /*================= END OF TEST ==================*/ diff --git a/tests/open_text.c b/tests/open_text.c index 4b16311..73f0b1b 100644 --- a/tests/open_text.c +++ b/tests/open_text.c @@ -19,8 +19,9 @@ static int test_open_w (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); + assert (rc == TREXIO_SUCCESS); // close current session rc = trexio_close(file); @@ -42,8 +43,9 @@ static int test_open_r (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file != NULL); + assert (rc == TREXIO_SUCCESS); // close current session rc = trexio_close(file); @@ -65,8 +67,9 @@ static int test_open_void (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'read' mode - file = trexio_open(file_name, 'r', backend); + file = trexio_open(file_name, 'r', backend, &rc); assert (file == NULL); + fprintf(stderr, "%s \n", trexio_string_of_error(rc)); /*================= END OF TEST ==================*/ diff --git a/tests/overwrite_all_hdf5.c b/tests/overwrite_all_hdf5.c index ae0bad7..bcbbaf5 100644 --- a/tests/overwrite_all_hdf5.c +++ b/tests/overwrite_all_hdf5.c @@ -47,7 +47,7 @@ static int test_write (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write the data @@ -95,7 +95,7 @@ static int test_overwrite (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // check that the previously written data cannot be overwritten diff --git a/tests/overwrite_all_text.c b/tests/overwrite_all_text.c index 4e5ef42..11e5518 100644 --- a/tests/overwrite_all_text.c +++ b/tests/overwrite_all_text.c @@ -47,7 +47,7 @@ static int test_write (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // write the data @@ -95,7 +95,7 @@ static int test_overwrite (const char* file_name, const back_end_t backend) { /*================= START OF TEST ==================*/ // open file in 'write' mode - file = trexio_open(file_name, 'w', backend); + file = trexio_open(file_name, 'w', backend, &rc); assert (file != NULL); // check that the previously written data cannot be overwritten diff --git a/tests/test_f.f90 b/tests/test_f.f90 index 1f0c230..42f9387 100644 --- a/tests/test_f.f90 +++ b/tests/test_f.f90 @@ -9,12 +9,16 @@ program test_trexio call test_read('test_write_f.dir', TREXIO_TEXT) call system('rm -rf test_write_f.dir') + call test_read_void('test_write_f.dir', TREXIO_TEXT) + call system('rm -rf test_write_f.h5') print *, 'call test_write(''test_write_f.h5'', TREXIO_HDF5)' call test_write('test_write_f.h5', TREXIO_HDF5) print *, 'call test_read(''test_write_f.h5'', TREXIO_HDF5)' call test_read('test_write_f.h5', TREXIO_HDF5) call system('rm -rf test_write_f.h5') + + call test_read_void('test_write_f.h5', TREXIO_HDF5) end program test_trexio @@ -68,7 +72,8 @@ subroutine test_write(file_name, back_end) ! ================= START OF TEST ===================== ! - trex_file = trexio_open(file_name, 'w', back_end) + trex_file = trexio_open(file_name, 'w', back_end, rc) + call trexio_assert(rc, TREXIO_SUCCESS) rc = trexio_has_nucleus_num(trex_file) call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 1') @@ -144,8 +149,8 @@ subroutine test_read(file_name, back_end) ! ================= START OF TEST ===================== ! - trex_file = trexio_open(file_name, 'r', back_end) - + trex_file = trexio_open(file_name, 'r', back_end, rc) + call trexio_assert(rc, TREXIO_SUCCESS) rc = trexio_read_nucleus_num(trex_file, num_read) call trexio_assert(rc, TREXIO_SUCCESS) @@ -214,3 +219,29 @@ subroutine test_read(file_name, back_end) end subroutine test_read +subroutine test_read_void(file_name, back_end) + +! ============ Test read of non-existing file =============== ! + + use trexio + implicit none + + character*(*), intent(in) :: file_name + integer, intent(in) :: back_end + + integer(8) :: trex_file + integer :: rc = 1 + character(128) :: str + +! ================= START OF TEST ===================== ! + + trex_file = trexio_open(file_name, 'r', back_end, rc) + call trexio_assert(rc, TREXIO_OPEN_ERROR) + + call trexio_string_of_error(rc, str) + print *, trim(str) + +! ================= END OF TEST ===================== ! + +end subroutine test_read_void + From 67b00efa9cb729c18515051a54511a70594c4b48 Mon Sep 17 00:00:00 2001 From: q-posev Date: Wed, 22 Sep 2021 16:40:55 +0200 Subject: [PATCH 2/4] handle return error of trexio_open in the Python API --- python/test/test_api.py | 19 ++++++++++++++++--- src/pytrexio.i | 1 + src/templates_front/templator_front.org | 17 ++++++++++++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/python/test/test_api.py b/python/test/test_api.py index ae1a1ab..f6b151d 100644 --- a/python/test/test_api.py +++ b/python/test/test_api.py @@ -49,7 +49,7 @@ nucleus_num = 12 try: trexio.write_nucleus_num(test_file, -100) except trexio.Error: - print("Writing negative nucleus_num: checked.") + print("Raise error for an attempt to write negative nucleus_num: checked.") # write nucleus_num in the file try: @@ -60,7 +60,7 @@ except: try: trexio.write_nucleus_num(test_file, nucleus_num*2) except trexio.Error: - print("Attempt to overwrite nucleus_num: checked.") + print("Raise error for an attempt to overwrite nucleus_num: checked.") # initialize charge arrays as a list and convert it to numpy array charges = [6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1.] @@ -199,7 +199,7 @@ assert rpoint_group==point_group if trexio.has_mo_num(test_file2): rmo_num = trexio.read_mo_num(test_file2) else: - print("Not reading the non-existing variable mo_num.") + print("Pass on reading the non-existing variable mo_num: checked") # close TREXIO file #trexio.close(test_file2) @@ -215,3 +215,16 @@ except: #==========================================================# +#==========================================================# +#======= OPEN NON-EXISTING FILE TO TEST TREXIO.OPEN =======# +#==========================================================# + +try: + void_file = trexio.File('non_existing.file', 'r', TEST_TREXIO_BACKEND) +except trexio.Error as e: + if e.error == trexio.TREXIO_OPEN_ERROR: + print("Opening non-existing file returns TREXIO_OPEN_ERROR: checked") + else: + raise ValueError("[DEV]: error handling of trexio_open function has changed; check the consistency") + +#==========================================================# diff --git a/src/pytrexio.i b/src/pytrexio.i index 1665eb9..87da064 100644 --- a/src/pytrexio.i +++ b/src/pytrexio.i @@ -37,6 +37,7 @@ %apply int *OUTPUT { int64_t* const num}; %apply float *OUTPUT { float* const num}; %apply float *OUTPUT { double* const num}; +%apply int *OUTPUT { trexio_exit_code* const rc_open}; /* Does not work for arrays (SIGSEGV) */ diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org index 44728df..10629ec 100644 --- a/src/templates_front/templator_front.org +++ b/src/templates_front/templator_front.org @@ -911,11 +911,22 @@ def open(file_name: str, mode: str, back_end: int): >>> trex_file = tr_open("example.h5", "w", TREXIO_HDF5) """ + # The new trexio_open function is capable of returning error code which SWIG can append to the output trexio_s file struct + # However, if trexio_s* == NULL, then SWIG returns only an error code rc_open instead of a list [trexio_s, rc_open] + # Thus, the following try/except sequence is needed try: - trexio_file = pytr.trexio_open(file_name, mode, back_end) - assert trexio_file is not None + return_obj = pytr.trexio_open(file_name, mode, back_end) + assert return_obj is not None + if isinstance(return_obj, int): + raise Error(return_obj) + else: + rc_open = return_obj[1] + # this is a sanity check in case the code evolves and SWIG issue is patched + if rc_open == TREXIO_SUCCESS: + trexio_file = return_obj[0] + assert trexio_file is not None except AssertionError: - raise Exception(f"Could not open TREXIO file {file_name} using trexio_open function. Please make sure that there are no typos in the file name.") + raise Exception(f"Could not open TREXIO file {file_name} using trexio_open function. The return value is None (NULL pointer).") return trexio_file #+end_src From 8ef0c1963f00866829c9afa74e858606092be7d7 Mon Sep 17 00:00:00 2001 From: q-posev Date: Wed, 22 Sep 2021 16:43:18 +0200 Subject: [PATCH 3/4] add unit tests in C for trexio_open errors --- tests/open_hdf5.c | 29 ++++++++++++++++++++++++----- tests/open_text.c | 29 ++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/tests/open_hdf5.c b/tests/open_hdf5.c index 20289e9..20bc339 100644 --- a/tests/open_hdf5.c +++ b/tests/open_hdf5.c @@ -57,18 +57,37 @@ static int test_open_r (const char* file_name, const back_end_t backend) { } -static int test_open_void (const char* file_name, const back_end_t backend) { +static int test_open_errors (const back_end_t backend) { -/* Try to open the non-existing TREXIO file in 'read' mode */ +/* Try to call trexio_open with bad arguments */ trexio_t* file = NULL; trexio_exit_code rc; /*================= START OF TEST ==================*/ - // open file in 'read' mode - file = trexio_open(file_name, 'r', backend, &rc); + // open non-existing file in 'r' (read) mode, should return TREXIO_OPEN_ERROR + file = trexio_open(TREXIO_VOID, 'r', backend, &rc); assert (file == NULL); + assert (rc == TREXIO_OPEN_ERROR); + fprintf(stderr, "%s \n", trexio_string_of_error(rc)); + + // open file with empty file name, should return TREXIO_INVALID_ARG_1 + file = trexio_open("", 'w', backend, &rc); + assert (file == NULL); + assert (rc == TREXIO_INVALID_ARG_1); + fprintf(stderr, "%s \n", trexio_string_of_error(rc)); + + // open existing file in non-supported I/O mode, should return TREXIO_INVALID_ARG_2 + file = trexio_open(TREXIO_FILE, 'k', backend, &rc); + assert (file == NULL); + assert (rc == TREXIO_INVALID_ARG_2); + fprintf(stderr, "%s \n", trexio_string_of_error(rc)); + + // open existing file with non-supported back end, should return TREXIO_INVALID_ARG_3 + file = trexio_open(TREXIO_VOID, 'w', 666, &rc); + assert (file == NULL); + assert (rc == TREXIO_INVALID_ARG_3); fprintf(stderr, "%s \n", trexio_string_of_error(rc)); /*================= END OF TEST ==================*/ @@ -87,7 +106,7 @@ int main(void) { test_open_w (TREXIO_FILE, TEST_BACKEND); test_open_r (TREXIO_FILE, TEST_BACKEND); - test_open_void (TREXIO_VOID, TEST_BACKEND); + test_open_errors(TEST_BACKEND); rc = system(RM_COMMAND); assert (rc == 0); diff --git a/tests/open_text.c b/tests/open_text.c index 73f0b1b..0aa904a 100644 --- a/tests/open_text.c +++ b/tests/open_text.c @@ -57,18 +57,37 @@ static int test_open_r (const char* file_name, const back_end_t backend) { } -static int test_open_void (const char* file_name, const back_end_t backend) { +static int test_open_errors (const back_end_t backend) { -/* Try to open the non-existing TREXIO file in 'read' mode */ +/* Try to call trexio_open with bad arguments */ trexio_t* file = NULL; trexio_exit_code rc; /*================= START OF TEST ==================*/ - // open file in 'read' mode - file = trexio_open(file_name, 'r', backend, &rc); + // open non-existing file in 'r' (read) mode, should return TREXIO_OPEN_ERROR + file = trexio_open(TREXIO_VOID, 'r', backend, &rc); assert (file == NULL); + assert (rc == TREXIO_OPEN_ERROR); + fprintf(stderr, "%s \n", trexio_string_of_error(rc)); + + // open file with empty file name, should return TREXIO_INVALID_ARG_1 + file = trexio_open("", 'w', backend, &rc); + assert (file == NULL); + assert (rc == TREXIO_INVALID_ARG_1); + fprintf(stderr, "%s \n", trexio_string_of_error(rc)); + + // open existing file in non-supported I/O mode, should return TREXIO_INVALID_ARG_2 + file = trexio_open(TREXIO_FILE, 'k', backend, &rc); + assert (file == NULL); + assert (rc == TREXIO_INVALID_ARG_2); + fprintf(stderr, "%s \n", trexio_string_of_error(rc)); + + // open existing file with non-supported back end, should return TREXIO_INVALID_ARG_3 + file = trexio_open(TREXIO_VOID, 'w', 666, &rc); + assert (file == NULL); + assert (rc == TREXIO_INVALID_ARG_3); fprintf(stderr, "%s \n", trexio_string_of_error(rc)); /*================= END OF TEST ==================*/ @@ -87,7 +106,7 @@ int main(void) { test_open_w (TREXIO_FILE, TEST_BACKEND); test_open_r (TREXIO_FILE, TEST_BACKEND); - test_open_void (TREXIO_VOID, TEST_BACKEND); + test_open_errors(TEST_BACKEND); rc = system(RM_COMMAND); assert (rc == 0); From 2e2dac3982bbc9b2cc6bf924d96e44760c14e1fc Mon Sep 17 00:00:00 2001 From: q-posev Date: Fri, 24 Sep 2021 12:23:59 +0200 Subject: [PATCH 4/4] modify rc_open only if it is not a NULL pointer --- src/templates_front/templator_front.org | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org index 10629ec..b1a6d6e 100644 --- a/src/templates_front/templator_front.org +++ b/src/templates_front/templator_front.org @@ -714,23 +714,21 @@ trexio_open(const char* file_name, const char mode, { if (file_name == NULL || file_name[0] == '\0') { - *rc_open = TREXIO_INVALID_ARG_1; + if (rc_open != NULL) *rc_open = TREXIO_INVALID_ARG_1; return NULL; } /* Check overflow in file_name */ if (back_end < 0 || back_end >= TREXIO_INVALID_BACK_END) { - *rc_open = TREXIO_INVALID_ARG_3; + if (rc_open != NULL) *rc_open = TREXIO_INVALID_ARG_3; return NULL; } if (mode != 'r' && mode != 'w') { - *rc_open = TREXIO_INVALID_ARG_2; + if (rc_open != NULL) *rc_open = TREXIO_INVALID_ARG_2; return NULL; } - if (rc_open == NULL) return NULL; - trexio_t* result = NULL; void* result_tmp = NULL; @@ -758,14 +756,14 @@ trexio_open(const char* file_name, const char mode, strncpy(result->file_name, file_name, TREXIO_MAX_FILENAME_LENGTH); if (result->file_name[TREXIO_MAX_FILENAME_LENGTH-1] != '\0') { - *rc_open = TREXIO_INVALID_ARG_1; + if (rc_open != NULL) *rc_open = TREXIO_INVALID_ARG_1; free(result); return NULL; } strncpy(result->version, PACKAGE_VERSION, 16); if (result->version[15] != '\0') { - *rc_open = TREXIO_FAILURE; + if (rc_open != NULL) *rc_open = TREXIO_FAILURE; free(result); return NULL; } @@ -803,14 +801,14 @@ trexio_open(const char* file_name, const char mode, } if (rc != TREXIO_SUCCESS) { - *rc_open = TREXIO_OPEN_ERROR; + if (rc_open != NULL) *rc_open = TREXIO_OPEN_ERROR; free(result); return NULL; } rc = trexio_has_metadata_package_version(result); if (rc == TREXIO_FAILURE) { - *rc_open = TREXIO_OPEN_ERROR; + if (rc_open != NULL) *rc_open = TREXIO_OPEN_ERROR; free(result); return NULL; } @@ -834,7 +832,7 @@ trexio_open(const char* file_name, const char mode, } if (rc != TREXIO_SUCCESS) { - *rc_open = TREXIO_OPEN_ERROR; + if (rc_open != NULL) *rc_open = TREXIO_OPEN_ERROR; free(result); return NULL; } @@ -861,12 +859,12 @@ trexio_open(const char* file_name, const char mode, } if (rc != TREXIO_SUCCESS) { - *rc_open = TREXIO_LOCK_ERROR; + if (rc_open != NULL) *rc_open = TREXIO_LOCK_ERROR; free(result); return NULL; } - *rc_open = TREXIO_SUCCESS; + if (rc_open != NULL) *rc_open = TREXIO_SUCCESS; return result; } #+end_src