1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-06-30 00:44:52 +02:00

Added tests

This commit is contained in:
Anthony Scemama 2020-10-16 19:42:12 +02:00
parent 1879d3a67c
commit 534e11cccb
2 changed files with 192 additions and 31 deletions

View File

@ -2,8 +2,8 @@
# vim: syntax=c # vim: syntax=c
#+TITLE: QMCkl C header #+TITLE: QMCkl C header
This file is included in all other C header files, and produces the This file produces the =qmckl.h= header file, which is included in all
=qmckl.h= header file. other C header files. It is the main entry point to the library.
#+BEGIN_SRC C :tangle qmckl.h #+BEGIN_SRC C :tangle qmckl.h
#ifndef QMCKL_H #ifndef QMCKL_H
@ -27,13 +27,20 @@ typedef int qmckl_exit_code;
** Precision-related constants ** Precision-related constants
Controlling numerical precision enables optimizations. Here, the
default parameters determining the target numerical precision and
range are defined.
#+BEGIN_SRC C :tangle qmckl.h #+BEGIN_SRC C :tangle qmckl.h
#define QMCKL_DEFAULT_PRECISION 53 #define QMCKL_DEFAULT_PRECISION 53
#define QMCKL_DEFAULT_RANGE 2 #define QMCKL_DEFAULT_RANGE 11
#+END_SRC #+END_SRC
* Header files * Header files
All the functions expoed in the API are defined in the following
header files.
#+BEGIN_SRC C :tangle qmckl.h #+BEGIN_SRC C :tangle qmckl.h
#include "qmckl_context.h" #include "qmckl_context.h"
#+END_SRC #+END_SRC

View File

@ -5,29 +5,49 @@
This file is written in C because it is more natural to express the context in This file is written in C because it is more natural to express the context in
C than in Fortran. C than in Fortran.
#+BEGIN_SRC C :tangle qmckl_context.h 3 files are produced:
- a header file : =qmckl_context.h=
- a source file : =qmckl_context.c=
- a test file : =test_qmckl_context.c=
*** Header
#+BEGIN_SRC C :tangle qmckl_context.h
#ifndef QMCKL_CONTEXT_H #ifndef QMCKL_CONTEXT_H
#define QMCKL_CONTEXT_H #define QMCKL_CONTEXT_H
#include "qmckl.h" #include "qmckl.h"
#+END_SRC #+END_SRC
#+BEGIN_SRC C :tangle qmckl_context.c *** Source
#+BEGIN_SRC C :tangle qmckl_context.c
#include <stdlib.h> /* malloc */ #include <stdlib.h> /* malloc */
#include "qmckl_context.h" #include "qmckl_context.h"
#+END_SRC #+END_SRC
*** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c
#include "qmckl_context.h"
#include "qmckl_test.h"
int main() {
qmckl_exit_code rc; /* return code */
rc = QMCKL_SUCCESS;
#+END_SRC
* Context * Context
The context variable is a handle for the state of the library, and The context variable is a handle for the state of the library, and
is stored in the following data structure, which can't be seen is stored in the following data structure, which can't be seen
outside of the library. outside of the library. To simplify compatibility with other
languages, the pointer to the internal data structure is converted
into a 64-bit signed integer, defined in the =qmckl_context= type.
A value of 0 for the context is equivalent to a NULL pointer.
*** Header
#+BEGIN_SRC C :tangle qmckl_context.h #+BEGIN_SRC C :tangle qmckl_context.h
/* 64-bit integer */ /* 64-bit integer */
typedef long long int qmckl_context ; typedef long long int qmckl_context ;
#+END_SRC #+END_SRC
*** Source
#+BEGIN_SRC C :tangle qmckl_context.c #+BEGIN_SRC C :tangle qmckl_context.c
typedef struct qmckl_context_struct { typedef struct qmckl_context_struct {
struct qmckl_context_struct * prev; struct qmckl_context_struct * prev;
@ -36,16 +56,25 @@ typedef struct qmckl_context_struct {
} qmckl_context_struct; } qmckl_context_struct;
#+END_SRC #+END_SRC
*** Test
We declare here the variables used in the tests.
#+BEGIN_SRC C :tangle test_qmckl_context.c
qmckl_context context;
qmckl_context new_context;
#+END_SRC
** =qmckl_context_create= ** =qmckl_context_create=
To create a new context, use =qmckl_context_create()=. If the creation To create a new context, use =qmckl_context_create()=.
failed, the function returns =0=. On success, a pointer to a context - On success, returns a pointer to a context using the =qmckl_context= type
is returned as a 64-bit integer. - Returns 0 upon failure to allocate the internal data structure
*** Header
#+BEGIN_SRC C :tangle qmckl_context.h #+BEGIN_SRC C :tangle qmckl_context.h
qmckl_context qmckl_context_create(); qmckl_context qmckl_context_create();
#+END_SRC #+END_SRC
*** Source
#+BEGIN_SRC C :tangle qmckl_context.c #+BEGIN_SRC C :tangle qmckl_context.c
qmckl_context qmckl_context_create() { qmckl_context qmckl_context_create() {
@ -64,18 +93,44 @@ qmckl_context qmckl_context_create() {
} }
#+END_SRC #+END_SRC
*** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c
context = qmckl_context_create();
if (context == (qmckl_context) 0) {
eprintf("qmckl_context_create\n");
rc = QMCKL_FAILURE;
}
if ( ((qmckl_context_struct*) new_context)->precision != QMCKL_DEFAULT_PRECISION ) {
eprintf("qmckl_context_copy: No access to data\n");
rc = QMCKL_FAILURE;
}
#+END_SRC
** =qmckl_context_copy= ** =qmckl_context_copy=
This function makes a shallow copy of the current context.
- Copying the 0-valued context returns 0
- On success, returns a pointer to the new context using the =qmckl_context= type
- Returns 0 upon failure to allocate the internal data structure
for the new context
*** Header
#+BEGIN_SRC C :tangle qmckl_context.h #+BEGIN_SRC C :tangle qmckl_context.h
qmckl_context qmckl_context_copy(const qmckl_context context); qmckl_context qmckl_context_copy(const qmckl_context context);
#+END_SRC #+END_SRC
*** Source
#+BEGIN_SRC C :tangle qmckl_context.c #+BEGIN_SRC C :tangle qmckl_context.c
qmckl_context qmckl_context_copy(const qmckl_context context) { qmckl_context qmckl_context_copy(const qmckl_context context) {
qmckl_context_struct* old_context; qmckl_context_struct* old_context;
qmckl_context_struct* new_context; qmckl_context_struct* new_context;
if (context == (qmckl_context) 0) {
return (qmckl_context) 0;
}
new_context = (qmckl_context_struct*) malloc (sizeof(qmckl_context_struct)); new_context = (qmckl_context_struct*) malloc (sizeof(qmckl_context_struct));
if (new_context == NULL) { if (new_context == NULL) {
return (qmckl_context) 0; return (qmckl_context) 0;
@ -91,32 +146,124 @@ qmckl_context qmckl_context_copy(const qmckl_context context) {
} }
#+END_SRC #+END_SRC
** =qmckl_context_destroy= *** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c
To delete a new context, use =qmckl_context_destroy()=. If the deletion new_context = qmckl_context_copy(context);
failed, the function returns =0=. On success, the function returns =1= if (new_context == (qmckl_context) 0) {
implying that the context has been freed. eprintf("qmckl_context_copy: Allocation failure\n");
rc = QMCKL_FAILURE;
#+BEGIN_SRC C :tangle qmckl_context.h }
int qmckl_context_destroy(qmckl_context context); if (new_context == context ) {
eprintf("qmckl_context_copy: Same pointer\n");
rc = QMCKL_FAILURE;
}
if ( ((qmckl_context_struct*) new_context)->precision != QMCKL_DEFAULT_PRECISION ) {
eprintf("qmckl_context_copy: No access to data\n");
rc = QMCKL_FAILURE;
}
#+END_SRC #+END_SRC
** =qmckl_context_previous=
Returns the previous context
- On success, returns the ancestor of the current context
- Returns 0 for the initial context
- Returns 0 for the 0-valued context
*** Header
#+BEGIN_SRC C :tangle qmckl_context.h
qmckl_context qmckl_context_previous(const qmckl_context context);
#+END_SRC
*** Source
#+BEGIN_SRC C :tangle qmckl_context.c #+BEGIN_SRC C :tangle qmckl_context.c
int qmckl_context_destroy(qmckl_context context) { qmckl_context qmckl_context_previous(const qmckl_context context) {
qmckl_context_struct* ctx; qmckl_context_struct* ctx;
if (context == (qmckl_context) 0) {
return (qmckl_context) 0;
}
ctx = (qmckl_context_struct*) context; ctx = (qmckl_context_struct*) context;
return (qmckl_context) ctx->prev;
}
#+END_SRC
*** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c
if (qmckl_context_previous(new_context) == (qmckl_context) 0) {
eprintf("qmckl_context_copy: Null pointer\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_previous(new_context) != context) {
eprintf("qmckl_context_copy: Wrong pointer\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_previous(context) != (qmckl_context) 0) {
eprintf("qmckl_context_copy: Expected null pointer (1)\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_previous((qmckl_context) 0) != (qmckl_context) 0) {
eprintf("qmckl_context_copy: Expected null pointer (2)\n");
rc = QMCKL_FAILURE;
}
#+END_SRC
** =qmckl_context_destroy=
Destroys the current context, leaving the ancestors untouched.
- Succeeds if the current context is properly destroyed
- Fails otherwise
- Fails is the 0-valued context is given in argument
The context given in parameter is overwritten by the 0-valued
context, so a pointer is passed to the function.
*** Header
#+BEGIN_SRC C :tangle qmckl_context.h
qmckl_exit_code qmckl_context_destroy(qmckl_context * context);
#+END_SRC
*** Source
#+BEGIN_SRC C :tangle qmckl_context.c
qmckl_exit_code qmckl_context_destroy(qmckl_context *context) {
qmckl_context_struct* ctx;
ctx = (qmckl_context_struct*) *context;
if (ctx == NULL) { if (ctx == NULL) {
return 0; return QMCKL_FAILURE;
} }
free(ctx); free(ctx);
return 1; *context = (qmckl_context) 0;
return QMCKL_SUCCESS;
} }
#+END_SRC #+END_SRC
*** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c
if (new_context == (qmckl_context) 0) {
eprintf("qmckl_context_destroy: new_context is NULL\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_destroy(&new_context) == QMCKL_FAILURE) {
eprintf("qmckl_context_destroy: Unable to destroy the new_context\n");
rc = QMCKL_FAILURE;
}
if (new_context != (qmckl_context) 0) {
eprintf("qmckl_context_destroy: new_context should be NULL\n");
rc = QMCKL_FAILURE;
}
if (qmckl_context_destroy((qmckl_context) 0) == QMCKL_SUCCESS) {
eprintf("qmckl_context_destroy: Failure expected with NULL pointer\n");
rc = QMCKL_FAILURE;
}
#+END_SRC
* Precision * Precision
The following functions set and get the expected required precision The following functions set and get the expected required precision
@ -239,9 +386,16 @@ int qmckl_context_get_range(const qmckl_context context) {
* End of header * End of files
#+BEGIN_SRC C :tangle qmckl_context.h *** Header
#+BEGIN_SRC C :tangle qmckl_context.h
#endif #endif
#+END_SRC #+END_SRC
*** Test
#+BEGIN_SRC C :tangle test_qmckl_context.c
return QMCKL_SUCCESS;
}
#+END_SRC