1 /* 2 * ***************************************************************************** 3 * 4 * Copyright (c) 2018-2019 Gavin D. Howard and contributors. 5 * 6 * All rights reserved. 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 * Definitions for bc's VM. 33 * 34 */ 35 36 #ifndef BC_VM_H 37 #define BC_VM_H 38 39 #include <stddef.h> 40 #include <limits.h> 41 42 #include <signal.h> 43 44 #if BC_ENABLE_NLS 45 46 # ifdef _WIN32 47 # error NLS is not supported on Windows. 48 # endif // _WIN32 49 50 #include <nl_types.h> 51 52 #endif // BC_ENABLE_NLS 53 54 #include <status.h> 55 #include <num.h> 56 #include <parse.h> 57 #include <program.h> 58 #include <history.h> 59 60 #if !BC_ENABLED && !DC_ENABLED 61 #error Must define BC_ENABLED, DC_ENABLED, or both 62 #endif 63 64 // CHAR_BIT must be at least 6. 65 #if CHAR_BIT < 6 66 #error CHAR_BIT must be at least 6. 67 #endif 68 69 #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 85 #define GEN_STR(V) #V 86 #define GEN_STR2(V) GEN_STR(V) 87 88 #define BC_VERSION GEN_STR2(VERSION) 89 #define BC_EXECPREFIX GEN_STR2(EXECPREFIX) 90 #define BC_MAINEXEC GEN_STR2(MAINEXEC) 91 92 // Windows has deprecated isatty(). 93 #ifdef _WIN32 94 #define isatty _isatty 95 #endif // _WIN32 96 97 #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_P (UINTMAX_C(1)<<7) 105 #define BC_FLAG_TTYIN (UINTMAX_C(1)<<8) 106 #define BC_TTYIN (vm->flags & BC_FLAG_TTYIN) 107 #define BC_TTY (vm->tty) 108 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)) 112 #define BC_I (vm->flags & BC_FLAG_I) 113 #define BC_G (BC_ENABLED && (vm->flags & BC_FLAG_G)) 114 #define DC_X (DC_ENABLED && (vm->flags & DC_FLAG_X)) 115 #define BC_P (vm->flags & BC_FLAG_P) 116 117 #define BC_USE_PROMPT (!BC_P && BC_TTY && !BC_IS_POSIX) 118 119 #define BC_MAX(a, b) ((a) > (b) ? (a) : (b)) 120 #define BC_MIN(a, b) ((a) < (b) ? (a) : (b)) 121 122 #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)) 126 #define BC_MAX_NAME BC_MAX_STRING 127 #define BC_MAX_NUM BC_MAX_SCALE 128 #define BC_MAX_EXP ((ulong) (BC_NUM_BIGDIG_MAX)) 129 #define BC_MAX_VARS ((ulong) (SIZE_MAX - 1)) 130 131 #define BC_IS_BC (BC_ENABLED && (!DC_ENABLED || vm->name[0] != 'd')) 132 #define BC_IS_POSIX (BC_S || BC_W) 133 134 #if BC_ENABLE_SIGNALS 135 136 #define BC_SIG BC_UNLIKELY(vm->sig != vm->sig_chk) 137 #define BC_NO_SIG BC_LIKELY(vm->sig == vm->sig_chk) 138 139 #define BC_SIGTERM_VAL (SIG_ATOMIC_MAX) 140 #define BC_SIGTERM (vm->sig == BC_SIGTERM_VAL) 141 #define BC_SIGINT (vm->sig && vm->sig != BC_SIGTERM_VAL) 142 143 #else // BC_ENABLE_SIGNALS 144 #define BC_SIG (0) 145 #define BC_NO_SIG (1) 146 #endif // BC_ENABLE_SIGNALS 147 148 #define bc_vm_err(e) (bc_vm_error((e), 0)) 149 #define bc_vm_verr(e, ...) (bc_vm_error((e), 0, __VA_ARGS__)) 150 151 #define BC_IO_ERR(e, f) (BC_ERR((e) < 0 || ferror(f))) 152 #define BC_STATUS_IS_ERROR(s) \ 153 ((s) >= BC_STATUS_ERROR_MATH && (s) <= BC_STATUS_ERROR_FATAL) 154 #define BC_ERROR_SIGNAL_ONLY(s) (BC_ENABLE_SIGNALS && BC_ERR(s)) 155 156 #define BC_VM_INVALID_CATALOG ((nl_catd) -1) 157 158 typedef struct BcVm { 159 160 BcParse prs; 161 BcProgram prog; 162 163 size_t nchars; 164 165 const char* file; 166 167 #if BC_ENABLE_SIGNALS 168 const char *sigmsg; 169 volatile sig_atomic_t sig; 170 sig_atomic_t sig_chk; 171 uchar siglen; 172 #endif // BC_ENABLE_SIGNALS 173 174 uint16_t flags; 175 uchar read_ret; 176 bool tty; 177 178 uint16_t line_len; 179 180 BcBigDig maxes[BC_PROG_GLOBALS_LEN]; 181 182 BcVec files; 183 BcVec exprs; 184 185 const char *name; 186 const char *help; 187 188 #if BC_ENABLE_HISTORY 189 BcHistory history; 190 #endif // BC_ENABLE_HISTORY 191 192 BcLexNext next; 193 BcParseParse parse; 194 BcParseExpr expr; 195 196 const char *func_header; 197 198 const char *err_ids[BC_ERR_IDX_NELEMS + BC_ENABLED]; 199 const char *err_msgs[BC_ERROR_NELEMS]; 200 201 const char *locale; 202 203 BcBigDig last_base; 204 BcBigDig last_pow; 205 BcBigDig last_exp; 206 BcBigDig last_rem; 207 208 #if BC_ENABLE_NLS 209 nl_catd catalog; 210 #endif // BC_ENABLE_NLS 211 212 } BcVm; 213 214 #if BC_ENABLED 215 BcStatus bc_vm_posixError(BcError e, size_t line, ...); 216 #endif // BC_ENABLED 217 218 void bc_vm_info(const char* const help); 219 BcStatus bc_vm_boot(int argc, char *argv[], const char *env_len, 220 const char* const env_args, const char* env_exp_quit); 221 void bc_vm_shutdown(void); 222 223 size_t bc_vm_printf(const char *fmt, ...); 224 void bc_vm_puts(const char *str, FILE *restrict f); 225 void bc_vm_putchar(int c); 226 void bc_vm_fflush(FILE *restrict f); 227 228 size_t bc_vm_arraySize(size_t n, size_t size); 229 size_t bc_vm_growSize(size_t a, size_t b); 230 void* bc_vm_malloc(size_t n); 231 void* bc_vm_realloc(void *ptr, size_t n); 232 char* bc_vm_strdup(const char *str); 233 234 BcStatus bc_vm_error(BcError e, size_t line, ...); 235 236 extern const char bc_copyright[]; 237 extern const char* const bc_err_line; 238 extern const char* const bc_err_func_header; 239 extern const char *bc_errs[]; 240 extern const uchar bc_err_ids[]; 241 extern const char* const bc_err_msgs[]; 242 243 extern BcVm *vm; 244 245 #endif // BC_VM_H 246