From 2e6b16027b06efefc2d791778c8f03e547235676 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Mon, 13 Jun 2022 10:02:05 +0300 Subject: [PATCH] Common: feature macros --- .github/workflows/mruby.yml | 5 +- .github/workflows/ruby.yml | 34 +- .github/workflows/rust.yml | 11 +- .gitignore | 1 + bindings/mruby/mrblib/kernaux.rb | 24 +- bindings/mruby/src/assert.c | 3 - bindings/mruby/src/cmdline.c | 7 +- bindings/mruby/src/main.c | 9 +- bindings/mruby/src/main.h | 9 + bindings/mruby/src/ntoa.c | 7 +- bindings/mruby/src/printf.c | 10 +- bindings/mruby/src/version.c | 49 ++ bindings/mruby/test/cmdline.rb | 136 +++--- bindings/mruby/test/ntoa.rb | 462 +++++++++--------- bindings/mruby/test/printf.rb | 46 +- bindings/ruby/ext/default/assert.c | 3 +- bindings/ruby/ext/default/cmdline.c | 7 +- bindings/ruby/ext/default/extconf.rb | 28 -- bindings/ruby/ext/default/file.c | 7 +- bindings/ruby/ext/default/main.c | 38 +- bindings/ruby/ext/default/main.h | 23 + bindings/ruby/ext/default/ntoa.c | 71 +-- bindings/ruby/ext/default/printf.c | 7 +- bindings/ruby/ext/default/version.c | 61 +++ bindings/ruby/lib/kernaux/version.rb | 51 -- .../ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb | 2 +- .../ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb | 2 +- .../ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb | 2 +- .../ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb | 2 +- .../ruby/spec/lib/kernaux/ntoa/itoa_spec.rb | 2 +- .../ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb | 2 +- .../ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb | 2 +- .../ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb | 2 +- .../ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb | 2 +- .../ruby/spec/lib/kernaux/ntoa/utoa_spec.rb | 2 +- bindings/rust/kernaux-sys/Cargo.toml | 5 + bindings/rust/kernaux-sys/src/lib.rs | 7 + bindings/rust/kernaux-sys/src/version.rs | 7 + bindings/rust/kernaux/Cargo.toml | 6 + bindings/rust/kernaux/src/lib.rs | 6 + bindings/rust/kernaux/src/version.rs | 1 + configure.ac | 1 + include/Makefile.am | 3 +- include/kernaux.h.in | 2 + include/kernaux/version.h.in | 17 + 45 files changed, 612 insertions(+), 572 deletions(-) create mode 100644 bindings/mruby/src/version.c create mode 100644 bindings/ruby/ext/default/main.h create mode 100644 bindings/ruby/ext/default/version.c create mode 100644 bindings/rust/kernaux-sys/src/version.rs create mode 120000 bindings/rust/kernaux/src/version.rs create mode 100644 include/kernaux/version.h.in diff --git a/.github/workflows/mruby.yml b/.github/workflows/mruby.yml index 3ae5d6e..92f0213 100644 --- a/.github/workflows/mruby.yml +++ b/.github/workflows/mruby.yml @@ -11,6 +11,9 @@ jobs: runs-on: ubuntu-latest env: MRUBY_YAML_USE_SYSTEM_LIBRARY: x + strategy: + matrix: + packages: ['', '--without-all'] steps: - uses: actions/checkout@v2 with: @@ -23,7 +26,7 @@ jobs: - name: autogen run: ./autogen.sh - name: configure - run: ./configure CFLAGS='-O3' + run: ./configure ${{matrix.packages}} CFLAGS='-O3' - name: make run: make - name: install diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 1d63dcd..7d2935e 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -9,6 +9,9 @@ on: jobs: test: runs-on: ubuntu-latest + strategy: + matrix: + packages: ['', '--without-all'] steps: - uses: actions/checkout@v2 - uses: ruby/setup-ruby@v1 @@ -19,7 +22,7 @@ jobs: - name: autogen run: ./autogen.sh - name: configure - run: ./configure CFLAGS='-O3' + run: ./configure ${{matrix.packages}} CFLAGS='-O3' - name: make run: make - name: install @@ -36,32 +39,3 @@ jobs: - working-directory: bindings/ruby name: cppcheck run: cppcheck --quiet --error-exitcode=1 --std=c99 --enable=warning,style,performance,portability . - - cond: - runs-on: ubuntu-latest - env: - SKIP_COVERAGE: x - steps: - - uses: actions/checkout@v2 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.0 - - name: dependencies - run: sudo apt-get --yes install - - name: autogen - run: ./autogen.sh - - name: configure - run: ./configure --without-all CFLAGS='-O3' - - name: make - run: make - - name: install - run: sudo make install - - working-directory: bindings/ruby - name: setup - run: ./bin/setup - - working-directory: bindings/ruby - name: compile - run: rake compile - - working-directory: bindings/ruby - name: test & lint - run: rake diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1e7ba00..9d733bb 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -9,6 +9,12 @@ on: jobs: test: runs-on: ubuntu-latest + strategy: + matrix: + packages: + - {} + - configure: '--without-all' + cargo: '--no-default-features' steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 @@ -18,11 +24,14 @@ jobs: - name: autogen run: ./autogen.sh - name: configure - run: ./configure CFLAGS='-O3' + run: ./configure ${{matrix.packages.configure}} CFLAGS='-O3' - name: make run: make - name: install run: sudo make install + - working-directory: bindings/rust + name: test + run: cargo build ${{matrix.packages.cargo}} - working-directory: bindings/rust name: test run: cargo test diff --git a/.gitignore b/.gitignore index a66693f..65c778b 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,7 @@ /include/kernaux.h /include/kernaux/console.h /include/kernaux/printf.h +/include/kernaux/version.h /examples/assert_guards /examples/assert_simple diff --git a/bindings/mruby/mrblib/kernaux.rb b/bindings/mruby/mrblib/kernaux.rb index cf9cff7..ec0600f 100644 --- a/bindings/mruby/mrblib/kernaux.rb +++ b/bindings/mruby/mrblib/kernaux.rb @@ -9,18 +9,20 @@ module KernAux SPRINTF1_BUFFER_SIZE = 10_000 - def self.sprintf(*args) - args.map do |arg| - if arg.is_a? Array - sprintf1(*arg) - else - arg - end - end.join.freeze - end + if Version.supports_printf? + def self.sprintf(*args) + args.map do |arg| + if arg.is_a? Array + sprintf1(*arg) + else + arg + end + end.join.freeze + end - def self.sprintf1(format, *args) - snprintf1(SPRINTF1_BUFFER_SIZE, format, *args).first + def self.sprintf1(format, *args) + snprintf1(SPRINTF1_BUFFER_SIZE, format, *args).first + end end class Error < RuntimeError; end diff --git a/bindings/mruby/src/assert.c b/bindings/mruby/src/assert.c index 2173637..b9f5d66 100644 --- a/bindings/mruby/src/assert.c +++ b/bindings/mruby/src/assert.c @@ -3,9 +3,6 @@ #include #include -#include - -#include #include #include #include diff --git a/bindings/mruby/src/cmdline.c b/bindings/mruby/src/cmdline.c index be2977e..2967877 100644 --- a/bindings/mruby/src/cmdline.c +++ b/bindings/mruby/src/cmdline.c @@ -4,9 +4,6 @@ #include #include -#include - -#include #include #include #include @@ -14,6 +11,8 @@ #define ARGV_COUNT_MAX 256 #define BUFFER_SIZE 4096 +#ifdef KERNAUX_VERSION_SUPPORTS_CMDLINE + static mrb_value rb_KernAux_cmdline(mrb_state *mrb, mrb_value self); void init_cmdline(mrb_state *const mrb) @@ -69,3 +68,5 @@ mrb_value rb_KernAux_cmdline(mrb_state *const mrb, mrb_value self) free(buffer); return mrb_obj_freeze(mrb, mrb_ary_new_from_values(mrb, argc, values)); } + +#endif // KERNAUX_VERSION_SUPPORTS_CMDLINE diff --git a/bindings/mruby/src/main.c b/bindings/mruby/src/main.c index 8c682d7..067055b 100644 --- a/bindings/mruby/src/main.c +++ b/bindings/mruby/src/main.c @@ -2,7 +2,6 @@ #include -#include #include #define MRB_STACK_SIZE 100 @@ -25,9 +24,17 @@ void mrb_mruby_kernaux_gem_init(mrb_state *const mrb) mrb_define_class_under_id(mrb, rb_KernAux, MRB_SYM(Error), E_RUNTIME_ERROR); init_assert(mrb); + init_version(mrb); + +#ifdef KERNAUX_VERSION_SUPPORTS_CMDLINE init_cmdline(mrb); +#endif // KERNAUX_VERSION_SUPPORTS_CMDLINE +#ifdef KERNAUX_VERSION_SUPPORTS_NTOA init_ntoa(mrb); +#endif // KERNAUX_VERSION_SUPPORTS_NTOA +#ifdef KERNAUX_VERSION_SUPPORTS_PRINTF init_printf(mrb); +#endif // KERNAUX_VERSION_SUPPORTS_PRINTF } void current_mrb_start(mrb_state *mrb) diff --git a/bindings/mruby/src/main.h b/bindings/mruby/src/main.h index 4b4a531..7b029f5 100644 --- a/bindings/mruby/src/main.h +++ b/bindings/mruby/src/main.h @@ -1,6 +1,7 @@ #ifndef __MAIN_H__ #define __MAIN_H__ +#include #include void current_mrb_start(mrb_state *mrb); @@ -8,8 +9,16 @@ void current_mrb_finish(mrb_state *mrb); mrb_state *current_mrb_get(); void init_assert(mrb_state *mrb); +void init_version(mrb_state *mrb); + +#ifdef KERNAUX_VERSION_SUPPORTS_CMDLINE void init_cmdline(mrb_state *mrb); +#endif // KERNAUX_VERSION_SUPPORTS_CMDLINE +#ifdef KERNAUX_VERSION_SUPPORTS_NTOA void init_ntoa(mrb_state *mrb); +#endif // KERNAUX_VERSION_SUPPORTS_NTOA +#ifdef KERNAUX_VERSION_SUPPORTS_PRINTF void init_printf(mrb_state *mrb); +#endif // KERNAUX_VERSION_SUPPORTS_PRINTF #endif diff --git a/bindings/mruby/src/ntoa.c b/bindings/mruby/src/ntoa.c index 6e6e4fa..73f16b3 100644 --- a/bindings/mruby/src/ntoa.c +++ b/bindings/mruby/src/ntoa.c @@ -2,13 +2,12 @@ #include -#include - -#include #include #include #include +#ifdef KERNAUX_VERSION_SUPPORTS_NTOA + static mrb_value rb_KernAux_utoa(mrb_state *mrb, mrb_value self); static mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self); @@ -297,3 +296,5 @@ int convert_base(mrb_state *mrb, mrb_value base_rb) return mrb_integer(base_rb); } } + +#endif // KERNAUX_VERSION_SUPPORTS_NTOA diff --git a/bindings/mruby/src/printf.c b/bindings/mruby/src/printf.c index 24a15af..ce8ca62 100644 --- a/bindings/mruby/src/printf.c +++ b/bindings/mruby/src/printf.c @@ -1,14 +1,14 @@ -#include "dynarg.h" #include "main.h" -#include +#include "dynarg.h" + +#include -#include #include #include #include -#include +#ifdef KERNAUX_VERSION_SUPPORTS_PRINTF static mrb_value rb_KernAux_snprintf1(mrb_state *mrb, mrb_value self); @@ -120,3 +120,5 @@ mrb_value rb_KernAux_snprintf1(mrb_state *const mrb, mrb_value self) values[1] = mrb_fixnum_value(slen); return mrb_obj_freeze(mrb, mrb_ary_new_from_values(mrb, 2, values)); } + +#endif // KERNAUX_VERSION_SUPPORTS_PRINTF diff --git a/bindings/mruby/src/version.c b/bindings/mruby/src/version.c new file mode 100644 index 0000000..0f0988d --- /dev/null +++ b/bindings/mruby/src/version.c @@ -0,0 +1,49 @@ +#include "main.h" + +#include +#include + +static mrb_value rb_KernAux_Version_supports_cmdlineQN(mrb_state *mrb, mrb_value self); +static mrb_value rb_KernAux_Version_supports_ntoaQN(mrb_state *mrb, mrb_value self); +static mrb_value rb_KernAux_Version_supports_printfQN(mrb_state *mrb, mrb_value self); + +void init_version(mrb_state *const mrb) +{ + struct RClass *const rb_KernAux = mrb_module_get_id(mrb, MRB_SYM(KernAux)); + struct RClass *const rb_KernAux_Version = + mrb_define_module_under_id(mrb, rb_KernAux, MRB_SYM(Version)); + + mrb_define_class_method(mrb, rb_KernAux_Version, "supports_cmdline?", + rb_KernAux_Version_supports_cmdlineQN, MRB_ARGS_REQ(0)); + mrb_define_class_method(mrb, rb_KernAux_Version, "supports_ntoa?", + rb_KernAux_Version_supports_ntoaQN, MRB_ARGS_REQ(0)); + mrb_define_class_method(mrb, rb_KernAux_Version, "supports_printf?", + rb_KernAux_Version_supports_printfQN, MRB_ARGS_REQ(0)); +} + +mrb_value rb_KernAux_Version_supports_cmdlineQN(mrb_state *const mrb, const mrb_value self) +{ +#ifdef KERNAUX_VERSION_SUPPORTS_CMDLINE + return mrb_true_value(); +#else + return mrb_false_value(); +#endif +} + +mrb_value rb_KernAux_Version_supports_ntoaQN(mrb_state *const mrb, const mrb_value self) +{ +#ifdef KERNAUX_VERSION_SUPPORTS_NTOA + return mrb_true_value(); +#else + return mrb_false_value(); +#endif +} + +mrb_value rb_KernAux_Version_supports_printfQN(mrb_state *const mrb, const mrb_value self) +{ +#ifdef KERNAUX_VERSION_SUPPORTS_PRINTF + return mrb_true_value(); +#else + return mrb_false_value(); +#endif +} diff --git a/bindings/mruby/test/cmdline.rb b/bindings/mruby/test/cmdline.rb index 2125ca9..8b6e5b2 100644 --- a/bindings/mruby/test/cmdline.rb +++ b/bindings/mruby/test/cmdline.rb @@ -11,81 +11,83 @@ def test_cmdline(str, expected) assert_equal result, expected end -assert 'default' do - test_cmdline 'foo bar\\ baz "car cdr"', ['foo', 'bar baz', 'car cdr'] -end - -assert 'when str is empty' do - test_cmdline '', [] -end - -assert 'when str has invalid type' do - assert_raise TypeError, 'Integer cannot be converted to String' do - KernAux.cmdline 123 +if KernAux::Version.supports_cmdline? + assert 'default' do + test_cmdline 'foo bar\\ baz "car cdr"', ['foo', 'bar baz', 'car cdr'] end -end -assert 'when str has EOL after backslash' do - assert_raise KernAux::CmdlineError, 'EOL after backslash' do - KernAux.cmdline '\\' + assert 'when str is empty' do + test_cmdline '', [] end -end -assert 'when str has EOL after backslash inside quote' do - assert_raise KernAux::CmdlineError, 'EOL after backslash inside quote' do - KernAux.cmdline '"\\' - end -end - -assert 'when str has unescaped quotation mark' do - assert_raise KernAux::CmdlineError, 'unescaped quotation mark' do - KernAux.cmdline 'foo"' - end -end - -assert 'when str has EOL inside quote' do - assert_raise KernAux::CmdlineError, 'EOL inside quote' do - KernAux.cmdline '"' - end -end - -assert 'when there are not too many args' do - test_cmdline 'a ' * 256, ['a'] * 256 -end - -assert 'when there are too many args' do - assert_raise KernAux::CmdlineError, 'too many args' do - KernAux.cmdline 'a ' * 257 - end -end - -assert 'when args don\'t cause buffer overflow' do - test_cmdline 'a' * 4095, ['a' * 4095] -end - -assert 'when args cause buffer overflow' do - assert_raise KernAux::CmdlineError, 'buffer overflow' do - KernAux.cmdline 'a' * 4096 - end -end - -assert 'usign common tests' do - cmdline_yml = File.expand_path('../../../../common/cmdline.yml', __FILE__) - - YAML.load(File.read(cmdline_yml)).each do |test| - escape_str = lambda do |str| - eval "\"#{str}\"", nil, __FILE__, __LINE__ # "str" + assert 'when str has invalid type' do + assert_raise TypeError, 'Integer cannot be converted to String' do + KernAux.cmdline 123 end + end - cmdline = escape_str.call test['cmdline'] - argv_count_max = test['argv_count_max'] - buffer_size = test['buffer_size'] - result = test['result']&.map(&escape_str) + assert 'when str has EOL after backslash' do + assert_raise KernAux::CmdlineError, 'EOL after backslash' do + KernAux.cmdline '\\' + end + end - next unless argv_count_max.nil? && buffer_size.nil? && !result.nil? + assert 'when str has EOL after backslash inside quote' do + assert_raise KernAux::CmdlineError, 'EOL after backslash inside quote' do + KernAux.cmdline '"\\' + end + end - assert "transforms #{cmdline.inspect} to #{result.inspect}" do - assert_equal KernAux.cmdline(cmdline), result + assert 'when str has unescaped quotation mark' do + assert_raise KernAux::CmdlineError, 'unescaped quotation mark' do + KernAux.cmdline 'foo"' + end + end + + assert 'when str has EOL inside quote' do + assert_raise KernAux::CmdlineError, 'EOL inside quote' do + KernAux.cmdline '"' + end + end + + assert 'when there are not too many args' do + test_cmdline 'a ' * 256, ['a'] * 256 + end + + assert 'when there are too many args' do + assert_raise KernAux::CmdlineError, 'too many args' do + KernAux.cmdline 'a ' * 257 + end + end + + assert 'when args don\'t cause buffer overflow' do + test_cmdline 'a' * 4095, ['a' * 4095] + end + + assert 'when args cause buffer overflow' do + assert_raise KernAux::CmdlineError, 'buffer overflow' do + KernAux.cmdline 'a' * 4096 + end + end + + assert 'usign common tests' do + cmdline_yml = File.expand_path('../../../../common/cmdline.yml', __FILE__) + + YAML.load(File.read(cmdline_yml)).each do |test| + escape_str = lambda do |str| + eval "\"#{str}\"", nil, __FILE__, __LINE__ # "str" + end + + cmdline = escape_str.call test['cmdline'] + argv_count_max = test['argv_count_max'] + buffer_size = test['buffer_size'] + result = test['result']&.map(&escape_str) + + next unless argv_count_max.nil? && buffer_size.nil? && !result.nil? + + assert "transforms #{cmdline.inspect} to #{result.inspect}" do + assert_equal KernAux.cmdline(cmdline), result + end end end end diff --git a/bindings/mruby/test/ntoa.rb b/bindings/mruby/test/ntoa.rb index 8545a64..f4ea68c 100644 --- a/bindings/mruby/test/ntoa.rb +++ b/bindings/mruby/test/ntoa.rb @@ -56,241 +56,243 @@ def test_itoa16(number, expected) common_assert expected, KernAux.itoa16(number) end -assert 'KernAux.utoa' do - number = Random.rand(2**32 - 1) - base = 2 + Random.rand(36 - 2) - test_utoa number, base, number.to_s(base) - - base = 2 + Random.rand(36 - 2) - test_utoa 0, base, '0' - - number = 2**32 - 1 - base = 2 + Random.rand(36 - 2) - test_utoa number, base, number.to_s(base) - - assert_raise RangeError, 'can\'t convert negative number to uint64_t' do - base = 2 + Random.rand(36 - 2) - KernAux.utoa(-1, base) - end - - number = Random.rand(2**32 - 1) - base = -(2 + Random.rand(36 - 2)) - test_utoa number, base, number.to_s(-base).upcase - - number = Random.rand(2**32 - 1) - test_utoa number, :b, number.to_s(2) - - number = Random.rand(2**32 - 1) - test_utoa number, :B, number.to_s(2) - - number = Random.rand(2**32 - 1) - test_utoa number, :o, number.to_s(8) - - number = Random.rand(2**32 - 1) - test_utoa number, :O, number.to_s(8) - - number = Random.rand(2**32 - 1) - test_utoa number, :d, number.to_s(10) - - number = Random.rand(2**32 - 1) - test_utoa number, :D, number.to_s(10) - - number = Random.rand(2**32 - 1) - test_utoa number, :h, number.to_s(16) - - number = Random.rand(2**32 - 1) - test_utoa number, :x, number.to_s(16) - - number = Random.rand(2**32 - 1) - test_utoa number, :H, number.to_s(16).upcase - - number = Random.rand(2**32 - 1) - test_utoa number, :X, number.to_s(16).upcase - - number = Random.rand(2**32 - 1) - base = 2 + Random.rand(36 - 2) - prefix = 'foo' - test_utoax number, base, prefix, "#{prefix}#{number.abs.to_s(base)}" - - number = Random.rand(2**32 - 1) - base = 2 + Random.rand(36 - 2) - prefix = 'a' * 100 - test_utoax number, base, prefix, "#{prefix}#{number.abs.to_s(base)}" - - assert_raise( - KernAux::TooLongNtoaPrefixError, - 'prefix length 101 is too long', - ) do +if KernAux::Version.supports_ntoa? + assert 'KernAux.utoa' do number = Random.rand(2**32 - 1) base = 2 + Random.rand(36 - 2) - prefix = 'a' * 101 - KernAux.utoa(number, base, prefix) + test_utoa number, base, number.to_s(base) + + base = 2 + Random.rand(36 - 2) + test_utoa 0, base, '0' + + number = 2**32 - 1 + base = 2 + Random.rand(36 - 2) + test_utoa number, base, number.to_s(base) + + assert_raise RangeError, 'can\'t convert negative number to uint64_t' do + base = 2 + Random.rand(36 - 2) + KernAux.utoa(-1, base) + end + + number = Random.rand(2**32 - 1) + base = -(2 + Random.rand(36 - 2)) + test_utoa number, base, number.to_s(-base).upcase + + number = Random.rand(2**32 - 1) + test_utoa number, :b, number.to_s(2) + + number = Random.rand(2**32 - 1) + test_utoa number, :B, number.to_s(2) + + number = Random.rand(2**32 - 1) + test_utoa number, :o, number.to_s(8) + + number = Random.rand(2**32 - 1) + test_utoa number, :O, number.to_s(8) + + number = Random.rand(2**32 - 1) + test_utoa number, :d, number.to_s(10) + + number = Random.rand(2**32 - 1) + test_utoa number, :D, number.to_s(10) + + number = Random.rand(2**32 - 1) + test_utoa number, :h, number.to_s(16) + + number = Random.rand(2**32 - 1) + test_utoa number, :x, number.to_s(16) + + number = Random.rand(2**32 - 1) + test_utoa number, :H, number.to_s(16).upcase + + number = Random.rand(2**32 - 1) + test_utoa number, :X, number.to_s(16).upcase + + number = Random.rand(2**32 - 1) + base = 2 + Random.rand(36 - 2) + prefix = 'foo' + test_utoax number, base, prefix, "#{prefix}#{number.abs.to_s(base)}" + + number = Random.rand(2**32 - 1) + base = 2 + Random.rand(36 - 2) + prefix = 'a' * 100 + test_utoax number, base, prefix, "#{prefix}#{number.abs.to_s(base)}" + + assert_raise( + KernAux::TooLongNtoaPrefixError, + 'prefix length 101 is too long', + ) do + number = Random.rand(2**32 - 1) + base = 2 + Random.rand(36 - 2) + prefix = 'a' * 101 + KernAux.utoa(number, base, prefix) + end end -end -assert 'KernAux.itoa' do - number = Random.rand(2**31 - 1) * [1, -1].sample - base = 2 + Random.rand(36 - 2) - test_itoa number, base, number.to_s(base) - - base = 2 + Random.rand(36 - 2) - test_itoa 0, base, '0' - - base = 2 + Random.rand(36 - 2) - test_itoa 1, base, '1' - - base = 2 + Random.rand(36 - 2) - test_itoa(-1, base, '-1') - - number = 2**31 - 1 - base = 2 + Random.rand(36 - 2) - test_itoa number, base, number.to_s(base) - - number = -(2**31 - 1) - base = 2 + Random.rand(36 - 2) - test_itoa number, base, number.to_s(base) - - number = 2**31 - 1 - base = -(2 + Random.rand(36 - 2)) - test_itoa number, base, number.to_s(-base).upcase - - number = -(2**31 - 1) - base = -(2 + Random.rand(36 - 2)) - test_itoa number, base, number.to_s(-base).upcase - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :b, number.to_s(2) - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :B, number.to_s(2) - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :o, number.to_s(8) - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :O, number.to_s(8) - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :d, number.to_s(10) - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :D, number.to_s(10) - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :h, number.to_s(16) - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :x, number.to_s(16) - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :H, number.to_s(16).upcase - - number = Random.rand(2**31 - 1) * [1, -1].sample - test_itoa number, :X, number.to_s(16).upcase - - number = Random.rand(2**31 - 1) * [1, -1].sample - base = 2 + Random.rand(36 - 2) - prefix = 'foo' - sign = number < 0 ? '-' : '' - test_itoax number, base, prefix, "#{sign}#{prefix}#{number.abs.to_s(base)}" - - number = Random.rand(2**31 - 1) * [1, -1].sample - base = 2 + Random.rand(36 - 2) - prefix = 'a' * 100 - sign = number < 0 ? '-' : '' - test_itoax number, base, prefix, "#{sign}#{prefix}#{number.abs.to_s(base)}" - - assert_raise( - KernAux::TooLongNtoaPrefixError, - 'prefix length 101 is too long', - ) do + assert 'KernAux.itoa' do number = Random.rand(2**31 - 1) * [1, -1].sample base = 2 + Random.rand(36 - 2) - prefix = 'a' * 101 - KernAux.itoa(number, base, prefix) + test_itoa number, base, number.to_s(base) + + base = 2 + Random.rand(36 - 2) + test_itoa 0, base, '0' + + base = 2 + Random.rand(36 - 2) + test_itoa 1, base, '1' + + base = 2 + Random.rand(36 - 2) + test_itoa(-1, base, '-1') + + number = 2**31 - 1 + base = 2 + Random.rand(36 - 2) + test_itoa number, base, number.to_s(base) + + number = -(2**31 - 1) + base = 2 + Random.rand(36 - 2) + test_itoa number, base, number.to_s(base) + + number = 2**31 - 1 + base = -(2 + Random.rand(36 - 2)) + test_itoa number, base, number.to_s(-base).upcase + + number = -(2**31 - 1) + base = -(2 + Random.rand(36 - 2)) + test_itoa number, base, number.to_s(-base).upcase + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :b, number.to_s(2) + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :B, number.to_s(2) + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :o, number.to_s(8) + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :O, number.to_s(8) + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :d, number.to_s(10) + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :D, number.to_s(10) + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :h, number.to_s(16) + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :x, number.to_s(16) + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :H, number.to_s(16).upcase + + number = Random.rand(2**31 - 1) * [1, -1].sample + test_itoa number, :X, number.to_s(16).upcase + + number = Random.rand(2**31 - 1) * [1, -1].sample + base = 2 + Random.rand(36 - 2) + prefix = 'foo' + sign = number < 0 ? '-' : '' + test_itoax number, base, prefix, "#{sign}#{prefix}#{number.abs.to_s(base)}" + + number = Random.rand(2**31 - 1) * [1, -1].sample + base = 2 + Random.rand(36 - 2) + prefix = 'a' * 100 + sign = number < 0 ? '-' : '' + test_itoax number, base, prefix, "#{sign}#{prefix}#{number.abs.to_s(base)}" + + assert_raise( + KernAux::TooLongNtoaPrefixError, + 'prefix length 101 is too long', + ) do + number = Random.rand(2**31 - 1) * [1, -1].sample + base = 2 + Random.rand(36 - 2) + prefix = 'a' * 101 + KernAux.itoa(number, base, prefix) + end + end + + assert 'KernAux.utoa2' do + test_utoa2 0, '0b0' + test_utoa2 1, '0b1' + test_utoa2 123, '0b1111011' + test_utoa2 2**32 - 1, "0b#{(2**32 - 1).to_s(2)}" + + assert_raise RangeError, 'can\'t convert negative number to uint64_t' do + KernAux.utoa2(-1) + end + end + + assert 'KernAux.itoa2' do + test_itoa2 0, '0b0' + test_itoa2 1, '0b1' + test_itoa2(-1, '-0b1') + test_itoa2 123, '0b1111011' + test_itoa2(-123, '-0b1111011') + test_itoa2 2**31 - 1, "0b#{(2**31 - 1).to_s(2)}" + test_itoa2(-2**31, "-0b#{(2**31).to_s(2)}") + end + + assert 'KernAux.utoa8' do + test_utoa8 0, '0o0' + test_utoa8 0o1, '0o1' + test_utoa8 0o123, '0o123' + test_utoa8 2**32 - 1, "0o#{(2**32 - 1).to_s(8)}" + + assert_raise RangeError, 'can\'t convert negative number to uint64_t' do + KernAux.utoa8(-1) + end + end + + assert 'KernAux.itoa8' do + test_itoa8 0, '0o0' + test_itoa8 0o1, '0o1' + test_itoa8(-0o1, '-0o1') + test_itoa8 0o123, '0o123' + test_itoa8(-0o123, '-0o123') + test_itoa8 2**31 - 1, "0o#{(2**31 - 1).to_s(8)}" + test_itoa8(-2**31, "-0o#{(2**31).to_s(8)}") + end + + assert 'KernAux.utoa10' do + test_utoa10 0, '0' + test_utoa10 1, '1' + test_utoa10 123, '123' + test_utoa10 2**32 - 1, (2**32 - 1).to_s + + assert_raise RangeError, 'can\'t convert negative number to uint64_t' do + KernAux.utoa10(-1) + end + end + + assert 'KernAux.itoa10' do + test_itoa10 0, '0' + test_itoa10 1, '1' + test_itoa10(-1, '-1') + test_itoa10 123, '123' + test_itoa10(-123, '-123') + test_itoa10 2**31 - 1, (2**31 - 1).to_s + test_itoa10(-2**31, (-2**31).to_s) + end + + assert 'KernAux.utoa16' do + test_utoa16 0, '0x0' + test_utoa16 1, '0x1' + test_utoa16 0x123, '0x123' + test_utoa16 2**32 - 1, "0x#{(2**32 - 1).to_s(16)}" + + assert_raise RangeError, 'can\'t convert negative number to uint64_t' do + KernAux.utoa16(-1) + end + end + + assert 'KernAux.itoa16' do + test_itoa16 0, '0x0' + test_itoa16 1, '0x1' + test_itoa16(-1, '-0x1') + test_itoa16 0x123, '0x123' + test_itoa16(-0x123, '-0x123') + test_itoa16 2**31 - 1, "0x#{(2**31 - 1).to_s(16)}" + test_itoa16(-2**31, "-0x#{(2**31).to_s(16)}") end end - -assert 'KernAux.utoa2' do - test_utoa2 0, '0b0' - test_utoa2 1, '0b1' - test_utoa2 123, '0b1111011' - test_utoa2 2**32 - 1, "0b#{(2**32 - 1).to_s(2)}" - - assert_raise RangeError, 'can\'t convert negative number to uint64_t' do - KernAux.utoa2(-1) - end -end - -assert 'KernAux.itoa2' do - test_itoa2 0, '0b0' - test_itoa2 1, '0b1' - test_itoa2(-1, '-0b1') - test_itoa2 123, '0b1111011' - test_itoa2(-123, '-0b1111011') - test_itoa2 2**31 - 1, "0b#{(2**31 - 1).to_s(2)}" - test_itoa2(-2**31, "-0b#{(2**31).to_s(2)}") -end - -assert 'KernAux.utoa8' do - test_utoa8 0, '0o0' - test_utoa8 0o1, '0o1' - test_utoa8 0o123, '0o123' - test_utoa8 2**32 - 1, "0o#{(2**32 - 1).to_s(8)}" - - assert_raise RangeError, 'can\'t convert negative number to uint64_t' do - KernAux.utoa8(-1) - end -end - -assert 'KernAux.itoa8' do - test_itoa8 0, '0o0' - test_itoa8 0o1, '0o1' - test_itoa8(-0o1, '-0o1') - test_itoa8 0o123, '0o123' - test_itoa8(-0o123, '-0o123') - test_itoa8 2**31 - 1, "0o#{(2**31 - 1).to_s(8)}" - test_itoa8(-2**31, "-0o#{(2**31).to_s(8)}") -end - -assert 'KernAux.utoa10' do - test_utoa10 0, '0' - test_utoa10 1, '1' - test_utoa10 123, '123' - test_utoa10 2**32 - 1, (2**32 - 1).to_s - - assert_raise RangeError, 'can\'t convert negative number to uint64_t' do - KernAux.utoa10(-1) - end -end - -assert 'KernAux.itoa10' do - test_itoa10 0, '0' - test_itoa10 1, '1' - test_itoa10(-1, '-1') - test_itoa10 123, '123' - test_itoa10(-123, '-123') - test_itoa10 2**31 - 1, (2**31 - 1).to_s - test_itoa10(-2**31, (-2**31).to_s) -end - -assert 'KernAux.utoa16' do - test_utoa16 0, '0x0' - test_utoa16 1, '0x1' - test_utoa16 0x123, '0x123' - test_utoa16 2**32 - 1, "0x#{(2**32 - 1).to_s(16)}" - - assert_raise RangeError, 'can\'t convert negative number to uint64_t' do - KernAux.utoa16(-1) - end -end - -assert 'KernAux.itoa16' do - test_itoa16 0, '0x0' - test_itoa16 1, '0x1' - test_itoa16(-1, '-0x1') - test_itoa16 0x123, '0x123' - test_itoa16(-0x123, '-0x123') - test_itoa16 2**31 - 1, "0x#{(2**31 - 1).to_s(16)}" - test_itoa16(-2**31, "-0x#{(2**31).to_s(16)}") -end diff --git a/bindings/mruby/test/printf.rb b/bindings/mruby/test/printf.rb index a81d88a..1a745ae 100644 --- a/bindings/mruby/test/printf.rb +++ b/bindings/mruby/test/printf.rb @@ -1,34 +1,36 @@ # TODO: implement this # rubocop:disable Style/BlockComments =begin -assert 'KernAux.sprintf' do - [ - ['', 'using regular tests'], - ['_orig', 'using original tests'], - ].each do |(suffix, description)| - assert description do - printf_yml = - File.expand_path("../../../../common/printf#{suffix}.yml", __FILE__) +if KernAux::Version.supports_printf? + assert 'KernAux.sprintf' do + [ + ['', 'using regular tests'], + ['_orig', 'using original tests'], + ].each do |(suffix, description)| + assert description do + printf_yml = + File.expand_path("../../../../common/printf#{suffix}.yml", __FILE__) - YAML.load(File.read(printf_yml)).each do |test| - expected = test['result'] + YAML.load(File.read(printf_yml)).each do |test| + expected = test['result'] - args = test['args'].map do |arg| - if arg.is_a? String - arg - else - arg.map do |item| - if item.is_a? Array - item[0] - else - item + args = test['args'].map do |arg| + if arg.is_a? String + arg + else + arg.map do |item| + if item.is_a? Array + item[0] + else + item + end end end end - end - assert "transforms #{args.inspect} to #{expected.inspect}" do - assert_equal expected, KernAux.sprintf(*args) + assert "transforms #{args.inspect} to #{expected.inspect}" do + assert_equal expected, KernAux.sprintf(*args) + end end end end diff --git a/bindings/ruby/ext/default/assert.c b/bindings/ruby/ext/default/assert.c index c114230..e5e7fdf 100644 --- a/bindings/ruby/ext/default/assert.c +++ b/bindings/ruby/ext/default/assert.c @@ -1,5 +1,4 @@ -#include -#include +#include "main.h" static void assert_cb(const char *file, int line, const char *msg); diff --git a/bindings/ruby/ext/default/cmdline.c b/bindings/ruby/ext/default/cmdline.c index 25935c2..835250a 100644 --- a/bindings/ruby/ext/default/cmdline.c +++ b/bindings/ruby/ext/default/cmdline.c @@ -1,7 +1,6 @@ -#include -#include +#include "main.h" -#ifdef HAVE_KERNAUX_CMDLINE +#ifdef KERNAUX_VERSION_SUPPORTS_CMDLINE #define ARGV_COUNT_MAX 256 #define BUFFER_SIZE 4096 @@ -92,4 +91,4 @@ VALUE rb_KernAux_cmdline(const VALUE self_rb, VALUE cmdline_rb) return rb_funcall(result_rb, rb_intern_freeze, 0); } -#endif // HAVE_KERNAUX_CMDLINE +#endif // KERNAUX_VERSION_SUPPORTS_CMDLINE diff --git a/bindings/ruby/ext/default/extconf.rb b/bindings/ruby/ext/default/extconf.rb index f40183d..e370b63 100644 --- a/bindings/ruby/ext/default/extconf.rb +++ b/bindings/ruby/ext/default/extconf.rb @@ -11,32 +11,4 @@ unless have_var 'kernaux_assert_cb', 'kernaux.h' raise 'kernaux_assert_cb not found' end -# Package "cmdline" -have_func 'kernaux_cmdline' - -# Package "file" -have_func 'KernAux_File_create' - -# Package "ntoa" -have_func 'kernaux_utoa' -have_func 'kernaux_itoa' -have_func 'kernaux_utoa2' -have_func 'kernaux_itoa2' -have_func 'kernaux_utoa8' -have_func 'kernaux_itoa8' -have_func 'kernaux_utoa10' -have_func 'kernaux_itoa10' -have_func 'kernaux_utoa16' -have_func 'kernaux_itoa16' - -# Package "printf" -have_func 'kernaux_snprintf' - -# Package "printf-fmt" -# TODO: do something if not found? -have_func 'KernAux_PrintfFmt_Spec_create' -have_func 'KernAux_PrintfFmt_Spec_parse' -have_func 'KernAux_PrintfFmt_Spec_set_width' -have_func 'KernAux_PrintfFmt_Spec_set_precision' - raise 'can\'t create Makefile' unless create_makefile 'kernaux/default' diff --git a/bindings/ruby/ext/default/file.c b/bindings/ruby/ext/default/file.c index 221a93d..4c28e90 100644 --- a/bindings/ruby/ext/default/file.c +++ b/bindings/ruby/ext/default/file.c @@ -1,7 +1,6 @@ -#include -#include +#include "main.h" -#ifdef HAVE_KERNAUX_FILE_CREATE +#ifdef KERNAUX_VERSION_SUPPORTS_FILE static VALUE rb_KernAux_File_initialize(VALUE self, VALUE out); @@ -27,4 +26,4 @@ VALUE rb_KernAux_File_initialize(VALUE self, VALUE out) return Qnil; } -#endif // HAVE_KERNAUX_FILE_CREATE +#endif // KERNAUX_VERSION_SUPPORTS_FILE diff --git a/bindings/ruby/ext/default/main.c b/bindings/ruby/ext/default/main.c index 4c317a4..c2b3f27 100644 --- a/bindings/ruby/ext/default/main.c +++ b/bindings/ruby/ext/default/main.c @@ -1,34 +1,20 @@ -#include -#include -#include -#include - -#include -#include - -void init_assert(); -void init_ntoa(); -#ifdef HAVE_KERNAUX_CMDLINE -void init_cmdline(); -#endif // HAVE_KERNAUX_CMDLINE -#ifdef HAVE_KERNAUX_FILE_CREATE -void init_file(); -#endif // HAVE_KERNAUX_FILE_CREATE -#ifdef HAVE_KERNAUX_SNPRINTF -void init_printf(); -#endif // HAVE_KERNAUX_SNPRINTF +#include "main.h" void Init_default() { + init_version(); init_assert(); - init_ntoa(); -#ifdef HAVE_KERNAUX_CMDLINE + +#ifdef KERNAUX_VERSION_SUPPORTS_CMDLINE init_cmdline(); -#endif // HAVE_KERNAUX_CMDLINE -#ifdef HAVE_KERNAUX_FILE_CREATE +#endif // KERNAUX_VERSION_SUPPORTS_CMDLINE +#ifdef KERNAUX_VERSION_SUPPORTS_FILE init_file(); -#endif // HAVE_KERNAUX_FILE_CREATE -#ifdef HAVE_KERNAUX_SNPRINTF +#endif // KERNAUX_VERSION_SUPPORTS_FILE +#ifdef KERNAUX_VERSION_SUPPORTS_NTOA + init_ntoa(); +#endif // KERNAUX_VERSION_SUPPORTS_NTOA +#ifdef KERNAUX_VERSION_SUPPORTS_PRINTF init_printf(); -#endif // HAVE_KERNAUX_SNPRINTF +#endif // KERNAUX_VERSION_SUPPORTS_PRINTF } diff --git a/bindings/ruby/ext/default/main.h b/bindings/ruby/ext/default/main.h new file mode 100644 index 0000000..531e09d --- /dev/null +++ b/bindings/ruby/ext/default/main.h @@ -0,0 +1,23 @@ +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#include +#include + +void init_version(); +void init_assert(); + +#ifdef KERNAUX_VERSION_SUPPORTS_CMDLINE +void init_cmdline(); +#endif // KERNAUX_VERSION_SUPPORTS_CMDLINE +#ifdef KERNAUX_VERSION_SUPPORTS_FILE +void init_file(); +#endif // KERNAUX_VERSION_SUPPORTS_FILE +#ifdef KERNAUX_VERSION_SUPPORTS_NTOA +void init_ntoa(); +#endif // KERNAUX_VERSION_SUPPORTS_NTOA +#ifdef KERNAUX_VERSION_SUPPORTS_PRINTF +void init_printf(); +#endif // KERNAUX_VERSION_SUPPORTS_PRINTF + +#endif diff --git a/bindings/ruby/ext/default/ntoa.c b/bindings/ruby/ext/default/ntoa.c index b9ba94d..a671fa5 100644 --- a/bindings/ruby/ext/default/ntoa.c +++ b/bindings/ruby/ext/default/ntoa.c @@ -1,36 +1,17 @@ -#include -#include +#include "main.h" + +#ifdef KERNAUX_VERSION_SUPPORTS_NTOA -#ifdef HAVE_KERNAUX_UTOA static VALUE rb_KernAux_utoa(int argc, const VALUE *argv, VALUE self); -#endif -#ifdef HAVE_KERNAUX_ITOA static VALUE rb_KernAux_itoa(int argc, const VALUE *argv, VALUE self); -#endif -#ifdef HAVE_KERNAUX_UTOA2 static VALUE rb_KernAux_utoa2(VALUE self, VALUE number); -#endif -#ifdef HAVE_KERNAUX_ITOA2 static VALUE rb_KernAux_itoa2(VALUE self, VALUE number); -#endif -#ifdef HAVE_KERNAUX_UTOA8 static VALUE rb_KernAux_utoa8(VALUE self, VALUE number); -#endif -#ifdef HAVE_KERNAUX_ITOA8 static VALUE rb_KernAux_itoa8(VALUE self, VALUE number); -#endif -#ifdef HAVE_KERNAUX_UTOA10 static VALUE rb_KernAux_utoa10(VALUE self, VALUE number); -#endif -#ifdef HAVE_KERNAUX_ITOA10 static VALUE rb_KernAux_itoa10(VALUE self, VALUE number); -#endif -#ifdef HAVE_KERNAUX_UTOA16 static VALUE rb_KernAux_utoa16(VALUE self, VALUE number); -#endif -#ifdef HAVE_KERNAUX_ITOA16 static VALUE rb_KernAux_itoa16(VALUE self, VALUE number); -#endif static ID rb_intern_LESS = Qnil; static ID rb_intern_b = Qnil; @@ -50,9 +31,7 @@ static VALUE rb_KernAux_Error = Qnil; static VALUE rb_KernAux_InvalidNtoaBaseError = Qnil; static VALUE rb_KernAux_TooLongNtoaPrefixError = Qnil; -#if defined(HAVE_KERNAUX_UTOA) || defined(HAVE_KERNAUX_ITOA) static int convert_base(VALUE base); -#endif void init_ntoa() { @@ -79,39 +58,18 @@ void init_ntoa() rb_define_class_under(rb_KernAux, "TooLongNtoaPrefixError", rb_KernAux_Error)); -#ifdef HAVE_KERNAUX_UTOA rb_define_singleton_method(rb_KernAux, "utoa", rb_KernAux_utoa, -1); -#endif -#ifdef HAVE_KERNAUX_ITOA rb_define_singleton_method(rb_KernAux, "itoa", rb_KernAux_itoa, -1); -#endif -#ifdef HAVE_KERNAUX_UTOA2 rb_define_singleton_method(rb_KernAux, "utoa2", rb_KernAux_utoa2, 1); -#endif -#ifdef HAVE_KERNAUX_ITOA2 rb_define_singleton_method(rb_KernAux, "itoa2", rb_KernAux_itoa2, 1); -#endif -#ifdef HAVE_KERNAUX_UTOA8 rb_define_singleton_method(rb_KernAux, "utoa8", rb_KernAux_utoa8, 1); -#endif -#ifdef HAVE_KERNAUX_ITOA8 rb_define_singleton_method(rb_KernAux, "itoa8", rb_KernAux_itoa8, 1); -#endif -#ifdef HAVE_KERNAUX_UTOA10 rb_define_singleton_method(rb_KernAux, "utoa10", rb_KernAux_utoa10, 1); -#endif -#ifdef HAVE_KERNAUX_ITOA10 rb_define_singleton_method(rb_KernAux, "itoa10", rb_KernAux_itoa10, 1); -#endif -#ifdef HAVE_KERNAUX_UTOA16 rb_define_singleton_method(rb_KernAux, "utoa16", rb_KernAux_utoa16, 1); -#endif -#ifdef HAVE_KERNAUX_ITOA16 rb_define_singleton_method(rb_KernAux, "itoa16", rb_KernAux_itoa16, 1); -#endif } -#ifdef HAVE_KERNAUX_UTOA VALUE rb_KernAux_utoa(const int argc, const VALUE *argv, const VALUE self) { if (argc < 2 || argc > 3) { @@ -150,9 +108,7 @@ VALUE rb_KernAux_utoa(const int argc, const VALUE *argv, const VALUE self) kernaux_utoa(NUM2ULL(number_rb), buffer, convert_base(base_rb), prefix); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#ifdef HAVE_KERNAUX_ITOA VALUE rb_KernAux_itoa(const int argc, const VALUE *argv, const VALUE self) { if (argc < 2 || argc > 3) { @@ -188,9 +144,7 @@ VALUE rb_KernAux_itoa(const int argc, const VALUE *argv, const VALUE self) kernaux_itoa(NUM2LL(number_rb), buffer, convert_base(base_rb), prefix); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#ifdef HAVE_KERNAUX_UTOA2 VALUE rb_KernAux_utoa2( const VALUE self_rb __attribute__((unused)), const VALUE number_rb @@ -203,9 +157,7 @@ VALUE rb_KernAux_utoa2( kernaux_utoa2(NUM2ULL(number_rb), buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#ifdef HAVE_KERNAUX_ITOA2 VALUE rb_KernAux_itoa2( const VALUE self_rb __attribute__((unused)), const VALUE number_rb @@ -215,9 +167,7 @@ VALUE rb_KernAux_itoa2( kernaux_itoa2(NUM2LL(number_rb), buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#ifdef HAVE_KERNAUX_UTOA8 VALUE rb_KernAux_utoa8( const VALUE self_rb __attribute__((unused)), const VALUE number_rb @@ -230,9 +180,7 @@ VALUE rb_KernAux_utoa8( kernaux_utoa8(NUM2ULL(number_rb), buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#ifdef HAVE_KERNAUX_ITOA8 VALUE rb_KernAux_itoa8( const VALUE self_rb __attribute__((unused)), const VALUE number_rb @@ -242,9 +190,7 @@ VALUE rb_KernAux_itoa8( kernaux_itoa8(NUM2LL(number_rb), buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#ifdef HAVE_KERNAUX_UTOA10 VALUE rb_KernAux_utoa10( const VALUE self_rb __attribute__((unused)), const VALUE number_rb @@ -257,9 +203,7 @@ VALUE rb_KernAux_utoa10( kernaux_utoa10(NUM2ULL(number_rb), buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#ifdef HAVE_KERNAUX_ITOA10 VALUE rb_KernAux_itoa10( const VALUE self_rb __attribute__((unused)), const VALUE number_rb @@ -269,9 +213,7 @@ VALUE rb_KernAux_itoa10( kernaux_itoa10(NUM2LL(number_rb), buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#ifdef HAVE_KERNAUX_UTOA16 VALUE rb_KernAux_utoa16( const VALUE self_rb __attribute__((unused)), const VALUE number_rb @@ -284,9 +226,7 @@ VALUE rb_KernAux_utoa16( kernaux_utoa16(NUM2ULL(number_rb), buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#ifdef HAVE_KERNAUX_ITOA16 VALUE rb_KernAux_itoa16( const VALUE self_rb __attribute__((unused)), const VALUE number_rb @@ -296,9 +236,7 @@ VALUE rb_KernAux_itoa16( kernaux_itoa16(NUM2LL(number_rb), buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } -#endif -#if defined(HAVE_KERNAUX_UTOA) || defined(HAVE_KERNAUX_ITOA) int convert_base(const VALUE base_rb) { if (TYPE(base_rb) == T_SYMBOL) { @@ -320,4 +258,5 @@ int convert_base(const VALUE base_rb) return NUM2INT(base_rb); } } -#endif + +#endif // KERNAUX_VERSION_SUPPORTS_NTOA diff --git a/bindings/ruby/ext/default/printf.c b/bindings/ruby/ext/default/printf.c index 1ca4f95..70bd064 100644 --- a/bindings/ruby/ext/default/printf.c +++ b/bindings/ruby/ext/default/printf.c @@ -1,9 +1,8 @@ -#include -#include +#include "main.h" #include "dynarg.h" -#ifdef HAVE_KERNAUX_SNPRINTF +#ifdef KERNAUX_VERSION_SUPPORTS_PRINTF static VALUE rb_KernAux_snprintf1(int argc, const VALUE *argv, VALUE self); @@ -116,4 +115,4 @@ VALUE rb_KernAux_snprintf1( return rb_funcall(result_rb, rb_intern_freeze, 0); } -#endif // HAVE_KERNAUX_SNPRINTF +#endif // KERNAUX_VERSION_SUPPORTS_PRINTF diff --git a/bindings/ruby/ext/default/version.c b/bindings/ruby/ext/default/version.c new file mode 100644 index 0000000..c986030 --- /dev/null +++ b/bindings/ruby/ext/default/version.c @@ -0,0 +1,61 @@ +#include "main.h" + +static VALUE rb_KernAux_Version_supports_cmdlineQN(VALUE self); +static VALUE rb_KernAux_Version_supports_fileQN(VALUE self); +static VALUE rb_KernAux_Version_supports_ntoaQN(VALUE self); +static VALUE rb_KernAux_Version_supports_printfQN(VALUE self); + +static VALUE rb_KernAux = Qnil; +static VALUE rb_KernAux_Version = Qnil; + +void init_version() +{ + rb_gc_register_mark_object(rb_KernAux = rb_define_module("KernAux")); + rb_gc_register_mark_object(rb_KernAux_Version = + rb_define_module_under(rb_KernAux, "Version")); + + rb_define_singleton_method(rb_KernAux_Version, "supports_cmdline?", + rb_KernAux_Version_supports_cmdlineQN, 0); + rb_define_singleton_method(rb_KernAux_Version, "supports_file?", + rb_KernAux_Version_supports_fileQN, 0); + rb_define_singleton_method(rb_KernAux_Version, "supports_ntoa?", + rb_KernAux_Version_supports_ntoaQN, 0); + rb_define_singleton_method(rb_KernAux_Version, "supports_printf?", + rb_KernAux_Version_supports_printfQN, 0); +} + +VALUE rb_KernAux_Version_supports_cmdlineQN(VALUE self) +{ +#ifdef KERNAUX_VERSION_SUPPORTS_CMDLINE + return Qtrue; +#else + return Qfalse; +#endif +} + +VALUE rb_KernAux_Version_supports_fileQN(VALUE self) +{ +#ifdef KERNAUX_VERSION_SUPPORTS_FILE + return Qtrue; +#else + return Qfalse; +#endif +} + +VALUE rb_KernAux_Version_supports_ntoaQN(VALUE self) +{ +#ifdef KERNAUX_VERSION_SUPPORTS_NTOA + return Qtrue; +#else + return Qfalse; +#endif +} + +VALUE rb_KernAux_Version_supports_printfQN(VALUE self) +{ +#ifdef KERNAUX_VERSION_SUPPORTS_PRINTF + return Qtrue; +#else + return Qfalse; +#endif +} diff --git a/bindings/ruby/lib/kernaux/version.rb b/bindings/ruby/lib/kernaux/version.rb index 186af76..7619db7 100644 --- a/bindings/ruby/lib/kernaux/version.rb +++ b/bindings/ruby/lib/kernaux/version.rb @@ -9,56 +9,5 @@ module KernAux # supported by the library. # module Version - def self.supports_cmdline? - KernAux.singleton_class.method_defined? :cmdline - end - - def self.supports_file? - defined? KernAux::File - end - - def self.supports_itoa? - KernAux.singleton_class.method_defined? :itoa - end - - def self.supports_itoa2? - KernAux.singleton_class.method_defined? :itoa2 - end - - def self.supports_itoa8? - KernAux.singleton_class.method_defined? :itoa8 - end - - def self.supports_itoa10? - KernAux.singleton_class.method_defined? :itoa10 - end - - def self.supports_itoa16? - KernAux.singleton_class.method_defined? :itoa16 - end - - def self.supports_printf? - KernAux.singleton_class.method_defined? :snprintf1 - end - - def self.supports_utoa? - KernAux.singleton_class.method_defined? :utoa - end - - def self.supports_utoa2? - KernAux.singleton_class.method_defined? :utoa2 - end - - def self.supports_utoa8? - KernAux.singleton_class.method_defined? :utoa8 - end - - def self.supports_utoa10? - KernAux.singleton_class.method_defined? :utoa10 - end - - def self.supports_utoa16? - KernAux.singleton_class.method_defined? :utoa16 - end end end diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb index e82a595..e46a3e1 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_itoa10? and RSpec.describe KernAux, '.itoa10' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.itoa10' do subject(:itoa10) { described_class.itoa10 number } let(:number) { rand((-2**63)..(2**63 - 1)) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb index 08a5e21..e03c0ba 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_itoa16? and RSpec.describe KernAux, '.itoa16' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.itoa16' do subject(:itoa16) { described_class.itoa16 number } let(:number) { rand((-2**63)..(2**63 - 1)) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb index bcec00d..33d4d58 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_itoa2? and RSpec.describe KernAux, '.itoa2' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.itoa2' do subject(:itoa2) { described_class.itoa2 number } let(:number) { rand((-2**63)..(2**63 - 1)) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb index 4da180a..4d99391 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_itoa8? and RSpec.describe KernAux, '.itoa8' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.itoa8' do subject(:itoa8) { described_class.itoa8 number } let(:number) { rand((-2**63)..(2**63 - 1)) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa_spec.rb index a594f6c..49a675f 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_itoa? and RSpec.describe KernAux, '.itoa' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.itoa' do subject(:itoa) { described_class.itoa number, base, prefix } let(:number) { rand((-2**63)..(2**63 - 1)) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb index 635dae1..20f07a9 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_utoa10? and RSpec.describe KernAux, '.utoa10' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.utoa10' do subject(:utoa10) { described_class.utoa10 number } let(:number) { rand 0..(2**64 - 1) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb index 264b1d7..73f3e82 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_utoa16? and RSpec.describe KernAux, '.utoa16' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.utoa16' do subject(:utoa16) { described_class.utoa16 number } let(:number) { rand 0..(2**64 - 1) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb index ee727f2..ccd2b65 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_utoa2? and RSpec.describe KernAux, '.utoa2' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.utoa2' do subject(:utoa2) { described_class.utoa2 number } let(:number) { rand 0..(2**64 - 1) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb index 957b88d..967246f 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_utoa8? and RSpec.describe KernAux, '.utoa8' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.utoa8' do subject(:utoa8) { described_class.utoa8 number } let(:number) { rand 0..(2**64 - 1) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa_spec.rb index 5daf6e2..b305bbc 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -KernAux::Version.supports_utoa? and RSpec.describe KernAux, '.utoa' do +KernAux::Version.supports_ntoa? and RSpec.describe KernAux, '.utoa' do subject(:utoa) { described_class.utoa number, base, prefix } let(:number) { rand 0..(2**64 - 1) } diff --git a/bindings/rust/kernaux-sys/Cargo.toml b/bindings/rust/kernaux-sys/Cargo.toml index b47aa26..287d09a 100644 --- a/bindings/rust/kernaux-sys/Cargo.toml +++ b/bindings/rust/kernaux-sys/Cargo.toml @@ -12,6 +12,11 @@ keywords = ["ffi", "no_std", "no-std", "embedded", "bindings"] categories = ["embedded", "external-ffi-bindings", "no-std", "parsing"] publish = true +[features] +default = ["cmdline", "ntoa"] +cmdline = [] +ntoa = [] + [dependencies.libc] version = "0.2.113" default-features = false diff --git a/bindings/rust/kernaux-sys/src/lib.rs b/bindings/rust/kernaux-sys/src/lib.rs index 527cabb..b8c022e 100644 --- a/bindings/rust/kernaux-sys/src/lib.rs +++ b/bindings/rust/kernaux-sys/src/lib.rs @@ -4,9 +4,16 @@ extern crate std; pub mod assert; +pub mod version; + +#[cfg(feature = "cmdline")] pub mod cmdline; +#[cfg(feature = "ntoa")] pub mod ntoa; pub use assert::*; + +#[cfg(feature = "cmdline")] pub use cmdline::cmdline; +#[cfg(feature = "ntoa")] pub use ntoa::{MAX_PREFIX_LEN as NTOA_MAX_PREFIX_LEN, *}; diff --git a/bindings/rust/kernaux-sys/src/version.rs b/bindings/rust/kernaux-sys/src/version.rs new file mode 100644 index 0000000..83ade00 --- /dev/null +++ b/bindings/rust/kernaux-sys/src/version.rs @@ -0,0 +1,7 @@ +pub fn supports_cmdline() -> bool { + cfg!(feature = "cmdline") +} + +pub fn supports_ntoa() -> bool { + cfg!(feature = "ntoa") +} diff --git a/bindings/rust/kernaux/Cargo.toml b/bindings/rust/kernaux/Cargo.toml index 172e668..38e333d 100644 --- a/bindings/rust/kernaux/Cargo.toml +++ b/bindings/rust/kernaux/Cargo.toml @@ -12,11 +12,17 @@ keywords = ["ffi", "embedded", "bindings"] categories = ["api-bindings", "embedded", "parsing"] publish = true +[features] +default = ["cmdline", "ntoa"] +cmdline = ["kernaux-sys/cmdline"] +ntoa = ["kernaux-sys/ntoa"] + [dependencies] ctor = "0.1.22" [dependencies.kernaux-sys] version = "0.3.0" +default-features = false path = "../kernaux-sys" [dependencies.libc] diff --git a/bindings/rust/kernaux/src/lib.rs b/bindings/rust/kernaux/src/lib.rs index c2e69fe..7ad1f67 100644 --- a/bindings/rust/kernaux/src/lib.rs +++ b/bindings/rust/kernaux/src/lib.rs @@ -1,16 +1,22 @@ pub mod assert; +pub mod version; + +#[cfg(feature = "ntoa")] pub mod ntoa; +#[cfg(feature = "ntoa")] pub use ntoa::{ itoa, itoa10, itoa16, itoa2, itoa8, utoa, utoa10, utoa16, utoa2, utoa8, Config as NtoaConfig, Error as NtoaError, Result as NtoaResult, }; #[cfg(test)] +#[cfg(feature = "ntoa")] mod tests { use super::*; #[test] + #[cfg(feature = "ntoa")] fn test_ntoa() { assert_eq!(NtoaConfig::try_from('x').unwrap().base(), 16); assert_eq!(NtoaConfig::try_from('x').unwrap().uppercase(), false); diff --git a/bindings/rust/kernaux/src/version.rs b/bindings/rust/kernaux/src/version.rs new file mode 120000 index 0000000..a9ed635 --- /dev/null +++ b/bindings/rust/kernaux/src/version.rs @@ -0,0 +1 @@ +../../kernaux-sys/src/version.rs \ No newline at end of file diff --git a/configure.ac b/configure.ac index f22eb64..7ebacbf 100644 --- a/configure.ac +++ b/configure.ac @@ -32,6 +32,7 @@ AC_CONFIG_FILES([ include/kernaux.h include/kernaux/console.h include/kernaux/printf.h + include/kernaux/version.h tests/Makefile ]) diff --git a/include/Makefile.am b/include/Makefile.am index fa33ef5..dd404f2 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -3,7 +3,8 @@ nobase_include_HEADERS = \ kernaux/arch/i386.h \ kernaux/arch/riscv64.h \ kernaux/arch/x86_64.h \ - kernaux/assert.h + kernaux/assert.h \ + kernaux/version.h if ASM_I386 nobase_include_HEADERS += kernaux/asm/i386.h diff --git a/include/kernaux.h.in b/include/kernaux.h.in index 97135e8..e346c5d 100644 --- a/include/kernaux.h.in +++ b/include/kernaux.h.in @@ -3,6 +3,8 @@ contain architecture-specific assembly functions. */ +#include + #include @comment_line_cmdline@#include diff --git a/include/kernaux/version.h.in b/include/kernaux/version.h.in new file mode 100644 index 0000000..3b74aa8 --- /dev/null +++ b/include/kernaux/version.h.in @@ -0,0 +1,17 @@ +#ifndef KERNAUX_INCLUDED_VERSION +#define KERNAUX_INCLUDED_VERSION + +@comment_line_cmdline@#define KERNAUX_VERSION_SUPPORTS_CMDLINE +@comment_line_console@#define KERNAUX_VERSION_SUPPORTS_CONSOLE +@comment_line_elf@#define KERNAUX_VERSION_SUPPORTS_ELF +@comment_line_file@#define KERNAUX_VERSION_SUPPORTS_FILE +@comment_line_framebuffer@#define KERNAUX_VERSION_SUPPORTS_FRAMEBUFFER +@comment_line_mbr@#define KERNAUX_VERSION_SUPPORTS_MBR +@comment_line_multiboot2@#define KERNAUX_VERSION_SUPPORTS_MULTIBOOT2 +@comment_line_ntoa@#define KERNAUX_VERSION_SUPPORTS_NTOA +@comment_line_pfa@#define KERNAUX_VERSION_SUPPORTS_PFA +@comment_line_printf@#define KERNAUX_VERSION_SUPPORTS_PRINTF +@comment_line_printf_fmt@#define KERNAUX_VERSION_SUPPORTS_PRINTF_FMT +@comment_line_units@#define KERNAUX_VERSION_SUPPORTS_UNITS + +#endif