1*5a6e8488SAndroid Build Coastguard Worker /* 2*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 3*5a6e8488SAndroid Build Coastguard Worker * 4*5a6e8488SAndroid Build Coastguard Worker * SPDX-License-Identifier: BSD-2-Clause 5*5a6e8488SAndroid Build Coastguard Worker * 6*5a6e8488SAndroid Build Coastguard Worker * Copyright (c) 2018-2024 Gavin D. Howard and contributors. 7*5a6e8488SAndroid Build Coastguard Worker * 8*5a6e8488SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without 9*5a6e8488SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met: 10*5a6e8488SAndroid Build Coastguard Worker * 11*5a6e8488SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright notice, this 12*5a6e8488SAndroid Build Coastguard Worker * list of conditions and the following disclaimer. 13*5a6e8488SAndroid Build Coastguard Worker * 14*5a6e8488SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright notice, 15*5a6e8488SAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation 16*5a6e8488SAndroid Build Coastguard Worker * and/or other materials provided with the distribution. 17*5a6e8488SAndroid Build Coastguard Worker * 18*5a6e8488SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*5a6e8488SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*5a6e8488SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*5a6e8488SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*5a6e8488SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*5a6e8488SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*5a6e8488SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*5a6e8488SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*5a6e8488SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*5a6e8488SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*5a6e8488SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE. 29*5a6e8488SAndroid Build Coastguard Worker * 30*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 31*5a6e8488SAndroid Build Coastguard Worker * 32*5a6e8488SAndroid Build Coastguard Worker * All bc status codes and cross-platform portability. 33*5a6e8488SAndroid Build Coastguard Worker * 34*5a6e8488SAndroid Build Coastguard Worker */ 35*5a6e8488SAndroid Build Coastguard Worker 36*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_STATUS_H 37*5a6e8488SAndroid Build Coastguard Worker #define BC_STATUS_H 38*5a6e8488SAndroid Build Coastguard Worker 39*5a6e8488SAndroid Build Coastguard Worker #ifdef _WIN32 40*5a6e8488SAndroid Build Coastguard Worker #include <Windows.h> 41*5a6e8488SAndroid Build Coastguard Worker #include <BaseTsd.h> 42*5a6e8488SAndroid Build Coastguard Worker #include <stdio.h> 43*5a6e8488SAndroid Build Coastguard Worker #include <io.h> 44*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32 45*5a6e8488SAndroid Build Coastguard Worker 46*5a6e8488SAndroid Build Coastguard Worker #include <stdint.h> 47*5a6e8488SAndroid Build Coastguard Worker #include <sys/types.h> 48*5a6e8488SAndroid Build Coastguard Worker 49*5a6e8488SAndroid Build Coastguard Worker // Windows has deprecated isatty() and the rest of these. Or doesn't have them. 50*5a6e8488SAndroid Build Coastguard Worker // So these are just fixes for Windows. 51*5a6e8488SAndroid Build Coastguard Worker #ifdef _WIN32 52*5a6e8488SAndroid Build Coastguard Worker 53*5a6e8488SAndroid Build Coastguard Worker // This one is special. Windows did not like me defining an 54*5a6e8488SAndroid Build Coastguard Worker // inline function that was not given a definition in a header 55*5a6e8488SAndroid Build Coastguard Worker // file. This suppresses that by making inline functions non-inline. 56*5a6e8488SAndroid Build Coastguard Worker #define inline 57*5a6e8488SAndroid Build Coastguard Worker 58*5a6e8488SAndroid Build Coastguard Worker #define restrict __restrict 59*5a6e8488SAndroid Build Coastguard Worker #define strdup _strdup 60*5a6e8488SAndroid Build Coastguard Worker #define write(f, b, s) _write((f), (b), (unsigned int) (s)) 61*5a6e8488SAndroid Build Coastguard Worker #define read(f, b, s) _read((f), (b), (unsigned int) (s)) 62*5a6e8488SAndroid Build Coastguard Worker #define close _close 63*5a6e8488SAndroid Build Coastguard Worker #define open(f, n, m) \ 64*5a6e8488SAndroid Build Coastguard Worker _sopen_s((f), (n), (m) | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE) 65*5a6e8488SAndroid Build Coastguard Worker #define sigjmp_buf jmp_buf 66*5a6e8488SAndroid Build Coastguard Worker #define sigsetjmp(j, s) setjmp(j) 67*5a6e8488SAndroid Build Coastguard Worker #define siglongjmp longjmp 68*5a6e8488SAndroid Build Coastguard Worker #define isatty _isatty 69*5a6e8488SAndroid Build Coastguard Worker #define STDIN_FILENO _fileno(stdin) 70*5a6e8488SAndroid Build Coastguard Worker #define STDOUT_FILENO _fileno(stdout) 71*5a6e8488SAndroid Build Coastguard Worker #define STDERR_FILENO _fileno(stderr) 72*5a6e8488SAndroid Build Coastguard Worker #define S_ISDIR(m) ((m) & (_S_IFDIR)) 73*5a6e8488SAndroid Build Coastguard Worker #define O_RDONLY _O_RDONLY 74*5a6e8488SAndroid Build Coastguard Worker #define stat _stat 75*5a6e8488SAndroid Build Coastguard Worker #define fstat _fstat 76*5a6e8488SAndroid Build Coastguard Worker #define BC_FILE_SEP '\\' 77*5a6e8488SAndroid Build Coastguard Worker 78*5a6e8488SAndroid Build Coastguard Worker #else // _WIN32 79*5a6e8488SAndroid Build Coastguard Worker #define BC_FILE_SEP '/' 80*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32 81*5a6e8488SAndroid Build Coastguard Worker 82*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_ENABLED 83*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLED (1) 84*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 85*5a6e8488SAndroid Build Coastguard Worker 86*5a6e8488SAndroid Build Coastguard Worker #ifndef DC_ENABLED 87*5a6e8488SAndroid Build Coastguard Worker #define DC_ENABLED (1) 88*5a6e8488SAndroid Build Coastguard Worker #endif // DC_ENABLED 89*5a6e8488SAndroid Build Coastguard Worker 90*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_ENABLE_EXTRA_MATH 91*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLE_EXTRA_MATH (1) 92*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH 93*5a6e8488SAndroid Build Coastguard Worker 94*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_ENABLE_LIBRARY 95*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLE_LIBRARY (0) 96*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_LIBRARY 97*5a6e8488SAndroid Build Coastguard Worker 98*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_ENABLE_HISTORY 99*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLE_HISTORY (1) 100*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_HISTORY 101*5a6e8488SAndroid Build Coastguard Worker 102*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_ENABLE_EDITLINE 103*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLE_EDITLINE (0) 104*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EDITLINE 105*5a6e8488SAndroid Build Coastguard Worker 106*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_ENABLE_READLINE 107*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLE_READLINE (0) 108*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_READLINE 109*5a6e8488SAndroid Build Coastguard Worker 110*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_ENABLE_NLS 111*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLE_NLS (0) 112*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_NLS 113*5a6e8488SAndroid Build Coastguard Worker 114*5a6e8488SAndroid Build Coastguard Worker #ifdef __OpenBSD__ 115*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_READLINE 116*5a6e8488SAndroid Build Coastguard Worker #error Cannot use readline on OpenBSD 117*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_READLINE 118*5a6e8488SAndroid Build Coastguard Worker #endif // __OpenBSD__ 119*5a6e8488SAndroid Build Coastguard Worker 120*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EDITLINE && BC_ENABLE_READLINE 121*5a6e8488SAndroid Build Coastguard Worker #error Must enable only one of editline or readline, not both. 122*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EDITLINE && BC_ENABLE_READLINE 123*5a6e8488SAndroid Build Coastguard Worker 124*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EDITLINE || BC_ENABLE_READLINE 125*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLE_LINE_LIB (1) 126*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_EDITLINE || BC_ENABLE_READLINE 127*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLE_LINE_LIB (0) 128*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EDITLINE || BC_ENABLE_READLINE 129*5a6e8488SAndroid Build Coastguard Worker 130*5a6e8488SAndroid Build Coastguard Worker // This is error checking for fuzz builds. 131*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_AFL 132*5a6e8488SAndroid Build Coastguard Worker #ifndef __AFL_HAVE_MANUAL_CONTROL 133*5a6e8488SAndroid Build Coastguard Worker #error Must compile with afl-clang-fast or afl-clang-lto for fuzzing 134*5a6e8488SAndroid Build Coastguard Worker #endif // __AFL_HAVE_MANUAL_CONTROL 135*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_AFL 136*5a6e8488SAndroid Build Coastguard Worker 137*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_ENABLE_MEMCHECK 138*5a6e8488SAndroid Build Coastguard Worker #define BC_ENABLE_MEMCHECK (0) 139*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_MEMCHECK 140*5a6e8488SAndroid Build Coastguard Worker 141*5a6e8488SAndroid Build Coastguard Worker /** 142*5a6e8488SAndroid Build Coastguard Worker * Mark a variable as unused. 143*5a6e8488SAndroid Build Coastguard Worker * @param e The variable to mark as unused. 144*5a6e8488SAndroid Build Coastguard Worker */ 145*5a6e8488SAndroid Build Coastguard Worker #define BC_UNUSED(e) ((void) (e)) 146*5a6e8488SAndroid Build Coastguard Worker 147*5a6e8488SAndroid Build Coastguard Worker // If users want, they can define this to something like __builtin_expect(e, 1). 148*5a6e8488SAndroid Build Coastguard Worker // It might give a performance improvement. 149*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_LIKELY 150*5a6e8488SAndroid Build Coastguard Worker 151*5a6e8488SAndroid Build Coastguard Worker /** 152*5a6e8488SAndroid Build Coastguard Worker * Mark a branch expression as likely. 153*5a6e8488SAndroid Build Coastguard Worker * @param e The expression to mark as likely. 154*5a6e8488SAndroid Build Coastguard Worker */ 155*5a6e8488SAndroid Build Coastguard Worker #define BC_LIKELY(e) (e) 156*5a6e8488SAndroid Build Coastguard Worker 157*5a6e8488SAndroid Build Coastguard Worker #endif // BC_LIKELY 158*5a6e8488SAndroid Build Coastguard Worker 159*5a6e8488SAndroid Build Coastguard Worker // If users want, they can define this to something like __builtin_expect(e, 0). 160*5a6e8488SAndroid Build Coastguard Worker // It might give a performance improvement. 161*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_UNLIKELY 162*5a6e8488SAndroid Build Coastguard Worker 163*5a6e8488SAndroid Build Coastguard Worker /** 164*5a6e8488SAndroid Build Coastguard Worker * Mark a branch expression as unlikely. 165*5a6e8488SAndroid Build Coastguard Worker * @param e The expression to mark as unlikely. 166*5a6e8488SAndroid Build Coastguard Worker */ 167*5a6e8488SAndroid Build Coastguard Worker #define BC_UNLIKELY(e) (e) 168*5a6e8488SAndroid Build Coastguard Worker 169*5a6e8488SAndroid Build Coastguard Worker #endif // BC_UNLIKELY 170*5a6e8488SAndroid Build Coastguard Worker 171*5a6e8488SAndroid Build Coastguard Worker /** 172*5a6e8488SAndroid Build Coastguard Worker * Mark a branch expression as an error, if true. 173*5a6e8488SAndroid Build Coastguard Worker * @param e The expression to mark as an error, if true. 174*5a6e8488SAndroid Build Coastguard Worker */ 175*5a6e8488SAndroid Build Coastguard Worker #define BC_ERR(e) BC_UNLIKELY(e) 176*5a6e8488SAndroid Build Coastguard Worker 177*5a6e8488SAndroid Build Coastguard Worker /** 178*5a6e8488SAndroid Build Coastguard Worker * Mark a branch expression as not an error, if true. 179*5a6e8488SAndroid Build Coastguard Worker * @param e The expression to mark as not an error, if true. 180*5a6e8488SAndroid Build Coastguard Worker */ 181*5a6e8488SAndroid Build Coastguard Worker #define BC_NO_ERR(s) BC_LIKELY(s) 182*5a6e8488SAndroid Build Coastguard Worker 183*5a6e8488SAndroid Build Coastguard Worker // Disable extra debug code by default. 184*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_DEBUG_CODE 185*5a6e8488SAndroid Build Coastguard Worker #define BC_DEBUG_CODE (0) 186*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG_CODE 187*5a6e8488SAndroid Build Coastguard Worker 188*5a6e8488SAndroid Build Coastguard Worker #if defined(__clang__) 189*5a6e8488SAndroid Build Coastguard Worker #define BC_CLANG (1) 190*5a6e8488SAndroid Build Coastguard Worker #else // defined(__clang__) 191*5a6e8488SAndroid Build Coastguard Worker #define BC_CLANG (0) 192*5a6e8488SAndroid Build Coastguard Worker #endif // defined(__clang__) 193*5a6e8488SAndroid Build Coastguard Worker 194*5a6e8488SAndroid Build Coastguard Worker #if defined(__GNUC__) && !BC_CLANG 195*5a6e8488SAndroid Build Coastguard Worker #define BC_GCC (1) 196*5a6e8488SAndroid Build Coastguard Worker #else // defined(__GNUC__) && !BC_CLANG 197*5a6e8488SAndroid Build Coastguard Worker #define BC_GCC (0) 198*5a6e8488SAndroid Build Coastguard Worker #endif // defined(__GNUC__) && !BC_CLANG 199*5a6e8488SAndroid Build Coastguard Worker 200*5a6e8488SAndroid Build Coastguard Worker // We want to be able to use _Noreturn on C11 compilers. 201*5a6e8488SAndroid Build Coastguard Worker #if __STDC_VERSION__ >= 201112L 202*5a6e8488SAndroid Build Coastguard Worker 203*5a6e8488SAndroid Build Coastguard Worker #include <stdnoreturn.h> 204*5a6e8488SAndroid Build Coastguard Worker #define BC_NORETURN _Noreturn 205*5a6e8488SAndroid Build Coastguard Worker #define BC_C11 (1) 206*5a6e8488SAndroid Build Coastguard Worker 207*5a6e8488SAndroid Build Coastguard Worker #else // __STDC_VERSION__ 208*5a6e8488SAndroid Build Coastguard Worker 209*5a6e8488SAndroid Build Coastguard Worker #if BC_CLANG 210*5a6e8488SAndroid Build Coastguard Worker #if __has_attribute(noreturn) 211*5a6e8488SAndroid Build Coastguard Worker #define BC_NORETURN __attribute((noreturn)) 212*5a6e8488SAndroid Build Coastguard Worker #else // __has_attribute(noreturn) 213*5a6e8488SAndroid Build Coastguard Worker #define BC_NORETURN 214*5a6e8488SAndroid Build Coastguard Worker #endif // __has_attribute(noreturn) 215*5a6e8488SAndroid Build Coastguard Worker 216*5a6e8488SAndroid Build Coastguard Worker #else // BC_CLANG 217*5a6e8488SAndroid Build Coastguard Worker 218*5a6e8488SAndroid Build Coastguard Worker #define BC_NORETURN 219*5a6e8488SAndroid Build Coastguard Worker 220*5a6e8488SAndroid Build Coastguard Worker #endif // BC_CLANG 221*5a6e8488SAndroid Build Coastguard Worker 222*5a6e8488SAndroid Build Coastguard Worker #define BC_MUST_RETURN 223*5a6e8488SAndroid Build Coastguard Worker #define BC_C11 (0) 224*5a6e8488SAndroid Build Coastguard Worker 225*5a6e8488SAndroid Build Coastguard Worker #endif // __STDC_VERSION__ 226*5a6e8488SAndroid Build Coastguard Worker 227*5a6e8488SAndroid Build Coastguard Worker #define BC_HAS_UNREACHABLE (0) 228*5a6e8488SAndroid Build Coastguard Worker #define BC_HAS_COMPUTED_GOTO (0) 229*5a6e8488SAndroid Build Coastguard Worker 230*5a6e8488SAndroid Build Coastguard Worker // GCC and Clang complain if fallthroughs are not marked with their special 231*5a6e8488SAndroid Build Coastguard Worker // attribute. Jerks. This creates a define for marking the fallthroughs that is 232*5a6e8488SAndroid Build Coastguard Worker // nothing on other compilers. 233*5a6e8488SAndroid Build Coastguard Worker #if BC_CLANG || BC_GCC 234*5a6e8488SAndroid Build Coastguard Worker 235*5a6e8488SAndroid Build Coastguard Worker #if defined(__has_attribute) 236*5a6e8488SAndroid Build Coastguard Worker 237*5a6e8488SAndroid Build Coastguard Worker #if __has_attribute(fallthrough) 238*5a6e8488SAndroid Build Coastguard Worker #define BC_FALLTHROUGH __attribute__((fallthrough)); 239*5a6e8488SAndroid Build Coastguard Worker #else // __has_attribute(fallthrough) 240*5a6e8488SAndroid Build Coastguard Worker #define BC_FALLTHROUGH 241*5a6e8488SAndroid Build Coastguard Worker #endif // __has_attribute(fallthrough) 242*5a6e8488SAndroid Build Coastguard Worker 243*5a6e8488SAndroid Build Coastguard Worker #if BC_GCC 244*5a6e8488SAndroid Build Coastguard Worker 245*5a6e8488SAndroid Build Coastguard Worker #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 246*5a6e8488SAndroid Build Coastguard Worker #undef BC_HAS_UNREACHABLE 247*5a6e8488SAndroid Build Coastguard Worker #define BC_HAS_UNREACHABLE (1) 248*5a6e8488SAndroid Build Coastguard Worker #endif // __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 249*5a6e8488SAndroid Build Coastguard Worker 250*5a6e8488SAndroid Build Coastguard Worker #else // BC_GCC 251*5a6e8488SAndroid Build Coastguard Worker 252*5a6e8488SAndroid Build Coastguard Worker #if __clang_major__ >= 4 253*5a6e8488SAndroid Build Coastguard Worker #undef BC_HAS_UNREACHABLE 254*5a6e8488SAndroid Build Coastguard Worker #define BC_HAS_UNREACHABLE (1) 255*5a6e8488SAndroid Build Coastguard Worker #endif // __clang_major__ >= 4 256*5a6e8488SAndroid Build Coastguard Worker 257*5a6e8488SAndroid Build Coastguard Worker #endif // BC_GCC 258*5a6e8488SAndroid Build Coastguard Worker 259*5a6e8488SAndroid Build Coastguard Worker #else // defined(__has_attribute) 260*5a6e8488SAndroid Build Coastguard Worker #define BC_FALLTHROUGH 261*5a6e8488SAndroid Build Coastguard Worker #endif // defined(__has_attribute) 262*5a6e8488SAndroid Build Coastguard Worker #else // BC_CLANG || BC_GCC 263*5a6e8488SAndroid Build Coastguard Worker #define BC_FALLTHROUGH 264*5a6e8488SAndroid Build Coastguard Worker #endif // BC_CLANG || BC_GCC 265*5a6e8488SAndroid Build Coastguard Worker 266*5a6e8488SAndroid Build Coastguard Worker #if BC_HAS_UNREACHABLE 267*5a6e8488SAndroid Build Coastguard Worker 268*5a6e8488SAndroid Build Coastguard Worker #define BC_UNREACHABLE __builtin_unreachable(); 269*5a6e8488SAndroid Build Coastguard Worker 270*5a6e8488SAndroid Build Coastguard Worker #else // BC_HAS_UNREACHABLE 271*5a6e8488SAndroid Build Coastguard Worker 272*5a6e8488SAndroid Build Coastguard Worker #ifdef _WIN32 273*5a6e8488SAndroid Build Coastguard Worker 274*5a6e8488SAndroid Build Coastguard Worker #define BC_UNREACHABLE __assume(0); 275*5a6e8488SAndroid Build Coastguard Worker 276*5a6e8488SAndroid Build Coastguard Worker #else // _WIN32 277*5a6e8488SAndroid Build Coastguard Worker 278*5a6e8488SAndroid Build Coastguard Worker #define BC_UNREACHABLE 279*5a6e8488SAndroid Build Coastguard Worker 280*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32 281*5a6e8488SAndroid Build Coastguard Worker 282*5a6e8488SAndroid Build Coastguard Worker #endif // BC_HAS_UNREACHABLE 283*5a6e8488SAndroid Build Coastguard Worker 284*5a6e8488SAndroid Build Coastguard Worker #if BC_GCC 285*5a6e8488SAndroid Build Coastguard Worker 286*5a6e8488SAndroid Build Coastguard Worker #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 287*5a6e8488SAndroid Build Coastguard Worker 288*5a6e8488SAndroid Build Coastguard Worker #undef BC_HAS_COMPUTED_GOTO 289*5a6e8488SAndroid Build Coastguard Worker #define BC_HAS_COMPUTED_GOTO (1) 290*5a6e8488SAndroid Build Coastguard Worker 291*5a6e8488SAndroid Build Coastguard Worker #endif // __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 292*5a6e8488SAndroid Build Coastguard Worker 293*5a6e8488SAndroid Build Coastguard Worker #endif // BC_GCC 294*5a6e8488SAndroid Build Coastguard Worker 295*5a6e8488SAndroid Build Coastguard Worker #if BC_CLANG 296*5a6e8488SAndroid Build Coastguard Worker 297*5a6e8488SAndroid Build Coastguard Worker #if __clang_major__ >= 4 298*5a6e8488SAndroid Build Coastguard Worker 299*5a6e8488SAndroid Build Coastguard Worker #undef BC_HAS_COMPUTED_GOTO 300*5a6e8488SAndroid Build Coastguard Worker #define BC_HAS_COMPUTED_GOTO (1) 301*5a6e8488SAndroid Build Coastguard Worker 302*5a6e8488SAndroid Build Coastguard Worker #endif // __clang_major__ >= 4 303*5a6e8488SAndroid Build Coastguard Worker 304*5a6e8488SAndroid Build Coastguard Worker #endif // BC_CLANG 305*5a6e8488SAndroid Build Coastguard Worker 306*5a6e8488SAndroid Build Coastguard Worker #ifdef BC_NO_COMPUTED_GOTO 307*5a6e8488SAndroid Build Coastguard Worker 308*5a6e8488SAndroid Build Coastguard Worker #undef BC_HAS_COMPUTED_GOTO 309*5a6e8488SAndroid Build Coastguard Worker #define BC_HAS_COMPUTED_GOTO (0) 310*5a6e8488SAndroid Build Coastguard Worker 311*5a6e8488SAndroid Build Coastguard Worker #endif // BC_NO_COMPUTED_GOTO 312*5a6e8488SAndroid Build Coastguard Worker 313*5a6e8488SAndroid Build Coastguard Worker #if BC_GCC 314*5a6e8488SAndroid Build Coastguard Worker #ifdef __OpenBSD__ 315*5a6e8488SAndroid Build Coastguard Worker // The OpenBSD GCC doesn't like inline. 316*5a6e8488SAndroid Build Coastguard Worker #define inline 317*5a6e8488SAndroid Build Coastguard Worker #endif // __OpenBSD__ 318*5a6e8488SAndroid Build Coastguard Worker #endif // BC_GCC 319*5a6e8488SAndroid Build Coastguard Worker 320*5a6e8488SAndroid Build Coastguard Worker // Workarounds for AIX's POSIX incompatibility. 321*5a6e8488SAndroid Build Coastguard Worker #ifndef SIZE_MAX 322*5a6e8488SAndroid Build Coastguard Worker #define SIZE_MAX __SIZE_MAX__ 323*5a6e8488SAndroid Build Coastguard Worker #endif // SIZE_MAX 324*5a6e8488SAndroid Build Coastguard Worker #ifndef UINTMAX_C 325*5a6e8488SAndroid Build Coastguard Worker #define UINTMAX_C __UINTMAX_C 326*5a6e8488SAndroid Build Coastguard Worker #endif // UINTMAX_C 327*5a6e8488SAndroid Build Coastguard Worker #ifndef UINT32_C 328*5a6e8488SAndroid Build Coastguard Worker #define UINT32_C __UINT32_C 329*5a6e8488SAndroid Build Coastguard Worker #endif // UINT32_C 330*5a6e8488SAndroid Build Coastguard Worker #ifndef UINT_FAST32_MAX 331*5a6e8488SAndroid Build Coastguard Worker #define UINT_FAST32_MAX __UINT_FAST32_MAX__ 332*5a6e8488SAndroid Build Coastguard Worker #endif // UINT_FAST32_MAX 333*5a6e8488SAndroid Build Coastguard Worker #ifndef UINT16_MAX 334*5a6e8488SAndroid Build Coastguard Worker #define UINT16_MAX __UINT16_MAX__ 335*5a6e8488SAndroid Build Coastguard Worker #endif // UINT16_MAX 336*5a6e8488SAndroid Build Coastguard Worker #ifndef SIG_ATOMIC_MAX 337*5a6e8488SAndroid Build Coastguard Worker #define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__ 338*5a6e8488SAndroid Build Coastguard Worker #endif // SIG_ATOMIC_MAX 339*5a6e8488SAndroid Build Coastguard Worker 340*5a6e8488SAndroid Build Coastguard Worker // Yes, this has to be here. 341*5a6e8488SAndroid Build Coastguard Worker #include <bcl.h> 342*5a6e8488SAndroid Build Coastguard Worker 343*5a6e8488SAndroid Build Coastguard Worker // All of these set defaults for settings. 344*5a6e8488SAndroid Build Coastguard Worker 345*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 346*5a6e8488SAndroid Build Coastguard Worker 347*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_DEFAULT_BANNER 348*5a6e8488SAndroid Build Coastguard Worker #define BC_DEFAULT_BANNER (0) 349*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEFAULT_BANNER 350*5a6e8488SAndroid Build Coastguard Worker 351*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 352*5a6e8488SAndroid Build Coastguard Worker 353*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_DEFAULT_SIGINT_RESET 354*5a6e8488SAndroid Build Coastguard Worker #define BC_DEFAULT_SIGINT_RESET (1) 355*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEFAULT_SIGINT_RESET 356*5a6e8488SAndroid Build Coastguard Worker 357*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_DEFAULT_TTY_MODE 358*5a6e8488SAndroid Build Coastguard Worker #define BC_DEFAULT_TTY_MODE (1) 359*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEFAULT_TTY_MODE 360*5a6e8488SAndroid Build Coastguard Worker 361*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_DEFAULT_PROMPT 362*5a6e8488SAndroid Build Coastguard Worker #define BC_DEFAULT_PROMPT BC_DEFAULT_TTY_MODE 363*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEFAULT_PROMPT 364*5a6e8488SAndroid Build Coastguard Worker 365*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_DEFAULT_EXPR_EXIT 366*5a6e8488SAndroid Build Coastguard Worker #define BC_DEFAULT_EXPR_EXIT (1) 367*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEFAULT_EXPR_EXIT 368*5a6e8488SAndroid Build Coastguard Worker 369*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_DEFAULT_DIGIT_CLAMP 370*5a6e8488SAndroid Build Coastguard Worker #define BC_DEFAULT_DIGIT_CLAMP (0) 371*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEFAULT_DIGIT_CLAMP 372*5a6e8488SAndroid Build Coastguard Worker 373*5a6e8488SAndroid Build Coastguard Worker // All of these set defaults for settings. 374*5a6e8488SAndroid Build Coastguard Worker #ifndef DC_DEFAULT_SIGINT_RESET 375*5a6e8488SAndroid Build Coastguard Worker #define DC_DEFAULT_SIGINT_RESET (1) 376*5a6e8488SAndroid Build Coastguard Worker #endif // DC_DEFAULT_SIGINT_RESET 377*5a6e8488SAndroid Build Coastguard Worker 378*5a6e8488SAndroid Build Coastguard Worker #ifndef DC_DEFAULT_TTY_MODE 379*5a6e8488SAndroid Build Coastguard Worker #define DC_DEFAULT_TTY_MODE (0) 380*5a6e8488SAndroid Build Coastguard Worker #endif // DC_DEFAULT_TTY_MODE 381*5a6e8488SAndroid Build Coastguard Worker 382*5a6e8488SAndroid Build Coastguard Worker #ifndef DC_DEFAULT_HISTORY 383*5a6e8488SAndroid Build Coastguard Worker #define DC_DEFAULT_HISTORY DC_DEFAULT_TTY_MODE 384*5a6e8488SAndroid Build Coastguard Worker #endif // DC_DEFAULT_HISTORY 385*5a6e8488SAndroid Build Coastguard Worker 386*5a6e8488SAndroid Build Coastguard Worker #ifndef DC_DEFAULT_PROMPT 387*5a6e8488SAndroid Build Coastguard Worker #define DC_DEFAULT_PROMPT DC_DEFAULT_TTY_MODE 388*5a6e8488SAndroid Build Coastguard Worker #endif // DC_DEFAULT_PROMPT 389*5a6e8488SAndroid Build Coastguard Worker 390*5a6e8488SAndroid Build Coastguard Worker #ifndef DC_DEFAULT_EXPR_EXIT 391*5a6e8488SAndroid Build Coastguard Worker #define DC_DEFAULT_EXPR_EXIT (1) 392*5a6e8488SAndroid Build Coastguard Worker #endif // DC_DEFAULT_EXPR_EXIT 393*5a6e8488SAndroid Build Coastguard Worker 394*5a6e8488SAndroid Build Coastguard Worker #ifndef DC_DEFAULT_DIGIT_CLAMP 395*5a6e8488SAndroid Build Coastguard Worker #define DC_DEFAULT_DIGIT_CLAMP (0) 396*5a6e8488SAndroid Build Coastguard Worker #endif // DC_DEFAULT_DIGIT_CLAMP 397*5a6e8488SAndroid Build Coastguard Worker 398*5a6e8488SAndroid Build Coastguard Worker /// Statuses, which mark either which category of error happened, or some other 399*5a6e8488SAndroid Build Coastguard Worker /// status that matters. 400*5a6e8488SAndroid Build Coastguard Worker typedef enum BcStatus 401*5a6e8488SAndroid Build Coastguard Worker { 402*5a6e8488SAndroid Build Coastguard Worker /// Normal status. 403*5a6e8488SAndroid Build Coastguard Worker BC_STATUS_SUCCESS = 0, 404*5a6e8488SAndroid Build Coastguard Worker 405*5a6e8488SAndroid Build Coastguard Worker /// Math error. 406*5a6e8488SAndroid Build Coastguard Worker BC_STATUS_ERROR_MATH, 407*5a6e8488SAndroid Build Coastguard Worker 408*5a6e8488SAndroid Build Coastguard Worker /// Parse (and lex) error. 409*5a6e8488SAndroid Build Coastguard Worker BC_STATUS_ERROR_PARSE, 410*5a6e8488SAndroid Build Coastguard Worker 411*5a6e8488SAndroid Build Coastguard Worker /// Runtime error. 412*5a6e8488SAndroid Build Coastguard Worker BC_STATUS_ERROR_EXEC, 413*5a6e8488SAndroid Build Coastguard Worker 414*5a6e8488SAndroid Build Coastguard Worker /// Fatal error. 415*5a6e8488SAndroid Build Coastguard Worker BC_STATUS_ERROR_FATAL, 416*5a6e8488SAndroid Build Coastguard Worker 417*5a6e8488SAndroid Build Coastguard Worker /// EOF status. 418*5a6e8488SAndroid Build Coastguard Worker BC_STATUS_EOF, 419*5a6e8488SAndroid Build Coastguard Worker 420*5a6e8488SAndroid Build Coastguard Worker /// Quit status. This means that bc/dc is in the process of quitting. 421*5a6e8488SAndroid Build Coastguard Worker BC_STATUS_QUIT, 422*5a6e8488SAndroid Build Coastguard Worker 423*5a6e8488SAndroid Build Coastguard Worker } BcStatus; 424*5a6e8488SAndroid Build Coastguard Worker 425*5a6e8488SAndroid Build Coastguard Worker /// Errors, which are more specific errors. 426*5a6e8488SAndroid Build Coastguard Worker typedef enum BcErr 427*5a6e8488SAndroid Build Coastguard Worker { 428*5a6e8488SAndroid Build Coastguard Worker // Math errors. 429*5a6e8488SAndroid Build Coastguard Worker 430*5a6e8488SAndroid Build Coastguard Worker /// Negative number used when not allowed. 431*5a6e8488SAndroid Build Coastguard Worker BC_ERR_MATH_NEGATIVE, 432*5a6e8488SAndroid Build Coastguard Worker 433*5a6e8488SAndroid Build Coastguard Worker /// Non-integer used when not allowed. 434*5a6e8488SAndroid Build Coastguard Worker BC_ERR_MATH_NON_INTEGER, 435*5a6e8488SAndroid Build Coastguard Worker 436*5a6e8488SAndroid Build Coastguard Worker /// Conversion to a hardware integer would overflow. 437*5a6e8488SAndroid Build Coastguard Worker BC_ERR_MATH_OVERFLOW, 438*5a6e8488SAndroid Build Coastguard Worker 439*5a6e8488SAndroid Build Coastguard Worker /// Divide by zero. 440*5a6e8488SAndroid Build Coastguard Worker BC_ERR_MATH_DIVIDE_BY_ZERO, 441*5a6e8488SAndroid Build Coastguard Worker 442*5a6e8488SAndroid Build Coastguard Worker // Fatal errors. 443*5a6e8488SAndroid Build Coastguard Worker 444*5a6e8488SAndroid Build Coastguard Worker /// An allocation or reallocation failed. 445*5a6e8488SAndroid Build Coastguard Worker BC_ERR_FATAL_ALLOC_ERR, 446*5a6e8488SAndroid Build Coastguard Worker 447*5a6e8488SAndroid Build Coastguard Worker /// I/O failure. 448*5a6e8488SAndroid Build Coastguard Worker BC_ERR_FATAL_IO_ERR, 449*5a6e8488SAndroid Build Coastguard Worker 450*5a6e8488SAndroid Build Coastguard Worker /// File error, such as permissions or file does not exist. 451*5a6e8488SAndroid Build Coastguard Worker BC_ERR_FATAL_FILE_ERR, 452*5a6e8488SAndroid Build Coastguard Worker 453*5a6e8488SAndroid Build Coastguard Worker /// File is binary, not text, error. 454*5a6e8488SAndroid Build Coastguard Worker BC_ERR_FATAL_BIN_FILE, 455*5a6e8488SAndroid Build Coastguard Worker 456*5a6e8488SAndroid Build Coastguard Worker /// Attempted to read a directory as a file error. 457*5a6e8488SAndroid Build Coastguard Worker BC_ERR_FATAL_PATH_DIR, 458*5a6e8488SAndroid Build Coastguard Worker 459*5a6e8488SAndroid Build Coastguard Worker /// Invalid option error. 460*5a6e8488SAndroid Build Coastguard Worker BC_ERR_FATAL_OPTION, 461*5a6e8488SAndroid Build Coastguard Worker 462*5a6e8488SAndroid Build Coastguard Worker /// Option with required argument not given an argument. 463*5a6e8488SAndroid Build Coastguard Worker BC_ERR_FATAL_OPTION_NO_ARG, 464*5a6e8488SAndroid Build Coastguard Worker 465*5a6e8488SAndroid Build Coastguard Worker /// Option with no argument given an argument. 466*5a6e8488SAndroid Build Coastguard Worker BC_ERR_FATAL_OPTION_ARG, 467*5a6e8488SAndroid Build Coastguard Worker 468*5a6e8488SAndroid Build Coastguard Worker /// Option argument is invalid. 469*5a6e8488SAndroid Build Coastguard Worker BC_ERR_FATAL_ARG, 470*5a6e8488SAndroid Build Coastguard Worker 471*5a6e8488SAndroid Build Coastguard Worker // Runtime errors. 472*5a6e8488SAndroid Build Coastguard Worker 473*5a6e8488SAndroid Build Coastguard Worker /// Invalid ibase value. 474*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_IBASE, 475*5a6e8488SAndroid Build Coastguard Worker 476*5a6e8488SAndroid Build Coastguard Worker /// Invalid obase value. 477*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_OBASE, 478*5a6e8488SAndroid Build Coastguard Worker 479*5a6e8488SAndroid Build Coastguard Worker /// Invalid scale value. 480*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_SCALE, 481*5a6e8488SAndroid Build Coastguard Worker 482*5a6e8488SAndroid Build Coastguard Worker /// Invalid expression parsed by read(). 483*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_READ_EXPR, 484*5a6e8488SAndroid Build Coastguard Worker 485*5a6e8488SAndroid Build Coastguard Worker /// read() used within an expression given to a read() call. 486*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_REC_READ, 487*5a6e8488SAndroid Build Coastguard Worker 488*5a6e8488SAndroid Build Coastguard Worker /// Type error. 489*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_TYPE, 490*5a6e8488SAndroid Build Coastguard Worker 491*5a6e8488SAndroid Build Coastguard Worker /// Stack has too few elements error. 492*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_STACK, 493*5a6e8488SAndroid Build Coastguard Worker 494*5a6e8488SAndroid Build Coastguard Worker /// Register stack has too few elements error. 495*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_STACK_REGISTER, 496*5a6e8488SAndroid Build Coastguard Worker 497*5a6e8488SAndroid Build Coastguard Worker /// Wrong number of arguments error. 498*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_PARAMS, 499*5a6e8488SAndroid Build Coastguard Worker 500*5a6e8488SAndroid Build Coastguard Worker /// Undefined function error. 501*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_UNDEF_FUNC, 502*5a6e8488SAndroid Build Coastguard Worker 503*5a6e8488SAndroid Build Coastguard Worker /// Void value used in an expression error. 504*5a6e8488SAndroid Build Coastguard Worker BC_ERR_EXEC_VOID_VAL, 505*5a6e8488SAndroid Build Coastguard Worker 506*5a6e8488SAndroid Build Coastguard Worker // Parse (and lex) errors. 507*5a6e8488SAndroid Build Coastguard Worker 508*5a6e8488SAndroid Build Coastguard Worker /// EOF encountered when not expected error. 509*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_EOF, 510*5a6e8488SAndroid Build Coastguard Worker 511*5a6e8488SAndroid Build Coastguard Worker /// Invalid character error. 512*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_CHAR, 513*5a6e8488SAndroid Build Coastguard Worker 514*5a6e8488SAndroid Build Coastguard Worker /// Invalid string (no ending quote) error. 515*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_STRING, 516*5a6e8488SAndroid Build Coastguard Worker 517*5a6e8488SAndroid Build Coastguard Worker /// Invalid comment (no end found) error. 518*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_COMMENT, 519*5a6e8488SAndroid Build Coastguard Worker 520*5a6e8488SAndroid Build Coastguard Worker /// Invalid token encountered error. 521*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_TOKEN, 522*5a6e8488SAndroid Build Coastguard Worker 523*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 524*5a6e8488SAndroid Build Coastguard Worker 525*5a6e8488SAndroid Build Coastguard Worker /// Invalid expression error. 526*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_EXPR, 527*5a6e8488SAndroid Build Coastguard Worker 528*5a6e8488SAndroid Build Coastguard Worker /// Expression is empty error. 529*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_EMPTY_EXPR, 530*5a6e8488SAndroid Build Coastguard Worker 531*5a6e8488SAndroid Build Coastguard Worker /// Print statement is invalid error. 532*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_PRINT, 533*5a6e8488SAndroid Build Coastguard Worker 534*5a6e8488SAndroid Build Coastguard Worker /// Function definition is invalid error. 535*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_FUNC, 536*5a6e8488SAndroid Build Coastguard Worker 537*5a6e8488SAndroid Build Coastguard Worker /// Assignment is invalid error. 538*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_ASSIGN, 539*5a6e8488SAndroid Build Coastguard Worker 540*5a6e8488SAndroid Build Coastguard Worker /// No auto identifiers given for an auto statement error. 541*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_NO_AUTO, 542*5a6e8488SAndroid Build Coastguard Worker 543*5a6e8488SAndroid Build Coastguard Worker /// Duplicate local (parameter or auto) error. 544*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_DUP_LOCAL, 545*5a6e8488SAndroid Build Coastguard Worker 546*5a6e8488SAndroid Build Coastguard Worker /// Invalid block (within braces) error. 547*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_BLOCK, 548*5a6e8488SAndroid Build Coastguard Worker 549*5a6e8488SAndroid Build Coastguard Worker /// Invalid return statement for void functions. 550*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_RET_VOID, 551*5a6e8488SAndroid Build Coastguard Worker 552*5a6e8488SAndroid Build Coastguard Worker /// Reference attached to a variable, not an array, error. 553*5a6e8488SAndroid Build Coastguard Worker BC_ERR_PARSE_REF_VAR, 554*5a6e8488SAndroid Build Coastguard Worker 555*5a6e8488SAndroid Build Coastguard Worker // POSIX-only errors. 556*5a6e8488SAndroid Build Coastguard Worker 557*5a6e8488SAndroid Build Coastguard Worker /// Name length greater than 1 error. 558*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_NAME_LEN, 559*5a6e8488SAndroid Build Coastguard Worker 560*5a6e8488SAndroid Build Coastguard Worker /// Non-POSIX comment used error. 561*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_COMMENT, 562*5a6e8488SAndroid Build Coastguard Worker 563*5a6e8488SAndroid Build Coastguard Worker /// Non-POSIX keyword error. 564*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_KW, 565*5a6e8488SAndroid Build Coastguard Worker 566*5a6e8488SAndroid Build Coastguard Worker /// Non-POSIX . (last) error. 567*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_DOT, 568*5a6e8488SAndroid Build Coastguard Worker 569*5a6e8488SAndroid Build Coastguard Worker /// Non-POSIX return error. 570*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_RET, 571*5a6e8488SAndroid Build Coastguard Worker 572*5a6e8488SAndroid Build Coastguard Worker /// Non-POSIX boolean operator used error. 573*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_BOOL, 574*5a6e8488SAndroid Build Coastguard Worker 575*5a6e8488SAndroid Build Coastguard Worker /// POSIX relation operator used outside if, while, or for statements error. 576*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_REL_POS, 577*5a6e8488SAndroid Build Coastguard Worker 578*5a6e8488SAndroid Build Coastguard Worker /// Multiple POSIX relation operators used in an if, while, or for statement 579*5a6e8488SAndroid Build Coastguard Worker /// error. 580*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_MULTIREL, 581*5a6e8488SAndroid Build Coastguard Worker 582*5a6e8488SAndroid Build Coastguard Worker /// Empty statements in POSIX for loop error. 583*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_FOR, 584*5a6e8488SAndroid Build Coastguard Worker 585*5a6e8488SAndroid Build Coastguard Worker /// POSIX's grammar does not allow a function definition right after a 586*5a6e8488SAndroid Build Coastguard Worker /// semicolon. 587*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_FUNC_AFTER_SEMICOLON, 588*5a6e8488SAndroid Build Coastguard Worker 589*5a6e8488SAndroid Build Coastguard Worker /// Non-POSIX exponential (scientific or engineering) number used error. 590*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_EXP_NUM, 591*5a6e8488SAndroid Build Coastguard Worker 592*5a6e8488SAndroid Build Coastguard Worker /// Non-POSIX array reference error. 593*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_REF, 594*5a6e8488SAndroid Build Coastguard Worker 595*5a6e8488SAndroid Build Coastguard Worker /// Non-POSIX void error. 596*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_VOID, 597*5a6e8488SAndroid Build Coastguard Worker 598*5a6e8488SAndroid Build Coastguard Worker /// Non-POSIX brace position used error. 599*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_BRACE, 600*5a6e8488SAndroid Build Coastguard Worker 601*5a6e8488SAndroid Build Coastguard Worker /// String used in expression. 602*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_EXPR_STRING, 603*5a6e8488SAndroid Build Coastguard Worker 604*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 605*5a6e8488SAndroid Build Coastguard Worker 606*5a6e8488SAndroid Build Coastguard Worker // Number of elements. 607*5a6e8488SAndroid Build Coastguard Worker BC_ERR_NELEMS, 608*5a6e8488SAndroid Build Coastguard Worker 609*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 610*5a6e8488SAndroid Build Coastguard Worker 611*5a6e8488SAndroid Build Coastguard Worker /// A marker for the start of POSIX errors. 612*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_START = BC_ERR_POSIX_NAME_LEN, 613*5a6e8488SAndroid Build Coastguard Worker 614*5a6e8488SAndroid Build Coastguard Worker /// A marker for the end of POSIX errors. 615*5a6e8488SAndroid Build Coastguard Worker BC_ERR_POSIX_END = BC_ERR_POSIX_EXPR_STRING, 616*5a6e8488SAndroid Build Coastguard Worker 617*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 618*5a6e8488SAndroid Build Coastguard Worker 619*5a6e8488SAndroid Build Coastguard Worker } BcErr; 620*5a6e8488SAndroid Build Coastguard Worker 621*5a6e8488SAndroid Build Coastguard Worker // The indices of each category of error in bc_errs[], and used in bc_err_ids[] 622*5a6e8488SAndroid Build Coastguard Worker // to associate actual errors with their categories. 623*5a6e8488SAndroid Build Coastguard Worker 624*5a6e8488SAndroid Build Coastguard Worker /// Math error category. 625*5a6e8488SAndroid Build Coastguard Worker #define BC_ERR_IDX_MATH (0) 626*5a6e8488SAndroid Build Coastguard Worker 627*5a6e8488SAndroid Build Coastguard Worker /// Parse (and lex) error category. 628*5a6e8488SAndroid Build Coastguard Worker #define BC_ERR_IDX_PARSE (1) 629*5a6e8488SAndroid Build Coastguard Worker 630*5a6e8488SAndroid Build Coastguard Worker /// Runtime error category. 631*5a6e8488SAndroid Build Coastguard Worker #define BC_ERR_IDX_EXEC (2) 632*5a6e8488SAndroid Build Coastguard Worker 633*5a6e8488SAndroid Build Coastguard Worker /// Fatal error category. 634*5a6e8488SAndroid Build Coastguard Worker #define BC_ERR_IDX_FATAL (3) 635*5a6e8488SAndroid Build Coastguard Worker 636*5a6e8488SAndroid Build Coastguard Worker /// Number of categories. 637*5a6e8488SAndroid Build Coastguard Worker #define BC_ERR_IDX_NELEMS (4) 638*5a6e8488SAndroid Build Coastguard Worker 639*5a6e8488SAndroid Build Coastguard Worker // If bc is enabled, we add an extra category for POSIX warnings. 640*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED 641*5a6e8488SAndroid Build Coastguard Worker 642*5a6e8488SAndroid Build Coastguard Worker /// POSIX warning category. 643*5a6e8488SAndroid Build Coastguard Worker #define BC_ERR_IDX_WARN (BC_ERR_IDX_NELEMS) 644*5a6e8488SAndroid Build Coastguard Worker 645*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED 646*5a6e8488SAndroid Build Coastguard Worker 647*5a6e8488SAndroid Build Coastguard Worker /** 648*5a6e8488SAndroid Build Coastguard Worker * The mode bc is in. This is basically what input it is processing. 649*5a6e8488SAndroid Build Coastguard Worker */ 650*5a6e8488SAndroid Build Coastguard Worker typedef enum BcMode 651*5a6e8488SAndroid Build Coastguard Worker { 652*5a6e8488SAndroid Build Coastguard Worker /// Expressions mode. 653*5a6e8488SAndroid Build Coastguard Worker BC_MODE_EXPRS, 654*5a6e8488SAndroid Build Coastguard Worker 655*5a6e8488SAndroid Build Coastguard Worker /// File mode. 656*5a6e8488SAndroid Build Coastguard Worker BC_MODE_FILE, 657*5a6e8488SAndroid Build Coastguard Worker 658*5a6e8488SAndroid Build Coastguard Worker #if !BC_ENABLE_OSSFUZZ 659*5a6e8488SAndroid Build Coastguard Worker 660*5a6e8488SAndroid Build Coastguard Worker /// stdin mode. 661*5a6e8488SAndroid Build Coastguard Worker BC_MODE_STDIN, 662*5a6e8488SAndroid Build Coastguard Worker 663*5a6e8488SAndroid Build Coastguard Worker #endif // !BC_ENABLE_OSSFUZZ 664*5a6e8488SAndroid Build Coastguard Worker 665*5a6e8488SAndroid Build Coastguard Worker } BcMode; 666*5a6e8488SAndroid Build Coastguard Worker 667*5a6e8488SAndroid Build Coastguard Worker /// Do a longjmp(). This is what to use when activating an "exception", i.e., a 668*5a6e8488SAndroid Build Coastguard Worker /// longjmp(). With debug code, it will print the name of the function it jumped 669*5a6e8488SAndroid Build Coastguard Worker /// from. 670*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG_CODE 671*5a6e8488SAndroid Build Coastguard Worker #define BC_JMP bc_vm_jmp(__func__) 672*5a6e8488SAndroid Build Coastguard Worker #else // BC_DEBUG_CODE 673*5a6e8488SAndroid Build Coastguard Worker #define BC_JMP bc_vm_jmp() 674*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG_CODE 675*5a6e8488SAndroid Build Coastguard Worker 676*5a6e8488SAndroid Build Coastguard Worker #if !BC_ENABLE_LIBRARY 677*5a6e8488SAndroid Build Coastguard Worker 678*5a6e8488SAndroid Build Coastguard Worker /// Returns true if an exception is in flight, false otherwise. 679*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_EXC(vm) \ 680*5a6e8488SAndroid Build Coastguard Worker BC_UNLIKELY((vm)->status != (sig_atomic_t) BC_STATUS_SUCCESS || (vm)->sig) 681*5a6e8488SAndroid Build Coastguard Worker 682*5a6e8488SAndroid Build Coastguard Worker /// Returns true if there is *no* exception in flight, false otherwise. 683*5a6e8488SAndroid Build Coastguard Worker #define BC_NO_SIG_EXC(vm) \ 684*5a6e8488SAndroid Build Coastguard Worker BC_LIKELY((vm)->status == (sig_atomic_t) BC_STATUS_SUCCESS && !(vm)->sig) 685*5a6e8488SAndroid Build Coastguard Worker 686*5a6e8488SAndroid Build Coastguard Worker #ifndef _WIN32 687*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_INTERRUPT(vm) \ 688*5a6e8488SAndroid Build Coastguard Worker BC_UNLIKELY((vm)->sig != 0 && (vm)->sig != SIGWINCH) 689*5a6e8488SAndroid Build Coastguard Worker #else // _WIN32 690*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_INTERRUPT(vm) BC_UNLIKELY((vm)->sig != 0) 691*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32 692*5a6e8488SAndroid Build Coastguard Worker 693*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG 694*5a6e8488SAndroid Build Coastguard Worker 695*5a6e8488SAndroid Build Coastguard Worker /// Assert that signals are locked. There are non-async-signal-safe functions in 696*5a6e8488SAndroid Build Coastguard Worker /// bc, and they *must* have signals locked. Other functions are expected to 697*5a6e8488SAndroid Build Coastguard Worker /// *not* have signals locked, for reasons. So this is a pre-built assert 698*5a6e8488SAndroid Build Coastguard Worker /// (no-op in non-debug mode) that check that signals are locked. 699*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_ASSERT_LOCKED \ 700*5a6e8488SAndroid Build Coastguard Worker do \ 701*5a6e8488SAndroid Build Coastguard Worker { \ 702*5a6e8488SAndroid Build Coastguard Worker assert(vm->sig_lock); \ 703*5a6e8488SAndroid Build Coastguard Worker } \ 704*5a6e8488SAndroid Build Coastguard Worker while (0) 705*5a6e8488SAndroid Build Coastguard Worker 706*5a6e8488SAndroid Build Coastguard Worker /// Assert that signals are unlocked. There are non-async-signal-safe functions 707*5a6e8488SAndroid Build Coastguard Worker /// in bc, and they *must* have signals locked. Other functions are expected to 708*5a6e8488SAndroid Build Coastguard Worker /// *not* have signals locked, for reasons. So this is a pre-built assert 709*5a6e8488SAndroid Build Coastguard Worker /// (no-op in non-debug mode) that check that signals are unlocked. 710*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_ASSERT_NOT_LOCKED \ 711*5a6e8488SAndroid Build Coastguard Worker do \ 712*5a6e8488SAndroid Build Coastguard Worker { \ 713*5a6e8488SAndroid Build Coastguard Worker assert(vm->sig_lock == 0); \ 714*5a6e8488SAndroid Build Coastguard Worker } \ 715*5a6e8488SAndroid Build Coastguard Worker while (0) 716*5a6e8488SAndroid Build Coastguard Worker 717*5a6e8488SAndroid Build Coastguard Worker #else // BC_DEBUG 718*5a6e8488SAndroid Build Coastguard Worker 719*5a6e8488SAndroid Build Coastguard Worker /// Assert that signals are locked. There are non-async-signal-safe functions in 720*5a6e8488SAndroid Build Coastguard Worker /// bc, and they *must* have signals locked. Other functions are expected to 721*5a6e8488SAndroid Build Coastguard Worker /// *not* have signals locked, for reasons. So this is a pre-built assert 722*5a6e8488SAndroid Build Coastguard Worker /// (no-op in non-debug mode) that check that signals are locked. 723*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_ASSERT_LOCKED 724*5a6e8488SAndroid Build Coastguard Worker 725*5a6e8488SAndroid Build Coastguard Worker /// Assert that signals are unlocked. There are non-async-signal-safe functions 726*5a6e8488SAndroid Build Coastguard Worker /// in bc, and they *must* have signals locked. Other functions are expected to 727*5a6e8488SAndroid Build Coastguard Worker /// *not* have signals locked, for reasons. So this is a pre-built assert 728*5a6e8488SAndroid Build Coastguard Worker /// (no-op in non-debug mode) that check that signals are unlocked. 729*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_ASSERT_NOT_LOCKED 730*5a6e8488SAndroid Build Coastguard Worker 731*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG 732*5a6e8488SAndroid Build Coastguard Worker 733*5a6e8488SAndroid Build Coastguard Worker /// Locks signals. 734*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_LOCK \ 735*5a6e8488SAndroid Build Coastguard Worker do \ 736*5a6e8488SAndroid Build Coastguard Worker { \ 737*5a6e8488SAndroid Build Coastguard Worker BC_SIG_ASSERT_NOT_LOCKED; \ 738*5a6e8488SAndroid Build Coastguard Worker vm->sig_lock = 1; \ 739*5a6e8488SAndroid Build Coastguard Worker } \ 740*5a6e8488SAndroid Build Coastguard Worker while (0) 741*5a6e8488SAndroid Build Coastguard Worker 742*5a6e8488SAndroid Build Coastguard Worker /// Unlocks signals. If a signal happened, then this will cause a jump. 743*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_UNLOCK \ 744*5a6e8488SAndroid Build Coastguard Worker do \ 745*5a6e8488SAndroid Build Coastguard Worker { \ 746*5a6e8488SAndroid Build Coastguard Worker BC_SIG_ASSERT_LOCKED; \ 747*5a6e8488SAndroid Build Coastguard Worker vm->sig_lock = 0; \ 748*5a6e8488SAndroid Build Coastguard Worker if (vm->sig) BC_JMP; \ 749*5a6e8488SAndroid Build Coastguard Worker } \ 750*5a6e8488SAndroid Build Coastguard Worker while (0) 751*5a6e8488SAndroid Build Coastguard Worker 752*5a6e8488SAndroid Build Coastguard Worker /// Locks signals, regardless of if they are already locked. This is really only 753*5a6e8488SAndroid Build Coastguard Worker /// used after labels that longjmp() goes to after the jump because the cleanup 754*5a6e8488SAndroid Build Coastguard Worker /// code must have signals locked, and BC_LONGJMP_CONT will unlock signals if it 755*5a6e8488SAndroid Build Coastguard Worker /// doesn't jump. 756*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_MAYLOCK \ 757*5a6e8488SAndroid Build Coastguard Worker do \ 758*5a6e8488SAndroid Build Coastguard Worker { \ 759*5a6e8488SAndroid Build Coastguard Worker vm->sig_lock = 1; \ 760*5a6e8488SAndroid Build Coastguard Worker } \ 761*5a6e8488SAndroid Build Coastguard Worker while (0) 762*5a6e8488SAndroid Build Coastguard Worker 763*5a6e8488SAndroid Build Coastguard Worker /// Unlocks signals, regardless of if they were already unlocked. If a signal 764*5a6e8488SAndroid Build Coastguard Worker /// happened, then this will cause a jump. 765*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_MAYUNLOCK \ 766*5a6e8488SAndroid Build Coastguard Worker do \ 767*5a6e8488SAndroid Build Coastguard Worker { \ 768*5a6e8488SAndroid Build Coastguard Worker vm->sig_lock = 0; \ 769*5a6e8488SAndroid Build Coastguard Worker if (vm->sig) BC_JMP; \ 770*5a6e8488SAndroid Build Coastguard Worker } \ 771*5a6e8488SAndroid Build Coastguard Worker while (0) 772*5a6e8488SAndroid Build Coastguard Worker 773*5a6e8488SAndroid Build Coastguard Worker /** 774*5a6e8488SAndroid Build Coastguard Worker * Locks signals, but stores the old lock state, to be restored later by 775*5a6e8488SAndroid Build Coastguard Worker * BC_SIG_TRYUNLOCK. 776*5a6e8488SAndroid Build Coastguard Worker * @param v The variable to store the old lock state to. 777*5a6e8488SAndroid Build Coastguard Worker */ 778*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_TRYLOCK(v) \ 779*5a6e8488SAndroid Build Coastguard Worker do \ 780*5a6e8488SAndroid Build Coastguard Worker { \ 781*5a6e8488SAndroid Build Coastguard Worker v = vm->sig_lock; \ 782*5a6e8488SAndroid Build Coastguard Worker vm->sig_lock = 1; \ 783*5a6e8488SAndroid Build Coastguard Worker } \ 784*5a6e8488SAndroid Build Coastguard Worker while (0) 785*5a6e8488SAndroid Build Coastguard Worker 786*5a6e8488SAndroid Build Coastguard Worker /** 787*5a6e8488SAndroid Build Coastguard Worker * Restores the previous state of a signal lock, and if it is now unlocked, 788*5a6e8488SAndroid Build Coastguard Worker * initiates an exception/jump. 789*5a6e8488SAndroid Build Coastguard Worker * @param v The old lock state. 790*5a6e8488SAndroid Build Coastguard Worker */ 791*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_TRYUNLOCK(v) \ 792*5a6e8488SAndroid Build Coastguard Worker do \ 793*5a6e8488SAndroid Build Coastguard Worker { \ 794*5a6e8488SAndroid Build Coastguard Worker vm->sig_lock = (v); \ 795*5a6e8488SAndroid Build Coastguard Worker if (!(v) && vm->sig) BC_JMP; \ 796*5a6e8488SAndroid Build Coastguard Worker } \ 797*5a6e8488SAndroid Build Coastguard Worker while (0) 798*5a6e8488SAndroid Build Coastguard Worker 799*5a6e8488SAndroid Build Coastguard Worker /// Stops a stack unwinding. Technically, a stack unwinding needs to be done 800*5a6e8488SAndroid Build Coastguard Worker /// manually, but it will always be done unless certain flags are cleared. This 801*5a6e8488SAndroid Build Coastguard Worker /// clears the flags. 802*5a6e8488SAndroid Build Coastguard Worker #define BC_LONGJMP_STOP \ 803*5a6e8488SAndroid Build Coastguard Worker do \ 804*5a6e8488SAndroid Build Coastguard Worker { \ 805*5a6e8488SAndroid Build Coastguard Worker vm->sig_pop = 0; \ 806*5a6e8488SAndroid Build Coastguard Worker vm->sig = 0; \ 807*5a6e8488SAndroid Build Coastguard Worker } \ 808*5a6e8488SAndroid Build Coastguard Worker while (0) 809*5a6e8488SAndroid Build Coastguard Worker 810*5a6e8488SAndroid Build Coastguard Worker /** 811*5a6e8488SAndroid Build Coastguard Worker * Sets a jump like BC_SETJMP, but unlike BC_SETJMP, it assumes signals are 812*5a6e8488SAndroid Build Coastguard Worker * locked and will just set the jump. This does *not* have a call to 813*5a6e8488SAndroid Build Coastguard Worker * bc_vec_grow() because it is assumed that BC_SETJMP_LOCKED(l) is used *after* 814*5a6e8488SAndroid Build Coastguard Worker * the initializations that need the setjmp(). 815*5a6e8488SAndroid Build Coastguard Worker * param l The label to jump to on a longjmp(). 816*5a6e8488SAndroid Build Coastguard Worker */ 817*5a6e8488SAndroid Build Coastguard Worker #define BC_SETJMP_LOCKED(vm, l) \ 818*5a6e8488SAndroid Build Coastguard Worker do \ 819*5a6e8488SAndroid Build Coastguard Worker { \ 820*5a6e8488SAndroid Build Coastguard Worker sigjmp_buf sjb; \ 821*5a6e8488SAndroid Build Coastguard Worker BC_SIG_ASSERT_LOCKED; \ 822*5a6e8488SAndroid Build Coastguard Worker if (sigsetjmp(sjb, 0)) \ 823*5a6e8488SAndroid Build Coastguard Worker { \ 824*5a6e8488SAndroid Build Coastguard Worker assert(BC_SIG_EXC(vm)); \ 825*5a6e8488SAndroid Build Coastguard Worker goto l; \ 826*5a6e8488SAndroid Build Coastguard Worker } \ 827*5a6e8488SAndroid Build Coastguard Worker bc_vec_push(&vm->jmp_bufs, &sjb); \ 828*5a6e8488SAndroid Build Coastguard Worker } \ 829*5a6e8488SAndroid Build Coastguard Worker while (0) 830*5a6e8488SAndroid Build Coastguard Worker 831*5a6e8488SAndroid Build Coastguard Worker /// Used after cleanup labels set by BC_SETJMP and BC_SETJMP_LOCKED to jump to 832*5a6e8488SAndroid Build Coastguard Worker /// the next place. This is what continues the stack unwinding. This basically 833*5a6e8488SAndroid Build Coastguard Worker /// copies BC_SIG_UNLOCK into itself, but that is because its condition for 834*5a6e8488SAndroid Build Coastguard Worker /// jumping is BC_SIG_EXC, not just that a signal happened. 835*5a6e8488SAndroid Build Coastguard Worker #define BC_LONGJMP_CONT(vm) \ 836*5a6e8488SAndroid Build Coastguard Worker do \ 837*5a6e8488SAndroid Build Coastguard Worker { \ 838*5a6e8488SAndroid Build Coastguard Worker BC_SIG_ASSERT_LOCKED; \ 839*5a6e8488SAndroid Build Coastguard Worker if (!vm->sig_pop) bc_vec_pop(&vm->jmp_bufs); \ 840*5a6e8488SAndroid Build Coastguard Worker vm->sig_lock = 0; \ 841*5a6e8488SAndroid Build Coastguard Worker if (BC_SIG_EXC(vm)) BC_JMP; \ 842*5a6e8488SAndroid Build Coastguard Worker } \ 843*5a6e8488SAndroid Build Coastguard Worker while (0) 844*5a6e8488SAndroid Build Coastguard Worker 845*5a6e8488SAndroid Build Coastguard Worker #else // !BC_ENABLE_LIBRARY 846*5a6e8488SAndroid Build Coastguard Worker 847*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_LOCK 848*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_UNLOCK 849*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_MAYLOCK 850*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_TRYLOCK(lock) 851*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_TRYUNLOCK(lock) 852*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_ASSERT_LOCKED 853*5a6e8488SAndroid Build Coastguard Worker 854*5a6e8488SAndroid Build Coastguard Worker /// Returns true if an exception is in flight, false otherwise. 855*5a6e8488SAndroid Build Coastguard Worker #define BC_SIG_EXC(vm) \ 856*5a6e8488SAndroid Build Coastguard Worker BC_UNLIKELY(vm->status != (sig_atomic_t) BC_STATUS_SUCCESS) 857*5a6e8488SAndroid Build Coastguard Worker 858*5a6e8488SAndroid Build Coastguard Worker /// Returns true if there is *no* exception in flight, false otherwise. 859*5a6e8488SAndroid Build Coastguard Worker #define BC_NO_SIG_EXC(vm) \ 860*5a6e8488SAndroid Build Coastguard Worker BC_LIKELY(vm->status == (sig_atomic_t) BC_STATUS_SUCCESS) 861*5a6e8488SAndroid Build Coastguard Worker 862*5a6e8488SAndroid Build Coastguard Worker /// Used after cleanup labels set by BC_SETJMP and BC_SETJMP_LOCKED to jump to 863*5a6e8488SAndroid Build Coastguard Worker /// the next place. This is what continues the stack unwinding. This basically 864*5a6e8488SAndroid Build Coastguard Worker /// copies BC_SIG_UNLOCK into itself, but that is because its condition for 865*5a6e8488SAndroid Build Coastguard Worker /// jumping is BC_SIG_EXC, not just that a signal happened. 866*5a6e8488SAndroid Build Coastguard Worker #define BC_LONGJMP_CONT(vm) \ 867*5a6e8488SAndroid Build Coastguard Worker do \ 868*5a6e8488SAndroid Build Coastguard Worker { \ 869*5a6e8488SAndroid Build Coastguard Worker bc_vec_pop(&vm->jmp_bufs); \ 870*5a6e8488SAndroid Build Coastguard Worker if (BC_SIG_EXC(vm)) BC_JMP; \ 871*5a6e8488SAndroid Build Coastguard Worker } \ 872*5a6e8488SAndroid Build Coastguard Worker while (0) 873*5a6e8488SAndroid Build Coastguard Worker 874*5a6e8488SAndroid Build Coastguard Worker #endif // !BC_ENABLE_LIBRARY 875*5a6e8488SAndroid Build Coastguard Worker 876*5a6e8488SAndroid Build Coastguard Worker /** 877*5a6e8488SAndroid Build Coastguard Worker * Sets a jump, and sets it up as well so that if a longjmp() happens, bc will 878*5a6e8488SAndroid Build Coastguard Worker * immediately goto a label where some cleanup code is. This one assumes that 879*5a6e8488SAndroid Build Coastguard Worker * signals are not locked and will lock them, set the jump, and unlock them. 880*5a6e8488SAndroid Build Coastguard Worker * Setting the jump also includes pushing the jmp_buf onto the jmp_buf stack. 881*5a6e8488SAndroid Build Coastguard Worker * This grows the jmp_bufs vector first to prevent a fatal error from happening 882*5a6e8488SAndroid Build Coastguard Worker * after the setjmp(). This is done because BC_SETJMP(l) is assumed to be used 883*5a6e8488SAndroid Build Coastguard Worker * *before* the actual initialization calls that need the setjmp(). 884*5a6e8488SAndroid Build Coastguard Worker * param l The label to jump to on a longjmp(). 885*5a6e8488SAndroid Build Coastguard Worker */ 886*5a6e8488SAndroid Build Coastguard Worker #define BC_SETJMP(vm, l) \ 887*5a6e8488SAndroid Build Coastguard Worker do \ 888*5a6e8488SAndroid Build Coastguard Worker { \ 889*5a6e8488SAndroid Build Coastguard Worker sigjmp_buf sjb; \ 890*5a6e8488SAndroid Build Coastguard Worker BC_SIG_LOCK; \ 891*5a6e8488SAndroid Build Coastguard Worker bc_vec_grow(&vm->jmp_bufs, 1); \ 892*5a6e8488SAndroid Build Coastguard Worker if (sigsetjmp(sjb, 0)) \ 893*5a6e8488SAndroid Build Coastguard Worker { \ 894*5a6e8488SAndroid Build Coastguard Worker assert(BC_SIG_EXC(vm)); \ 895*5a6e8488SAndroid Build Coastguard Worker goto l; \ 896*5a6e8488SAndroid Build Coastguard Worker } \ 897*5a6e8488SAndroid Build Coastguard Worker bc_vec_push(&vm->jmp_bufs, &sjb); \ 898*5a6e8488SAndroid Build Coastguard Worker BC_SIG_UNLOCK; \ 899*5a6e8488SAndroid Build Coastguard Worker } \ 900*5a6e8488SAndroid Build Coastguard Worker while (0) 901*5a6e8488SAndroid Build Coastguard Worker 902*5a6e8488SAndroid Build Coastguard Worker /// Unsets a jump. It always assumes signals are locked. This basically just 903*5a6e8488SAndroid Build Coastguard Worker /// pops a jmp_buf off of the stack of jmp_bufs, and since the jump mechanism 904*5a6e8488SAndroid Build Coastguard Worker /// always jumps to the location at the top of the stack, this effectively 905*5a6e8488SAndroid Build Coastguard Worker /// undoes a setjmp(). 906*5a6e8488SAndroid Build Coastguard Worker #define BC_UNSETJMP(vm) \ 907*5a6e8488SAndroid Build Coastguard Worker do \ 908*5a6e8488SAndroid Build Coastguard Worker { \ 909*5a6e8488SAndroid Build Coastguard Worker BC_SIG_ASSERT_LOCKED; \ 910*5a6e8488SAndroid Build Coastguard Worker bc_vec_pop(&vm->jmp_bufs); \ 911*5a6e8488SAndroid Build Coastguard Worker } \ 912*5a6e8488SAndroid Build Coastguard Worker while (0) 913*5a6e8488SAndroid Build Coastguard Worker 914*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_LIBRARY 915*5a6e8488SAndroid Build Coastguard Worker 916*5a6e8488SAndroid Build Coastguard Worker #define BC_SETJMP_LOCKED(vm, l) BC_SETJMP(vm, l) 917*5a6e8488SAndroid Build Coastguard Worker 918*5a6e8488SAndroid Build Coastguard Worker // Various convenience macros for calling the bc's error handling routine. 919*5a6e8488SAndroid Build Coastguard Worker 920*5a6e8488SAndroid Build Coastguard Worker /** 921*5a6e8488SAndroid Build Coastguard Worker * Call bc's error handling routine. 922*5a6e8488SAndroid Build Coastguard Worker * @param e The error. 923*5a6e8488SAndroid Build Coastguard Worker * @param l The line of the script that the error happened. 924*5a6e8488SAndroid Build Coastguard Worker * @param ... Extra arguments for error messages as necessary. 925*5a6e8488SAndroid Build Coastguard Worker */ 926*5a6e8488SAndroid Build Coastguard Worker #define bc_error(e, l, ...) (bc_vm_handleError((e))) 927*5a6e8488SAndroid Build Coastguard Worker 928*5a6e8488SAndroid Build Coastguard Worker /** 929*5a6e8488SAndroid Build Coastguard Worker * Call bc's error handling routine. 930*5a6e8488SAndroid Build Coastguard Worker * @param e The error. 931*5a6e8488SAndroid Build Coastguard Worker */ 932*5a6e8488SAndroid Build Coastguard Worker #define bc_err(e) (bc_vm_handleError((e))) 933*5a6e8488SAndroid Build Coastguard Worker 934*5a6e8488SAndroid Build Coastguard Worker /** 935*5a6e8488SAndroid Build Coastguard Worker * Call bc's error handling routine. 936*5a6e8488SAndroid Build Coastguard Worker * @param e The error. 937*5a6e8488SAndroid Build Coastguard Worker */ 938*5a6e8488SAndroid Build Coastguard Worker #define bc_verr(e, ...) (bc_vm_handleError((e))) 939*5a6e8488SAndroid Build Coastguard Worker 940*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_LIBRARY 941*5a6e8488SAndroid Build Coastguard Worker 942*5a6e8488SAndroid Build Coastguard Worker // Various convenience macros for calling the bc's error handling routine. 943*5a6e8488SAndroid Build Coastguard Worker 944*5a6e8488SAndroid Build Coastguard Worker /** 945*5a6e8488SAndroid Build Coastguard Worker * Call bc's error handling routine. 946*5a6e8488SAndroid Build Coastguard Worker * @param e The error. 947*5a6e8488SAndroid Build Coastguard Worker * @param l The line of the script that the error happened. 948*5a6e8488SAndroid Build Coastguard Worker * @param ... Extra arguments for error messages as necessary. 949*5a6e8488SAndroid Build Coastguard Worker */ 950*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG 951*5a6e8488SAndroid Build Coastguard Worker #define bc_error(e, l, ...) \ 952*5a6e8488SAndroid Build Coastguard Worker (bc_vm_handleError((e), __FILE__, __LINE__, (l), __VA_ARGS__)) 953*5a6e8488SAndroid Build Coastguard Worker #else // BC_DEBUG 954*5a6e8488SAndroid Build Coastguard Worker #define bc_error(e, l, ...) (bc_vm_handleError((e), (l), __VA_ARGS__)) 955*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG 956*5a6e8488SAndroid Build Coastguard Worker 957*5a6e8488SAndroid Build Coastguard Worker /** 958*5a6e8488SAndroid Build Coastguard Worker * Call bc's error handling routine. 959*5a6e8488SAndroid Build Coastguard Worker * @param e The error. 960*5a6e8488SAndroid Build Coastguard Worker */ 961*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG 962*5a6e8488SAndroid Build Coastguard Worker #define bc_err(e) (bc_vm_handleError((e), __FILE__, __LINE__, 0)) 963*5a6e8488SAndroid Build Coastguard Worker #else // BC_DEBUG 964*5a6e8488SAndroid Build Coastguard Worker #define bc_err(e) (bc_vm_handleError((e), 0)) 965*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG 966*5a6e8488SAndroid Build Coastguard Worker 967*5a6e8488SAndroid Build Coastguard Worker /** 968*5a6e8488SAndroid Build Coastguard Worker * Call bc's error handling routine. 969*5a6e8488SAndroid Build Coastguard Worker * @param e The error. 970*5a6e8488SAndroid Build Coastguard Worker */ 971*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG 972*5a6e8488SAndroid Build Coastguard Worker #define bc_verr(e, ...) \ 973*5a6e8488SAndroid Build Coastguard Worker (bc_vm_handleError((e), __FILE__, __LINE__, 0, __VA_ARGS__)) 974*5a6e8488SAndroid Build Coastguard Worker #else // BC_DEBUG 975*5a6e8488SAndroid Build Coastguard Worker #define bc_verr(e, ...) (bc_vm_handleError((e), 0, __VA_ARGS__)) 976*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG 977*5a6e8488SAndroid Build Coastguard Worker 978*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_LIBRARY 979*5a6e8488SAndroid Build Coastguard Worker 980*5a6e8488SAndroid Build Coastguard Worker /** 981*5a6e8488SAndroid Build Coastguard Worker * Returns true if status @a s is an error, false otherwise. 982*5a6e8488SAndroid Build Coastguard Worker * @param s The status to test. 983*5a6e8488SAndroid Build Coastguard Worker * @return True if @a s is an error, false otherwise. 984*5a6e8488SAndroid Build Coastguard Worker */ 985*5a6e8488SAndroid Build Coastguard Worker #define BC_STATUS_IS_ERROR(s) \ 986*5a6e8488SAndroid Build Coastguard Worker ((s) >= BC_STATUS_ERROR_MATH && (s) <= BC_STATUS_ERROR_FATAL) 987*5a6e8488SAndroid Build Coastguard Worker 988*5a6e8488SAndroid Build Coastguard Worker // Convenience macros that can be placed at the beginning and exits of functions 989*5a6e8488SAndroid Build Coastguard Worker // for easy marking of where functions are entered and exited. 990*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG_CODE 991*5a6e8488SAndroid Build Coastguard Worker #define BC_FUNC_ENTER \ 992*5a6e8488SAndroid Build Coastguard Worker do \ 993*5a6e8488SAndroid Build Coastguard Worker { \ 994*5a6e8488SAndroid Build Coastguard Worker size_t bc_func_enter_i; \ 995*5a6e8488SAndroid Build Coastguard Worker for (bc_func_enter_i = 0; bc_func_enter_i < vm->func_depth; \ 996*5a6e8488SAndroid Build Coastguard Worker ++bc_func_enter_i) \ 997*5a6e8488SAndroid Build Coastguard Worker { \ 998*5a6e8488SAndroid Build Coastguard Worker bc_file_puts(&vm->ferr, bc_flush_none, " "); \ 999*5a6e8488SAndroid Build Coastguard Worker } \ 1000*5a6e8488SAndroid Build Coastguard Worker vm->func_depth += 1; \ 1001*5a6e8488SAndroid Build Coastguard Worker bc_file_printf(&vm->ferr, "Entering %s\n", __func__); \ 1002*5a6e8488SAndroid Build Coastguard Worker bc_file_flush(&vm->ferr, bc_flush_none); \ 1003*5a6e8488SAndroid Build Coastguard Worker } \ 1004*5a6e8488SAndroid Build Coastguard Worker while (0); 1005*5a6e8488SAndroid Build Coastguard Worker 1006*5a6e8488SAndroid Build Coastguard Worker #define BC_FUNC_EXIT \ 1007*5a6e8488SAndroid Build Coastguard Worker do \ 1008*5a6e8488SAndroid Build Coastguard Worker { \ 1009*5a6e8488SAndroid Build Coastguard Worker size_t bc_func_enter_i; \ 1010*5a6e8488SAndroid Build Coastguard Worker vm->func_depth -= 1; \ 1011*5a6e8488SAndroid Build Coastguard Worker for (bc_func_enter_i = 0; bc_func_enter_i < vm->func_depth; \ 1012*5a6e8488SAndroid Build Coastguard Worker ++bc_func_enter_i) \ 1013*5a6e8488SAndroid Build Coastguard Worker { \ 1014*5a6e8488SAndroid Build Coastguard Worker bc_file_puts(&vm->ferr, bc_flush_none, " "); \ 1015*5a6e8488SAndroid Build Coastguard Worker } \ 1016*5a6e8488SAndroid Build Coastguard Worker bc_file_printf(&vm->ferr, "Leaving %s\n", __func__); \ 1017*5a6e8488SAndroid Build Coastguard Worker bc_file_flush(&vm->ferr, bc_flush_none); \ 1018*5a6e8488SAndroid Build Coastguard Worker } \ 1019*5a6e8488SAndroid Build Coastguard Worker while (0); 1020*5a6e8488SAndroid Build Coastguard Worker #else // BC_DEBUG_CODE 1021*5a6e8488SAndroid Build Coastguard Worker #define BC_FUNC_ENTER 1022*5a6e8488SAndroid Build Coastguard Worker #define BC_FUNC_EXIT 1023*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG_CODE 1024*5a6e8488SAndroid Build Coastguard Worker 1025*5a6e8488SAndroid Build Coastguard Worker #endif // BC_STATUS_H 1026