1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-07-18 17:03:43 +02:00
qmckl/src/qmckl_error.org

204 lines
7.1 KiB
Org Mode
Raw Normal View History

2021-03-09 01:16:23 +01:00
#+TITLE: Error handling
#+SETUPFILE: ../docs/theme.setup
2021-03-10 12:58:38 +01:00
* Headers :noexport:
2021-03-09 01:16:23 +01:00
#+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 <stdint.h>
#include "qmckl_error.h"
#+end_src
2021-03-05 03:45:30 +01:00
2021-03-09 01:16:23 +01:00
#+begin_src c :tangle (eval c_test) :noweb yes
2021-03-05 03:45:30 +01:00
#include "qmckl.h"
#include "munit.h"
2021-03-09 01:16:23 +01:00
MunitResult test_<<filename()>>() {
#+end_src
2021-03-05 03:45:30 +01:00
2021-03-18 18:02:06 +01:00
#+begin_src c :comments org :tangle (eval h)
#include <errno.h>
#include <string.h>
#+end_src
2021-03-19 19:02:43 +01:00
2021-03-10 12:58:38 +01:00
*
:PROPERTIES:
:UNNUMBERED: t
:END:
2021-03-05 03:45:30 +01:00
2021-03-09 01:16:23 +01:00
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.
2021-03-05 03:45:30 +01:00
All the functions return with an exit code, defined as
2021-03-09 01:16:23 +01:00
#+NAME: type-exit-code
#+begin_src c :comments org :tangle (eval h)
2021-03-05 03:45:30 +01:00
typedef int32_t qmckl_exit_code;
2021-03-09 01:16:23 +01:00
#+end_src
The exit code returns the completion status of the function to the
2021-03-10 12:58:38 +01:00
calling program. When a function call completed successfully,
~QMCKL_SUCCESS~ is returned. If one of the functions of
2021-03-09 01:16:23 +01:00
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
2021-03-19 18:17:01 +01:00
| Macro | Code | Description |
|-----------------------------+------+------------------------|
| ~QMCKL_SUCCESS~ | 0 | 'Success' |
| ~QMCKL_INVALID_ARG_1~ | 1 | 'Invalid argument 1' |
| ~QMCKL_INVALID_ARG_2~ | 2 | 'Invalid argument 2' |
| ~QMCKL_INVALID_ARG_3~ | 3 | 'Invalid argument 3' |
| ~QMCKL_INVALID_ARG_4~ | 4 | 'Invalid argument 4' |
| ~QMCKL_INVALID_ARG_5~ | 5 | 'Invalid argument 5' |
| ~QMCKL_INVALID_ARG_6~ | 6 | 'Invalid argument 6' |
| ~QMCKL_INVALID_ARG_7~ | 7 | 'Invalid argument 7' |
| ~QMCKL_INVALID_ARG_8~ | 8 | 'Invalid argument 8' |
| ~QMCKL_INVALID_ARG_9~ | 9 | 'Invalid argument 9' |
| ~QMCKL_INVALID_ARG_10~ | 10 | 'Invalid argument 10' |
| ~QMCKL_FAILURE~ | 101 | 'Failure' |
| ~QMCKL_ERRNO~ | 102 | strerror(errno) |
| ~QMCKL_INVALID_CONTEXT~ | 103 | 'Invalid context' |
| ~QMCKL_ALLOCATION_FAILED~ | 104 | 'Allocation failed' |
| ~QMCKL_DEALLOCATION_FAILED~ | 105 | 'De-allocation failed' |
| ~QMCKL_INVALID_EXIT_CODE~ | 106 | 'Invalid exit code' |
2021-03-09 01:16:23 +01:00
# We need to force Emacs not to indent the Python code:
# -*- org-src-preserve-indentation: t
2021-03-19 18:17:01 +01:00
2021-03-10 12:58:38 +01:00
#+begin_src python :var table=table-exit-codes :results drawer :exports none
2021-03-05 03:45:30 +01:00
""" This script generates the C and Fortran constants for the error
codes from the org-mode table.
"""
2021-03-10 12:58:38 +01:00
result = [ "#+begin_src c :comments org :tangle (eval h) :exports none" ]
2021-03-19 18:17:01 +01:00
for (text, code,_) in table:
2021-03-05 03:45:30 +01:00
text=text.replace("~","")
result += [ f"#define {text:30s} {code:d}" ]
2021-03-09 01:16:23 +01:00
result += [ "#+end_src" ]
2021-03-05 03:45:30 +01:00
result += [ "" ]
2021-03-10 12:58:38 +01:00
result += [ "#+begin_src f90 :comments org :tangle (eval fh) :exports none" ]
2021-03-19 18:17:01 +01:00
for (text, code,_) in table:
2021-03-05 03:45:30 +01:00
text=text.replace("~","")
result += [ f" integer, parameter :: {text:30s} = {code:d}" ]
2021-03-09 01:16:23 +01:00
result += [ "#+end_src" ]
2021-03-05 03:45:30 +01:00
return '\n'.join(result)
2021-03-09 01:16:23 +01:00
#+end_src
#+RESULTS:
:results:
2021-03-10 12:58:38 +01:00
#+begin_src c :comments org :tangle (eval h) :exports none
2021-03-09 01:16:23 +01:00
#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
2021-03-10 12:58:38 +01:00
#define QMCKL_FAILURE 101
#define QMCKL_ERRNO 102
#define QMCKL_INVALID_CONTEXT 103
#define QMCKL_ALLOCATION_FAILED 104
2021-03-18 19:12:39 +01:00
#define QMCKL_DEALLOCATION_FAILED 105
#define QMCKL_INVALID_EXIT_CODE 106
2021-03-09 01:16:23 +01:00
#+end_src
2021-03-10 12:58:38 +01:00
#+begin_src f90 :comments org :tangle (eval fh) :exports none
2021-03-09 01:16:23 +01:00
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
2021-03-10 12:58:38 +01:00
integer, parameter :: QMCKL_FAILURE = 101
integer, parameter :: QMCKL_ERRNO = 102
integer, parameter :: QMCKL_INVALID_CONTEXT = 103
integer, parameter :: QMCKL_ALLOCATION_FAILED = 104
2021-03-18 19:12:39 +01:00
integer, parameter :: QMCKL_DEALLOCATION_FAILED = 105
integer, parameter :: QMCKL_INVALID_EXIT_CODE = 106
2021-03-09 01:16:23 +01:00
#+end_src
:end:
2021-03-05 03:45:30 +01:00
2021-03-19 18:17:01 +01:00
The ~qmckl_strerror~ converts an exit code into a string. The
string is assumed to be large enough to contain the error message
(typically 128 characters).
#+NAME: MAX_STRING_LENGTH
: 128
2021-03-19 18:17:01 +01:00
#+begin_src c :comments org :tangle (eval h) :exports none :noweb yes
void qmckl_string_of_error(qmckl_exit_code error, char string[<<MAX_STRING_LENGTH()>>]);
2021-03-19 18:17:01 +01:00
#+end_src
The text strings are extracted from the previous table.
#+NAME:cases
#+begin_src python :var table=table-exit-codes :exports none
""" 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}:
message = {message};
break;""" ]
return '\n'.join(result)
#+end_src
# Source
2021-03-19 18:17:01 +01:00
#+begin_src c :comments org :tangle (eval c) :noweb yes
void qmckl_string_of_error(qmckl_exit_code error, char string[<<MAX_STRING_LENGTH()>>]) {
2021-03-19 18:17:01 +01:00
char* message;
switch (error) {
<<cases()>>
}
strncpy(string,message,<<MAX_STRING_LENGTH()>>);
2021-03-19 18:17:01 +01:00
}
#+end_src
# Fortran interface
#+begin_src f90 :tangle (eval fh) :noexport :noweb yes
interface
2021-03-19 19:11:06 +01:00
subroutine qmckl_string_of_error (error, string) bind(C)
use, intrinsic :: iso_c_binding
2021-03-19 19:11:06 +01:00
integer (c_int32_t), intent(in), value :: error
character, intent(out) :: string(<<MAX_STRING_LENGTH()>>)
end subroutine qmckl_string_of_error
end interface
#+end_src
2021-03-10 12:58:38 +01:00
* End of files :noexport:
2021-03-05 03:45:30 +01:00
2021-03-10 12:58:38 +01:00
** Test
2021-03-09 01:16:23 +01:00
#+begin_src c :comments link :tangle (eval c_test)
2021-03-05 03:45:30 +01:00
return MUNIT_OK;
}
2021-03-09 01:16:23 +01:00
#+end_src
2021-03-05 03:45:30 +01:00
2021-03-09 01:16:23 +01:00
# -*- mode: org -*-
# vim: syntax=c
2021-03-05 03:45:30 +01:00