mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00

The previous value of 1_000 was added with a reference to the Bison
parser[^1], but the value of YYMAXDEPTH in the Bison docs is 10_000,
not 1_000.
[^1]: https://www.gnu.org/software/bison/manual/html_node/Memory-Management.html
Fixes [Bug #21044]
e098533ab4
Co-authored-by: Nony Dutton <nonydutton@gmail.com>
260 lines
7.9 KiB
C
260 lines
7.9 KiB
C
/**
|
|
* @file defines.h
|
|
*
|
|
* Macro definitions used throughout the prism library.
|
|
*
|
|
* This file should be included first by any *.h or *.c in prism for consistency
|
|
* and to ensure that the macros are defined before they are used.
|
|
*/
|
|
#ifndef PRISM_DEFINES_H
|
|
#define PRISM_DEFINES_H
|
|
|
|
#include <ctype.h>
|
|
#include <limits.h>
|
|
#include <math.h>
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
/**
|
|
* We want to be able to use the PRI* macros for printing out integers, but on
|
|
* some platforms they aren't included unless this is already defined.
|
|
*/
|
|
#define __STDC_FORMAT_MACROS
|
|
// Include sys/types.h before inttypes.h to work around issue with
|
|
// certain versions of GCC and newlib which causes omission of PRIx64
|
|
#include <sys/types.h>
|
|
#include <inttypes.h>
|
|
|
|
/**
|
|
* When we are parsing using recursive descent, we want to protect against
|
|
* malicious payloads that could attempt to crash our parser. We do this by
|
|
* specifying a maximum depth to which we are allowed to recurse.
|
|
*/
|
|
#ifndef PRISM_DEPTH_MAXIMUM
|
|
#define PRISM_DEPTH_MAXIMUM 10000
|
|
#endif
|
|
|
|
/**
|
|
* By default, we compile with -fvisibility=hidden. When this is enabled, we
|
|
* need to mark certain functions as being publically-visible. This macro does
|
|
* that in a compiler-agnostic way.
|
|
*/
|
|
#ifndef PRISM_EXPORTED_FUNCTION
|
|
# ifdef PRISM_EXPORT_SYMBOLS
|
|
# ifdef _WIN32
|
|
# define PRISM_EXPORTED_FUNCTION __declspec(dllexport) extern
|
|
# else
|
|
# define PRISM_EXPORTED_FUNCTION __attribute__((__visibility__("default"))) extern
|
|
# endif
|
|
# else
|
|
# define PRISM_EXPORTED_FUNCTION
|
|
# endif
|
|
#endif
|
|
|
|
/**
|
|
* Certain compilers support specifying that a function accepts variadic
|
|
* parameters that look like printf format strings to provide a better developer
|
|
* experience when someone is using the function. This macro does that in a
|
|
* compiler-agnostic way.
|
|
*/
|
|
#if defined(__GNUC__)
|
|
# if defined(__MINGW_PRINTF_FORMAT)
|
|
# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((format(__MINGW_PRINTF_FORMAT, string_index, argument_index)))
|
|
# else
|
|
# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((format(printf, string_index, argument_index)))
|
|
# endif
|
|
#elif defined(__clang__)
|
|
# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((__format__(__printf__, string_index, argument_index)))
|
|
#else
|
|
# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index)
|
|
#endif
|
|
|
|
/**
|
|
* GCC will warn if you specify a function or parameter that is unused at
|
|
* runtime. This macro allows you to mark a function or parameter as unused in a
|
|
* compiler-agnostic way.
|
|
*/
|
|
#if defined(__GNUC__)
|
|
# define PRISM_ATTRIBUTE_UNUSED __attribute__((unused))
|
|
#else
|
|
# define PRISM_ATTRIBUTE_UNUSED
|
|
#endif
|
|
|
|
/**
|
|
* Old Visual Studio versions do not support the inline keyword, so we need to
|
|
* define it to be __inline.
|
|
*/
|
|
#if defined(_MSC_VER) && !defined(inline)
|
|
# define inline __inline
|
|
#endif
|
|
|
|
/**
|
|
* Old Visual Studio versions before 2015 do not implement sprintf, but instead
|
|
* implement _snprintf. We standard that here.
|
|
*/
|
|
#if !defined(snprintf) && defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
# define snprintf _snprintf
|
|
#endif
|
|
|
|
/**
|
|
* A simple utility macro to concatenate two tokens together, necessary when one
|
|
* of the tokens is itself a macro.
|
|
*/
|
|
#define PM_CONCATENATE(left, right) left ## right
|
|
|
|
/**
|
|
* We want to be able to use static assertions, but they weren't standardized
|
|
* until C11. As such, we polyfill it here by making a hacky typedef that will
|
|
* fail to compile due to a negative array size if the condition is false.
|
|
*/
|
|
#if defined(_Static_assert)
|
|
# define PM_STATIC_ASSERT(line, condition, message) _Static_assert(condition, message)
|
|
#else
|
|
# define PM_STATIC_ASSERT(line, condition, message) typedef char PM_CONCATENATE(static_assert_, line)[(condition) ? 1 : -1]
|
|
#endif
|
|
|
|
/**
|
|
* In general, libc for embedded systems does not support memory-mapped files.
|
|
* If the target platform is POSIX or Windows, we can map a file in memory and
|
|
* read it in a more efficient manner.
|
|
*/
|
|
#ifdef _WIN32
|
|
# define PRISM_HAS_MMAP
|
|
#else
|
|
# include <unistd.h>
|
|
# ifdef _POSIX_MAPPED_FILES
|
|
# define PRISM_HAS_MMAP
|
|
# endif
|
|
#endif
|
|
|
|
/**
|
|
* If PRISM_HAS_NO_FILESYSTEM is defined, then we want to exclude all filesystem
|
|
* related code from the library. All filesystem related code should be guarded
|
|
* by PRISM_HAS_FILESYSTEM.
|
|
*/
|
|
#ifndef PRISM_HAS_NO_FILESYSTEM
|
|
# define PRISM_HAS_FILESYSTEM
|
|
#endif
|
|
|
|
/**
|
|
* isinf on POSIX systems it accepts a float, a double, or a long double.
|
|
* But mingw didn't provide an isinf macro, only an isinf function that only
|
|
* accepts floats, so we need to use _finite instead.
|
|
*/
|
|
#ifdef __MINGW64__
|
|
#include <float.h>
|
|
#define PRISM_ISINF(x) (!_finite(x))
|
|
#else
|
|
#define PRISM_ISINF(x) isinf(x)
|
|
#endif
|
|
|
|
/**
|
|
* If you build prism with a custom allocator, configure it with
|
|
* "-D PRISM_XALLOCATOR" to use your own allocator that defines xmalloc,
|
|
* xrealloc, xcalloc, and xfree.
|
|
*
|
|
* For example, your `prism_xallocator.h` file could look like this:
|
|
*
|
|
* ```
|
|
* #ifndef PRISM_XALLOCATOR_H
|
|
* #define PRISM_XALLOCATOR_H
|
|
* #define xmalloc my_malloc
|
|
* #define xrealloc my_realloc
|
|
* #define xcalloc my_calloc
|
|
* #define xfree my_free
|
|
* #endif
|
|
* ```
|
|
*/
|
|
#ifdef PRISM_XALLOCATOR
|
|
#include "prism_xallocator.h"
|
|
#else
|
|
#ifndef xmalloc
|
|
/**
|
|
* The malloc function that should be used. This can be overridden with
|
|
* the PRISM_XALLOCATOR define.
|
|
*/
|
|
#define xmalloc malloc
|
|
#endif
|
|
|
|
#ifndef xrealloc
|
|
/**
|
|
* The realloc function that should be used. This can be overridden with
|
|
* the PRISM_XALLOCATOR define.
|
|
*/
|
|
#define xrealloc realloc
|
|
#endif
|
|
|
|
#ifndef xcalloc
|
|
/**
|
|
* The calloc function that should be used. This can be overridden with
|
|
* the PRISM_XALLOCATOR define.
|
|
*/
|
|
#define xcalloc calloc
|
|
#endif
|
|
|
|
#ifndef xfree
|
|
/**
|
|
* The free function that should be used. This can be overridden with the
|
|
* PRISM_XALLOCATOR define.
|
|
*/
|
|
#define xfree free
|
|
#endif
|
|
#endif
|
|
|
|
/**
|
|
* If PRISM_BUILD_MINIMAL is defined, then we're going to define every possible
|
|
* switch that will turn off certain features of prism.
|
|
*/
|
|
#ifdef PRISM_BUILD_MINIMAL
|
|
/** Exclude the serialization API. */
|
|
#define PRISM_EXCLUDE_SERIALIZATION
|
|
|
|
/** Exclude the JSON serialization API. */
|
|
#define PRISM_EXCLUDE_JSON
|
|
|
|
/** Exclude the Array#pack parser API. */
|
|
#define PRISM_EXCLUDE_PACK
|
|
|
|
/** Exclude the prettyprint API. */
|
|
#define PRISM_EXCLUDE_PRETTYPRINT
|
|
|
|
/** Exclude the full set of encodings, using the minimal only. */
|
|
#define PRISM_ENCODING_EXCLUDE_FULL
|
|
#endif
|
|
|
|
/**
|
|
* Support PRISM_LIKELY and PRISM_UNLIKELY to help the compiler optimize its
|
|
* branch predication.
|
|
*/
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
/** The compiler should predicate that this branch will be taken. */
|
|
#define PRISM_LIKELY(x) __builtin_expect(!!(x), 1)
|
|
|
|
/** The compiler should predicate that this branch will not be taken. */
|
|
#define PRISM_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
|
#else
|
|
/** Void because this platform does not support branch prediction hints. */
|
|
#define PRISM_LIKELY(x) (x)
|
|
|
|
/** Void because this platform does not support branch prediction hints. */
|
|
#define PRISM_UNLIKELY(x) (x)
|
|
#endif
|
|
|
|
/**
|
|
* We use -Wimplicit-fallthrough to guard potentially unintended fall-through between cases of a switch.
|
|
* Use PRISM_FALLTHROUGH to explicitly annotate cases where the fallthrough is intentional.
|
|
*/
|
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L // C23 or later
|
|
#define PRISM_FALLTHROUGH [[fallthrough]];
|
|
#elif defined(__GNUC__) || defined(__clang__)
|
|
#define PRISM_FALLTHROUGH __attribute__((fallthrough));
|
|
#elif defined(_MSC_VER)
|
|
#define PRISM_FALLTHROUGH __fallthrough;
|
|
#else
|
|
#define PRISM_FALLTHROUGH
|
|
#endif
|
|
|
|
#endif
|