1 //------------------------------------------------------------------------------
2 // SLIP_LU/SLIP_gmp.h: definitions for SLIP_gmp.c
3 //------------------------------------------------------------------------------
4 
5 // SLIP_LU: (c) 2019-2020, Chris Lourenco, Jinhao Chen, Erick Moreno-Centeno,
6 // Timothy A. Davis, Texas A&M University.  All Rights Reserved.  See
7 // SLIP_LU/License for the license.
8 
9 //------------------------------------------------------------------------------
10 
11 // These macros are used by SLIP_gmp.c to create wrapper functions around all
12 // GMP functions used by SLIP_LU, to safely handle out-of-memory conditions.
13 // They are placed in this separate #include file so that a future developer
14 // can use them to construct their own wrappers around GMP functions.  See
15 // SLIP_gmp.c for more details.
16 
17 #ifndef SLIP_GMP_H
18 #define SLIP_GMP_H
19 
20 #define SLIP_GMP_WRAPPER_START                                          \
21 {                                                                       \
22     slip_gmp_nmalloc = 0 ;                                              \
23     /* setjmp returns 0 if called from here, or > 0 if from longjmp */  \
24     int slip_gmp_status = setjmp (slip_gmp_environment) ;               \
25     if (slip_gmp_status != 0)                                           \
26     {                                                                   \
27         /* failure from longjmp */                                      \
28         slip_gmp_failure (slip_gmp_status) ;                            \
29         return (SLIP_OUT_OF_MEMORY) ;                                   \
30     }                                                                   \
31 }
32 
33 #define SLIP_GMPZ_WRAPPER_START(x)                                      \
34 {                                                                       \
35     slip_gmpz_archive = (mpz_t *) x;                                    \
36     slip_gmpq_archive = NULL;                                           \
37     slip_gmpfr_archive = NULL;                                          \
38     SLIP_GMP_WRAPPER_START;                                             \
39 }
40 
41 #define SLIP_GMPQ_WRAPPER_START(x)                                      \
42 {                                                                       \
43     slip_gmpz_archive = NULL;                                           \
44     slip_gmpq_archive =(mpq_t *) x;                                     \
45     slip_gmpfr_archive = NULL;                                          \
46     SLIP_GMP_WRAPPER_START;                                             \
47 }
48 
49 #define SLIP_GMPFR_WRAPPER_START(x)                                     \
50 {                                                                       \
51     slip_gmpz_archive = NULL;                                           \
52     slip_gmpq_archive = NULL;                                           \
53     slip_gmpfr_archive = (mpfr_t *) x;                                  \
54     SLIP_GMP_WRAPPER_START;                                             \
55 }
56 
57 #define SLIP_GMP_WRAPPER_FINISH                                         \
58 {                                                                       \
59     /* clear (but do not free) the list.  The caller must ensure */     \
60     /* the result is eventually freed. */                               \
61     slip_gmpz_archive = NULL ;                                          \
62     slip_gmpq_archive = NULL ;                                          \
63     slip_gmpfr_archive = NULL ;                                         \
64     slip_gmp_nmalloc = 0 ;                                              \
65 }
66 
67 // free a block of memory, and also remove it from the archive if it's there
68 #define SLIP_GMP_SAFE_FREE(p)                                           \
69 {                                                                       \
70     if (slip_gmpz_archive != NULL)                                      \
71     {                                                                   \
72         if (p == SLIP_MPZ_PTR(*slip_gmpz_archive))                      \
73         {                                                               \
74             SLIP_MPZ_PTR(*slip_gmpz_archive) = NULL ;                   \
75         }                                                               \
76     }                                                                   \
77     else if (slip_gmpq_archive != NULL)                                 \
78     {                                                                   \
79         if (p == SLIP_MPZ_PTR(SLIP_MPQ_NUM(*slip_gmpq_archive)))        \
80         {                                                               \
81             SLIP_MPZ_PTR(SLIP_MPQ_NUM(*slip_gmpq_archive)) = NULL ;     \
82         }                                                               \
83         if (p == SLIP_MPZ_PTR(SLIP_MPQ_DEN(*slip_gmpq_archive)))        \
84         {                                                               \
85             SLIP_MPZ_PTR(SLIP_MPQ_DEN(*slip_gmpq_archive)) = NULL ;     \
86         }                                                               \
87     }                                                                   \
88     else if (slip_gmpfr_archive != NULL)                                \
89     {                                                                   \
90         if (p == SLIP_MPFR_REAL_PTR(*slip_gmpfr_archive))               \
91         {                                                               \
92             SLIP_MPFR_MANT(*slip_gmpfr_archive) = NULL ;                \
93         }                                                               \
94     }                                                                   \
95     SLIP_FREE (p) ;                                                     \
96 }
97 
98 #endif
99 
100