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