mirror of
https://github.com/TREX-CoE/qmckl.git
synced 2024-08-17 02:41:43 +02:00
Add tag to check if memory pointers are valid
This commit is contained in:
parent
87cfdc88d3
commit
ec7df80028
@ -1,5 +1,5 @@
|
|||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS=-fPIC -fexceptions -Wall -Werror -Wpedantic -Wextra
|
CFLAGS=-fPIC -fexceptions -Wall -Werror -Wpedantic -Wextra -g
|
||||||
|
|
||||||
FC=gfortran
|
FC=gfortran
|
||||||
FFLAGS=-fcheck=all -Waliasing -Wampersand -Wconversion -Wsurprising -Wintrinsics-std -Wno-tabs -Wintrinsic-shadow -Wline-truncation -Wreal-q-constant -Wuninitialized -fbacktrace -ffpe-trap=zero,overflow,underflow -finit-real=nan
|
FFLAGS=-fcheck=all -Waliasing -Wampersand -Wconversion -Wsurprising -Wintrinsics-std -Wno-tabs -Wintrinsic-shadow -Wline-truncation -Wreal-q-constant -Wuninitialized -fbacktrace -ffpe-trap=zero,overflow,underflow -finit-real=nan
|
||||||
|
@ -51,27 +51,50 @@ typedef long long int qmckl_context ;
|
|||||||
#+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;
|
||||||
|
unsigned int tag;
|
||||||
int precision;
|
int precision;
|
||||||
int range;
|
int range;
|
||||||
} qmckl_context_struct;
|
} qmckl_context_struct;
|
||||||
|
|
||||||
|
#define VALID_TAG 0xBEEFFACE
|
||||||
|
#define INVALID_TAG 0xDEADBEEF
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
The tag is used internally to check if the memory domain pointed by
|
||||||
|
a pointer is a valid context.
|
||||||
|
|
||||||
*** Test
|
*** Test
|
||||||
We declare here the variables used in the tests.
|
We declare here the variables used in the tests.
|
||||||
#+BEGIN_SRC C :tangle test_qmckl_context.c
|
#+BEGIN_SRC C :tangle test_qmckl_context.c
|
||||||
qmckl_context context;
|
qmckl_context context;
|
||||||
qmckl_context new_context;
|
qmckl_context new_context;
|
||||||
|
|
||||||
/* This needs to be repeated in the tests because we don't want to
|
|
||||||
expose it in the headers.
|
|
||||||
*/
|
|
||||||
typedef struct qmckl_context_struct {
|
|
||||||
struct qmckl_context_struct * prev;
|
|
||||||
int precision;
|
|
||||||
int range;
|
|
||||||
} qmckl_context_struct;
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
|
||||||
|
** =qmckl_context_check=
|
||||||
|
|
||||||
|
Checks if the domain pointed by the pointer is a valid context.
|
||||||
|
Returns the input =qmckl_context= if the context is valid, 0 otherwise.
|
||||||
|
|
||||||
|
*** Header
|
||||||
|
#+BEGIN_SRC C :tangle qmckl_context.h
|
||||||
|
qmckl_context qmckl_context_check(qmckl_context context) ;
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** Source
|
||||||
|
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||||
|
qmckl_context qmckl_context_check(qmckl_context context) {
|
||||||
|
qmckl_context_struct * ctx;
|
||||||
|
|
||||||
|
if (context == (qmckl_context) 0) return (qmckl_context) 0;
|
||||||
|
|
||||||
|
ctx = (qmckl_context_struct*) context;
|
||||||
|
if (ctx->tag != VALID_TAG) return (qmckl_context) 0;
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
** =qmckl_context_create=
|
** =qmckl_context_create=
|
||||||
|
|
||||||
To create a new context, use =qmckl_context_create()=.
|
To create a new context, use =qmckl_context_create()=.
|
||||||
@ -97,6 +120,7 @@ qmckl_context qmckl_context_create() {
|
|||||||
context->prev = NULL;
|
context->prev = NULL;
|
||||||
context->precision = QMCKL_DEFAULT_PRECISION;
|
context->precision = QMCKL_DEFAULT_PRECISION;
|
||||||
context->range = QMCKL_DEFAULT_RANGE;
|
context->range = QMCKL_DEFAULT_RANGE;
|
||||||
|
context->tag = VALID_TAG;
|
||||||
|
|
||||||
return (qmckl_context) context;
|
return (qmckl_context) context;
|
||||||
}
|
}
|
||||||
@ -109,15 +133,14 @@ qmckl_context qmckl_context_create() {
|
|||||||
fprintf(stderr,"qmckl_context_create\n");
|
fprintf(stderr,"qmckl_context_create\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
if ( ((qmckl_context_struct*) new_context)->precision != QMCKL_DEFAULT_PRECISION ) {
|
if ( qmckl_context_check(context) != context) {
|
||||||
fprintf(stderr,"qmckl_context_copy: No access to data\n");
|
fprintf(stderr,"qmckl_context_create: Invalid context\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** =qmckl_context_copy=
|
** =qmckl_context_copy=
|
||||||
|
|
||||||
|
|
||||||
This function makes a shallow copy of the current context.
|
This function makes a shallow copy of the current context.
|
||||||
- Copying the 0-valued context returns 0
|
- Copying the 0-valued context returns 0
|
||||||
- On success, returns a pointer to the new context using the =qmckl_context= type
|
- On success, returns a pointer to the new context using the =qmckl_context= type
|
||||||
@ -135,8 +158,11 @@ 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;
|
||||||
|
qmckl_context checked_context;
|
||||||
|
|
||||||
if (context == (qmckl_context) 0) {
|
checked_context = qmckl_context_check(context);
|
||||||
|
|
||||||
|
if (checked_context == (qmckl_context) 0) {
|
||||||
return (qmckl_context) 0;
|
return (qmckl_context) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,14 +171,16 @@ qmckl_context qmckl_context_copy(const qmckl_context context) {
|
|||||||
return (qmckl_context) 0;
|
return (qmckl_context) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_context = (qmckl_context_struct*) context;
|
old_context = (qmckl_context_struct*) checked_context;
|
||||||
|
|
||||||
new_context->prev = old_context;
|
new_context->prev = old_context;
|
||||||
new_context->precision = old_context->precision;
|
new_context->precision = old_context->precision;
|
||||||
new_context->range = old_context->range;
|
new_context->range = old_context->range;
|
||||||
|
new_context->tag = VALID_TAG;
|
||||||
|
|
||||||
return (qmckl_context) new_context;
|
return (qmckl_context) new_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
*** Test
|
*** Test
|
||||||
@ -166,10 +194,11 @@ qmckl_context qmckl_context_copy(const qmckl_context context) {
|
|||||||
fprintf(stderr,"qmckl_context_copy: Same pointer\n");
|
fprintf(stderr,"qmckl_context_copy: Same pointer\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
if ( ((qmckl_context_struct*) new_context)->precision != QMCKL_DEFAULT_PRECISION ) {
|
if ( qmckl_context_check(new_context) != new_context) {
|
||||||
fprintf(stderr,"qmckl_context_copy: No access to data\n");
|
fprintf(stderr,"qmckl_context_copy: No access to data\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** =qmckl_context_previous=
|
** =qmckl_context_previous=
|
||||||
@ -188,33 +217,35 @@ qmckl_context qmckl_context_previous(const qmckl_context context);
|
|||||||
#+BEGIN_SRC C :tangle qmckl_context.c
|
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||||
qmckl_context qmckl_context_previous(const qmckl_context context) {
|
qmckl_context qmckl_context_previous(const qmckl_context context) {
|
||||||
|
|
||||||
|
qmckl_context checked_context;
|
||||||
qmckl_context_struct* ctx;
|
qmckl_context_struct* ctx;
|
||||||
|
|
||||||
if (context == (qmckl_context) 0) {
|
checked_context = qmckl_context_check(context);
|
||||||
|
if (checked_context == (qmckl_context) 0) {
|
||||||
return (qmckl_context) 0;
|
return (qmckl_context) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = (qmckl_context_struct*) context;
|
ctx = (qmckl_context_struct*) checked_context;
|
||||||
return (qmckl_context) ctx->prev;
|
return qmckl_context_check((qmckl_context) ctx->prev);
|
||||||
}
|
}
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
*** Test
|
*** Test
|
||||||
#+BEGIN_SRC C :tangle test_qmckl_context.c
|
#+BEGIN_SRC C :tangle test_qmckl_context.c
|
||||||
if (qmckl_context_previous(new_context) == (qmckl_context) 0) {
|
if (qmckl_context_previous(new_context) == (qmckl_context) 0) {
|
||||||
fprintf(stderr,"qmckl_context_copy: Null pointer\n");
|
fprintf(stderr,"qmckl_context_previous: Null pointer\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
if (qmckl_context_previous(new_context) != context) {
|
if (qmckl_context_previous(new_context) != context) {
|
||||||
fprintf(stderr,"qmckl_context_copy: Wrong pointer\n");
|
fprintf(stderr,"qmckl_context_previous: Wrong pointer\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
if (qmckl_context_previous(context) != (qmckl_context) 0) {
|
if (qmckl_context_previous(context) != (qmckl_context) 0) {
|
||||||
fprintf(stderr,"qmckl_context_copy: Expected null pointer (1)\n");
|
fprintf(stderr,"qmckl_context_previous: Expected null pointer (1)\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
if (qmckl_context_previous((qmckl_context) 0) != (qmckl_context) 0) {
|
if (qmckl_context_previous((qmckl_context) 0) != (qmckl_context) 0) {
|
||||||
fprintf(stderr,"qmckl_context_copy: Expected null pointer (2)\n");
|
fprintf(stderr,"qmckl_context_previous: Expected null pointer (2)\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
@ -224,45 +255,52 @@ qmckl_context qmckl_context_previous(const qmckl_context context) {
|
|||||||
Destroys the current context, leaving the ancestors untouched.
|
Destroys the current context, leaving the ancestors untouched.
|
||||||
- Succeeds if the current context is properly destroyed
|
- Succeeds if the current context is properly destroyed
|
||||||
- Fails otherwise
|
- Fails otherwise
|
||||||
- Fails is the 0-valued context is given in argument
|
- Fails if the 0-valued context is given in argument
|
||||||
|
- Fails if the the pointer is not a valid context
|
||||||
|
|
||||||
The context given in parameter is overwritten by the 0-valued
|
|
||||||
context, so a pointer is passed to the function.
|
|
||||||
|
|
||||||
*** Header
|
*** Header
|
||||||
#+BEGIN_SRC C :tangle qmckl_context.h
|
#+BEGIN_SRC C :tangle qmckl_context.h
|
||||||
qmckl_exit_code qmckl_context_destroy(qmckl_context * context);
|
qmckl_exit_code qmckl_context_destroy(qmckl_context context);
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
*** Source
|
*** Source
|
||||||
#+BEGIN_SRC C :tangle qmckl_context.c
|
#+BEGIN_SRC C :tangle qmckl_context.c
|
||||||
qmckl_exit_code qmckl_context_destroy(qmckl_context *context) {
|
qmckl_exit_code qmckl_context_destroy(qmckl_context context) {
|
||||||
|
|
||||||
qmckl_context_struct* ctx;
|
qmckl_context_struct* ctx;
|
||||||
|
qmckl_context checked_context;
|
||||||
|
|
||||||
|
checked_context = qmckl_context_check(context);
|
||||||
|
if (checked_context == (qmckl_context) 0) return QMCKL_FAILURE;
|
||||||
|
|
||||||
ctx = (qmckl_context_struct*) *context;
|
ctx = (qmckl_context_struct*) context;
|
||||||
|
if (ctx == NULL) return QMCKL_FAILURE;
|
||||||
if (ctx == NULL) {
|
|
||||||
return QMCKL_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ctx->tag = INVALID_TAG;
|
||||||
free(ctx);
|
free(ctx);
|
||||||
*context = (qmckl_context) 0;
|
|
||||||
return QMCKL_SUCCESS;
|
return QMCKL_SUCCESS;
|
||||||
}
|
}
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
*** Test
|
*** Test
|
||||||
#+BEGIN_SRC C :tangle test_qmckl_context.c
|
#+BEGIN_SRC C :tangle test_qmckl_context.c
|
||||||
|
if (qmckl_context_check(new_context) != new_context) {
|
||||||
|
fprintf(stderr,"qmckl_context_destroy: new_context is invalid\n");
|
||||||
|
rc = QMCKL_FAILURE;
|
||||||
|
}
|
||||||
if (new_context == (qmckl_context) 0) {
|
if (new_context == (qmckl_context) 0) {
|
||||||
fprintf(stderr,"qmckl_context_destroy: new_context is NULL\n");
|
fprintf(stderr,"qmckl_context_destroy: new_context is NULL\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
if (qmckl_context_destroy(&new_context) == QMCKL_FAILURE) {
|
if (qmckl_context_destroy(new_context) == QMCKL_FAILURE) {
|
||||||
fprintf(stderr,"qmckl_context_destroy: Unable to destroy the new_context\n");
|
fprintf(stderr,"qmckl_context_destroy: Unable to destroy the new_context\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
if (new_context != (qmckl_context) 0) {
|
if (qmckl_context_check(new_context) == new_context) {
|
||||||
|
fprintf(stderr,"qmckl_context_destroy: new_context is valid\n");
|
||||||
|
rc = QMCKL_FAILURE;
|
||||||
|
}
|
||||||
|
if (qmckl_context_check(new_context) != (qmckl_context) 0) {
|
||||||
fprintf(stderr,"qmckl_context_destroy: new_context should be NULL\n");
|
fprintf(stderr,"qmckl_context_destroy: new_context should be NULL\n");
|
||||||
rc = QMCKL_FAILURE;
|
rc = QMCKL_FAILURE;
|
||||||
}
|
}
|
||||||
@ -272,7 +310,7 @@ qmckl_exit_code qmckl_context_destroy(qmckl_context *context) {
|
|||||||
}
|
}
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
|
||||||
* Precision
|
* Precision
|
||||||
|
|
||||||
The following functions set and get the expected required precision
|
The following functions set and get the expected required precision
|
||||||
|
Loading…
Reference in New Issue
Block a user