1
0
Fork 0
mirror of https://github.com/tailix/libkernaux.git synced 2024-11-13 11:04:27 -05:00

Common: ntoa fixes

This commit is contained in:
Alex Kotov 2022-05-30 15:55:38 +03:00
parent 53f782ce5a
commit 995bac1f73
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
6 changed files with 53 additions and 13 deletions

View file

@ -16,6 +16,7 @@ static mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self);
static mrb_value rb_KernAux_utoa10(mrb_state *mrb, mrb_value self); static mrb_value rb_KernAux_utoa10(mrb_state *mrb, mrb_value self);
static mrb_value rb_KernAux_itoa10(mrb_state *mrb, mrb_value self); static mrb_value rb_KernAux_itoa10(mrb_state *mrb, mrb_value self);
static mrb_value rb_KernAux_utoa16(mrb_state *mrb, mrb_value self); static mrb_value rb_KernAux_utoa16(mrb_state *mrb, mrb_value self);
static mrb_value rb_KernAux_itoa16(mrb_state *mrb, mrb_value self); static mrb_value rb_KernAux_itoa16(mrb_state *mrb, mrb_value self);
@ -29,6 +30,8 @@ void init_ntoa(mrb_state *const mrb)
mrb_define_class_under_id(mrb, rb_KernAux, MRB_SYM(InvalidNtoaBaseError), mrb_define_class_under_id(mrb, rb_KernAux, MRB_SYM(InvalidNtoaBaseError),
rb_KernAux_Error); rb_KernAux_Error);
mrb_define_class_under_id(mrb, rb_KernAux, MRB_SYM(TooLongNtoaPrefixError),
rb_KernAux_Error);
mrb_define_class_method(mrb, rb_KernAux, "utoa", mrb_define_class_method(mrb, rb_KernAux, "utoa",
rb_KernAux_utoa, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1)); rb_KernAux_utoa, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
@ -39,6 +42,7 @@ void init_ntoa(mrb_state *const mrb)
rb_KernAux_utoa10, MRB_ARGS_REQ(1)); rb_KernAux_utoa10, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, rb_KernAux, "itoa10", mrb_define_class_method(mrb, rb_KernAux, "itoa10",
rb_KernAux_itoa10, MRB_ARGS_REQ(1)); rb_KernAux_itoa10, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, rb_KernAux, "utoa16", mrb_define_class_method(mrb, rb_KernAux, "utoa16",
rb_KernAux_utoa16, MRB_ARGS_REQ(1)); rb_KernAux_utoa16, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, rb_KernAux, "itoa16", mrb_define_class_method(mrb, rb_KernAux, "itoa16",
@ -58,7 +62,15 @@ mrb_value rb_KernAux_utoa(mrb_state *mrb, mrb_value self)
"can't convert negative number to uint64_t"); "can't convert negative number to uint64_t");
} }
if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) { if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, struct RClass *const rb_KernAux =
mrb_module_get_id(mrb, MRB_SYM(KernAux));
struct RClass *const rb_KernAux_TooLongNtoaPrefixError =
mrb_class_get_under_id(
mrb,
rb_KernAux,
MRB_SYM(TooLongNtoaPrefixError)
);
mrb_raisef(mrb, rb_KernAux_TooLongNtoaPrefixError,
"prefix length %d is too long", prefix_len); "prefix length %d is too long", prefix_len);
} }
@ -81,7 +93,15 @@ mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self)
mrb_get_args(mrb, "io|s!", &value, &base, &prefix, &prefix_len); mrb_get_args(mrb, "io|s!", &value, &base, &prefix, &prefix_len);
if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) { if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, struct RClass *const rb_KernAux =
mrb_module_get_id(mrb, MRB_SYM(KernAux));
struct RClass *const rb_KernAux_TooLongNtoaPrefixError =
mrb_class_get_under_id(
mrb,
rb_KernAux,
MRB_SYM(TooLongNtoaPrefixError)
);
mrb_raisef(mrb, rb_KernAux_TooLongNtoaPrefixError,
"prefix length %d is too long", prefix_len); "prefix length %d is too long", prefix_len);
} }

View file

@ -52,8 +52,8 @@ assert 'KernAux.utoa' do
base = 2 + Random.rand(36 - 2) base = 2 + Random.rand(36 - 2)
test_utoa number, base, number.to_s(base) test_utoa number, base, number.to_s(base)
base = 2 + Random.rand(36 - 2)
assert_raise RangeError, 'can\'t convert negative number to uint64_t' do assert_raise RangeError, 'can\'t convert negative number to uint64_t' do
base = 2 + Random.rand(36 - 2)
KernAux.utoa(-1, base) KernAux.utoa(-1, base)
end end
@ -101,7 +101,10 @@ assert 'KernAux.utoa' do
prefix = 'a' * 100 prefix = 'a' * 100
test_utoax number, base, prefix, "#{prefix}#{number.abs.to_s(base)}" test_utoax number, base, prefix, "#{prefix}#{number.abs.to_s(base)}"
assert_raise ArgumentError, 'prefix length 101 is too long' do assert_raise(
KernAux::TooLongNtoaPrefixError,
'prefix length 101 is too long',
) do
number = Random.rand(2**32 - 1) number = Random.rand(2**32 - 1)
base = 2 + Random.rand(36 - 2) base = 2 + Random.rand(36 - 2)
prefix = 'a' * 101 prefix = 'a' * 101
@ -181,7 +184,10 @@ assert 'KernAux.itoa' do
sign = number < 0 ? '-' : '' sign = number < 0 ? '-' : ''
test_itoax number, base, prefix, "#{sign}#{prefix}#{number.abs.to_s(base)}" test_itoax number, base, prefix, "#{sign}#{prefix}#{number.abs.to_s(base)}"
assert_raise ArgumentError, 'prefix length 101 is too long' do assert_raise(
KernAux::TooLongNtoaPrefixError,
'prefix length 101 is too long',
) do
number = Random.rand(2**31 - 1) * [1, -1].sample number = Random.rand(2**31 - 1) * [1, -1].sample
base = 2 + Random.rand(36 - 2) base = 2 + Random.rand(36 - 2)
prefix = 'a' * 101 prefix = 'a' * 101

View file

@ -9,7 +9,6 @@ static VALUE rb_KernAux_utoa(VALUE self, VALUE number, VALUE base, VALUE prefix)
#ifdef HAVE_KERNAUX_ITOA #ifdef HAVE_KERNAUX_ITOA
static VALUE rb_KernAux_itoa(VALUE self, VALUE number, VALUE base, VALUE prefix); static VALUE rb_KernAux_itoa(VALUE self, VALUE number, VALUE base, VALUE prefix);
#endif #endif
#ifdef HAVE_KERNAUX_UTOA10 #ifdef HAVE_KERNAUX_UTOA10
static VALUE rb_KernAux_utoa10(VALUE self, VALUE number); static VALUE rb_KernAux_utoa10(VALUE self, VALUE number);
#endif #endif
@ -39,6 +38,7 @@ static ID rb_intern_X = Qnil;
static VALUE rb_KernAux = Qnil; static VALUE rb_KernAux = Qnil;
static VALUE rb_KernAux_Error = Qnil; static VALUE rb_KernAux_Error = Qnil;
static VALUE rb_KernAux_InvalidNtoaBaseError = Qnil; static VALUE rb_KernAux_InvalidNtoaBaseError = Qnil;
static VALUE rb_KernAux_TooLongNtoaPrefixError = Qnil;
#if defined(HAVE_KERNAUX_UTOA) || defined(HAVE_KERNAUX_ITOA) #if defined(HAVE_KERNAUX_UTOA) || defined(HAVE_KERNAUX_ITOA)
static int convert_base(VALUE base); static int convert_base(VALUE base);
@ -65,6 +65,9 @@ void init_ntoa()
rb_gc_register_mark_object(rb_KernAux_InvalidNtoaBaseError = rb_gc_register_mark_object(rb_KernAux_InvalidNtoaBaseError =
rb_define_class_under(rb_KernAux, "InvalidNtoaBaseError", rb_define_class_under(rb_KernAux, "InvalidNtoaBaseError",
rb_KernAux_Error)); rb_KernAux_Error));
rb_gc_register_mark_object(rb_KernAux_TooLongNtoaPrefixError =
rb_define_class_under(rb_KernAux, "TooLongNtoaPrefixError",
rb_KernAux_Error));
#ifdef HAVE_KERNAUX_UTOA #ifdef HAVE_KERNAUX_UTOA
rb_define_singleton_method(rb_KernAux, "utoa", rb_KernAux_utoa, 3); rb_define_singleton_method(rb_KernAux, "utoa", rb_KernAux_utoa, 3);
@ -72,7 +75,6 @@ void init_ntoa()
#ifdef HAVE_KERNAUX_ITOA #ifdef HAVE_KERNAUX_ITOA
rb_define_singleton_method(rb_KernAux, "itoa", rb_KernAux_itoa, 3); rb_define_singleton_method(rb_KernAux, "itoa", rb_KernAux_itoa, 3);
#endif #endif
#ifdef HAVE_KERNAUX_UTOA10 #ifdef HAVE_KERNAUX_UTOA10
rb_define_singleton_method(rb_KernAux, "utoa10", rb_KernAux_utoa10, 1); rb_define_singleton_method(rb_KernAux, "utoa10", rb_KernAux_utoa10, 1);
#endif #endif
@ -107,7 +109,7 @@ VALUE rb_KernAux_utoa(
if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) { if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) {
rb_raise( rb_raise(
rb_eArgError, rb_KernAux_TooLongNtoaPrefixError,
"prefix length %ld is too long", "prefix length %ld is too long",
prefix_len prefix_len
); );
@ -137,7 +139,7 @@ VALUE rb_KernAux_itoa(
if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) { if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) {
rb_raise( rb_raise(
rb_eArgError, rb_KernAux_TooLongNtoaPrefixError,
"prefix length %ld is too long", "prefix length %ld is too long",
prefix_len prefix_len
); );

View file

@ -127,7 +127,7 @@ module KernAux
# @!parse [ruby] # @!parse [ruby]
## ##
# @!method utoa(number, base) # @!method utoa(number, base, prefix)
# Convert `uint64_t` to a string in multiple numeral systems. # Convert `uint64_t` to a string in multiple numeral systems.
# #
# Base can be a positive or negative integer between 2 and 36, or a symbol # Base can be a positive or negative integer between 2 and 36, or a symbol
@ -139,16 +139,18 @@ module KernAux
# #
# @param number [Integer] a number between 0 and `UINT64_MAX` # @param number [Integer] a number between 0 and `UINT64_MAX`
# @param base [Integer, Symbol] base of a numeral system # @param base [Integer, Symbol] base of a numeral system
# @param prefix [nil, String] string to put before a number
# @return [String] # @return [String]
# #
# @raise [RangeError] number is out of range # @raise [RangeError] number is out of range
# @raise [InvalidNtoaBaseError] base is invalid # @raise [InvalidNtoaBaseError] base is invalid
# @raise [TooLongNtoaPrefixError] prefix is too long
# #
# @see .itoa Convert signed integers # @see .itoa Convert signed integers
## ##
## ##
# @!method itoa(number, base) # @!method itoa(number, base, prefix)
# Convert `int64_t` to a string in multiple numeral systems. # Convert `int64_t` to a string in multiple numeral systems.
# #
# Base can be a positive or negative integer between 2 and 36, or a symbol # Base can be a positive or negative integer between 2 and 36, or a symbol
@ -160,10 +162,12 @@ module KernAux
# #
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX` # @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
# @param base [Integer, Symbol] base of a numeral system # @param base [Integer, Symbol] base of a numeral system
# @param prefix [nil, String] string to put between a sign and a number
# @return [String] # @return [String]
# #
# @raise [RangeError] number is out of range # @raise [RangeError] number is out of range
# @raise [InvalidNtoaBaseError] base is invalid # @raise [InvalidNtoaBaseError] base is invalid
# @raise [TooLongNtoaPrefixError] prefix is too long
# #
# @see .utoa Convert unsigned integers # @see .utoa Convert unsigned integers
## ##
@ -235,4 +239,12 @@ module KernAux
# @see .itoa # @see .itoa
# #
class InvalidNtoaBaseError < Error; end class InvalidNtoaBaseError < Error; end
##
# Raised when prefix is too long.
#
# @see .utoa
# @see .itoa
#
class TooLongNtoaPrefixError < Error; end
end end

View file

@ -221,7 +221,7 @@ RSpec.describe KernAux, '.itoa' do
specify do specify do
expect { itoa }.to raise_error( expect { itoa }.to raise_error(
ArgumentError, described_class::TooLongNtoaPrefixError,
"prefix length #{prefix.length} is too long", "prefix length #{prefix.length} is too long",
) )
end end

View file

@ -193,7 +193,7 @@ RSpec.describe KernAux, '.utoa' do
specify do specify do
expect { utoa }.to raise_error( expect { utoa }.to raise_error(
ArgumentError, described_class::TooLongNtoaPrefixError,
"prefix length #{prefix.length} is too long", "prefix length #{prefix.length} is too long",
) )
end end