blob: 5fe20de19a096697edeb9ef4da411b22d05d34ab [file] [log] [blame]
Brian Callahan1c761962019-04-02 18:37:44 -04001/*
Gavin Howardd5551672018-09-22 19:52:42 -06002 * *****************************************************************************
3 *
Gavin Howard7345cb92019-04-08 14:13:43 -06004 * Copyright (c) 2018-2019 Gavin D. Howard and contributors.
Gavin Howardd5551672018-09-22 19:52:42 -06005 *
Gavin Howard7345cb92019-04-08 14:13:43 -06006 * All rights reserved.
Gavin Howardd5551672018-09-22 19:52:42 -06007 *
Gavin Howard7345cb92019-04-08 14:13:43 -06008 * 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.
Gavin Howardd5551672018-09-22 19:52:42 -060029 *
30 * *****************************************************************************
31 *
32 * Definitions for bc's VM.
33 *
34 */
35
36#ifndef BC_VM_H
37#define BC_VM_H
38
Gavin Howard411f7322018-09-26 17:21:19 -060039#include <stddef.h>
Gavin Howardd5551672018-09-22 19:52:42 -060040#include <limits.h>
41
Gavin Howardaa660542019-01-08 11:25:04 -070042#include <signal.h>
Gavin Howard6075b442019-03-28 10:03:51 -060043
Gavin Howard8ffac9b2019-02-20 16:13:49 -070044#if BC_ENABLE_NLS
Gavin Howard6075b442019-03-28 10:03:51 -060045
46# ifdef _WIN32
47# error NLS is not supported on Windows.
48# endif // _WIN32
49
Gavin Howard50080252019-02-20 15:27:43 -070050#include <nl_types.h>
Gavin Howard6075b442019-03-28 10:03:51 -060051
Gavin Howard8ffac9b2019-02-20 16:13:49 -070052#endif // BC_ENABLE_NLS
Gavin Howardaa660542019-01-08 11:25:04 -070053
Gavin Howardd5551672018-09-22 19:52:42 -060054#include <status.h>
Gavin Howard1009a162019-05-18 12:26:09 -060055#include <num.h>
Gavin Howardd5551672018-09-22 19:52:42 -060056#include <parse.h>
57#include <program.h>
Gavin Howardbceb32d2018-12-12 22:23:51 -070058#include <history.h>
Gavin Howardd5551672018-09-22 19:52:42 -060059
Gavin Howard40a085f2018-12-03 12:08:59 -070060#if !BC_ENABLED && !DC_ENABLED
Gavin Howarde6e84762018-10-03 11:46:34 -060061#error Must define BC_ENABLED, DC_ENABLED, or both
Gavin Howarda0ccea62018-09-26 21:02:22 -060062#endif
63
Gavin Howard9e485442019-01-03 09:29:19 -070064// CHAR_BIT must be at least 6.
65#if CHAR_BIT < 6
66#error CHAR_BIT must be at least 6.
Gavin Howardc1902aa2018-12-20 15:54:28 -070067#endif
68
Gavin Howard77d016f2019-04-22 09:44:43 -060069#ifndef BC_ENABLE_NLS
70#define BC_ENABLE_NLS (0)
71#endif // BC_ENABLE_NLS
72
73#ifndef BC_ENABLE_SIGNALS
74#define BC_ENABLE_SIGNALS (1)
75#endif // BC_ENABLE_SIGNALS
76
77#ifndef MAINEXEC
78#define MAINEXEC bc
79#endif
80
81#ifndef EXECPREFIX
82#define EXECPREFIX
83#endif
84
Gavin Howard50080252019-02-20 15:27:43 -070085#define GEN_STR(V) #V
86#define GEN_STR2(V) GEN_STR(V)
87
88#define BC_VERSION GEN_STR2(VERSION)
Gavin Howard36ae6292019-04-01 07:30:27 -060089#define BC_EXECPREFIX GEN_STR2(EXECPREFIX)
Gavin Howardc1075ce2019-04-01 13:52:38 -060090#define BC_MAINEXEC GEN_STR2(MAINEXEC)
Gavin Howarda95501a2018-10-03 16:13:34 -060091
Gavin Howard66f2a6b2018-12-14 14:31:08 -070092// Windows has deprecated isatty().
93#ifdef _WIN32
94#define isatty _isatty
95#endif // _WIN32
96
Gavin Howardf2d9a652019-05-11 07:38:32 -060097#define DC_FLAG_X (UINTMAX_C(1)<<0)
98#define BC_FLAG_W (UINTMAX_C(1)<<1)
99#define BC_FLAG_S (UINTMAX_C(1)<<2)
100#define BC_FLAG_Q (UINTMAX_C(1)<<3)
101#define BC_FLAG_L (UINTMAX_C(1)<<4)
102#define BC_FLAG_I (UINTMAX_C(1)<<5)
103#define BC_FLAG_G (UINTMAX_C(1)<<6)
Gavin Howard06384342019-05-26 08:29:05 -0600104#define BC_FLAG_P (UINTMAX_C(1)<<7)
105#define BC_FLAG_TTYIN (UINTMAX_C(1)<<8)
Gavin Howard48354e82019-01-02 18:15:56 -0700106#define BC_TTYIN (vm->flags & BC_FLAG_TTYIN)
Gavin Howard5e59c392019-05-20 07:51:10 -0600107#define BC_TTY (vm->tty)
Gavin Howard48354e82019-01-02 18:15:56 -0700108
109#define BC_S (BC_ENABLED && (vm->flags & BC_FLAG_S))
110#define BC_W (BC_ENABLED && (vm->flags & BC_FLAG_W))
111#define BC_L (BC_ENABLED && (vm->flags & BC_FLAG_L))
Gavin Howard5b9393a2019-05-26 08:27:40 -0600112#define BC_I (vm->flags & BC_FLAG_I)
Gavin Howard75389d12019-02-25 16:39:02 -0700113#define BC_G (BC_ENABLED && (vm->flags & BC_FLAG_G))
Gavin Howard48354e82019-01-02 18:15:56 -0700114#define DC_X (DC_ENABLED && (vm->flags & DC_FLAG_X))
Gavin Howard06384342019-05-26 08:29:05 -0600115#define BC_P (vm->flags & BC_FLAG_P)
116
Gavin Howardb6cc5ef2019-06-13 08:29:36 -0600117#define BC_USE_PROMPT (!BC_P && BC_TTY && !BC_IS_POSIX)
Gavin Howardd5551672018-09-22 19:52:42 -0600118
119#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
120#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
121
Gavin Howarde6476862019-05-23 08:54:15 -0600122#define BC_MAX_OBASE ((ulong) (BC_BASE_POW))
123#define BC_MAX_DIM ((ulong) (SIZE_MAX - 1))
124#define BC_MAX_SCALE ((ulong) (BC_NUM_BIGDIG_MAX - 1))
125#define BC_MAX_STRING ((ulong) (BC_NUM_BIGDIG_MAX - 1))
Gavin Howardd5551672018-09-22 19:52:42 -0600126#define BC_MAX_NAME BC_MAX_STRING
Gavin Howard530e3072019-04-23 16:23:36 -0600127#define BC_MAX_NUM BC_MAX_SCALE
Gavin Howarde6476862019-05-23 08:54:15 -0600128#define BC_MAX_EXP ((ulong) (BC_NUM_BIGDIG_MAX))
129#define BC_MAX_VARS ((ulong) (SIZE_MAX - 1))
Gavin Howardd5551672018-09-22 19:52:42 -0600130
Gavin Howard664476c2019-01-03 14:57:19 -0700131#define BC_IS_BC (BC_ENABLED && (!DC_ENABLED || vm->name[0] != 'd'))
Gavin Howarda6527882019-02-19 20:23:17 -0700132#define BC_IS_POSIX (BC_S || BC_W)
Gavin Howardf878d332018-12-03 12:58:38 -0700133
Gavin Howard112304b2018-12-04 14:30:01 -0700134#if BC_ENABLE_SIGNALS
Gavin Howardb9a0b862019-01-08 11:47:09 -0700135
Gavin Howardc281d422019-05-22 19:32:13 -0600136#define BC_SIG BC_UNLIKELY(vm->sig != vm->sig_chk)
137#define BC_NO_SIG BC_LIKELY(vm->sig == vm->sig_chk)
Gavin Howardb9a0b862019-01-08 11:47:09 -0700138
Gavin Howarda3d4c972019-05-28 18:47:37 -0600139#define BC_SIGTERM_VAL (SIG_ATOMIC_MAX)
Gavin Howardc281d422019-05-22 19:32:13 -0600140#define BC_SIGTERM (vm->sig == BC_SIGTERM_VAL)
141#define BC_SIGINT (vm->sig && vm->sig != BC_SIGTERM_VAL)
Gavin Howardb9a0b862019-01-08 11:47:09 -0700142
Gavin Howard112304b2018-12-04 14:30:01 -0700143#else // BC_ENABLE_SIGNALS
Gavin Howard4eb14652019-02-25 14:26:53 -0700144#define BC_SIG (0)
145#define BC_NO_SIG (1)
Gavin Howard112304b2018-12-04 14:30:01 -0700146#endif // BC_ENABLE_SIGNALS
147
Gavin Howard7536dcf2018-12-15 19:27:09 -0700148#define bc_vm_err(e) (bc_vm_error((e), 0))
Gavin Howardecc7fc22018-12-31 13:21:47 -0700149#define bc_vm_verr(e, ...) (bc_vm_error((e), 0, __VA_ARGS__))
Gavin Howard7536dcf2018-12-15 19:27:09 -0700150
Gavin Howard42a832d2019-06-14 18:33:53 -0600151#define BC_IO_ERR(e, f) (BC_ERR((e) < 0 || ferror(f)))
Gavin Howardfb4f2b82019-02-19 08:43:27 -0700152#define BC_STATUS_IS_ERROR(s) \
Gavin Howardecc04352019-05-23 07:32:51 -0600153 ((s) >= BC_STATUS_ERROR_MATH && (s) <= BC_STATUS_ERROR_FATAL)
Gavin Howardecafd4f2019-02-23 09:30:45 -0700154#define BC_ERROR_SIGNAL_ONLY(s) (BC_ENABLE_SIGNALS && BC_ERR(s))
Gavin Howardfb4f2b82019-02-19 08:43:27 -0700155
Gavin Howardb63c8a12019-05-24 21:06:01 -0600156#define BC_VM_INVALID_CATALOG ((nl_catd) -1)
157
Gavin Howard6365b242018-10-08 10:34:26 -0600158typedef struct BcVm {
Gavin Howard773c86b2018-11-02 14:07:19 -0600159
Gavin Howard6365b242018-10-08 10:34:26 -0600160 BcParse prs;
161 BcProgram prog;
162
Gavin Howardab5e9632019-01-02 13:32:02 -0700163 size_t nchars;
164
Gavin Howard7536dcf2018-12-15 19:27:09 -0700165 const char* file;
166
Gavin Howard48354e82019-01-02 18:15:56 -0700167#if BC_ENABLE_SIGNALS
Gavin Howard2d188a52019-02-25 14:19:08 -0700168 const char *sigmsg;
Gavin Howard30586492019-05-21 00:26:14 -0600169 volatile sig_atomic_t sig;
Gavin Howardc281d422019-05-22 19:32:13 -0600170 sig_atomic_t sig_chk;
Gavin Howard90c43802019-05-21 08:13:32 -0600171 uchar siglen;
Gavin Howard48354e82019-01-02 18:15:56 -0700172#endif // BC_ENABLE_SIGNALS
173
Gavin Howard06384342019-05-26 08:29:05 -0600174 uint16_t flags;
Gavin Howard180f6ba2018-12-27 14:01:28 -0700175 uchar read_ret;
Gavin Howard5e59c392019-05-20 07:51:10 -0600176 bool tty;
Gavin Howarda89d2f52018-12-27 13:56:19 -0700177
Gavin Howardbd848202019-05-18 11:50:42 -0600178 uint16_t line_len;
179
180 BcBigDig maxes[BC_PROG_GLOBALS_LEN];
181
Gavin Howard6365b242018-10-08 10:34:26 -0600182 BcVec files;
Gavin Howard6365b242018-10-08 10:34:26 -0600183 BcVec exprs;
184
Gavin Howardf4983b82018-09-27 10:44:21 -0600185 const char *name;
Gavin Howard07f0d102018-12-04 14:28:03 -0700186 const char *help;
Gavin Howard07f0d102018-12-04 14:28:03 -0700187
Gavin Howardbceb32d2018-12-12 22:23:51 -0700188#if BC_ENABLE_HISTORY
Gavin Howard6e04ac22018-12-12 22:33:53 -0700189 BcHistory history;
Gavin Howardbceb32d2018-12-12 22:23:51 -0700190#endif // BC_ENABLE_HISTORY
191
Gavin Howard48354e82019-01-02 18:15:56 -0700192 BcLexNext next;
193 BcParseParse parse;
194 BcParseExpr expr;
Gavin Howard5ec75732018-12-03 12:11:28 -0700195
Gavin Howard2425bf22019-04-08 17:05:45 -0600196 const char *func_header;
197
198 const char *err_ids[BC_ERR_IDX_NELEMS + BC_ENABLED];
Gavin Howard50080252019-02-20 15:27:43 -0700199 const char *err_msgs[BC_ERROR_NELEMS];
200
Gavin Howard013a2302019-04-01 15:00:39 -0600201 const char *locale;
Gavin Howard50080252019-02-20 15:27:43 -0700202
Gavin Howardba0e16f2019-05-18 19:33:01 -0600203 BcBigDig last_base;
204 BcBigDig last_pow;
205 BcBigDig last_exp;
206 BcBigDig last_rem;
207
Gavin Howard50080252019-02-20 15:27:43 -0700208#if BC_ENABLE_NLS
209 nl_catd catalog;
210#endif // BC_ENABLE_NLS
211
Gavin Howard70e3d602018-12-11 11:00:49 -0700212} BcVm;
Gavin Howardd5551672018-09-22 19:52:42 -0600213
Gavin Howard40a085f2018-12-03 12:08:59 -0700214#if BC_ENABLED
Gavin Howard7536dcf2018-12-15 19:27:09 -0700215BcStatus bc_vm_posixError(BcError e, size_t line, ...);
Gavin Howardf8f232b2018-10-11 17:29:47 -0600216#endif // BC_ENABLED
Gavin Howardd5551672018-09-22 19:52:42 -0600217
Gavin Howarda84ad992018-12-03 19:11:06 -0700218void bc_vm_info(const char* const help);
Gavin Howard64f1e822019-05-21 08:40:19 -0600219BcStatus bc_vm_boot(int argc, char *argv[], const char *env_len,
220 const char* const env_args);
Gavin Howard0bc5dcf2019-05-21 21:44:21 -0600221void bc_vm_shutdown(void);
Gavin Howarda84ad992018-12-03 19:11:06 -0700222
Gavin Howardf7699f22019-01-02 13:02:48 -0700223size_t bc_vm_printf(const char *fmt, ...);
Gavin Howard48af52e2018-10-30 14:47:38 -0600224void bc_vm_puts(const char *str, FILE *restrict f);
225void bc_vm_putchar(int c);
226void bc_vm_fflush(FILE *restrict f);
227
Gavin Howard5bede412019-02-23 09:31:28 -0700228size_t bc_vm_arraySize(size_t n, size_t size);
Gavin Howard007afdf2019-02-23 09:45:42 -0700229size_t bc_vm_growSize(size_t a, size_t b);
Gavin Howardad0ecfe2018-10-30 01:16:01 -0600230void* bc_vm_malloc(size_t n);
231void* bc_vm_realloc(void *ptr, size_t n);
232char* bc_vm_strdup(const char *str);
233
Gavin Howard7536dcf2018-12-15 19:27:09 -0700234BcStatus bc_vm_error(BcError e, size_t line, ...);
Gavin Howard0f31f5b2018-12-03 11:15:46 -0700235
Gavin Howard40a085f2018-12-03 12:08:59 -0700236#if BC_ENABLED
Gavin Howard9fbeaa82018-12-27 18:13:28 -0700237extern const char bc_lib[];
238extern const char *bc_lib_name;
239#if BC_ENABLE_EXTRA_MATH
240extern const char bc_lib2[];
241extern const char *bc_lib2_name;
242#endif // BC_ENABLE_EXTRA_MATH
Gavin Howarda95501a2018-10-03 16:13:34 -0600243#endif // BC_ENABLED
Gavin Howard4ffe5a92018-09-26 20:58:31 -0600244
Gavin Howarda95501a2018-10-03 16:13:34 -0600245extern const char bc_copyright[];
Gavin Howard7536dcf2018-12-15 19:27:09 -0700246extern const char* const bc_err_line;
Gavin Howard2425bf22019-04-08 17:05:45 -0600247extern const char* const bc_err_func_header;
Gavin Howardd5551672018-09-22 19:52:42 -0600248extern const char *bc_errs[];
Gavin Howard5f349d42019-04-09 14:14:00 -0600249extern const uchar bc_err_ids[];
Gavin Howard1cbfe242019-01-09 17:13:11 -0700250extern const char* const bc_err_msgs[];
Gavin Howardf89006a2018-10-29 13:01:51 -0600251
Gavin Howard70e3d602018-12-11 11:00:49 -0700252extern BcVm *vm;
Gavin Howardd5551672018-09-22 19:52:42 -0600253
254#endif // BC_VM_H