1/*
2 * *****************************************************************************
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2018-2023 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 public header for the bc library.
33 *
34 */
35
36#ifndef BC_BCL_H
37#define BC_BCL_H
38
39#include <stdbool.h>
40#include <stdlib.h>
41#include <limits.h>
42#include <stdint.h>
43
44#ifndef NDEBUG
45#define BC_DEBUG (1)
46#else // NDEBUG
47#define BC_DEBUG (0)
48#endif // NDEBUG
49
50#ifdef _WIN32
51#include <Windows.h>
52#include <BaseTsd.h>
53#include <stdio.h>
54#include <io.h>
55#endif // _WIN32
56
57#ifdef _WIN32
58#define ssize_t SSIZE_T
59#endif // _WIN32
60
61#define BCL_SEED_ULONGS (4)
62#define BCL_SEED_SIZE (sizeof(long) * BCL_SEED_ULONGS)
63
64// For some reason, LONG_BIT is not defined in some versions of gcc.
65// I define it here to the minimum accepted value in the POSIX standard.
66#ifndef LONG_BIT
67#define LONG_BIT (32)
68#endif // LONG_BIT
69
70#ifndef BC_LONG_BIT
71#define BC_LONG_BIT LONG_BIT
72#endif // BC_LONG_BIT
73
74#if BC_LONG_BIT > LONG_BIT
75#error BC_LONG_BIT cannot be greater than LONG_BIT
76#endif // BC_LONG_BIT > LONG_BIT
77
78// For more information about the items here, see the either the
79// manuals/bcl.3.md or manuals/bcl.3 manuals.
80
81// BclBigDig is a fixed-size integer type that bcl can convert numbers to.
82//
83// BclRandInt is the type of fixed-size integer natively returned by the
84// pseudo-random number generator.
85#if BC_LONG_BIT >= 64
86
87typedef uint64_t BclBigDig;
88typedef uint64_t BclRandInt;
89
90#elif BC_LONG_BIT >= 32
91
92typedef uint32_t BclBigDig;
93typedef uint32_t BclRandInt;
94
95#else
96
97#error BC_LONG_BIT must be at least 32
98
99#endif // BC_LONG_BIT >= 64
100
101#ifndef BC_ENABLE_LIBRARY
102#define BC_ENABLE_LIBRARY (1)
103#endif // BC_ENABLE_LIBRARY
104
105#if BC_ENABLE_LIBRARY
106
107typedef enum BclError
108{
109	BCL_ERROR_NONE,
110
111	BCL_ERROR_INVALID_NUM,
112	BCL_ERROR_INVALID_CONTEXT,
113	BCL_ERROR_SIGNAL,
114
115	BCL_ERROR_MATH_NEGATIVE,
116	BCL_ERROR_MATH_NON_INTEGER,
117	BCL_ERROR_MATH_OVERFLOW,
118	BCL_ERROR_MATH_DIVIDE_BY_ZERO,
119
120	BCL_ERROR_PARSE_INVALID_STR,
121
122	BCL_ERROR_FATAL_ALLOC_ERR,
123	BCL_ERROR_FATAL_UNKNOWN_ERR,
124
125	BCL_ERROR_NELEMS,
126
127} BclError;
128
129typedef struct BclNumber
130{
131	size_t i;
132
133} BclNumber;
134
135struct BclCtxt;
136
137typedef struct BclCtxt* BclContext;
138
139BclError
140bcl_start(void);
141
142void
143bcl_end(void);
144
145BclError
146bcl_init(void);
147
148void
149bcl_free(void);
150
151bool
152bcl_abortOnFatalError(void);
153
154void
155bcl_setAbortOnFatalError(bool abrt);
156
157bool
158bcl_leadingZeroes(void);
159
160void
161bcl_setLeadingZeroes(bool leadingZeroes);
162
163bool
164bcl_digitClamp(void);
165
166void
167bcl_setDigitClamp(bool digitClamp);
168
169void
170bcl_gc(void);
171
172BclError
173bcl_pushContext(BclContext ctxt);
174
175void
176bcl_popContext(void);
177
178BclContext
179bcl_context(void);
180
181BclContext
182bcl_ctxt_create(void);
183
184void
185bcl_ctxt_free(BclContext ctxt);
186
187void
188bcl_ctxt_freeNums(BclContext ctxt);
189
190size_t
191bcl_ctxt_scale(BclContext ctxt);
192
193void
194bcl_ctxt_setScale(BclContext ctxt, size_t scale);
195
196size_t
197bcl_ctxt_ibase(BclContext ctxt);
198
199void
200bcl_ctxt_setIbase(BclContext ctxt, size_t ibase);
201
202size_t
203bcl_ctxt_obase(BclContext ctxt);
204
205void
206bcl_ctxt_setObase(BclContext ctxt, size_t obase);
207
208BclError
209bcl_err(BclNumber n);
210
211BclNumber
212bcl_num_create(void);
213
214void
215bcl_num_free(BclNumber n);
216
217bool
218bcl_num_neg(BclNumber n);
219
220void
221bcl_num_setNeg(BclNumber n, bool neg);
222
223size_t
224bcl_num_scale(BclNumber n);
225
226BclError
227bcl_num_setScale(BclNumber n, size_t scale);
228
229size_t
230bcl_num_len(BclNumber n);
231
232BclError
233bcl_copy(BclNumber d, BclNumber s);
234
235BclNumber
236bcl_dup(BclNumber s);
237
238BclError
239bcl_bigdig(BclNumber n, BclBigDig* result);
240
241BclError
242bcl_bigdig_keep(BclNumber n, BclBigDig* result);
243
244BclNumber
245bcl_bigdig2num(BclBigDig val);
246
247BclNumber
248bcl_add(BclNumber a, BclNumber b);
249
250BclNumber
251bcl_add_keep(BclNumber a, BclNumber b);
252
253BclNumber
254bcl_sub(BclNumber a, BclNumber b);
255
256BclNumber
257bcl_sub_keep(BclNumber a, BclNumber b);
258
259BclNumber
260bcl_mul(BclNumber a, BclNumber b);
261
262BclNumber
263bcl_mul_keep(BclNumber a, BclNumber b);
264
265BclNumber
266bcl_div(BclNumber a, BclNumber b);
267
268BclNumber
269bcl_div_keep(BclNumber a, BclNumber b);
270
271BclNumber
272bcl_mod(BclNumber a, BclNumber b);
273
274BclNumber
275bcl_mod_keep(BclNumber a, BclNumber b);
276
277BclNumber
278bcl_pow(BclNumber a, BclNumber b);
279
280BclNumber
281bcl_pow_keep(BclNumber a, BclNumber b);
282
283BclNumber
284bcl_lshift(BclNumber a, BclNumber b);
285
286BclNumber
287bcl_lshift_keep(BclNumber a, BclNumber b);
288
289BclNumber
290bcl_rshift(BclNumber a, BclNumber b);
291
292BclNumber
293bcl_rshift_keep(BclNumber a, BclNumber b);
294
295BclNumber
296bcl_sqrt(BclNumber a);
297
298BclNumber
299bcl_sqrt_keep(BclNumber a);
300
301BclError
302bcl_divmod(BclNumber a, BclNumber b, BclNumber* c, BclNumber* d);
303
304BclError
305bcl_divmod_keep(BclNumber a, BclNumber b, BclNumber* c, BclNumber* d);
306
307BclNumber
308bcl_modexp(BclNumber a, BclNumber b, BclNumber c);
309
310BclNumber
311bcl_modexp_keep(BclNumber a, BclNumber b, BclNumber c);
312
313ssize_t
314bcl_cmp(BclNumber a, BclNumber b);
315
316void
317bcl_zero(BclNumber n);
318
319void
320bcl_one(BclNumber n);
321
322BclNumber
323bcl_parse(const char* restrict val);
324
325char*
326bcl_string(BclNumber n);
327
328char*
329bcl_string_keep(BclNumber n);
330
331BclNumber
332bcl_irand(BclNumber a);
333
334BclNumber
335bcl_irand_keep(BclNumber a);
336
337BclNumber
338bcl_frand(size_t places);
339
340BclNumber
341bcl_ifrand(BclNumber a, size_t places);
342
343BclNumber
344bcl_ifrand_keep(BclNumber a, size_t places);
345
346BclError
347bcl_rand_seedWithNum(BclNumber n);
348
349BclError
350bcl_rand_seedWithNum_keep(BclNumber n);
351
352BclError
353bcl_rand_seed(unsigned char seed[BCL_SEED_SIZE]);
354
355void
356bcl_rand_reseed(void);
357
358BclNumber
359bcl_rand_seed2num(void);
360
361BclRandInt
362bcl_rand_int(void);
363
364BclRandInt
365bcl_rand_bounded(BclRandInt bound);
366
367#endif // BC_ENABLE_LIBRARY
368
369#endif // BC_BCL_H
370