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 55252884aeSStefan Eßer #include <status.h> 56252884aeSStefan Eßer #include <num.h> 57252884aeSStefan Eßer #include <parse.h> 58252884aeSStefan Eßer #include <program.h> 59252884aeSStefan Eßer #include <history.h> 6050696a6eSStefan Eßer 6150696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY 62252884aeSStefan Eßer #include <file.h> 6350696a6eSStefan Eßer #endif // !BC_ENABLE_LIBRARY 64252884aeSStefan Eßer 65252884aeSStefan Eßer #if !BC_ENABLED && !DC_ENABLED 66252884aeSStefan Eßer #error Must define BC_ENABLED, DC_ENABLED, or both 67252884aeSStefan Eßer #endif 68252884aeSStefan Eßer 69252884aeSStefan Eßer // CHAR_BIT must be at least 6. 70252884aeSStefan Eßer #if CHAR_BIT < 6 71252884aeSStefan Eßer #error CHAR_BIT must be at least 6. 72252884aeSStefan Eßer #endif 73252884aeSStefan Eßer 74252884aeSStefan Eßer #ifndef BC_ENABLE_NLS 75252884aeSStefan Eßer #define BC_ENABLE_NLS (0) 76252884aeSStefan Eßer #endif // BC_ENABLE_NLS 77252884aeSStefan Eßer 78252884aeSStefan Eßer #ifndef MAINEXEC 79252884aeSStefan Eßer #define MAINEXEC bc 80252884aeSStefan Eßer #endif 81252884aeSStefan Eßer 82252884aeSStefan Eßer #ifndef EXECPREFIX 83252884aeSStefan Eßer #define EXECPREFIX 84252884aeSStefan Eßer #endif 85252884aeSStefan Eßer 86252884aeSStefan Eßer #define GEN_STR(V) #V 87252884aeSStefan Eßer #define GEN_STR2(V) GEN_STR(V) 88252884aeSStefan Eßer 89252884aeSStefan Eßer #define BC_VERSION GEN_STR2(VERSION) 90252884aeSStefan Eßer #define BC_EXECPREFIX GEN_STR2(EXECPREFIX) 91252884aeSStefan Eßer #define BC_MAINEXEC GEN_STR2(MAINEXEC) 92252884aeSStefan Eßer 93252884aeSStefan Eßer // Windows has deprecated isatty(). 94252884aeSStefan Eßer #ifdef _WIN32 95252884aeSStefan Eßer #define isatty _isatty 96252884aeSStefan Eßer #endif // _WIN32 97252884aeSStefan Eßer 9850696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY 9950696a6eSStefan Eßer 1003aa99676SStefan Eßer #if DC_ENABLED 101252884aeSStefan Eßer #define DC_FLAG_X (UINTMAX_C(1)<<0) 1023aa99676SStefan Eßer #endif // DC_ENABLED 1033aa99676SStefan Eßer 1043aa99676SStefan Eßer #if BC_ENABLED 105252884aeSStefan Eßer #define BC_FLAG_W (UINTMAX_C(1)<<1) 106252884aeSStefan Eßer #define BC_FLAG_S (UINTMAX_C(1)<<2) 1073aa99676SStefan Eßer #define BC_FLAG_L (UINTMAX_C(1)<<3) 1083aa99676SStefan Eßer #define BC_FLAG_G (UINTMAX_C(1)<<4) 1093aa99676SStefan Eßer #endif // BC_ENABLED 1103aa99676SStefan Eßer 1115d934bc0SStefan Eßer #define BC_FLAG_I (UINTMAX_C(1)<<5) 1125d934bc0SStefan Eßer #define BC_FLAG_P (UINTMAX_C(1)<<6) 1135d934bc0SStefan Eßer #define BC_FLAG_TTYIN (UINTMAX_C(1)<<7) 1145d934bc0SStefan Eßer #define BC_FLAG_TTY (UINTMAX_C(1)<<8) 115252884aeSStefan Eßer #define BC_TTYIN (vm.flags & BC_FLAG_TTYIN) 116252884aeSStefan Eßer #define BC_TTY (vm.flags & BC_FLAG_TTY) 117252884aeSStefan Eßer 1183aa99676SStefan Eßer #if BC_ENABLED 1193aa99676SStefan Eßer 120cf7becd2SStefan Eßer #define BC_S (vm.flags & BC_FLAG_S) 121cf7becd2SStefan Eßer #define BC_W (vm.flags & BC_FLAG_W) 122cf7becd2SStefan Eßer #define BC_L (vm.flags & BC_FLAG_L) 123cf7becd2SStefan Eßer #define BC_G (vm.flags & BC_FLAG_G) 1243aa99676SStefan Eßer 1253aa99676SStefan Eßer #endif // BC_ENABLED 1263aa99676SStefan Eßer 1273aa99676SStefan Eßer #if DC_ENABLED 1283aa99676SStefan Eßer #define DC_X (vm.flags & DC_FLAG_X) 1293aa99676SStefan Eßer #endif // DC_ENABLED 1303aa99676SStefan Eßer 1313aa99676SStefan Eßer #define BC_I (vm.flags & BC_FLAG_I) 132252884aeSStefan Eßer #define BC_P (vm.flags & BC_FLAG_P) 133252884aeSStefan Eßer 1343aa99676SStefan Eßer #if BC_ENABLED 1353aa99676SStefan Eßer 1363aa99676SStefan Eßer #define BC_IS_POSIX (BC_S || BC_W) 1373aa99676SStefan Eßer 1383aa99676SStefan Eßer #if DC_ENABLED 1393aa99676SStefan Eßer #define BC_IS_BC (vm.name[0] != 'd') 1403aa99676SStefan Eßer #define BC_IS_DC (vm.name[0] == 'd') 1413aa99676SStefan Eßer #else // DC_ENABLED 1423aa99676SStefan Eßer #define BC_IS_BC (1) 1433aa99676SStefan Eßer #define BC_IS_DC (0) 1443aa99676SStefan Eßer #endif // DC_ENABLED 1453aa99676SStefan Eßer 1463aa99676SStefan Eßer #else // BC_ENABLED 1473aa99676SStefan Eßer #define BC_IS_POSIX (0) 1483aa99676SStefan Eßer #define BC_IS_BC (0) 1493aa99676SStefan Eßer #define BC_IS_DC (1) 1503aa99676SStefan Eßer #endif // BC_ENABLED 1513aa99676SStefan Eßer 1523aa99676SStefan Eßer #if BC_ENABLED 153252884aeSStefan Eßer #define BC_USE_PROMPT (!BC_P && BC_TTY && !BC_IS_POSIX) 1543aa99676SStefan Eßer #else // BC_ENABLED 1553aa99676SStefan Eßer #define BC_USE_PROMPT (!BC_P && BC_TTY) 1563aa99676SStefan Eßer #endif // BC_ENABLED 157252884aeSStefan Eßer 15850696a6eSStefan Eßer #endif // !BC_ENABLE_LIBRARY 15950696a6eSStefan Eßer 160252884aeSStefan Eßer #define BC_MAX(a, b) ((a) > (b) ? (a) : (b)) 161252884aeSStefan Eßer #define BC_MIN(a, b) ((a) < (b) ? (a) : (b)) 162252884aeSStefan Eßer 163252884aeSStefan Eßer #define BC_MAX_OBASE ((BcBigDig) (BC_BASE_POW)) 164252884aeSStefan Eßer #define BC_MAX_DIM ((BcBigDig) (SIZE_MAX - 1)) 165252884aeSStefan Eßer #define BC_MAX_SCALE ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1)) 166252884aeSStefan Eßer #define BC_MAX_STRING ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1)) 167252884aeSStefan Eßer #define BC_MAX_NAME BC_MAX_STRING 168252884aeSStefan Eßer #define BC_MAX_NUM BC_MAX_SCALE 169252884aeSStefan Eßer 170252884aeSStefan Eßer #if BC_ENABLE_EXTRA_MATH 171252884aeSStefan Eßer #define BC_MAX_RAND ((BcBigDig) (((BcRand) 0) - 1)) 172252884aeSStefan Eßer #endif // BC_ENABLE_EXTRA_MATH 173252884aeSStefan Eßer 174252884aeSStefan Eßer #define BC_MAX_EXP ((ulong) (BC_NUM_BIGDIG_MAX)) 175252884aeSStefan Eßer #define BC_MAX_VARS ((ulong) (SIZE_MAX - 1)) 176252884aeSStefan Eßer 177252884aeSStefan Eßer #if BC_DEBUG_CODE 178252884aeSStefan Eßer #define BC_VM_JMP bc_vm_jmp(__func__) 179252884aeSStefan Eßer #else // BC_DEBUG_CODE 180252884aeSStefan Eßer #define BC_VM_JMP bc_vm_jmp() 181252884aeSStefan Eßer #endif // BC_DEBUG_CODE 182252884aeSStefan Eßer 183252884aeSStefan Eßer #define BC_SIG_EXC \ 184252884aeSStefan Eßer BC_UNLIKELY(vm.status != (sig_atomic_t) BC_STATUS_SUCCESS || vm.sig) 185252884aeSStefan Eßer #define BC_NO_SIG_EXC \ 186252884aeSStefan Eßer BC_LIKELY(vm.status == (sig_atomic_t) BC_STATUS_SUCCESS && !vm.sig) 187252884aeSStefan Eßer 188252884aeSStefan Eßer #ifndef NDEBUG 189252884aeSStefan Eßer #define BC_SIG_ASSERT_LOCKED do { assert(vm.sig_lock); } while (0) 190252884aeSStefan Eßer #define BC_SIG_ASSERT_NOT_LOCKED do { assert(vm.sig_lock == 0); } while (0) 191252884aeSStefan Eßer #else // NDEBUG 192252884aeSStefan Eßer #define BC_SIG_ASSERT_LOCKED 193252884aeSStefan Eßer #define BC_SIG_ASSERT_NOT_LOCKED 194252884aeSStefan Eßer #endif // NDEBUG 195252884aeSStefan Eßer 196252884aeSStefan Eßer #define BC_SIG_LOCK \ 197252884aeSStefan Eßer do { \ 198252884aeSStefan Eßer BC_SIG_ASSERT_NOT_LOCKED; \ 199252884aeSStefan Eßer vm.sig_lock = 1; \ 200252884aeSStefan Eßer } while (0) 201252884aeSStefan Eßer 202252884aeSStefan Eßer #define BC_SIG_UNLOCK \ 203252884aeSStefan Eßer do { \ 204252884aeSStefan Eßer BC_SIG_ASSERT_LOCKED; \ 205252884aeSStefan Eßer vm.sig_lock = 0; \ 206252884aeSStefan Eßer if (BC_SIG_EXC) BC_VM_JMP; \ 207252884aeSStefan Eßer } while (0) 208252884aeSStefan Eßer 209252884aeSStefan Eßer #define BC_SIG_MAYLOCK \ 210252884aeSStefan Eßer do { \ 211252884aeSStefan Eßer vm.sig_lock = 1; \ 212252884aeSStefan Eßer } while (0) 213252884aeSStefan Eßer 214252884aeSStefan Eßer #define BC_SIG_MAYUNLOCK \ 215252884aeSStefan Eßer do { \ 216252884aeSStefan Eßer vm.sig_lock = 0; \ 217252884aeSStefan Eßer if (BC_SIG_EXC) BC_VM_JMP; \ 218252884aeSStefan Eßer } while (0) 219252884aeSStefan Eßer 220252884aeSStefan Eßer #define BC_SIG_TRYLOCK(v) \ 221252884aeSStefan Eßer do { \ 222252884aeSStefan Eßer v = vm.sig_lock; \ 223252884aeSStefan Eßer vm.sig_lock = 1; \ 224252884aeSStefan Eßer } while (0) 225252884aeSStefan Eßer 226252884aeSStefan Eßer #define BC_SIG_TRYUNLOCK(v) \ 227252884aeSStefan Eßer do { \ 228252884aeSStefan Eßer vm.sig_lock = (v); \ 229252884aeSStefan Eßer if (!(v) && BC_SIG_EXC) BC_VM_JMP; \ 230252884aeSStefan Eßer } while (0) 231252884aeSStefan Eßer 232252884aeSStefan Eßer #define BC_SETJMP(l) \ 233252884aeSStefan Eßer do { \ 234252884aeSStefan Eßer sigjmp_buf sjb; \ 235252884aeSStefan Eßer BC_SIG_LOCK; \ 236252884aeSStefan Eßer if (sigsetjmp(sjb, 0)) { \ 237252884aeSStefan Eßer assert(BC_SIG_EXC); \ 238252884aeSStefan Eßer goto l; \ 239252884aeSStefan Eßer } \ 240252884aeSStefan Eßer bc_vec_push(&vm.jmp_bufs, &sjb); \ 241252884aeSStefan Eßer BC_SIG_UNLOCK; \ 242252884aeSStefan Eßer } while (0) 243252884aeSStefan Eßer 244252884aeSStefan Eßer #define BC_SETJMP_LOCKED(l) \ 245252884aeSStefan Eßer do { \ 246252884aeSStefan Eßer sigjmp_buf sjb; \ 247252884aeSStefan Eßer BC_SIG_ASSERT_LOCKED; \ 248252884aeSStefan Eßer if (sigsetjmp(sjb, 0)) { \ 249252884aeSStefan Eßer assert(BC_SIG_EXC); \ 250252884aeSStefan Eßer goto l; \ 251252884aeSStefan Eßer } \ 252252884aeSStefan Eßer bc_vec_push(&vm.jmp_bufs, &sjb); \ 253252884aeSStefan Eßer } while (0) 254252884aeSStefan Eßer 255252884aeSStefan Eßer #define BC_LONGJMP_CONT \ 256252884aeSStefan Eßer do { \ 257252884aeSStefan Eßer BC_SIG_ASSERT_LOCKED; \ 258252884aeSStefan Eßer if (!vm.sig_pop) bc_vec_pop(&vm.jmp_bufs); \ 259252884aeSStefan Eßer BC_SIG_UNLOCK; \ 260252884aeSStefan Eßer } while (0) 261252884aeSStefan Eßer 262252884aeSStefan Eßer #define BC_UNSETJMP \ 263252884aeSStefan Eßer do { \ 264252884aeSStefan Eßer BC_SIG_ASSERT_LOCKED; \ 265252884aeSStefan Eßer bc_vec_pop(&vm.jmp_bufs); \ 266252884aeSStefan Eßer } while (0) 267252884aeSStefan Eßer 268252884aeSStefan Eßer #define BC_LONGJMP_STOP \ 269252884aeSStefan Eßer do { \ 270252884aeSStefan Eßer vm.sig_pop = 0; \ 271252884aeSStefan Eßer vm.sig = 0; \ 272252884aeSStefan Eßer } while (0) 273252884aeSStefan Eßer 274252884aeSStefan Eßer #define BC_VM_BUF_SIZE (1<<12) 275252884aeSStefan Eßer #define BC_VM_STDOUT_BUF_SIZE (1<<11) 276252884aeSStefan Eßer #define BC_VM_STDERR_BUF_SIZE (1<<10) 2773aa99676SStefan Eßer #define BC_VM_STDIN_BUF_SIZE (BC_VM_STDERR_BUF_SIZE - 1) 2783aa99676SStefan Eßer 2793aa99676SStefan Eßer #define BC_VM_SAFE_RESULT(r) ((r)->t >= BC_RESULT_TEMP) 280252884aeSStefan Eßer 28150696a6eSStefan Eßer #if BC_ENABLE_LIBRARY 28250696a6eSStefan Eßer #define bc_vm_error(e, l, ...) (bc_vm_handleError((e))) 28350696a6eSStefan Eßer #define bc_vm_err(e) (bc_vm_handleError((e))) 28450696a6eSStefan Eßer #define bc_vm_verr(e, ...) (bc_vm_handleError((e))) 28550696a6eSStefan Eßer #else // BC_ENABLE_LIBRARY 28650696a6eSStefan Eßer #define bc_vm_error(e, l, ...) (bc_vm_handleError((e), (l), __VA_ARGS__)) 28750696a6eSStefan Eßer #define bc_vm_err(e) (bc_vm_handleError((e), 0)) 28850696a6eSStefan Eßer #define bc_vm_verr(e, ...) (bc_vm_handleError((e), 0, __VA_ARGS__)) 28950696a6eSStefan Eßer #endif // BC_ENABLE_LIBRARY 290252884aeSStefan Eßer 291252884aeSStefan Eßer #define BC_STATUS_IS_ERROR(s) \ 292252884aeSStefan Eßer ((s) >= BC_STATUS_ERROR_MATH && (s) <= BC_STATUS_ERROR_FATAL) 293252884aeSStefan Eßer 294252884aeSStefan Eßer #define BC_VM_INVALID_CATALOG ((nl_catd) -1) 295252884aeSStefan Eßer 29650696a6eSStefan Eßer #if BC_DEBUG_CODE 29750696a6eSStefan Eßer #define BC_VM_FUNC_ENTER \ 29850696a6eSStefan Eßer do { \ 29950696a6eSStefan Eßer bc_file_printf(&vm.ferr, "Entering %s\n", __func__); \ 30050696a6eSStefan Eßer bc_file_flush(&vm.ferr); \ 30150696a6eSStefan Eßer } while (0); 30250696a6eSStefan Eßer 30350696a6eSStefan Eßer #define BC_VM_FUNC_EXIT \ 30450696a6eSStefan Eßer do { \ 30550696a6eSStefan Eßer bc_file_printf(&vm.ferr, "Leaving %s\n", __func__); \ 30650696a6eSStefan Eßer bc_file_flush(&vm.ferr); \ 30750696a6eSStefan Eßer } while (0); 30850696a6eSStefan Eßer #else // BC_DEBUG_CODE 30950696a6eSStefan Eßer #define BC_VM_FUNC_ENTER 31050696a6eSStefan Eßer #define BC_VM_FUNC_EXIT 31150696a6eSStefan Eßer #endif // BC_DEBUG_CODE 31250696a6eSStefan Eßer 313252884aeSStefan Eßer typedef struct BcVm { 314252884aeSStefan Eßer 315252884aeSStefan Eßer volatile sig_atomic_t status; 316252884aeSStefan Eßer volatile sig_atomic_t sig_pop; 317252884aeSStefan Eßer 31850696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY 319252884aeSStefan Eßer BcParse prs; 320252884aeSStefan Eßer BcProgram prog; 32110328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY 322252884aeSStefan Eßer 323252884aeSStefan Eßer BcVec jmp_bufs; 324252884aeSStefan Eßer 325252884aeSStefan Eßer BcVec temps; 326252884aeSStefan Eßer 32750696a6eSStefan Eßer #if BC_ENABLE_LIBRARY 32850696a6eSStefan Eßer 32950696a6eSStefan Eßer BcVec ctxts; 33050696a6eSStefan Eßer BcVec out; 33150696a6eSStefan Eßer 33250696a6eSStefan Eßer BcRNG rng; 33350696a6eSStefan Eßer 33450696a6eSStefan Eßer BclError err; 33550696a6eSStefan Eßer bool abrt; 33650696a6eSStefan Eßer 33750696a6eSStefan Eßer unsigned int refs; 33850696a6eSStefan Eßer 33950696a6eSStefan Eßer volatile sig_atomic_t running; 34050696a6eSStefan Eßer #endif // BC_ENABLE_LIBRARY 34150696a6eSStefan Eßer 34250696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY 343252884aeSStefan Eßer const char* file; 344252884aeSStefan Eßer 345252884aeSStefan Eßer const char *sigmsg; 34610328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY 347252884aeSStefan Eßer volatile sig_atomic_t sig_lock; 348252884aeSStefan Eßer volatile sig_atomic_t sig; 34950696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY 350252884aeSStefan Eßer uchar siglen; 351252884aeSStefan Eßer 352252884aeSStefan Eßer uchar read_ret; 353252884aeSStefan Eßer uint16_t flags; 354252884aeSStefan Eßer 355252884aeSStefan Eßer uint16_t nchars; 356252884aeSStefan Eßer uint16_t line_len; 357252884aeSStefan Eßer 3585d934bc0SStefan Eßer bool no_exit_exprs; 3599a995fe1SStefan Eßer bool exit_exprs; 360252884aeSStefan Eßer bool eof; 36110328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY 362252884aeSStefan Eßer 363252884aeSStefan Eßer BcBigDig maxes[BC_PROG_GLOBALS_LEN + BC_ENABLE_EXTRA_MATH]; 364252884aeSStefan Eßer 36550696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY 366252884aeSStefan Eßer BcVec files; 367252884aeSStefan Eßer BcVec exprs; 368252884aeSStefan Eßer 369252884aeSStefan Eßer const char *name; 370252884aeSStefan Eßer const char *help; 371252884aeSStefan Eßer 372252884aeSStefan Eßer #if BC_ENABLE_HISTORY 373252884aeSStefan Eßer BcHistory history; 374252884aeSStefan Eßer #endif // BC_ENABLE_HISTORY 375252884aeSStefan Eßer 376252884aeSStefan Eßer BcLexNext next; 377252884aeSStefan Eßer BcParseParse parse; 378252884aeSStefan Eßer BcParseExpr expr; 379252884aeSStefan Eßer 380252884aeSStefan Eßer const char *func_header; 381252884aeSStefan Eßer 382252884aeSStefan Eßer const char *err_ids[BC_ERR_IDX_NELEMS + BC_ENABLED]; 38350696a6eSStefan Eßer const char *err_msgs[BC_ERR_NELEMS]; 384252884aeSStefan Eßer 385252884aeSStefan Eßer const char *locale; 38610328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY 387252884aeSStefan Eßer 388252884aeSStefan Eßer BcBigDig last_base; 389252884aeSStefan Eßer BcBigDig last_pow; 390252884aeSStefan Eßer BcBigDig last_exp; 391252884aeSStefan Eßer BcBigDig last_rem; 392252884aeSStefan Eßer 39350696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY 394252884aeSStefan Eßer char *env_args_buffer; 395252884aeSStefan Eßer BcVec env_args; 39610328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY 397252884aeSStefan Eßer 398252884aeSStefan Eßer BcNum max; 39950696a6eSStefan Eßer BcNum max2; 400252884aeSStefan Eßer BcDig max_num[BC_NUM_BIGDIG_LOG10]; 40150696a6eSStefan Eßer BcDig max2_num[BC_NUM_BIGDIG_LOG10]; 402252884aeSStefan Eßer 40350696a6eSStefan Eßer #if !BC_ENABLE_LIBRARY 404252884aeSStefan Eßer BcFile fout; 405252884aeSStefan Eßer BcFile ferr; 406252884aeSStefan Eßer 407252884aeSStefan Eßer #if BC_ENABLE_NLS 408252884aeSStefan Eßer nl_catd catalog; 409252884aeSStefan Eßer #endif // BC_ENABLE_NLS 410252884aeSStefan Eßer 411252884aeSStefan Eßer char *buf; 412252884aeSStefan Eßer size_t buf_len; 41350696a6eSStefan Eßer #endif // !BC_ENABLE_LIBRARY 414252884aeSStefan Eßer 415252884aeSStefan Eßer } BcVm; 416252884aeSStefan Eßer 417252884aeSStefan Eßer void bc_vm_info(const char* const help); 418252884aeSStefan Eßer void bc_vm_boot(int argc, char *argv[], const char *env_len, 4195d934bc0SStefan Eßer const char* const env_args); 42050696a6eSStefan Eßer void bc_vm_init(void); 421252884aeSStefan Eßer void bc_vm_shutdown(void); 42250696a6eSStefan Eßer void bc_vm_freeTemps(void); 423252884aeSStefan Eßer 424252884aeSStefan Eßer void bc_vm_printf(const char *fmt, ...); 425252884aeSStefan Eßer void bc_vm_putchar(int c); 426252884aeSStefan Eßer size_t bc_vm_arraySize(size_t n, size_t size); 427252884aeSStefan Eßer size_t bc_vm_growSize(size_t a, size_t b); 428252884aeSStefan Eßer void* bc_vm_malloc(size_t n); 429252884aeSStefan Eßer void* bc_vm_realloc(void *ptr, size_t n); 430252884aeSStefan Eßer char* bc_vm_strdup(const char *str); 431252884aeSStefan Eßer 432252884aeSStefan Eßer #if BC_DEBUG_CODE 433252884aeSStefan Eßer void bc_vm_jmp(const char *f); 434252884aeSStefan Eßer #else // BC_DEBUG_CODE 435252884aeSStefan Eßer void bc_vm_jmp(void); 436252884aeSStefan Eßer #endif // BC_DEBUG_CODE 437252884aeSStefan Eßer 43850696a6eSStefan Eßer #if BC_ENABLE_LIBRARY 43950696a6eSStefan Eßer void bc_vm_handleError(BcErr e); 44010328f8bSStefan Eßer void bc_vm_fatalError(BcErr e); 44110328f8bSStefan Eßer void bc_vm_atexit(void); 44250696a6eSStefan Eßer #else // BC_ENABLE_LIBRARY 44350696a6eSStefan Eßer void bc_vm_handleError(BcErr e, size_t line, ...); 44410328f8bSStefan Eßer #if !BC_ENABLE_LIBRARY && !BC_ENABLE_MEMCHECK 44510328f8bSStefan Eßer BC_NORETURN 44610328f8bSStefan Eßer #endif // !BC_ENABLE_LIBRARY && !BC_ENABLE_MEMCHECK 44710328f8bSStefan Eßer void bc_vm_fatalError(BcErr e); 44810328f8bSStefan Eßer int bc_vm_atexit(int status); 44950696a6eSStefan Eßer #endif // BC_ENABLE_LIBRARY 450252884aeSStefan Eßer 451252884aeSStefan Eßer extern const char bc_copyright[]; 452252884aeSStefan Eßer extern const char* const bc_err_line; 453252884aeSStefan Eßer extern const char* const bc_err_func_header; 454252884aeSStefan Eßer extern const char *bc_errs[]; 455252884aeSStefan Eßer extern const uchar bc_err_ids[]; 456252884aeSStefan Eßer extern const char* const bc_err_msgs[]; 457252884aeSStefan Eßer 458252884aeSStefan Eßer extern BcVm vm; 459252884aeSStefan Eßer extern char output_bufs[BC_VM_BUF_SIZE]; 460252884aeSStefan Eßer 461252884aeSStefan Eßer #endif // BC_VM_H 462