diff --git a/include/ruby/internal/intern/bignum.h b/include/ruby/internal/intern/bignum.h index c27f77a1fb6eb9..6ab26fef715d74 100644 --- a/include/ruby/internal/intern/bignum.h +++ b/include/ruby/internal/intern/bignum.h @@ -26,6 +26,10 @@ # include #endif +#ifdef HAVE_SYS_TYPES_H +# include /* for ssize_t (note: on Windows ssize_t is */ +#endif /* `#define`d in ruby/config.h) */ + #include "ruby/internal/attr/nonnull.h" #include "ruby/internal/dllexport.h" #include "ruby/internal/value.h" @@ -841,6 +845,47 @@ size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret); */ int rb_absint_singlebit_p(VALUE val); +/** + * @name Flags for rb_int_parse_cstr() + * @{ + */ + +/** Allows a leading sign (`+` or `-`). */ +#define RB_INT_PARSE_SIGN 0x01 + +/** Allows underscores between digits. */ +#define RB_INT_PARSE_UNDERSCORE 0x02 + +/** Allows a base prefix (`0x`, `0b`, `0o`, `0d`). */ +#define RB_INT_PARSE_PREFIX 0x04 + +/** Shorthand for all of the above flags combined. */ +#define RB_INT_PARSE_ALL 0x07 + +/** Default flags (all features enabled). */ +#define RB_INT_PARSE_DEFAULT 0x07 + +/** @} */ + +/** + * Parses a C string to convert into a Ruby integer, with detailed control over + * parsing behaviour. Unlike rb_cstr_to_inum(), this function can report the + * end position of the parsed integer and the number of parsed digits. + * + * @param[in] str Pointer to the string to parse. + * @param[in] len Length of `str` in bytes, or `-1` to use `strlen(str)`. + * @param[out] endp If not `NULL`, the pointer to the first unparsed + * character is stored here on return. + * @param[out] ndigits If not `NULL`, the number of parsed digits (excluding + * prefix, sign, and underscores) is stored here. + * @param[in] base Base of conversion. `0` means auto-detect from + * prefix. `2..36` for explicit base. + * @param[in] flags Bitwise or of `RB_INT_PARSE_*` macros. + * @return A Ruby Integer (Fixnum or Bignum), or `Qnil` on parse failure + * (when no digits are found). + */ +VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags); + RBIMPL_SYMBOL_EXPORT_END() #endif /* RBIMPL_INTERN_BIGNUM_H */ diff --git a/internal/bignum.h b/internal/bignum.h index 0692bafed30d73..f11fbd3a4d096a 100644 --- a/internal/bignum.h +++ b/internal/bignum.h @@ -89,14 +89,6 @@ (FL_USHIFT+3) /* bit offset of BIGNUM_EMBED_LEN_MASK */ #define BIGNUM_EMBED_LEN_MAX (BIGNUM_EMBED_LEN_MASK >> BIGNUM_EMBED_LEN_SHIFT) -enum rb_int_parse_flags { - RB_INT_PARSE_SIGN = 0x01, - RB_INT_PARSE_UNDERSCORE = 0x02, - RB_INT_PARSE_PREFIX = 0x04, - RB_INT_PARSE_ALL = 0x07, - RB_INT_PARSE_DEFAULT = 0x07, -}; - struct RBignum { struct RBasic basic; union { @@ -166,7 +158,6 @@ VALUE rb_big_divrem_gmp(VALUE x, VALUE y); VALUE rb_big2str_gmp(VALUE x, int base); VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck); #endif -VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags); RUBY_SYMBOL_EXPORT_END #if HAVE_LONG_LONG