2 * *****************************************************************************
4 * SPDX-License-Identifier: BSD-2-Clause
6 * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
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.
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.
30 * *****************************************************************************
32 * The private header for the bc library.
36 #ifndef LIBBC_PRIVATE_H
37 #define LIBBC_PRIVATE_H
44 * A header for functions that need to lock and setjmp(). It also sets the
45 * variable that tells bcl that it is running.
46 * @param l The label to jump to on error.
48 #define BC_FUNC_HEADER_LOCK(l) \
51 BC_SETJMP_LOCKED(l); \
52 vm.err = BCL_ERROR_NONE; \
57 * A footer to unlock and stop the jumping if an error happened. It also sets
58 * the variable that tells bcl that it is running.
59 * @param e The error variable to set.
61 #define BC_FUNC_FOOTER_UNLOCK(e) \
63 BC_SIG_ASSERT_LOCKED; \
72 * A header that sets a jump and sets running.
73 * @param l The label to jump to on error.
75 #define BC_FUNC_HEADER(l) \
78 vm.err = BCL_ERROR_NONE; \
83 * A header that assumes that signals are already locked. It sets a jump and
85 * @param l The label to jump to on error.
87 #define BC_FUNC_HEADER_INIT(l) \
89 BC_SETJMP_LOCKED(l); \
90 vm.err = BCL_ERROR_NONE; \
95 * A footer for functions that do not return an error code. It clears running
96 * and unlocks the signals. It also stops the jumping.
98 #define BC_FUNC_FOOTER_NO_ERR \
107 * A footer for functions that *do* return an error code. It clears running and
108 * unlocks the signals. It also stops the jumping.
109 * @param e The error variable to set.
111 #define BC_FUNC_FOOTER(e) \
114 BC_FUNC_FOOTER_NO_ERR; \
118 * A footer that sets up n based the value of e and sets up the return value in
120 * @param c The context.
121 * @param e The error.
122 * @param n The number.
123 * @param idx The idx to set as the return value.
125 #define BC_MAYBE_SETUP(c, e, n, idx) \
127 if (BC_ERR((e) != BCL_ERROR_NONE)) { \
128 if ((n).num != NULL) bc_num_free(&(n)); \
129 idx.i = 0 - (size_t) (e); \
131 else idx = bcl_num_insert(c, &(n)); \
135 * A header to check the context and return an error encoded in a number if it
137 * @param c The context.
139 #define BC_CHECK_CTXT(c) \
142 if (BC_ERR(c == NULL)) { \
144 n_num.i = 0 - (size_t) BCL_ERROR_INVALID_CONTEXT; \
151 * A header to check the context and return an error directly if it is bad.
152 * @param c The context.
154 #define BC_CHECK_CTXT_ERR(c) \
157 if (BC_ERR(c == NULL)) { \
158 return BCL_ERROR_INVALID_CONTEXT; \
163 * A header to check the context and abort if it is bad.
164 * @param c The context.
166 #define BC_CHECK_CTXT_ASSERT(c) \
173 * A header to check the number in the context and return an error encoded as a
174 * @param c The context.
175 * number if it is bad.
176 * @param n The BclNumber.
178 #define BC_CHECK_NUM(c, n) \
180 if (BC_ERR((n).i >= (c)->nums.len)) { \
181 if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) return (n); \
184 n_num.i = 0 - (size_t) BCL_ERROR_INVALID_NUM; \
191 * A header to check the number in the context and return an error directly if
193 * @param c The context.
194 * @param n The BclNumber.
196 #define BC_CHECK_NUM_ERR(c, n) \
198 if (BC_ERR((n).i >= (c)->nums.len)) { \
199 if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) \
200 return (BclError) (0 - (n).i); \
201 else return BCL_ERROR_INVALID_NUM; \
206 * Turns a BclNumber into a BcNum.
207 * @param c The context.
208 * @param n The BclNumber.
210 #define BC_NUM(c, n) ((BcNum*) bc_vec_item(&(c)->nums, (n).i))
213 * Frees a BcNum for bcl. This is a destructor.
214 * @param num The BcNum to free, as a void pointer.
216 void bcl_num_destruct(void *num);
218 /// The actual context struct.
219 typedef struct BclCtxt {
221 /// The context's scale.
224 /// The context's ibase.
227 /// The context's obase.
230 /// A vector of BcNum numbers.
233 /// A vector of BclNumbers. These are the indices in nums that are currently
234 /// not used (because they were freed).
239 #endif // LIBBC_PRIVATE_H