1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2025-01-11 05:28:33 +01:00

Table to generate error codes and string_of_error function

This commit is contained in:
Anthony Scemama 2021-04-01 22:48:04 +02:00
parent 0419a8c87b
commit 4e47e497d5
4 changed files with 309 additions and 130 deletions

View File

@ -26,17 +26,27 @@ rm -f -- templates_front/populated/*
rm -f -- templates_text/populated/* rm -f -- templates_text/populated/*
rm -f -- templates_hdf5/populated/* rm -f -- templates_hdf5/populated/*
function tangle()
{
local command="(org-babel-tangle-file \"$1\")"
emacs --batch \
--eval "(require 'org)" \
--eval "(org-babel-do-load-languages 'org-babel-load-languages '((python . t)))" \
--eval "(setq org-confirm-babel-evaluate nil)" \
--eval "$command"
}
echo "tangle org files to generate templates" echo "tangle org files to generate templates"
cd templates_front cd templates_front
emacs --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "templator_front.org")' tangle templator_front.org
cd .. cd ..
cd templates_text cd templates_text
emacs --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "templator_text.org")' tangle templator_text.org
cd .. cd ..
cd templates_hdf5 cd templates_hdf5
emacs --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "templator_hdf5.org")' tangle templator_hdf5.org
cd .. cd ..
echo "run generator script to populate templates" echo "run generator script to populate templates"

View File

@ -1,6 +1,6 @@
#+Title: Templator for frontend #+Title: Templator for frontend
* Constant file prefixes (not used by generator) :noxport: * Constant file prefixes (not used by generator) :noexport:
#+NAME:header #+NAME:header
#+begin_src c #+begin_src c
@ -11,31 +11,19 @@
#+end_src #+end_src
#+begin_src fortran :tangle prefix_fortran.f90 :noweb yes #+begin_src f90 :tangle prefix_fortran.f90 :noweb yes
module trexio module trexio
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
implicit none implicit none
integer, parameter :: trexio_exit_code = 4
integer, parameter :: TREXIO_HDF5 = 0 integer, parameter :: TREXIO_HDF5 = 0
integer, parameter :: TREXIO_TEXT = 1 integer, parameter :: TREXIO_TEXT = 1
! integer, parameter :: TREXIO_JSON = 2 ! integer, parameter :: TREXIO_JSON = 2
integer, parameter :: TREXIO_INVALID_BACK_END = 3 integer, parameter :: TREXIO_INVALID_BACK_END = 3
#+end_src
integer, parameter :: TREXIO_FAILURE = -1
integer, parameter :: TREXIO_SUCCESS = 0
integer, parameter :: TREXIO_INVALID_ARG_1 = 1
integer, parameter :: TREXIO_INVALID_ARG_2 = 2
integer, parameter :: TREXIO_INVALID_ARG_3 = 3
integer, parameter :: TREXIO_INVALID_ARG_4 = 4
integer, parameter :: TREXIO_INVALID_ARG_5 = 5
integer, parameter :: TREXIO_END = 10
integer, parameter :: TREXIO_READONLY = 11
integer, parameter :: TREXIO_ERRNO = 12
integer, parameter :: TREXIO_INVALID_ID = 20
integer, parameter :: TREXIO_ALLOCATION_FAILED = 21
integer, parameter :: TREXIO_INVALID_NUM = 22
integer, parameter :: TREXIO_HAS_NOT = 30
#+end_src #+end_src
@ -46,6 +34,7 @@ module trexio
#include <stdint.h> #include <stdint.h>
typedef int32_t trexio_exit_code;
#+end_src #+end_src
#+begin_src c :tangle prefix_front.c :noweb yes #+begin_src c :tangle prefix_front.c :noweb yes
@ -110,11 +99,55 @@ module trexio
All calls to TREXIO are thread-safe. All calls to TREXIO are thread-safe.
** Error handling ** Error handling
#+begin_src c :tangle prefix_front.h
typedef int32_t trexio_exit_code;
#+NAME: table-exit-codes
| Macro | Code | Description |
|----------------------------+------+----------------------|
| ~TREXIO_FAILURE~ | -1 | 'Unknown failure' |
| ~TREXIO_SUCCESS~ | 0 | 'Success' |
| ~TREXIO_INVALID_ARG_1~ | 1 | 'Invalid argument 1' |
| ~TREXIO_INVALID_ARG_2~ | 2 | 'Invalid argument 2' |
| ~TREXIO_INVALID_ARG_3~ | 3 | 'Invalid argument 3' |
| ~TREXIO_INVALID_ARG_4~ | 4 | 'Invalid argument 4' |
| ~TREXIO_INVALID_ARG_5~ | 5 | 'Invalid argument 5' |
| ~TREXIO_END~ | 6 | 'End of file' |
| ~TREXIO_READONLY~ | 7 | 'Read-only file' |
| ~TREXIO_ERRNO~ | 8 | strerror(errno) |
| ~TREXIO_INVALID_ID~ | 9 | 'Invalid ID' |
| ~TREXIO_ALLOCATION_FAILED~ | 10 | 'Allocation failed' |
| ~TREXIO_HAS_NOT~ | 11 | 'Element absent' |
| ~TREXIO_INVALID_NUM~ | 12 | 'Invalid exit code' |
# We need to force Emacs not to indent the Python code:
# -*- org-src-preserve-indentation: t
#+begin_src python :var table=table-exit-codes :results drawer :exports none
""" This script generates the C and Fortran constants for the error
codes from the org-mode table.
"""
result = [ "#+begin_src c :tangle prefix_front.h :exports none" ]
for (text, code,_) in table:
text=text.replace("~","")
result += [ f"#define {text:30s} ((trexio_exit_code) {code:d})" ]
result += [ "#+end_src" ]
result += [ "" ]
result += [ "#+begin_src f90 :tangle prefix_fortran.f90 :exports none" ]
for (text, code,_) in table:
text=text.replace("~","")
result += [ f" integer(trexio_exit_code), parameter :: {text:30s} = {code:d}" ]
result += [ "#+end_src" ]
return '\n'.join(result)
#+end_src
#+RESULTS:
:results:
#+begin_src c :tangle prefix_front.h :exports none
#define TREXIO_FAILURE ((trexio_exit_code) -1) #define TREXIO_FAILURE ((trexio_exit_code) -1)
#define TREXIO_SUCCESS ((trexio_exit_code) 0) #define TREXIO_SUCCESS ((trexio_exit_code) 0)
#define TREXIO_INVALID_ARG_1 ((trexio_exit_code) 1) #define TREXIO_INVALID_ARG_1 ((trexio_exit_code) 1)
@ -122,16 +155,146 @@ typedef int32_t trexio_exit_code;
#define TREXIO_INVALID_ARG_3 ((trexio_exit_code) 3) #define TREXIO_INVALID_ARG_3 ((trexio_exit_code) 3)
#define TREXIO_INVALID_ARG_4 ((trexio_exit_code) 4) #define TREXIO_INVALID_ARG_4 ((trexio_exit_code) 4)
#define TREXIO_INVALID_ARG_5 ((trexio_exit_code) 5) #define TREXIO_INVALID_ARG_5 ((trexio_exit_code) 5)
#define TREXIO_END ( (trexio_exit_code) 10 ) #define TREXIO_END ((trexio_exit_code) 6)
#define TREXIO_READONLY ( (trexio_exit_code) 11 ) #define TREXIO_READONLY ((trexio_exit_code) 7)
#define TREXIO_ERRNO ( (trexio_exit_code) 12 ) #define TREXIO_ERRNO ((trexio_exit_code) 8)
#define TREXIO_INVALID_ID ( (trexio_exit_code) 20 ) #define TREXIO_INVALID_ID ((trexio_exit_code) 9)
#define TREXIO_ALLOCATION_FAILED ( (trexio_exit_code) 21 ) #define TREXIO_ALLOCATION_FAILED ((trexio_exit_code) 10)
#define TREXIO_INVALID_NUM ( (trexio_exit_code) 22 ) #define TREXIO_HAS_NOT ((trexio_exit_code) 11)
#define TREXIO_HAS_NOT ( (trexio_exit_code) 30 ) #define TREXIO_INVALID_NUM ((trexio_exit_code) 12)
#+end_src
#+begin_src f90 :tangle prefix_fortran.f90 :exports none
integer(trexio_exit_code), parameter :: TREXIO_FAILURE = -1
integer(trexio_exit_code), parameter :: TREXIO_SUCCESS = 0
integer(trexio_exit_code), parameter :: TREXIO_INVALID_ARG_1 = 1
integer(trexio_exit_code), parameter :: TREXIO_INVALID_ARG_2 = 2
integer(trexio_exit_code), parameter :: TREXIO_INVALID_ARG_3 = 3
integer(trexio_exit_code), parameter :: TREXIO_INVALID_ARG_4 = 4
integer(trexio_exit_code), parameter :: TREXIO_INVALID_ARG_5 = 5
integer(trexio_exit_code), parameter :: TREXIO_END = 6
integer(trexio_exit_code), parameter :: TREXIO_READONLY = 7
integer(trexio_exit_code), parameter :: TREXIO_ERRNO = 8
integer(trexio_exit_code), parameter :: TREXIO_INVALID_ID = 9
integer(trexio_exit_code), parameter :: TREXIO_ALLOCATION_FAILED = 10
integer(trexio_exit_code), parameter :: TREXIO_HAS_NOT = 11
integer(trexio_exit_code), parameter :: TREXIO_INVALID_NUM = 12
#+end_src
:end:
The ~trexio_string_of_error~ converts an exit code into a string. The
string is assumed to be large enough to contain the error message
(typically 128 characters).
◉ Decoding errors
To decode the error messages, ~trexio_string_of_error~ converts an
error code into a string.
#+NAME: MAX_STRING_LENGTH
: 128
#+begin_src c :tangle prefix_front.h :exports none :noweb yes
const char* trexio_string_of_error(const trexio_exit_code error);
void trexio_string_of_error_f(const trexio_exit_code error,
char result[<<MAX_STRING_LENGTH()>>]);
#+end_src
The text strings are extracted from the previous table.
#+NAME:cases
#+begin_src python :var table=table-exit-codes :exports none :noweb yes
""" This script extracts the text associated with the error codes
from the table.
"""
result = []
for (text, code, message) in table:
text = text.replace("~","")
message = message.replace("'",'"')
result += [ f"""case {text}:
return {message};
break;""" ]
return '\n'.join(result)
#+end_src #+end_src
#+RESULTS: cases
#+begin_example
case TREXIO_FAILURE:
return "Unknown failure";
break;
case TREXIO_SUCCESS:
return ;
break;
case TREXIO_INVALID_ARG_1:
return "Invalid argument 1";
break;
case TREXIO_INVALID_ARG_2:
return "Invalid argument 2";
break;
case TREXIO_INVALID_ARG_3:
return "Invalid argument 3";
break;
case TREXIO_INVALID_ARG_4:
return "Invalid argument 4";
break;
case TREXIO_INVALID_ARG_5:
return "Invalid argument 5";
break;
case TREXIO_END:
return "End of file";
break;
case TREXIO_READONLY:
return "Read-only file";
break;
case TREXIO_ERRNO:
return strerror(errno);
break;
case TREXIO_INVALID_ID:
return "Invalid ID";
break;
case TREXIO_ALLOCATION_FAILED:
return "Allocation failed";
break;
case TREXIO_HAS_NOT:
return "Element absent";
break;
case TREXIO_INVALID_NUM:
return "Invalid exit code";
break;
#+end_example
# Source
#+begin_src c :tangle prefix_front.c :noweb yes
const char* trexio_string_of_error(const trexio_exit_code error) {
switch (error) {
<<cases()>>
}
return "Unknown error";
}
void trexio_string_of_error_f(const trexio_exit_code error, char result[<<MAX_STRING_LENGTH()>>]) {
strncpy(result, trexio_string_of_error(error), <<MAX_STRING_LENGTH()>>);
}
#+end_src
# Fortran interface
#+begin_src f90 :tangle prefix_fortran.f90 :noexport :noweb yes
interface
subroutine trexio_string_of_error (error, string) bind(C, name='trexio_string_of_error_f')
use, intrinsic :: iso_c_binding
import
integer (trexio_exit_code), intent(in), value :: error
character, intent(out) :: string(<<MAX_STRING_LENGTH()>>)
end subroutine trexio_string_of_error
end interface
#+end_src
** Back ends ** Back ends
#+begin_src c :tangle prefix_front.h #+begin_src c :tangle prefix_front.h
@ -307,7 +470,7 @@ trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t b
} }
#+end_src #+end_src
#+begin_src fortran :tangle prefix_fortran.f90 #+begin_src f90 :tangle prefix_fortran.f90
interface interface
integer(8) function trexio_open_c (filename, mode, backend) bind(C, name="trexio_open") integer(8) function trexio_open_c (filename, mode, backend) bind(C, name="trexio_open")
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -392,7 +555,7 @@ trexio_exit_code trexio_close(trexio_t* file) {
} }
#+end_src #+end_src
#+begin_src fortran :tangle prefix_fortran.f90 #+begin_src f90 :tangle prefix_fortran.f90
interface interface
integer function trexio_close (trex_file) bind(C) integer function trexio_close (trex_file) bind(C)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -493,7 +656,7 @@ trexio_exit_code trexio_has_$group_num$(trexio_t* const file) {
} }
#+end_src #+end_src
#+begin_src fortran :tangle write_num_front_fortran.f90 #+begin_src f90 :tangle write_num_front_fortran.f90
interface interface
integer function trexio_write_$group_num$ (trex_file, num) bind(C) integer function trexio_write_$group_num$ (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -503,7 +666,7 @@ interface
end interface end interface
#+end_src #+end_src
#+begin_src fortran :tangle read_num_front_fortran.f90 #+begin_src f90 :tangle read_num_front_fortran.f90
interface interface
integer function trexio_read_$group_num$ (trex_file, num) bind(C) integer function trexio_read_$group_num$ (trex_file, num) bind(C)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -513,7 +676,7 @@ interface
end interface end interface
#+end_src #+end_src
#+begin_src fortran :tangle has_num_front_fortran.f90 #+begin_src f90 :tangle has_num_front_fortran.f90
interface interface
integer function trexio_has_$group_num$ (trex_file) bind(C) integer function trexio_has_$group_num$ (trex_file) bind(C)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -655,7 +818,7 @@ trexio_exit_code trexio_has_$group$_$group_dset$(trexio_t* const file) {
#+end_src #+end_src
#+begin_src fortran :tangle write_dset_front_fortran.f90 #+begin_src f90 :tangle write_dset_front_fortran.f90
interface interface
integer function trexio_write_$group$_$group_dset$ (trex_file, dset) bind(C) integer function trexio_write_$group$_$group_dset$ (trex_file, dset) bind(C)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -665,7 +828,7 @@ interface
end interface end interface
#+end_src #+end_src
#+begin_src fortran :tangle read_dset_front_fortran.f90 #+begin_src f90 :tangle read_dset_front_fortran.f90
interface interface
integer function trexio_read_$group$_$group_dset$ (trex_file, dset) bind(C) integer function trexio_read_$group$_$group_dset$ (trex_file, dset) bind(C)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -675,7 +838,7 @@ interface
end interface end interface
#+end_src #+end_src
#+begin_src fortran :tangle has_dset_front_fortran.f90 #+begin_src f90 :tangle has_dset_front_fortran.f90
interface interface
integer function trexio_has_$group$_$group_dset$ (trex_file) bind(C) integer function trexio_has_$group$_$group_dset$ (trex_file) bind(C)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -695,7 +858,7 @@ end interface
* Fortran helper/wrapper functions * Fortran helper/wrapper functions
#+begin_src fortran :tangle suffix_fortran.f90 #+begin_src f90 :tangle suffix_fortran.f90
contains contains
integer(8) function trexio_open (filename, mode, backend) integer(8) function trexio_open (filename, mode, backend)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -721,7 +884,7 @@ contains
#endif #endif
#+end_src #+end_src
#+begin_src fortran :tangle suffix_fortran.f90 #+begin_src f90 :tangle suffix_fortran.f90
end module trexio end module trexio
#+end_src #+end_src

View File

@ -19,6 +19,7 @@ int main() {
test_write(); test_write();
test_read(); test_read();
printf("%s\n", trexio_string_of_error(TREXIO_INVALID_ARG_2));
return 0 ; return 0 ;
} }

View File

@ -99,6 +99,8 @@ subroutine test_read()
double precision :: charge(12) double precision :: charge(12)
double precision :: coord(3,12) double precision :: coord(3,12)
character*(128) :: str
num = 12 num = 12
! ================= START OF TEST ===================== ! ! ================= START OF TEST ===================== !
@ -121,6 +123,9 @@ subroutine test_read()
rc = trexio_close(trex_file) rc = trexio_close(trex_file)
if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS CLOSE' if (rc == TREXIO_SUCCESS) write(*,*) 'SUCCESS CLOSE'
call trexio_string_of_error(TREXIO_READONLY,str)
write(*,*) str
! ================= END OF TEST ===================== ! ! ================= END OF TEST ===================== !
end subroutine test_read end subroutine test_read