#+TITLE: Error handling #+SETUPFILE: ../docs/theme.setup This file is written in C because it is more natural to express the error handling in C than in Fortran. ** Headers :noexport: #+NAME: filename #+begin_src elisp tangle: no (file-name-nondirectory (substring buffer-file-name 0 -4)) #+end_src #+begin_src c :tangle (eval c) #include #include "qmckl_error.h" #+end_src #+begin_src c :tangle (eval c_test) :noweb yes #include "qmckl.h" #include "munit.h" MunitResult test_<>() { #+end_src ** Error handling The library should never make the calling programs abort, nor perform any input/output operations. This decision has to be taken by the developer of the code calling the library. All the functions return with an <<>>, defined as #+NAME: type-exit-code #+begin_src c :comments org :tangle (eval h) typedef int32_t qmckl_exit_code; #+end_src The exit code returns the completion status of the function to the calling program. When a function call completed successfully, the ~QMCKL_SUCCESS~ exit code is returned. If one of the functions of the library fails to complete the requested task, an appropriate error code is returned to the program. Here is the complete list of exit codes. #+NAME: table-exit-codes | ~QMCKL_SUCCESS~ | 0 | | ~QMCKL_INVALID_ARG_1~ | 1 | | ~QMCKL_INVALID_ARG_2~ | 2 | | ~QMCKL_INVALID_ARG_3~ | 3 | | ~QMCKL_INVALID_ARG_4~ | 4 | | ~QMCKL_INVALID_ARG_5~ | 5 | | ~QMCKL_INVALID_ARG_6~ | 6 | | ~QMCKL_INVALID_ARG_7~ | 7 | | ~QMCKL_INVALID_ARG_8~ | 8 | | ~QMCKL_INVALID_ARG_9~ | 9 | | ~QMCKL_INVALID_ARG_10~ | 10 | | ~QMCKL_NULL_CONTEXT~ | 101 | | ~QMCKL_FAILURE~ | 102 | | ~QMCKL_ERRNO~ | 103 | | ~QMCKL_INVALID_EXIT_CODE~ | 104 | # 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 result """ This script generates the C and Fortran constants for the error codes from the org-mode table. """ result = [ "#+begin_src c :comments org :tangle (eval h)" ] for (text, code) in table: text=text.replace("~","") result += [ f"#define {text:30s} {code:d}" ] result += [ "#+end_src" ] result += [ "" ] result += [ "#+begin_src f90 :comments org :tangle (eval fh)" ] for (text, code) in table: text=text.replace("~","") result += [ f" integer, parameter :: {text:30s} = {code:d}" ] result += [ "#+end_src" ] return '\n'.join(result) #+end_src #+RESULTS: :results: #+begin_src c :comments org :tangle (eval h) #define QMCKL_SUCCESS 0 #define QMCKL_INVALID_ARG_1 1 #define QMCKL_INVALID_ARG_2 2 #define QMCKL_INVALID_ARG_3 3 #define QMCKL_INVALID_ARG_4 4 #define QMCKL_INVALID_ARG_5 5 #define QMCKL_INVALID_ARG_6 6 #define QMCKL_INVALID_ARG_7 7 #define QMCKL_INVALID_ARG_8 8 #define QMCKL_INVALID_ARG_9 9 #define QMCKL_INVALID_ARG_10 10 #define QMCKL_NULL_CONTEXT 101 #define QMCKL_FAILURE 102 #define QMCKL_ERRNO 103 #define QMCKL_INVALID_EXIT_CODE 104 #+end_src #+begin_src f90 :comments org :tangle (eval fh) integer, parameter :: QMCKL_SUCCESS = 0 integer, parameter :: QMCKL_INVALID_ARG_1 = 1 integer, parameter :: QMCKL_INVALID_ARG_2 = 2 integer, parameter :: QMCKL_INVALID_ARG_3 = 3 integer, parameter :: QMCKL_INVALID_ARG_4 = 4 integer, parameter :: QMCKL_INVALID_ARG_5 = 5 integer, parameter :: QMCKL_INVALID_ARG_6 = 6 integer, parameter :: QMCKL_INVALID_ARG_7 = 7 integer, parameter :: QMCKL_INVALID_ARG_8 = 8 integer, parameter :: QMCKL_INVALID_ARG_9 = 9 integer, parameter :: QMCKL_INVALID_ARG_10 = 10 integer, parameter :: QMCKL_NULL_CONTEXT = 101 integer, parameter :: QMCKL_FAILURE = 102 integer, parameter :: QMCKL_ERRNO = 103 integer, parameter :: QMCKL_INVALID_EXIT_CODE = 104 #+end_src :end: ** End of files :noexport: *** Test #+begin_src c :comments link :tangle (eval c_test) return MUNIT_OK; } #+end_src # -*- mode: org -*- # vim: syntax=c