1 /* 2 * ***************************************************************************** 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 * 6 * Copyright (c) 2018-2021 Gavin D. Howard and contributors. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * * Redistributions of source code must retain the above copyright notice, this 12 * list of conditions and the following disclaimer. 13 * 14 * * Redistributions in binary form must reproduce the above copyright notice, 15 * this list of conditions and the following disclaimer in the documentation 16 * and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 * ***************************************************************************** 31 * 32 * The private header for the bc library. 33 * 34 */ 35 36 #ifndef LIBBC_PRIVATE_H 37 #define LIBBC_PRIVATE_H 38 39 #include <bcl.h> 40 41 #include <num.h> 42 43 #define BC_FUNC_HEADER_LOCK(l) \ 44 do { \ 45 BC_SIG_LOCK; \ 46 BC_SETJMP_LOCKED(l); \ 47 vm.err = BCL_ERROR_NONE; \ 48 vm.running = 1; \ 49 } while (0) 50 51 #define BC_FUNC_FOOTER_UNLOCK(e) \ 52 do { \ 53 BC_SIG_ASSERT_LOCKED; \ 54 e = vm.err; \ 55 vm.running = 0; \ 56 BC_UNSETJMP; \ 57 BC_LONGJMP_STOP; \ 58 vm.sig_lock = 0; \ 59 } while (0) 60 61 #define BC_FUNC_HEADER(l) \ 62 do { \ 63 BC_SETJMP(l); \ 64 vm.err = BCL_ERROR_NONE; \ 65 vm.running = 1; \ 66 } while (0) 67 68 #define BC_FUNC_HEADER_INIT(l) \ 69 do { \ 70 BC_SETJMP_LOCKED(l); \ 71 vm.err = BCL_ERROR_NONE; \ 72 vm.running = 1; \ 73 } while (0) 74 75 #define BC_FUNC_FOOTER_NO_ERR \ 76 do { \ 77 vm.running = 0; \ 78 BC_UNSETJMP; \ 79 BC_LONGJMP_STOP; \ 80 vm.sig_lock = 0; \ 81 } while (0) 82 83 #define BC_FUNC_FOOTER(e) \ 84 do { \ 85 e = vm.err; \ 86 BC_FUNC_FOOTER_NO_ERR; \ 87 } while (0) 88 89 #define BC_FUNC_RESETJMP(l) \ 90 do { \ 91 BC_SIG_ASSERT_LOCKED; \ 92 BC_UNSETJMP; \ 93 BC_SETJMP_LOCKED(l); \ 94 } while (0) 95 96 #define BC_MAYBE_SETUP(c, e, n, idx) \ 97 do { \ 98 if (BC_ERR((e) != BCL_ERROR_NONE)) { \ 99 if ((n).num != NULL) bc_num_free(&(n)); \ 100 idx.i = 0 - (size_t) (e); \ 101 } \ 102 else idx = bcl_num_insert(c, &(n)); \ 103 } while (0) 104 105 #define BC_CHECK_CTXT(c) \ 106 do { \ 107 c = bcl_context(); \ 108 if (BC_ERR(c == NULL)) { \ 109 BclNumber n_num; \ 110 n_num.i = 0 - (size_t) BCL_ERROR_INVALID_CONTEXT; \ 111 return n_num; \ 112 } \ 113 } while (0) 114 115 #define BC_CHECK_CTXT_ERR(c) \ 116 do { \ 117 c = bcl_context(); \ 118 if (BC_ERR(c == NULL)) { \ 119 return BCL_ERROR_INVALID_CONTEXT; \ 120 } \ 121 } while (0) 122 123 #define BC_CHECK_CTXT_ASSERT(c) \ 124 do { \ 125 c = bcl_context(); \ 126 assert(c != NULL); \ 127 } while (0) 128 129 #define BC_CHECK_NUM(c, n) \ 130 do { \ 131 if (BC_ERR((n).i >= (c)->nums.len)) { \ 132 if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) return (n); \ 133 else { \ 134 BclNumber n_num; \ 135 n_num.i = 0 - (size_t) BCL_ERROR_INVALID_NUM; \ 136 return n_num; \ 137 } \ 138 } \ 139 } while (0) 140 141 #define BC_CHECK_NUM_ERR(c, n) \ 142 do { \ 143 if (BC_ERR((n).i >= (c)->nums.len)) { \ 144 if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) \ 145 return (BclError) (0 - (n).i); \ 146 else return BCL_ERROR_INVALID_NUM; \ 147 } \ 148 } while (0) 149 150 #define BC_NUM(c, n) ((BcNum*) bc_vec_item(&(c)->nums, (n).i)) 151 152 typedef size_t (*BcReqOp)(const BcNum*, const BcNum*, size_t); 153 154 typedef struct BclCtxt { 155 156 size_t scale; 157 size_t ibase; 158 size_t obase; 159 160 BcVec nums; 161 BcVec free_nums; 162 163 } BclCtxt; 164 165 #endif // LIBBC_PRIVATE_H 166