blob: 5591bf754d9d2959f324e109e5baad5d959a5b99 [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)
104#define BC_FLAG_TTYIN (UINTMAX_C(1)<<7)
Gavin Howard48354e82019-01-02 18:15:56 -0700105#define BC_TTYIN (vm->flags & BC_FLAG_TTYIN)
106
107#define BC_S (BC_ENABLED && (vm->flags & BC_FLAG_S))
108#define BC_W (BC_ENABLED && (vm->flags & BC_FLAG_W))
109#define BC_L (BC_ENABLED && (vm->flags & BC_FLAG_L))
Gavin Howard75389d12019-02-25 16:39:02 -0700110#define BC_I (BC_ENABLED && (vm->flags & BC_FLAG_I))
111#define BC_G (BC_ENABLED && (vm->flags & BC_FLAG_G))
Gavin Howard48354e82019-01-02 18:15:56 -0700112#define DC_X (DC_ENABLED && (vm->flags & DC_FLAG_X))
Gavin Howardd5551672018-09-22 19:52:42 -0600113
114#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
115#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
116
Gavin Howard92ba4e52019-05-10 20:49:13 -0600117#define BC_MAX_OBASE ((unsigned long) (BC_BASE_POW))
Gavin Howardf2d9a652019-05-11 07:38:32 -0600118#define BC_MAX_DIM ((unsigned long) (SIZE_MAX / sizeof(BcNum) - 1))
Gavin Howard2956a5e2019-05-08 08:04:06 -0600119#define BC_MAX_SCALE ((unsigned long) (BC_NUM_BIGDIG_MAX - 1))
120#define BC_MAX_STRING ((unsigned long) (BC_NUM_BIGDIG_MAX - 1))
Gavin Howardd5551672018-09-22 19:52:42 -0600121#define BC_MAX_NAME BC_MAX_STRING
Gavin Howard530e3072019-04-23 16:23:36 -0600122#define BC_MAX_NUM BC_MAX_SCALE
Gavin Howard2956a5e2019-05-08 08:04:06 -0600123#define BC_MAX_EXP ((unsigned long) (BC_NUM_BIGDIG_MAX - 1))
Gavin Howardf2d9a652019-05-11 07:38:32 -0600124#define BC_MAX_VARS ((unsigned long) (SIZE_MAX / sizeof(BcId) - 1))
Gavin Howardd5551672018-09-22 19:52:42 -0600125
Gavin Howard664476c2019-01-03 14:57:19 -0700126#define BC_IS_BC (BC_ENABLED && (!DC_ENABLED || vm->name[0] != 'd'))
Gavin Howarda6527882019-02-19 20:23:17 -0700127#define BC_IS_POSIX (BC_S || BC_W)
Gavin Howardf878d332018-12-03 12:58:38 -0700128
Gavin Howard112304b2018-12-04 14:30:01 -0700129#if BC_ENABLE_SIGNALS
Gavin Howardb9a0b862019-01-08 11:47:09 -0700130
Gavin Howard2d188a52019-02-25 14:19:08 -0700131#define BC_SIG BC_UNLIKELY(vm->sig)
132#define BC_NO_SIG BC_LIKELY(!vm->sig)
Gavin Howard5dbb48b2019-01-04 11:29:29 -0700133#define BC_SIGINT (vm->sig == SIGINT)
Gavin Howardb9a0b862019-01-08 11:47:09 -0700134
135#ifdef SIGQUIT
Gavin Howard5dbb48b2019-01-04 11:29:29 -0700136#define BC_SIGTERM (vm->sig == SIGTERM || vm->sig == SIGQUIT)
Gavin Howardb9a0b862019-01-08 11:47:09 -0700137#else // SIGQUIT
138#define BC_SIGTERM (vm->sig == SIGTERM)
139#endif // SIGQUIT
140
Gavin Howard112304b2018-12-04 14:30:01 -0700141#else // BC_ENABLE_SIGNALS
Gavin Howard4eb14652019-02-25 14:26:53 -0700142#define BC_SIG (0)
143#define BC_NO_SIG (1)
Gavin Howard112304b2018-12-04 14:30:01 -0700144#endif // BC_ENABLE_SIGNALS
145
Gavin Howard7536dcf2018-12-15 19:27:09 -0700146#define bc_vm_err(e) (bc_vm_error((e), 0))
Gavin Howardecc7fc22018-12-31 13:21:47 -0700147#define bc_vm_verr(e, ...) (bc_vm_error((e), 0, __VA_ARGS__))
Gavin Howard7536dcf2018-12-15 19:27:09 -0700148
Gavin Howard75abdc92019-02-25 13:47:16 -0700149#define BC_IO_ERR(e, f) (BC_ERR((e) == EOF || ferror(f)))
Gavin Howardfb4f2b82019-02-19 08:43:27 -0700150#define BC_STATUS_IS_ERROR(s) \
151 ((s) >= BC_STATUS_ERROR_MATH && (s) <= BC_STATUS_ERROR_PARSE)
Gavin Howardecafd4f2019-02-23 09:30:45 -0700152#define BC_ERROR_SIGNAL_ONLY(s) (BC_ENABLE_SIGNALS && BC_ERR(s))
Gavin Howardfb4f2b82019-02-19 08:43:27 -0700153
Gavin Howard6365b242018-10-08 10:34:26 -0600154typedef struct BcVm {
Gavin Howard773c86b2018-11-02 14:07:19 -0600155
Gavin Howard6365b242018-10-08 10:34:26 -0600156 BcParse prs;
157 BcProgram prog;
158
Gavin Howardab5e9632019-01-02 13:32:02 -0700159 size_t nchars;
160
Gavin Howard7536dcf2018-12-15 19:27:09 -0700161 const char* file;
162
Gavin Howard48354e82019-01-02 18:15:56 -0700163#if BC_ENABLE_SIGNALS
Gavin Howard2d188a52019-02-25 14:19:08 -0700164 const char *sigmsg;
165 uchar siglen;
Gavin Howard9e485442019-01-03 09:29:19 -0700166 uchar sig;
Gavin Howard48354e82019-01-02 18:15:56 -0700167#endif // BC_ENABLE_SIGNALS
168
Gavin Howarda89d2f52018-12-27 13:56:19 -0700169 uint8_t flags;
Gavin Howard180f6ba2018-12-27 14:01:28 -0700170 uchar read_ret;
Gavin Howarda89d2f52018-12-27 13:56:19 -0700171
Gavin Howardbd848202019-05-18 11:50:42 -0600172 uint16_t line_len;
173
174 BcBigDig maxes[BC_PROG_GLOBALS_LEN];
175
Gavin Howard6365b242018-10-08 10:34:26 -0600176 BcVec files;
Gavin Howard6365b242018-10-08 10:34:26 -0600177 BcVec exprs;
178
Gavin Howardf4983b82018-09-27 10:44:21 -0600179 const char *name;
Gavin Howard07f0d102018-12-04 14:28:03 -0700180 const char *help;
Gavin Howard07f0d102018-12-04 14:28:03 -0700181
Gavin Howard1ab22d22019-01-03 13:32:17 -0700182 char *env_args;
183
Gavin Howardbceb32d2018-12-12 22:23:51 -0700184#if BC_ENABLE_HISTORY
Gavin Howard6e04ac22018-12-12 22:33:53 -0700185 BcHistory history;
Gavin Howardbceb32d2018-12-12 22:23:51 -0700186#endif // BC_ENABLE_HISTORY
187
Gavin Howard48354e82019-01-02 18:15:56 -0700188 BcLexNext next;
189 BcParseParse parse;
190 BcParseExpr expr;
Gavin Howard5ec75732018-12-03 12:11:28 -0700191
Gavin Howard2425bf22019-04-08 17:05:45 -0600192 const char *func_header;
193
194 const char *err_ids[BC_ERR_IDX_NELEMS + BC_ENABLED];
Gavin Howard50080252019-02-20 15:27:43 -0700195 const char *err_msgs[BC_ERROR_NELEMS];
196
Gavin Howard013a2302019-04-01 15:00:39 -0600197 const char *locale;
Gavin Howard50080252019-02-20 15:27:43 -0700198
Gavin Howardba0e16f2019-05-18 19:33:01 -0600199 BcBigDig last_base;
200 BcBigDig last_pow;
201 BcBigDig last_exp;
202 BcBigDig last_rem;
203
Gavin Howard50080252019-02-20 15:27:43 -0700204#if BC_ENABLE_NLS
205 nl_catd catalog;
206#endif // BC_ENABLE_NLS
207
Gavin Howard70e3d602018-12-11 11:00:49 -0700208} BcVm;
Gavin Howardd5551672018-09-22 19:52:42 -0600209
Gavin Howard40a085f2018-12-03 12:08:59 -0700210#if BC_ENABLED
Gavin Howard7536dcf2018-12-15 19:27:09 -0700211BcStatus bc_vm_posixError(BcError e, size_t line, ...);
Gavin Howardf8f232b2018-10-11 17:29:47 -0600212#endif // BC_ENABLED
Gavin Howardd5551672018-09-22 19:52:42 -0600213
Gavin Howarda84ad992018-12-03 19:11:06 -0700214void bc_vm_info(const char* const help);
Gavin Howard70e3d602018-12-11 11:00:49 -0700215BcStatus bc_vm_boot(int argc, char *argv[], const char *env_len);
Gavin Howard1cbfe242019-01-09 17:13:11 -0700216void bc_vm_shutdown(void);
Gavin Howarda84ad992018-12-03 19:11:06 -0700217
Gavin Howardf7699f22019-01-02 13:02:48 -0700218size_t bc_vm_printf(const char *fmt, ...);
Gavin Howard48af52e2018-10-30 14:47:38 -0600219void bc_vm_puts(const char *str, FILE *restrict f);
220void bc_vm_putchar(int c);
221void bc_vm_fflush(FILE *restrict f);
222
Gavin Howard5bede412019-02-23 09:31:28 -0700223size_t bc_vm_arraySize(size_t n, size_t size);
Gavin Howard007afdf2019-02-23 09:45:42 -0700224size_t bc_vm_growSize(size_t a, size_t b);
Gavin Howardad0ecfe2018-10-30 01:16:01 -0600225void* bc_vm_malloc(size_t n);
226void* bc_vm_realloc(void *ptr, size_t n);
227char* bc_vm_strdup(const char *str);
228
Gavin Howard7536dcf2018-12-15 19:27:09 -0700229BcStatus bc_vm_error(BcError e, size_t line, ...);
Gavin Howard0f31f5b2018-12-03 11:15:46 -0700230
Gavin Howard40a085f2018-12-03 12:08:59 -0700231#if BC_ENABLED
Gavin Howard9fbeaa82018-12-27 18:13:28 -0700232extern const char bc_lib[];
233extern const char *bc_lib_name;
234#if BC_ENABLE_EXTRA_MATH
235extern const char bc_lib2[];
236extern const char *bc_lib2_name;
237#endif // BC_ENABLE_EXTRA_MATH
Gavin Howarda95501a2018-10-03 16:13:34 -0600238#endif // BC_ENABLED
Gavin Howard4ffe5a92018-09-26 20:58:31 -0600239
Gavin Howarda95501a2018-10-03 16:13:34 -0600240extern const char bc_copyright[];
Gavin Howard7536dcf2018-12-15 19:27:09 -0700241extern const char* const bc_err_line;
Gavin Howard2425bf22019-04-08 17:05:45 -0600242extern const char* const bc_err_func_header;
Gavin Howardd5551672018-09-22 19:52:42 -0600243extern const char *bc_errs[];
Gavin Howard5f349d42019-04-09 14:14:00 -0600244extern const uchar bc_err_ids[];
Gavin Howard1cbfe242019-01-09 17:13:11 -0700245extern const char* const bc_err_msgs[];
Gavin Howardf89006a2018-10-29 13:01:51 -0600246
Gavin Howard70e3d602018-12-11 11:00:49 -0700247extern BcVm *vm;
Gavin Howardd5551672018-09-22 19:52:42 -0600248
249#endif // BC_VM_H