xref: /freebsd/contrib/bc/include/vm.h (revision 23210c9f)
1252884aeSStefan Eßer /*
2252884aeSStefan Eßer  * *****************************************************************************
3252884aeSStefan Eßer  *
43aa99676SStefan Eßer  * SPDX-License-Identifier: BSD-2-Clause
5252884aeSStefan Eßer  *
610328f8bSStefan Eßer  * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
7252884aeSStefan Eßer  *
8252884aeSStefan Eßer  * Redistribution and use in source and binary forms, with or without
9252884aeSStefan Eßer  * modification, are permitted provided that the following conditions are met:
10252884aeSStefan Eßer  *
11252884aeSStefan Eßer  * * Redistributions of source code must retain the above copyright notice, this
12252884aeSStefan Eßer  *   list of conditions and the following disclaimer.
13252884aeSStefan Eßer  *
14252884aeSStefan Eßer  * * Redistributions in binary form must reproduce the above copyright notice,
15252884aeSStefan Eßer  *   this list of conditions and the following disclaimer in the documentation
16252884aeSStefan Eßer  *   and/or other materials provided with the distribution.
17252884aeSStefan Eßer  *
18252884aeSStefan Eßer  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19252884aeSStefan Eßer  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20252884aeSStefan Eßer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21252884aeSStefan Eßer  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22252884aeSStefan Eßer  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23252884aeSStefan Eßer  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24252884aeSStefan Eßer  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25252884aeSStefan Eßer  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26252884aeSStefan Eßer  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27252884aeSStefan Eßer  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28252884aeSStefan Eßer  * POSSIBILITY OF SUCH DAMAGE.
29252884aeSStefan Eßer  *
30252884aeSStefan Eßer  * *****************************************************************************
31252884aeSStefan Eßer  *
32252884aeSStefan Eßer  * Definitions for bc's VM.
33252884aeSStefan Eßer  *
34252884aeSStefan Eßer  */
35252884aeSStefan Eßer 
36252884aeSStefan Eßer #ifndef BC_VM_H
37252884aeSStefan Eßer #define BC_VM_H
38252884aeSStefan Eßer 
3950696a6eSStefan Eßer #include <assert.h>
40252884aeSStefan Eßer #include <stddef.h>
41252884aeSStefan Eßer #include <limits.h>
42252884aeSStefan Eßer 
43252884aeSStefan Eßer #include <signal.h>
44252884aeSStefan Eßer 
45252884aeSStefan Eßer #if BC_ENABLE_NLS
46252884aeSStefan Eßer 
47252884aeSStefan Eßer #ifdef _WIN32
48252884aeSStefan Eßer #error NLS is not supported on Windows.
49252884aeSStefan Eßer #endif // _WIN32
50252884aeSStefan Eßer 
51252884aeSStefan Eßer #include <nl_types.h>
52252884aeSStefan Eßer 
53252884aeSStefan Eßer #endif // BC_ENABLE_NLS
54252884aeSStefan Eßer 
557e5c51e5SStefan Eßer #include <version.h>
56252884aeSStefan Eßer #include <status.h>
57252884aeSStefan Eßer #include <num.h>
5844d4804dSStefan Eßer #include <lex.h>
59252884aeSStefan Eßer #include <parse.h>
60252884aeSStefan Eßer #include <program.h>
61252884aeSStefan Eßer #include <history.h>
6244d4804dSStefan Eßer #include <bc.h>
6350696a6eSStefan Eßer 
6444d4804dSStefan Eßer // We don't want to include this file for the library because it's unused.
6550696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY
66252884aeSStefan Eßer #include <file.h>
6750696a6eSStefan Eßer #endif // !BC_ENABLE_LIBRARY
68252884aeSStefan Eßer 
6944d4804dSStefan Eßer // This should be obvious. If neither calculator is enabled, barf.
70252884aeSStefan Eßer #if !BC_ENABLED && !DC_ENABLED
71252884aeSStefan Eßer #error Must define BC_ENABLED, DC_ENABLED, or both
72252884aeSStefan Eßer #endif
73252884aeSStefan Eßer 
7444d4804dSStefan Eßer // CHAR_BIT must be at least 6, for various reasons. I might want to bump this
7544d4804dSStefan Eßer // to 8 in the future.
76252884aeSStefan Eßer #if CHAR_BIT < 6
77252884aeSStefan Eßer #error CHAR_BIT must be at least 6.
78252884aeSStefan Eßer #endif
79252884aeSStefan Eßer 
8044d4804dSStefan Eßer // Set defaults.
8144d4804dSStefan Eßer //
82252884aeSStefan Eßer #ifndef BC_ENABLE_NLS
83252884aeSStefan Eßer #define BC_ENABLE_NLS (0)
84252884aeSStefan Eßer #endif // BC_ENABLE_NLS
85252884aeSStefan Eßer 
86252884aeSStefan Eßer #ifndef MAINEXEC
87252884aeSStefan Eßer #define MAINEXEC bc
887e5c51e5SStefan Eßer #endif // MAINEXEC
89252884aeSStefan Eßer 
907e5c51e5SStefan Eßer #ifndef _WIN32
91252884aeSStefan Eßer #ifndef EXECPREFIX
92252884aeSStefan Eßer #define EXECPREFIX
937e5c51e5SStefan Eßer #endif // EXECPREFIX
947e5c51e5SStefan Eßer #else // _WIN32
957e5c51e5SStefan Eßer #undef EXECPREFIX
967e5c51e5SStefan Eßer #endif // _WIN32
97252884aeSStefan Eßer 
9844d4804dSStefan Eßer /**
9944d4804dSStefan Eßer  * Generate a string from text.
10044d4804dSStefan Eßer  * @parm V  The text to generate a string for.
10144d4804dSStefan Eßer  */
102252884aeSStefan Eßer #define GEN_STR(V) #V
10344d4804dSStefan Eßer 
10444d4804dSStefan Eßer /**
10544d4804dSStefan Eßer  * Help generate a string from text. The preprocessor requires this two-step
10644d4804dSStefan Eßer  * process. Trust me.
10744d4804dSStefan Eßer  * @parm V  The text to generate a string for.
10844d4804dSStefan Eßer  */
109252884aeSStefan Eßer #define GEN_STR2(V) GEN_STR(V)
110252884aeSStefan Eßer 
11144d4804dSStefan Eßer /// The version as a string. VERSION must be defined previously, usually by the
11244d4804dSStefan Eßer /// build system.
113252884aeSStefan Eßer #define BC_VERSION GEN_STR2(VERSION)
11444d4804dSStefan Eßer 
11544d4804dSStefan Eßer /// The main executable name as a string. MAINEXEC must be defined previously,
11644d4804dSStefan Eßer /// usually by the build system.
117252884aeSStefan Eßer #define BC_MAINEXEC GEN_STR2(MAINEXEC)
11844d4804dSStefan Eßer 
11944d4804dSStefan Eßer /// The build type as a string. BUILD_TYPE must be defined previously, usually
12044d4804dSStefan Eßer /// by the build system.
1217e5c51e5SStefan Eßer #define BC_BUILD_TYPE GEN_STR2(BUILD_TYPE)
122252884aeSStefan Eßer 
12344d4804dSStefan Eßer // We only allow an empty executable prefix on Windows.
1247e5c51e5SStefan Eßer #ifndef _WIN32
1257e5c51e5SStefan Eßer #define BC_EXECPREFIX GEN_STR2(EXECPREFIX)
1267e5c51e5SStefan Eßer #else // _WIN32
1277e5c51e5SStefan Eßer #define BC_EXECPREFIX ""
128252884aeSStefan Eßer #endif // _WIN32
129252884aeSStefan Eßer 
13050696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY
13150696a6eSStefan Eßer 
1323aa99676SStefan Eßer #if DC_ENABLED
13344d4804dSStefan Eßer 
13444d4804dSStefan Eßer /// The flag for the extended register option.
135252884aeSStefan Eßer #define DC_FLAG_X (UINTMAX_C(1)<<0)
13644d4804dSStefan Eßer 
1373aa99676SStefan Eßer #endif // DC_ENABLED
1383aa99676SStefan Eßer 
1393aa99676SStefan Eßer #if BC_ENABLED
14044d4804dSStefan Eßer 
14144d4804dSStefan Eßer /// The flag for the POSIX warning option.
142252884aeSStefan Eßer #define BC_FLAG_W (UINTMAX_C(1)<<1)
14344d4804dSStefan Eßer 
14444d4804dSStefan Eßer /// The flag for the POSIX error option.
145252884aeSStefan Eßer #define BC_FLAG_S (UINTMAX_C(1)<<2)
14644d4804dSStefan Eßer 
14744d4804dSStefan Eßer /// The flag for the math library option.
1483aa99676SStefan Eßer #define BC_FLAG_L (UINTMAX_C(1)<<3)
14944d4804dSStefan Eßer 
15044d4804dSStefan Eßer /// The flag for the global stacks option.
1513aa99676SStefan Eßer #define BC_FLAG_G (UINTMAX_C(1)<<4)
15244d4804dSStefan Eßer 
1533aa99676SStefan Eßer #endif // BC_ENABLED
1543aa99676SStefan Eßer 
15544d4804dSStefan Eßer /// The flag for quiet, though this one is reversed; the option clears the flag.
15644d4804dSStefan Eßer #define BC_FLAG_Q (UINTMAX_C(1)<<5)
15744d4804dSStefan Eßer 
15844d4804dSStefan Eßer /// The flag for interactive.
15944d4804dSStefan Eßer #define BC_FLAG_I (UINTMAX_C(1)<<6)
16044d4804dSStefan Eßer 
16144d4804dSStefan Eßer /// The flag for prompt. This is also reversed; the option clears the flag.
16244d4804dSStefan Eßer #define BC_FLAG_P (UINTMAX_C(1)<<7)
16344d4804dSStefan Eßer 
16444d4804dSStefan Eßer /// The flag for read prompt. This is also reversed; the option clears the flag.
16544d4804dSStefan Eßer #define BC_FLAG_R (UINTMAX_C(1)<<8)
16644d4804dSStefan Eßer 
167d43fa8efSStefan Eßer /// The flag for a leading zero.
168d43fa8efSStefan Eßer #define BC_FLAG_Z (UINTMAX_C(1)<<9)
169d43fa8efSStefan Eßer 
17044d4804dSStefan Eßer /// The flag for stdin being a TTY.
171d43fa8efSStefan Eßer #define BC_FLAG_TTYIN (UINTMAX_C(1)<<10)
17244d4804dSStefan Eßer 
17344d4804dSStefan Eßer /// The flag for TTY mode.
174d43fa8efSStefan Eßer #define BC_FLAG_TTY (UINTMAX_C(1)<<11)
17544d4804dSStefan Eßer 
17644d4804dSStefan Eßer /// The flag for reset on SIGINT.
177d43fa8efSStefan Eßer #define BC_FLAG_SIGINT (UINTMAX_C(1)<<12)
17844d4804dSStefan Eßer 
17910041e99SStefan Eßer /// The flag for exiting with expressions.
18010041e99SStefan Eßer #define BC_FLAG_EXPR_EXIT (UINTMAX_C(1)<<13)
18110041e99SStefan Eßer 
18244d4804dSStefan Eßer /// A convenience macro for getting the TTYIN flag.
183252884aeSStefan Eßer #define BC_TTYIN (vm.flags & BC_FLAG_TTYIN)
18444d4804dSStefan Eßer 
18544d4804dSStefan Eßer /// A convenience macro for getting the TTY flag.
186252884aeSStefan Eßer #define BC_TTY (vm.flags & BC_FLAG_TTY)
187252884aeSStefan Eßer 
18844d4804dSStefan Eßer /// A convenience macro for getting the SIGINT flag.
18944d4804dSStefan Eßer #define BC_SIGINT (vm.flags & BC_FLAG_SIGINT)
19044d4804dSStefan Eßer 
1913aa99676SStefan Eßer #if BC_ENABLED
1923aa99676SStefan Eßer 
19344d4804dSStefan Eßer /// A convenience macro for getting the POSIX error flag.
194cf7becd2SStefan Eßer #define BC_S (vm.flags & BC_FLAG_S)
19544d4804dSStefan Eßer 
19644d4804dSStefan Eßer /// A convenience macro for getting the POSIX warning flag.
197cf7becd2SStefan Eßer #define BC_W (vm.flags & BC_FLAG_W)
19844d4804dSStefan Eßer 
19944d4804dSStefan Eßer /// A convenience macro for getting the math library flag.
200cf7becd2SStefan Eßer #define BC_L (vm.flags & BC_FLAG_L)
20144d4804dSStefan Eßer 
20244d4804dSStefan Eßer /// A convenience macro for getting the global stacks flag.
203cf7becd2SStefan Eßer #define BC_G (vm.flags & BC_FLAG_G)
2043aa99676SStefan Eßer 
2053aa99676SStefan Eßer #endif // BC_ENABLED
2063aa99676SStefan Eßer 
2073aa99676SStefan Eßer #if DC_ENABLED
20844d4804dSStefan Eßer 
20944d4804dSStefan Eßer /// A convenience macro for getting the extended register flag.
2103aa99676SStefan Eßer #define DC_X (vm.flags & DC_FLAG_X)
21144d4804dSStefan Eßer 
2123aa99676SStefan Eßer #endif // DC_ENABLED
2133aa99676SStefan Eßer 
21444d4804dSStefan Eßer /// A convenience macro for getting the interactive flag.
2153aa99676SStefan Eßer #define BC_I (vm.flags & BC_FLAG_I)
21644d4804dSStefan Eßer 
21744d4804dSStefan Eßer /// A convenience macro for getting the prompt flag.
218252884aeSStefan Eßer #define BC_P (vm.flags & BC_FLAG_P)
21944d4804dSStefan Eßer 
22044d4804dSStefan Eßer /// A convenience macro for getting the read prompt flag.
2217e5c51e5SStefan Eßer #define BC_R (vm.flags & BC_FLAG_R)
222252884aeSStefan Eßer 
223d43fa8efSStefan Eßer /// A convenience macro for getting the leading zero flag.
224d43fa8efSStefan Eßer #define BC_Z (vm.flags & BC_FLAG_Z)
225d43fa8efSStefan Eßer 
22610041e99SStefan Eßer /// A convenience macro for getting the expression exit flag.
22710041e99SStefan Eßer #define BC_EXPR_EXIT (vm.flags & BC_FLAG_EXPR_EXIT)
22810041e99SStefan Eßer 
2293aa99676SStefan Eßer #if BC_ENABLED
2303aa99676SStefan Eßer 
23144d4804dSStefan Eßer /// A convenience macro for checking if bc is in POSIX mode.
2323aa99676SStefan Eßer #define BC_IS_POSIX (BC_S || BC_W)
2333aa99676SStefan Eßer 
2343aa99676SStefan Eßer #if DC_ENABLED
23544d4804dSStefan Eßer 
23644d4804dSStefan Eßer /// Returns true if bc is running.
2373aa99676SStefan Eßer #define BC_IS_BC (vm.name[0] != 'd')
23844d4804dSStefan Eßer 
23944d4804dSStefan Eßer /// Returns true if dc is running.
2403aa99676SStefan Eßer #define BC_IS_DC (vm.name[0] == 'd')
24144d4804dSStefan Eßer 
2423aa99676SStefan Eßer #else // DC_ENABLED
24344d4804dSStefan Eßer 
24444d4804dSStefan Eßer /// Returns true if bc is running.
2453aa99676SStefan Eßer #define BC_IS_BC (1)
24644d4804dSStefan Eßer 
24744d4804dSStefan Eßer /// Returns true if dc is running.
2483aa99676SStefan Eßer #define BC_IS_DC (0)
24944d4804dSStefan Eßer 
2503aa99676SStefan Eßer #endif // DC_ENABLED
2513aa99676SStefan Eßer 
2523aa99676SStefan Eßer #else // BC_ENABLED
25344d4804dSStefan Eßer 
25444d4804dSStefan Eßer /// A convenience macro for checking if bc is in POSIX mode.
2553aa99676SStefan Eßer #define BC_IS_POSIX (0)
25644d4804dSStefan Eßer 
25744d4804dSStefan Eßer /// Returns true if bc is running.
2583aa99676SStefan Eßer #define BC_IS_BC (0)
25944d4804dSStefan Eßer 
26044d4804dSStefan Eßer /// Returns true if dc is running.
2613aa99676SStefan Eßer #define BC_IS_DC (1)
26244d4804dSStefan Eßer 
2633aa99676SStefan Eßer #endif // BC_ENABLED
2643aa99676SStefan Eßer 
26544d4804dSStefan Eßer /// A convenience macro for checking if the prompt is enabled.
26644d4804dSStefan Eßer #define BC_PROMPT (BC_P)
267252884aeSStefan Eßer 
268d43fa8efSStefan Eßer #else // !BC_ENABLE_LIBRARY
269d43fa8efSStefan Eßer 
270d43fa8efSStefan Eßer #define BC_Z (vm.leading_zeroes)
271d43fa8efSStefan Eßer 
27250696a6eSStefan Eßer #endif // !BC_ENABLE_LIBRARY
27350696a6eSStefan Eßer 
27444d4804dSStefan Eßer /**
27544d4804dSStefan Eßer  * Returns the max of its two arguments. This evaluates arguments twice, so be
27644d4804dSStefan Eßer  * careful what args you give it.
27744d4804dSStefan Eßer  * @param a  The first argument.
27844d4804dSStefan Eßer  * @param b  The second argument.
27944d4804dSStefan Eßer  * @return   The max of the two arguments.
28044d4804dSStefan Eßer  */
281252884aeSStefan Eßer #define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
28244d4804dSStefan Eßer 
28344d4804dSStefan Eßer /**
28444d4804dSStefan Eßer  * Returns the min of its two arguments. This evaluates arguments twice, so be
28544d4804dSStefan Eßer  * careful what args you give it.
28644d4804dSStefan Eßer  * @param a  The first argument.
28744d4804dSStefan Eßer  * @param b  The second argument.
28844d4804dSStefan Eßer  * @return   The min of the two arguments.
28944d4804dSStefan Eßer  */
290252884aeSStefan Eßer #define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
291252884aeSStefan Eßer 
29244d4804dSStefan Eßer /// Returns the max obase that is allowed.
293252884aeSStefan Eßer #define BC_MAX_OBASE ((BcBigDig) (BC_BASE_POW))
29444d4804dSStefan Eßer 
29544d4804dSStefan Eßer /// Returns the max array size that is allowed.
296252884aeSStefan Eßer #define BC_MAX_DIM ((BcBigDig) (SIZE_MAX - 1))
29744d4804dSStefan Eßer 
29844d4804dSStefan Eßer /// Returns the max scale that is allowed.
299252884aeSStefan Eßer #define BC_MAX_SCALE ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1))
30044d4804dSStefan Eßer 
30144d4804dSStefan Eßer /// Returns the max string length that is allowed.
302252884aeSStefan Eßer #define BC_MAX_STRING ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1))
30344d4804dSStefan Eßer 
30444d4804dSStefan Eßer /// Returns the max identifier length that is allowed.
305252884aeSStefan Eßer #define BC_MAX_NAME BC_MAX_STRING
30644d4804dSStefan Eßer 
30744d4804dSStefan Eßer /// Returns the max number size that is allowed.
308252884aeSStefan Eßer #define BC_MAX_NUM BC_MAX_SCALE
309252884aeSStefan Eßer 
310252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH
31144d4804dSStefan Eßer 
31244d4804dSStefan Eßer /// Returns the max random integer that can be returned.
313252884aeSStefan Eßer #define BC_MAX_RAND ((BcBigDig) (((BcRand) 0) - 1))
31444d4804dSStefan Eßer 
315252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH
316252884aeSStefan Eßer 
31744d4804dSStefan Eßer /// Returns the max exponent that is allowed.
318252884aeSStefan Eßer #define BC_MAX_EXP ((ulong) (BC_NUM_BIGDIG_MAX))
31944d4804dSStefan Eßer 
32044d4804dSStefan Eßer /// Returns the max number of variables that is allowed.
321252884aeSStefan Eßer #define BC_MAX_VARS ((ulong) (SIZE_MAX - 1))
322252884aeSStefan Eßer 
32344d4804dSStefan Eßer /// The size of the global buffer.
324252884aeSStefan Eßer #define BC_VM_BUF_SIZE (1<<12)
32544d4804dSStefan Eßer 
32644d4804dSStefan Eßer /// The amount of the global buffer allocated to stdout.
327252884aeSStefan Eßer #define BC_VM_STDOUT_BUF_SIZE (1<<11)
32844d4804dSStefan Eßer 
32944d4804dSStefan Eßer /// The amount of the global buffer allocated to stderr.
330252884aeSStefan Eßer #define BC_VM_STDERR_BUF_SIZE (1<<10)
33144d4804dSStefan Eßer 
33244d4804dSStefan Eßer /// The amount of the global buffer allocated to stdin.
3333aa99676SStefan Eßer #define BC_VM_STDIN_BUF_SIZE (BC_VM_STDERR_BUF_SIZE - 1)
3343aa99676SStefan Eßer 
33544d4804dSStefan Eßer /// The max number of temporary BcNums that can be kept.
33644d4804dSStefan Eßer #define BC_VM_MAX_TEMPS (1 << 9)
33744d4804dSStefan Eßer 
33844d4804dSStefan Eßer /// The capacity of the one BcNum, which is a constant.
33944d4804dSStefan Eßer #define BC_VM_ONE_CAP (1)
34044d4804dSStefan Eßer 
34144d4804dSStefan Eßer /**
34244d4804dSStefan Eßer  * Returns true if a BcResult is safe for garbage collection.
34344d4804dSStefan Eßer  * @param r  The BcResult to test.
34444d4804dSStefan Eßer  * @return   True if @a r is safe to garbage collect.
34544d4804dSStefan Eßer  */
3463aa99676SStefan Eßer #define BC_VM_SAFE_RESULT(r) ((r)->t >= BC_RESULT_TEMP)
347252884aeSStefan Eßer 
34844d4804dSStefan Eßer /// The invalid locale catalog return value.
349252884aeSStefan Eßer #define BC_VM_INVALID_CATALOG ((nl_catd) -1)
350252884aeSStefan Eßer 
35144d4804dSStefan Eßer /**
35244d4804dSStefan Eßer  * Returns true if the *unsigned* multiplication overflows.
35344d4804dSStefan Eßer  * @param a  The first operand.
35444d4804dSStefan Eßer  * @param b  The second operand.
35544d4804dSStefan Eßer  * @param r  The product.
35644d4804dSStefan Eßer  * @return   True if the multiplication of @a a and @a b overflows.
35744d4804dSStefan Eßer  */
35844d4804dSStefan Eßer #define BC_VM_MUL_OVERFLOW(a, b, r) \
35944d4804dSStefan Eßer 	((r) >= SIZE_MAX || ((a) != 0 && (r) / (a) != (b)))
36050696a6eSStefan Eßer 
36144d4804dSStefan Eßer /// The global vm struct. This holds all of the global data besides the file
36244d4804dSStefan Eßer /// buffers.
363252884aeSStefan Eßer typedef struct BcVm {
364252884aeSStefan Eßer 
36544d4804dSStefan Eßer 	/// The current status. This is volatile sig_atomic_t because it is also
36644d4804dSStefan Eßer 	/// used in the signal handler. See the development manual
36744d4804dSStefan Eßer 	/// (manuals/development.md#async-signal-safe-signal-handling) for more
36844d4804dSStefan Eßer 	/// information.
369252884aeSStefan Eßer 	volatile sig_atomic_t status;
37044d4804dSStefan Eßer 
37144d4804dSStefan Eßer 	/// Non-zero if a jump series is in progress and items should be popped off
37244d4804dSStefan Eßer 	/// the jmp_bufs vector. This is volatile sig_atomic_t because it is also
37344d4804dSStefan Eßer 	/// used in the signal handler. See the development manual
37444d4804dSStefan Eßer 	/// (manuals/development.md#async-signal-safe-signal-handling) for more
37544d4804dSStefan Eßer 	/// information.
376252884aeSStefan Eßer 	volatile sig_atomic_t sig_pop;
377252884aeSStefan Eßer 
37850696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY
37944d4804dSStefan Eßer 
38044d4804dSStefan Eßer 	/// The parser.
381252884aeSStefan Eßer 	BcParse prs;
38244d4804dSStefan Eßer 
38344d4804dSStefan Eßer 	/// The program.
384252884aeSStefan Eßer 	BcProgram prog;
38544d4804dSStefan Eßer 
38644d4804dSStefan Eßer 	/// A buffer for lines for stdin.
38744d4804dSStefan Eßer 	BcVec line_buf;
38844d4804dSStefan Eßer 
38944d4804dSStefan Eßer 	/// A buffer to hold a series of lines from stdin. Sometimes, multiple lines
39044d4804dSStefan Eßer 	/// are necessary for parsing, such as a comment that spans multiple lines.
39144d4804dSStefan Eßer 	BcVec buffer;
39244d4804dSStefan Eßer 
39344d4804dSStefan Eßer 	/// A parser to parse read expressions.
39444d4804dSStefan Eßer 	BcParse read_prs;
39544d4804dSStefan Eßer 
39644d4804dSStefan Eßer 	/// A buffer for read expressions.
39744d4804dSStefan Eßer 	BcVec read_buf;
39844d4804dSStefan Eßer 
39910328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY
400252884aeSStefan Eßer 
40144d4804dSStefan Eßer 	/// A vector of jmp_bufs for doing a jump series. This allows exception-type
40244d4804dSStefan Eßer 	/// error handling, while allowing me to do cleanup on the way.
403252884aeSStefan Eßer 	BcVec jmp_bufs;
404252884aeSStefan Eßer 
40544d4804dSStefan Eßer 	/// The number of temps in the temps array.
40644d4804dSStefan Eßer 	size_t temps_len;
407252884aeSStefan Eßer 
40850696a6eSStefan Eßer #if BC_ENABLE_LIBRARY
40950696a6eSStefan Eßer 
41044d4804dSStefan Eßer 	/// The vector of contexts for the library.
41150696a6eSStefan Eßer 	BcVec ctxts;
41244d4804dSStefan Eßer 
41344d4804dSStefan Eßer 	/// The vector for creating strings to pass to the client.
41450696a6eSStefan Eßer 	BcVec out;
41550696a6eSStefan Eßer 
41644d4804dSStefan Eßer 	/// The PRNG.
41750696a6eSStefan Eßer 	BcRNG rng;
41850696a6eSStefan Eßer 
41944d4804dSStefan Eßer 	/// The current error.
42050696a6eSStefan Eßer 	BclError err;
42144d4804dSStefan Eßer 
42244d4804dSStefan Eßer 	/// Whether or not bcl should abort on fatal errors.
42350696a6eSStefan Eßer 	bool abrt;
42450696a6eSStefan Eßer 
425d43fa8efSStefan Eßer 	/// Whether or not to print leading zeros.
426d43fa8efSStefan Eßer 	bool leading_zeroes;
427d43fa8efSStefan Eßer 
42844d4804dSStefan Eßer 	/// The number of "references," or times that the library was initialized.
42950696a6eSStefan Eßer 	unsigned int refs;
43050696a6eSStefan Eßer 
43144d4804dSStefan Eßer 	/// Non-zero if bcl is running. This is volatile sig_atomic_t because it is
43244d4804dSStefan Eßer 	/// also used in the signal handler. See the development manual
43344d4804dSStefan Eßer 	/// (manuals/development.md#async-signal-safe-signal-handling) for more
43444d4804dSStefan Eßer 	/// information.
43550696a6eSStefan Eßer 	volatile sig_atomic_t running;
43644d4804dSStefan Eßer 
43750696a6eSStefan Eßer #endif // BC_ENABLE_LIBRARY
43850696a6eSStefan Eßer 
43950696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY
44044d4804dSStefan Eßer 
44144d4804dSStefan Eßer 	/// A pointer to the filename of the current file. This is not owned by the
44244d4804dSStefan Eßer 	/// BcVm struct.
443252884aeSStefan Eßer 	const char* file;
444252884aeSStefan Eßer 
44544d4804dSStefan Eßer 	/// The message printed when SIGINT happens.
446252884aeSStefan Eßer 	const char *sigmsg;
44744d4804dSStefan Eßer 
44810328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY
44944d4804dSStefan Eßer 
45044d4804dSStefan Eßer 	/// Non-zero when signals are "locked." This is volatile sig_atomic_t
45144d4804dSStefan Eßer 	/// because it is also used in the signal handler. See the development
45244d4804dSStefan Eßer 	/// manual (manuals/development.md#async-signal-safe-signal-handling) for
45344d4804dSStefan Eßer 	/// more information.
454252884aeSStefan Eßer 	volatile sig_atomic_t sig_lock;
45544d4804dSStefan Eßer 
45644d4804dSStefan Eßer 	/// Non-zero when a signal has been received, but not acted on. This is
45744d4804dSStefan Eßer 	/// volatile sig_atomic_t because it is also used in the signal handler. See
45844d4804dSStefan Eßer 	/// the development manual
45944d4804dSStefan Eßer 	/// (manuals/development.md#async-signal-safe-signal-handling) for more
46044d4804dSStefan Eßer 	/// information.
461252884aeSStefan Eßer 	volatile sig_atomic_t sig;
46244d4804dSStefan Eßer 
46350696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY
46444d4804dSStefan Eßer 
46544d4804dSStefan Eßer 	/// The length of sigmsg.
466252884aeSStefan Eßer 	uchar siglen;
467252884aeSStefan Eßer 
46844d4804dSStefan Eßer 	/// The instruction used for returning from a read() call.
469252884aeSStefan Eßer 	uchar read_ret;
47044d4804dSStefan Eßer 
47144d4804dSStefan Eßer 	/// The flags field used by most macros above.
472252884aeSStefan Eßer 	uint16_t flags;
473252884aeSStefan Eßer 
47444d4804dSStefan Eßer 	/// The number of characters printed in the current line. This is used
47544d4804dSStefan Eßer 	/// because bc has a limit of the number of characters it can print per
47644d4804dSStefan Eßer 	/// line.
477252884aeSStefan Eßer 	uint16_t nchars;
47844d4804dSStefan Eßer 
47944d4804dSStefan Eßer 	/// The length of the line we can print. The user can set this if they wish.
480252884aeSStefan Eßer 	uint16_t line_len;
481252884aeSStefan Eßer 
48244d4804dSStefan Eßer 	/// True if bc should error if expressions are encountered during option
48344d4804dSStefan Eßer 	/// parsing, false otherwise.
48444d4804dSStefan Eßer 	bool no_exprs;
48544d4804dSStefan Eßer 
48644d4804dSStefan Eßer 	/// True if bc should exit if expresions are encountered.
4879a995fe1SStefan Eßer 	bool exit_exprs;
48844d4804dSStefan Eßer 
48944d4804dSStefan Eßer 	/// True if EOF was encountered.
490252884aeSStefan Eßer 	bool eof;
49144d4804dSStefan Eßer 
49244d4804dSStefan Eßer 	/// True if bc is currently reading from stdin.
49344d4804dSStefan Eßer 	bool is_stdin;
49444d4804dSStefan Eßer 
49544d4804dSStefan Eßer #if BC_ENABLED
49644d4804dSStefan Eßer 
49744d4804dSStefan Eßer 	/// True if keywords should not be redefined. This is only true for the
49844d4804dSStefan Eßer 	/// builtin math libraries for bc.
49944d4804dSStefan Eßer 	bool no_redefine;
50044d4804dSStefan Eßer 
50144d4804dSStefan Eßer #endif // BC_ENABLED
50244d4804dSStefan Eßer 
50310328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY
504252884aeSStefan Eßer 
50544d4804dSStefan Eßer 	/// An array of maxes for the globals.
506252884aeSStefan Eßer 	BcBigDig maxes[BC_PROG_GLOBALS_LEN + BC_ENABLE_EXTRA_MATH];
507252884aeSStefan Eßer 
50850696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY
50944d4804dSStefan Eßer 
51044d4804dSStefan Eßer 	/// A vector of filenames to process.
511252884aeSStefan Eßer 	BcVec files;
51244d4804dSStefan Eßer 
51344d4804dSStefan Eßer 	/// A vector of expressions to process.
514252884aeSStefan Eßer 	BcVec exprs;
515252884aeSStefan Eßer 
51644d4804dSStefan Eßer 	/// The name of the calculator under use. This is used by BC_IS_BC and
51744d4804dSStefan Eßer 	/// BC_IS_DC.
518252884aeSStefan Eßer 	const char *name;
51944d4804dSStefan Eßer 
52044d4804dSStefan Eßer 	/// The help text for the calculator.
521252884aeSStefan Eßer 	const char *help;
522252884aeSStefan Eßer 
523252884aeSStefan Eßer #if BC_ENABLE_HISTORY
52444d4804dSStefan Eßer 
52544d4804dSStefan Eßer 	/// The history data.
526252884aeSStefan Eßer 	BcHistory history;
52744d4804dSStefan Eßer 
528252884aeSStefan Eßer #endif // BC_ENABLE_HISTORY
529252884aeSStefan Eßer 
53044d4804dSStefan Eßer 	/// The function to call to get the next lex token.
531252884aeSStefan Eßer 	BcLexNext next;
53244d4804dSStefan Eßer 
53344d4804dSStefan Eßer 	/// The function to call to parse.
534252884aeSStefan Eßer 	BcParseParse parse;
53544d4804dSStefan Eßer 
53644d4804dSStefan Eßer 	/// The function to call to parse expressions.
537252884aeSStefan Eßer 	BcParseExpr expr;
538252884aeSStefan Eßer 
53944d4804dSStefan Eßer 	/// The text to display to label functions in error messages.
540252884aeSStefan Eßer 	const char *func_header;
541252884aeSStefan Eßer 
54244d4804dSStefan Eßer 	/// The names of the categories of errors.
543252884aeSStefan Eßer 	const char *err_ids[BC_ERR_IDX_NELEMS + BC_ENABLED];
54444d4804dSStefan Eßer 
54544d4804dSStefan Eßer 	/// The messages for each error.
54650696a6eSStefan Eßer 	const char *err_msgs[BC_ERR_NELEMS];
547252884aeSStefan Eßer 
54800698711SStefan Eßer #if BC_ENABLE_NLS
54944d4804dSStefan Eßer 	/// The locale.
550252884aeSStefan Eßer 	const char *locale;
55100698711SStefan Eßer #endif // BC_ENABLE_NLS
55244d4804dSStefan Eßer 
55310328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY
554252884aeSStefan Eßer 
55544d4804dSStefan Eßer 	/// The last base used to parse.
556252884aeSStefan Eßer 	BcBigDig last_base;
55744d4804dSStefan Eßer 
55844d4804dSStefan Eßer 	/// The last power of last_base used to parse.
559252884aeSStefan Eßer 	BcBigDig last_pow;
56044d4804dSStefan Eßer 
56144d4804dSStefan Eßer 	/// The last exponent of base that equals last_pow.
562252884aeSStefan Eßer 	BcBigDig last_exp;
56344d4804dSStefan Eßer 
56444d4804dSStefan Eßer 	/// BC_BASE_POW - last_pow.
565252884aeSStefan Eßer 	BcBigDig last_rem;
566252884aeSStefan Eßer 
56750696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY
56844d4804dSStefan Eßer 
56944d4804dSStefan Eßer 	/// A buffer of environment arguments. This is the actual value of the
57044d4804dSStefan Eßer 	/// environment variable.
571252884aeSStefan Eßer 	char *env_args_buffer;
57244d4804dSStefan Eßer 
57344d4804dSStefan Eßer 	/// A vector for environment arguments after parsing.
574252884aeSStefan Eßer 	BcVec env_args;
57544d4804dSStefan Eßer 
57644d4804dSStefan Eßer 	/// A BcNum set to constant 0.
57744d4804dSStefan Eßer 	BcNum zero;
57844d4804dSStefan Eßer 
57910328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY
580252884aeSStefan Eßer 
58144d4804dSStefan Eßer 	/// A BcNum set to constant 1.
58244d4804dSStefan Eßer 	BcNum one;
58344d4804dSStefan Eßer 
58444d4804dSStefan Eßer 	/// A BcNum holding the max number held by a BcBigDig plus 1.
585252884aeSStefan Eßer 	BcNum max;
58644d4804dSStefan Eßer 
58744d4804dSStefan Eßer 	/// A BcNum holding the max number held by a BcBigDig times 2 plus 1.
58850696a6eSStefan Eßer 	BcNum max2;
58944d4804dSStefan Eßer 
59044d4804dSStefan Eßer 	/// The BcDig array for max.
591252884aeSStefan Eßer 	BcDig max_num[BC_NUM_BIGDIG_LOG10];
59244d4804dSStefan Eßer 
59344d4804dSStefan Eßer 	/// The BcDig array for max2.
59450696a6eSStefan Eßer 	BcDig max2_num[BC_NUM_BIGDIG_LOG10];
595252884aeSStefan Eßer 
59644d4804dSStefan Eßer 	// The BcDig array for the one BcNum.
59744d4804dSStefan Eßer 	BcDig one_num[BC_VM_ONE_CAP];
59844d4804dSStefan Eßer 
59950696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY
60044d4804dSStefan Eßer 
60144d4804dSStefan Eßer 	// The BcDig array for the zero BcNum.
60244d4804dSStefan Eßer 	BcDig zero_num[BC_VM_ONE_CAP];
60344d4804dSStefan Eßer 
60444d4804dSStefan Eßer 	/// The stdout file.
605252884aeSStefan Eßer 	BcFile fout;
60644d4804dSStefan Eßer 
60744d4804dSStefan Eßer 	/// The stderr file.
608252884aeSStefan Eßer 	BcFile ferr;
609252884aeSStefan Eßer 
610252884aeSStefan Eßer #if BC_ENABLE_NLS
61144d4804dSStefan Eßer 
61244d4804dSStefan Eßer 	/// The locale catalog.
613252884aeSStefan Eßer 	nl_catd catalog;
61444d4804dSStefan Eßer 
615252884aeSStefan Eßer #endif // BC_ENABLE_NLS
616252884aeSStefan Eßer 
61744d4804dSStefan Eßer 	/// A pointer to the stdin buffer.
618252884aeSStefan Eßer 	char *buf;
61944d4804dSStefan Eßer 
62044d4804dSStefan Eßer 	/// The number of items in the input buffer.
621252884aeSStefan Eßer 	size_t buf_len;
62244d4804dSStefan Eßer 
62344d4804dSStefan Eßer 	/// The slab for constants in the main function. This is separate for
62444d4804dSStefan Eßer 	/// garbage collection reasons.
62544d4804dSStefan Eßer 	BcVec main_const_slab;
62644d4804dSStefan Eßer 
62744d4804dSStefan Eßer 	//// The slab for all other strings for the main function.
62844d4804dSStefan Eßer 	BcVec main_slabs;
62944d4804dSStefan Eßer 
63044d4804dSStefan Eßer 	/// The slab for function names, strings in other functions, and constants
63144d4804dSStefan Eßer 	/// in other functions.
63244d4804dSStefan Eßer 	BcVec other_slabs;
63344d4804dSStefan Eßer 
63444d4804dSStefan Eßer #if BC_ENABLED
63544d4804dSStefan Eßer 
63644d4804dSStefan Eßer 	/// An array of booleans for which bc keywords have been redefined if
63744d4804dSStefan Eßer 	/// BC_REDEFINE_KEYWORDS is non-zero.
63844d4804dSStefan Eßer 	bool redefined_kws[BC_LEX_NKWS];
63944d4804dSStefan Eßer 
64044d4804dSStefan Eßer #endif // BC_ENABLED
64150696a6eSStefan Eßer #endif // !BC_ENABLE_LIBRARY
642252884aeSStefan Eßer 
64344d4804dSStefan Eßer #if BC_DEBUG_CODE
64444d4804dSStefan Eßer 
64544d4804dSStefan Eßer 	/// The depth for BC_FUNC_ENTER and BC_FUNC_EXIT.
64644d4804dSStefan Eßer 	size_t func_depth;
64744d4804dSStefan Eßer 
64844d4804dSStefan Eßer #endif // BC_DEBUG_CODE
64944d4804dSStefan Eßer 
650252884aeSStefan Eßer } BcVm;
651252884aeSStefan Eßer 
65244d4804dSStefan Eßer /**
65344d4804dSStefan Eßer  * Print the copyright banner and help if it's non-NULL.
65444d4804dSStefan Eßer  * @param help  The help message to print if it's non-NULL.
65544d4804dSStefan Eßer  */
656252884aeSStefan Eßer void bc_vm_info(const char* const help);
65744d4804dSStefan Eßer 
65844d4804dSStefan Eßer /**
65944d4804dSStefan Eßer  * The entrance point for bc/dc together.
66044d4804dSStefan Eßer  * @param argc  The count of arguments.
66144d4804dSStefan Eßer  * @param argv  The argument array.
66244d4804dSStefan Eßer  */
66344d4804dSStefan Eßer void bc_vm_boot(int argc, char *argv[]);
66444d4804dSStefan Eßer 
66544d4804dSStefan Eßer /**
66644d4804dSStefan Eßer  * Initializes some of the BcVm global. This is separate to make things easier
66744d4804dSStefan Eßer  * on the library code.
66844d4804dSStefan Eßer  */
66950696a6eSStefan Eßer void bc_vm_init(void);
67044d4804dSStefan Eßer 
67144d4804dSStefan Eßer /**
67244d4804dSStefan Eßer  * Frees the BcVm global.
67344d4804dSStefan Eßer  */
674252884aeSStefan Eßer void bc_vm_shutdown(void);
67544d4804dSStefan Eßer 
67644d4804dSStefan Eßer /**
67744d4804dSStefan Eßer  * Add a temp to the temp array.
67844d4804dSStefan Eßer  * @param num  The BcDig array to add to the temp array.
67944d4804dSStefan Eßer  */
68044d4804dSStefan Eßer void bc_vm_addTemp(BcDig *num);
68144d4804dSStefan Eßer 
68244d4804dSStefan Eßer /**
68344d4804dSStefan Eßer  * Dish out a temp, or NULL if there are none.
68444d4804dSStefan Eßer  * @return  A temp, or NULL if none exist.
68544d4804dSStefan Eßer  */
68644d4804dSStefan Eßer BcDig* bc_vm_takeTemp(void);
68744d4804dSStefan Eßer 
68844d4804dSStefan Eßer /**
68944d4804dSStefan Eßer  * Frees all temporaries.
69044d4804dSStefan Eßer  */
69150696a6eSStefan Eßer void bc_vm_freeTemps(void);
692252884aeSStefan Eßer 
6937e5c51e5SStefan Eßer #if !BC_ENABLE_HISTORY
69444d4804dSStefan Eßer 
69544d4804dSStefan Eßer /**
69644d4804dSStefan Eßer  * Erases the flush argument if history does not exist because it does not
69744d4804dSStefan Eßer  * matter if history does not exist.
69844d4804dSStefan Eßer  */
6997e5c51e5SStefan Eßer #define bc_vm_putchar(c, t) bc_vm_putchar(c)
70044d4804dSStefan Eßer 
7017e5c51e5SStefan Eßer #endif // !BC_ENABLE_HISTORY
7027e5c51e5SStefan Eßer 
70344d4804dSStefan Eßer /**
70444d4804dSStefan Eßer  * Print to stdout with limited formating.
70544d4804dSStefan Eßer  * @param fmt  The format string.
70644d4804dSStefan Eßer  */
707252884aeSStefan Eßer void bc_vm_printf(const char *fmt, ...);
70844d4804dSStefan Eßer 
70944d4804dSStefan Eßer /**
71044d4804dSStefan Eßer  * Puts a char into the stdout buffer.
71144d4804dSStefan Eßer  * @param c     The character to put on the stdout buffer.
71244d4804dSStefan Eßer  * @param type  The flush type.
71344d4804dSStefan Eßer  */
7147e5c51e5SStefan Eßer void bc_vm_putchar(int c, BcFlushType type);
71544d4804dSStefan Eßer 
71644d4804dSStefan Eßer /**
71744d4804dSStefan Eßer  * Multiplies @a n and @a size and throws an allocation error if overflow
71844d4804dSStefan Eßer  * occurs.
71944d4804dSStefan Eßer  * @param n     The number of elements.
72044d4804dSStefan Eßer  * @param size  The size of each element.
72144d4804dSStefan Eßer  * @return      The product of @a n and @a size.
72244d4804dSStefan Eßer  */
723252884aeSStefan Eßer size_t bc_vm_arraySize(size_t n, size_t size);
72444d4804dSStefan Eßer 
72544d4804dSStefan Eßer /**
72644d4804dSStefan Eßer  * Adds @a a and @a b and throws an error if overflow occurs.
72744d4804dSStefan Eßer  * @param a  The first operand.
72844d4804dSStefan Eßer  * @param b  The second operand.
72944d4804dSStefan Eßer  * @return   The sum of @a a and @a b.
73044d4804dSStefan Eßer  */
731252884aeSStefan Eßer size_t bc_vm_growSize(size_t a, size_t b);
73244d4804dSStefan Eßer 
73344d4804dSStefan Eßer /**
73444d4804dSStefan Eßer  * Allocate @a n bytes and throw an allocation error if allocation fails.
73544d4804dSStefan Eßer  * @param n  The bytes to allocate.
73644d4804dSStefan Eßer  * @return   A pointer to the allocated memory.
73744d4804dSStefan Eßer  */
738252884aeSStefan Eßer void* bc_vm_malloc(size_t n);
73944d4804dSStefan Eßer 
74044d4804dSStefan Eßer /**
74144d4804dSStefan Eßer  * Reallocate @a ptr to be @a n bytes and throw an allocation error if
74244d4804dSStefan Eßer  * reallocation fails.
74344d4804dSStefan Eßer  * @param ptr  The pointer to a memory allocation to reallocate.
74444d4804dSStefan Eßer  * @param n    The bytes to allocate.
74544d4804dSStefan Eßer  * @return     A pointer to the reallocated memory.
74644d4804dSStefan Eßer  */
747252884aeSStefan Eßer void* bc_vm_realloc(void *ptr, size_t n);
74844d4804dSStefan Eßer 
74944d4804dSStefan Eßer /**
75044d4804dSStefan Eßer  * Allocates space for, and duplicates, @a str.
75144d4804dSStefan Eßer  * @param str  The string to allocate.
75244d4804dSStefan Eßer  * @return     The allocated string.
75344d4804dSStefan Eßer  */
754252884aeSStefan Eßer char* bc_vm_strdup(const char *str);
75544d4804dSStefan Eßer 
75644d4804dSStefan Eßer /**
75723210c9fSStefan Eßer  * Reads a line from stdin into BcVm's buffer field.
75844d4804dSStefan Eßer  * @param clear  True if the buffer should be cleared first, false otherwise.
75944d4804dSStefan Eßer  * @return       True if a line was read, false otherwise.
76044d4804dSStefan Eßer  */
76144d4804dSStefan Eßer bool bc_vm_readLine(bool clear);
76244d4804dSStefan Eßer 
76344d4804dSStefan Eßer /**
76423210c9fSStefan Eßer  * Reads a line from the command-line expressions into BcVm's buffer field.
76523210c9fSStefan Eßer  * @param clear  True if the buffer should be cleared first, false otherwise.
76623210c9fSStefan Eßer  * @return       True if a line was read, false otherwise.
76723210c9fSStefan Eßer  */
76823210c9fSStefan Eßer bool bc_vm_readBuf(bool clear);
76923210c9fSStefan Eßer 
77023210c9fSStefan Eßer /**
77144d4804dSStefan Eßer  * A convenience and portability function for OpenBSD's pledge().
77244d4804dSStefan Eßer  * @param promises      The promises to pledge().
77344d4804dSStefan Eßer  * @param execpromises  The exec promises to pledge().
77444d4804dSStefan Eßer  */
77544d4804dSStefan Eßer void bc_pledge(const char *promises, const char *execpromises);
77644d4804dSStefan Eßer 
77744d4804dSStefan Eßer /**
77844d4804dSStefan Eßer  * Returns the value of an environment variable.
77944d4804dSStefan Eßer  * @param var  The environment variable.
78044d4804dSStefan Eßer  * @return     The value of the environment variable.
78144d4804dSStefan Eßer  */
7827e5c51e5SStefan Eßer char* bc_vm_getenv(const char* var);
78344d4804dSStefan Eßer 
78444d4804dSStefan Eßer /**
78544d4804dSStefan Eßer  * Frees an environment variable value.
78644d4804dSStefan Eßer  * @param val  The value to free.
78744d4804dSStefan Eßer  */
78844d4804dSStefan Eßer void bc_vm_getenvFree(char* val);
789252884aeSStefan Eßer 
790252884aeSStefan Eßer #if BC_DEBUG_CODE
79144d4804dSStefan Eßer 
79244d4804dSStefan Eßer /**
79344d4804dSStefan Eßer  * Start executing a jump series.
79444d4804dSStefan Eßer  * @param f  The name of the function that started the jump series.
79544d4804dSStefan Eßer  */
796252884aeSStefan Eßer void bc_vm_jmp(const char *f);
797252884aeSStefan Eßer #else // BC_DEBUG_CODE
79844d4804dSStefan Eßer 
79944d4804dSStefan Eßer /**
80044d4804dSStefan Eßer  * Start executing a jump series.
80144d4804dSStefan Eßer  */
802252884aeSStefan Eßer void bc_vm_jmp(void);
80344d4804dSStefan Eßer 
804252884aeSStefan Eßer #endif // BC_DEBUG_CODE
805252884aeSStefan Eßer 
80650696a6eSStefan Eßer #if BC_ENABLE_LIBRARY
80744d4804dSStefan Eßer 
80844d4804dSStefan Eßer /**
80944d4804dSStefan Eßer  * Handle an error. This is the true error handler. It will start a jump series
81044d4804dSStefan Eßer  * if an error occurred. POSIX errors will not cause jumps when warnings are on
81144d4804dSStefan Eßer  * or no POSIX errors are enabled.
81244d4804dSStefan Eßer  * @param e  The error.
81344d4804dSStefan Eßer  */
81450696a6eSStefan Eßer void bc_vm_handleError(BcErr e);
81544d4804dSStefan Eßer 
81644d4804dSStefan Eßer /**
81744d4804dSStefan Eßer  * Handle a fatal error.
81844d4804dSStefan Eßer  * @param e  The error.
81944d4804dSStefan Eßer  */
82010328f8bSStefan Eßer void bc_vm_fatalError(BcErr e);
82144d4804dSStefan Eßer 
82244d4804dSStefan Eßer /**
82344d4804dSStefan Eßer  * A function to call at exit.
82444d4804dSStefan Eßer  */
82510328f8bSStefan Eßer void bc_vm_atexit(void);
82644d4804dSStefan Eßer 
82750696a6eSStefan Eßer #else // BC_ENABLE_LIBRARY
82844d4804dSStefan Eßer 
82944d4804dSStefan Eßer /**
83044d4804dSStefan Eßer  * Handle an error. This is the true error handler. It will start a jump series
83144d4804dSStefan Eßer  * if an error occurred. POSIX errors will not cause jumps when warnings are on
83244d4804dSStefan Eßer  * or no POSIX errors are enabled.
83344d4804dSStefan Eßer  * @param e     The error.
83444d4804dSStefan Eßer  * @param line  The source line where the error occurred.
83544d4804dSStefan Eßer  */
83650696a6eSStefan Eßer void bc_vm_handleError(BcErr e, size_t line, ...);
83744d4804dSStefan Eßer 
83844d4804dSStefan Eßer /**
83944d4804dSStefan Eßer  * Handle a fatal error.
84044d4804dSStefan Eßer  * @param e  The error.
84144d4804dSStefan Eßer  */
84244d4804dSStefan Eßer #if !BC_ENABLE_MEMCHECK
84310328f8bSStefan Eßer BC_NORETURN
84444d4804dSStefan Eßer #endif // !BC_ENABLE_MEMCHECK
84510328f8bSStefan Eßer void bc_vm_fatalError(BcErr e);
84644d4804dSStefan Eßer 
84744d4804dSStefan Eßer /**
84844d4804dSStefan Eßer  * A function to call at exit.
84944d4804dSStefan Eßer  * @param status  The exit status.
85044d4804dSStefan Eßer  */
85110328f8bSStefan Eßer int bc_vm_atexit(int status);
85250696a6eSStefan Eßer #endif // BC_ENABLE_LIBRARY
853252884aeSStefan Eßer 
85444d4804dSStefan Eßer /// A reference to the copyright header.
855252884aeSStefan Eßer extern const char bc_copyright[];
85644d4804dSStefan Eßer 
85744d4804dSStefan Eßer /// A reference to the format string for source code line printing.
858252884aeSStefan Eßer extern const char* const bc_err_line;
85944d4804dSStefan Eßer 
86044d4804dSStefan Eßer /// A reference to the format string for source code function printing.
861252884aeSStefan Eßer extern const char* const bc_err_func_header;
86244d4804dSStefan Eßer 
86344d4804dSStefan Eßer /// A reference to the array of default error category names.
864252884aeSStefan Eßer extern const char *bc_errs[];
86544d4804dSStefan Eßer 
86644d4804dSStefan Eßer /// A reference to the array of error category indices for each error.
867252884aeSStefan Eßer extern const uchar bc_err_ids[];
86844d4804dSStefan Eßer 
86944d4804dSStefan Eßer /// A reference to the array of default error messages.
870252884aeSStefan Eßer extern const char* const bc_err_msgs[];
871252884aeSStefan Eßer 
87244d4804dSStefan Eßer /// A reference to the pledge() promises at start.
87344d4804dSStefan Eßer extern const char bc_pledge_start[];
87444d4804dSStefan Eßer 
87544d4804dSStefan Eßer #if BC_ENABLE_HISTORY
87644d4804dSStefan Eßer 
87744d4804dSStefan Eßer /// A reference to the end pledge() promises when using history.
87844d4804dSStefan Eßer extern const char bc_pledge_end_history[];
87944d4804dSStefan Eßer 
88044d4804dSStefan Eßer #endif // BC_ENABLE_HISTORY
88144d4804dSStefan Eßer 
88244d4804dSStefan Eßer /// A reference to the end pledge() promises when *not* using history.
88344d4804dSStefan Eßer extern const char bc_pledge_end[];
88444d4804dSStefan Eßer 
88544d4804dSStefan Eßer /// A reference to the global data.
886252884aeSStefan Eßer extern BcVm vm;
88744d4804dSStefan Eßer 
88844d4804dSStefan Eßer /// A reference to the global output buffers.
889252884aeSStefan Eßer extern char output_bufs[BC_VM_BUF_SIZE];
890252884aeSStefan Eßer 
891252884aeSStefan Eßer #endif // BC_VM_H
892