mirror of
https://github.com/tailix/libclayer.git
synced 2024-11-13 11:04:17 -05:00
Remove bindings
This commit is contained in:
parent
772db061c5
commit
3102a9b57b
90 changed files with 0 additions and 5925 deletions
85
.cirrus.yml
85
.cirrus.yml
|
@ -17,88 +17,3 @@ main_freebsd_task:
|
|||
- sudo make install
|
||||
main_test_script:
|
||||
- make check
|
||||
|
||||
mruby_freebsd_task:
|
||||
name: mruby (FreeBSD)
|
||||
only_if: $CIRRUS_BRANCH == 'master' || $CIRRUS_BASE_BRANCH == 'master'
|
||||
env:
|
||||
CPATH: '/usr/local/include'
|
||||
LIBRARY_PATH: '/usr/local/lib'
|
||||
MRUBY_YAML_USE_SYSTEM_LIBRARY: x
|
||||
dependencies_script:
|
||||
- pkg install --yes autoconf automake git libtool rubygem-rake wget
|
||||
dependencies_mruby_script:
|
||||
- wget https://github.com/mruby/mruby/archive/3.1.0.zip -O mruby-3.1.0.zip
|
||||
- unzip mruby-3.1.0.zip
|
||||
main_build_script:
|
||||
- ./autogen.sh
|
||||
- ./configure CFLAGS='-O3'
|
||||
- make
|
||||
- sudo make install
|
||||
mruby_test_script:
|
||||
- cd mruby-3.1.0
|
||||
- MRUBY_CONFIG=../bindings/mruby/build_config.rb rake test
|
||||
|
||||
ruby_freebsd_task:
|
||||
name: Ruby (FreeBSD)
|
||||
only_if: $CIRRUS_BRANCH == 'master' || $CIRRUS_BASE_BRANCH == 'master'
|
||||
env:
|
||||
CPATH: '/usr/local/include'
|
||||
LIBRARY_PATH: '/usr/local/lib'
|
||||
dependencies_script:
|
||||
- pkg install --yes autoconf automake cppcheck git libtool wget
|
||||
dependencies_ruby_script:
|
||||
- wget https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.3.tar.gz
|
||||
- tar -xzf ruby-3.0.3.tar.gz
|
||||
- cd ruby-3.0.3
|
||||
- ./configure --disable-install-doc
|
||||
- make
|
||||
- sudo make install
|
||||
main_build_script:
|
||||
- ./autogen.sh
|
||||
- ./configure CFLAGS='-O3'
|
||||
- make
|
||||
- sudo make install
|
||||
ruby_build_script:
|
||||
- cd bindings/ruby
|
||||
- ./bin/setup
|
||||
- bundle exec rake compile
|
||||
ruby_test_script:
|
||||
- cd bindings/ruby
|
||||
- bundle exec rake
|
||||
|
||||
rust_freebsd_task:
|
||||
name: Rust (FreeBSD)
|
||||
only_if: $CIRRUS_BRANCH == 'master' || $CIRRUS_BASE_BRANCH == 'master'
|
||||
env:
|
||||
RUSTFLAGS: '-L /usr/local/lib'
|
||||
dependencies_script:
|
||||
- pkg install --yes autoconf automake libtool
|
||||
dependencies_rust_script:
|
||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
main_build_script:
|
||||
- ./autogen.sh
|
||||
- ./configure CFLAGS='-O3'
|
||||
- make
|
||||
- sudo make install
|
||||
rust_test_script:
|
||||
- cd bindings/rust
|
||||
- ~/.cargo/bin/cargo test
|
||||
- ~/.cargo/bin/cargo clippy
|
||||
- ~/.cargo/bin/cargo fmt --check
|
||||
|
||||
main_freebsd_port_task:
|
||||
name: Main (FreeBSD port)
|
||||
only_if: "changesInclude('.cirrus.yml', 'pkgs/freebsd/**')"
|
||||
dependencies_script:
|
||||
- pkg install --yes portfmt portlint porttools
|
||||
port_prepare_script:
|
||||
- echo 'DEVELOPER=yes' >> /etc/make.conf
|
||||
- rm -rf /usr/ports/devel/libkernaux/
|
||||
- cp -r $CIRRUS_WORKING_DIR/pkgs/freebsd/devel/libkernaux /usr/ports/devel/
|
||||
port_test_script:
|
||||
- cd /usr/ports/devel/libkernaux/
|
||||
- portfmt -D Makefile
|
||||
- portclippy --strict Makefile
|
||||
- portlint -A
|
||||
- port test .
|
||||
|
|
48
.github/workflows/mruby.yml
vendored
48
.github/workflows/mruby.yml
vendored
|
@ -1,48 +0,0 @@
|
|||
name: mruby
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MRUBY_YAML_USE_SYSTEM_LIBRARY: x
|
||||
strategy:
|
||||
matrix:
|
||||
assert: ['--disable-assert', '--enable-assert']
|
||||
packages:
|
||||
- configure: ''
|
||||
- configure: '--without-all'
|
||||
- configure: '--without-all --with-ntoa'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 3.0
|
||||
- name: dependencies
|
||||
run: sudo apt-get --yes install cppcheck libyaml-dev rake
|
||||
- name: autogen
|
||||
run: ./autogen.sh
|
||||
- name: configure
|
||||
run: ./configure ${{matrix.assert}} ${{matrix.packages.configure}} CFLAGS='-O3'
|
||||
- name: make
|
||||
run: make
|
||||
- name: install
|
||||
run: sudo make install
|
||||
- name: ldconfig
|
||||
run: sudo ldconfig
|
||||
- working-directory: vendor/mruby
|
||||
name: test
|
||||
run: MRUBY_CONFIG=../../bindings/mruby/build_config.rb rake test
|
||||
- working-directory: bindings/mruby
|
||||
name: setup
|
||||
run: ./bin/setup
|
||||
- working-directory: bindings/mruby
|
||||
name: lint
|
||||
run: rake
|
46
.github/workflows/ruby.yml
vendored
46
.github/workflows/ruby.yml
vendored
|
@ -1,46 +0,0 @@
|
|||
name: Ruby
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
assert: ['--disable-assert', '--enable-assert']
|
||||
packages:
|
||||
- configure: ''
|
||||
- configure: '--without-all'
|
||||
skip_coverage: 'x'
|
||||
- configure: '--without-all --with-ntoa'
|
||||
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 cppcheck
|
||||
- name: autogen
|
||||
run: ./autogen.sh
|
||||
- name: configure
|
||||
run: ./configure ${{matrix.assert}} ${{matrix.packages.configure}} CFLAGS='-O3'
|
||||
- name: make
|
||||
run: make
|
||||
- name: install
|
||||
run: sudo make install
|
||||
- name: ldconfig
|
||||
run: sudo ldconfig
|
||||
- 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: SKIP_COVERAGE='${{matrix.packages.skip_coverage}}' rake
|
45
.github/workflows/rust.yml
vendored
45
.github/workflows/rust.yml
vendored
|
@ -1,45 +0,0 @@
|
|||
name: Rust
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
assert: ['--disable-assert', '--enable-assert']
|
||||
packages:
|
||||
- configure: ''
|
||||
- configure: '--without-all'
|
||||
cargo: '--no-default-features'
|
||||
- configure: '--without-all --with-ntoa'
|
||||
cargo: '--no-default-features --features ntoa'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
components: rustfmt, clippy
|
||||
- name: autogen
|
||||
run: ./autogen.sh
|
||||
- name: configure
|
||||
run: ./configure ${{matrix.assert}} ${{matrix.packages.configure}} CFLAGS='-O3'
|
||||
- name: make
|
||||
run: make
|
||||
- name: install
|
||||
run: sudo make install
|
||||
- name: ldconfig
|
||||
run: sudo ldconfig
|
||||
- working-directory: bindings/rust
|
||||
name: test
|
||||
run: cargo test ${{matrix.packages.cargo}}
|
||||
- working-directory: bindings/rust
|
||||
name: clippy
|
||||
run: cargo clippy
|
||||
- working-directory: bindings/rust
|
||||
name: fmt
|
||||
run: cargo fmt --check
|
|
@ -162,33 +162,3 @@ if (foo) {
|
|||
if (foo)
|
||||
return bar;
|
||||
```
|
||||
|
||||
|
||||
|
||||
Python
|
||||
------
|
||||
|
||||
Nothing here yet.
|
||||
|
||||
|
||||
|
||||
Ruby
|
||||
----
|
||||
|
||||
* Freeze objects if you don't plan to modify them
|
||||
|
||||
### Matz's Ruby interpreter
|
||||
|
||||
Use **RuboCop**. See [bindings/ruby/.rubocop.yml](/bindings/ruby/.rubocop.yml)
|
||||
|
||||
### mruby
|
||||
|
||||
Use **RuboCop**. See [bindings/mruby/.rubocop.yml](/bindings/mruby/.rubocop.yml)
|
||||
|
||||
|
||||
|
||||
Rust
|
||||
----
|
||||
|
||||
Use **rustfmt** and **Clippy**.
|
||||
See [bindings/rust/rustfmt.toml](/bindings/rust/rustfmt.toml)
|
||||
|
|
7
bindings/mruby/.gitignore
vendored
7
bindings/mruby/.gitignore
vendored
|
@ -1,7 +0,0 @@
|
|||
/build_config.rb.lock
|
||||
|
||||
# For a library or gem, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in.
|
||||
/Gemfile.lock
|
||||
/.ruby-version
|
||||
/.ruby-gemset
|
|
@ -1,81 +0,0 @@
|
|||
require:
|
||||
- rubocop-performance
|
||||
- rubocop-rake
|
||||
|
||||
AllCops:
|
||||
# TODO: Explore which exact syntax version mruby is compatible with
|
||||
TargetRubyVersion: 2.7
|
||||
DisplayCopNames: true
|
||||
NewCops: enable
|
||||
|
||||
Layout/AccessModifierIndentation:
|
||||
EnforcedStyle: outdent
|
||||
|
||||
Layout/LineLength:
|
||||
Max: 80
|
||||
|
||||
Lint/AmbiguousOperatorPrecedence:
|
||||
Enabled: false
|
||||
|
||||
Lint/ReturnInVoidContext:
|
||||
Enabled: false
|
||||
|
||||
Metrics/BlockLength:
|
||||
Exclude:
|
||||
- 'Rakefile'
|
||||
- 'test/**/*.rb'
|
||||
|
||||
Metrics/BlockNesting:
|
||||
Exclude:
|
||||
- 'test/sprintf.rb'
|
||||
|
||||
Performance/CollectionLiteralInLoop:
|
||||
Exclude:
|
||||
- 'test/**/*.rb'
|
||||
|
||||
Security/Eval:
|
||||
Exclude:
|
||||
- 'test/**/*.rb'
|
||||
|
||||
Security/YAMLLoad:
|
||||
Exclude:
|
||||
- 'test/**/*.rb'
|
||||
|
||||
Style/AndOr:
|
||||
EnforcedStyle: conditionals
|
||||
|
||||
Style/Documentation:
|
||||
Exclude:
|
||||
- 'Rakefile'
|
||||
|
||||
Style/DoubleNegation:
|
||||
Enabled: false
|
||||
|
||||
Style/ExpandPathArguments:
|
||||
# __dir__ is not available in mruby
|
||||
Enabled: false
|
||||
|
||||
Style/FrozenStringLiteralComment:
|
||||
Enabled: false
|
||||
|
||||
Style/HashAsLastArrayItem:
|
||||
Enabled: false
|
||||
|
||||
Style/NumericPredicate:
|
||||
# Numeric#negative? is not available in mruby
|
||||
Enabled: false
|
||||
|
||||
Style/PerlBackrefs:
|
||||
Enabled: false
|
||||
|
||||
Style/TrailingCommaInArguments:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/TrailingCommaInArrayLiteral:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/TrailingCommaInHashLiteral:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/VariableInterpolation:
|
||||
Enabled: false
|
|
@ -1,9 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'bundler', '~> 2.2'
|
||||
gem 'rake', '~> 13.0'
|
||||
gem 'rubocop', '~> 1.25'
|
||||
gem 'rubocop-performance', '~> 1.13'
|
||||
gem 'rubocop-rake', '~> 0.6'
|
|
@ -1,26 +0,0 @@
|
|||
::KernAux
|
||||
=========
|
||||
|
||||
[![Build status](https://github.com/tailix/libkernaux/actions/workflows/mruby.yml/badge.svg)](https://github.com/tailix/libkernaux/actions/workflows/mruby.yml)
|
||||
[![Build status (FreeBSD)](https://api.cirrus-ci.com/github/tailix/libkernaux.svg?task=mruby%20(FreeBSD))](https://cirrus-ci.com/github/tailix/libkernaux)
|
||||
|
||||
Binding to [libkernaux](https://github.com/tailix/libkernaux) - auxiliary
|
||||
library for kernel development.
|
||||
|
||||
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
Add the following to your `build_config.rb`:
|
||||
|
||||
```ruby
|
||||
MRuby::Build.new do |conf|
|
||||
# ...
|
||||
conf.gem github: 'tailix/libkernaux',
|
||||
path: 'bindings/mruby',
|
||||
branch: 'v0.7.0',
|
||||
checksum_hash: '1cfff3fca3fc3f8990f43f0d6d5c91929c8f359c'
|
||||
# ...
|
||||
end
|
||||
```
|
|
@ -1,29 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
desc 'Run default checks'
|
||||
task default: :lint
|
||||
|
||||
desc 'Run code analysis tools'
|
||||
task lint: %i[rubocop cppcheck]
|
||||
|
||||
desc 'Fix code style (rubocop --auto-correct)'
|
||||
task fix: 'rubocop:auto_correct'
|
||||
|
||||
begin
|
||||
require 'rubocop/rake_task'
|
||||
RuboCop::RakeTask.new
|
||||
rescue LoadError
|
||||
nil
|
||||
end
|
||||
|
||||
desc 'Run cppcheck'
|
||||
task :cppcheck do
|
||||
sh(
|
||||
'cppcheck',
|
||||
'--quiet',
|
||||
'--error-exitcode=1',
|
||||
'--std=c99',
|
||||
'--enable=warning,style,performance,portability',
|
||||
__dir__,
|
||||
)
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eux
|
||||
|
||||
bundle install
|
||||
|
||||
# Do any other automated setup that you need to do here
|
|
@ -1,6 +0,0 @@
|
|||
MRuby::Build.new do |conf|
|
||||
conf.toolchain
|
||||
conf.enable_test
|
||||
conf.gem '.'
|
||||
conf.gem core: 'mruby-bin-mirb'
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
MRuby::Gem::Specification.new 'mruby-kernaux' do |spec|
|
||||
spec.version = '0.7.0'
|
||||
spec.license = 'MIT'
|
||||
spec.homepage =
|
||||
'https://github.com/tailix/libkernaux/tree/master/bindings/ruby'
|
||||
spec.author = 'Alex Kotov'
|
||||
|
||||
spec.summary =
|
||||
'Binding to libkernaux - auxiliary library for kernel development'
|
||||
|
||||
spec.description = <<~DESCRIPTION.split("\n").map(&:strip).join ' '
|
||||
Binding to libkernaux - auxiliary library for kernel development.
|
||||
DESCRIPTION
|
||||
|
||||
spec.add_test_dependency 'mruby-eval'
|
||||
spec.add_test_dependency 'mruby-io'
|
||||
spec.add_test_dependency 'mruby-random'
|
||||
spec.add_test_dependency 'mruby-yaml'
|
||||
|
||||
spec.linker.libraries << 'kernaux'
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
##
|
||||
# Binding to [libkernaux](https://github.com/tailix/libkernaux) - auxiliary
|
||||
# library for kernel development.
|
||||
#
|
||||
module KernAux
|
||||
DEFAULT_ASSERT_CB = @assert_cb = lambda { |file, line, msg|
|
||||
raise AssertError, "#{file}:#{line}:#{msg}"
|
||||
}
|
||||
|
||||
class Error < RuntimeError; end
|
||||
class AssertError < Error; end
|
||||
class CmdlineError < Error; end
|
||||
class InvalidNtoaBaseError < Error; end
|
||||
class TooLongNtoaPrefixError < Error; end
|
||||
end
|
|
@ -1,74 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <mruby/presym.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/variable.h>
|
||||
|
||||
static void assert_cb(const char *file, int line, const char *msg);
|
||||
|
||||
static mrb_value rb_KernAux_assert_cb(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_assert_cb_EQ(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_assert_do(mrb_state *mrb, mrb_value self);
|
||||
|
||||
void init_assert(mrb_state *const mrb)
|
||||
{
|
||||
kernaux_assert_cb = assert_cb;
|
||||
|
||||
struct RClass *const rb_KernAux = mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||
mrb_define_class_method(mrb, rb_KernAux, "assert_cb",
|
||||
rb_KernAux_assert_cb, MRB_ARGS_NONE());
|
||||
mrb_define_class_method(mrb, rb_KernAux, "assert_cb=",
|
||||
rb_KernAux_assert_cb_EQ, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, rb_KernAux, "assert_do",
|
||||
rb_KernAux_assert_do, MRB_ARGS_REQ(3));
|
||||
}
|
||||
|
||||
void assert_cb(const char *const file, const int line, const char *const msg)
|
||||
{
|
||||
mrb_state *const mrb = current_mrb_get();
|
||||
if (!mrb) return;
|
||||
|
||||
struct RClass *const self_rbc = mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||
mrb_value self_rb = mrb_obj_value(self_rbc);
|
||||
|
||||
mrb_value assert_cb_rb = mrb_iv_get(mrb, self_rb, MRB_IVSYM(assert_cb));
|
||||
if (mrb_nil_p(assert_cb_rb)) return;
|
||||
|
||||
mrb_value file_rb = mrb_str_new_lit(mrb, "");
|
||||
file_rb = mrb_str_cat_cstr(mrb, file_rb, file);
|
||||
|
||||
mrb_value line_rb = mrb_fixnum_value(line);
|
||||
|
||||
mrb_value msg_rb = mrb_str_new_lit(mrb, "");
|
||||
msg_rb = mrb_str_cat_cstr(mrb, msg_rb, msg);
|
||||
|
||||
mrb_funcall_id(
|
||||
mrb, assert_cb_rb, MRB_SYM(call), 3, file_rb, line_rb, msg_rb);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_assert_cb(mrb_state *const mrb, const mrb_value self_rb)
|
||||
{
|
||||
return mrb_iv_get(mrb, self_rb, MRB_IVSYM(assert_cb));
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_assert_cb_EQ(mrb_state *const mrb, const mrb_value self_rb)
|
||||
{
|
||||
mrb_value assert_cb_rb = mrb_nil_value();
|
||||
mrb_get_args(mrb, "o", &assert_cb_rb);
|
||||
mrb_iv_set(mrb, self_rb, MRB_IVSYM(assert_cb), assert_cb_rb);
|
||||
return assert_cb_rb;
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_assert_do(mrb_state *const mrb, const mrb_value self_rb)
|
||||
{
|
||||
const char *file = NULL;
|
||||
mrb_int line_rb = 0;
|
||||
const char *msg = NULL;
|
||||
mrb_get_args(mrb, "ziz", &file, &line_rb, &msg);
|
||||
|
||||
current_mrb_start(mrb);
|
||||
kernaux_assert_do(file, 0, msg);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
return mrb_nil_value();
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/presym.h>
|
||||
#include <mruby/string.h>
|
||||
|
||||
#define ARG_COUNT_MAX 256
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
#ifdef KERNAUX_VERSION_WITH_CMDLINE
|
||||
|
||||
static mrb_value rb_KernAux_cmdline(mrb_state *mrb, mrb_value self);
|
||||
|
||||
void init_cmdline(mrb_state *const mrb)
|
||||
{
|
||||
struct RClass *const rb_KernAux = mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||
struct RClass *const rb_KernAux_Error =
|
||||
mrb_class_get_under_id(mrb, rb_KernAux, MRB_SYM(Error));
|
||||
|
||||
mrb_define_class_under_id(mrb, rb_KernAux, MRB_SYM(CmdlineError),
|
||||
rb_KernAux_Error);
|
||||
|
||||
mrb_define_class_method(mrb, rb_KernAux, "cmdline",
|
||||
rb_KernAux_cmdline, MRB_ARGS_REQ(1));
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_cmdline(mrb_state *const mrb, mrb_value self)
|
||||
{
|
||||
const char *str;
|
||||
mrb_get_args(mrb, "z", &str);
|
||||
size_t argc;
|
||||
char error_msg[KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX];
|
||||
char **const argv = malloc(sizeof(char*) * ARG_COUNT_MAX);
|
||||
char *const buffer = malloc(BUFFER_SIZE);
|
||||
|
||||
const bool status = kernaux_cmdline(
|
||||
str,
|
||||
error_msg,
|
||||
&argc,
|
||||
argv,
|
||||
buffer,
|
||||
ARG_COUNT_MAX,
|
||||
BUFFER_SIZE
|
||||
);
|
||||
|
||||
if (!status) {
|
||||
free(argv);
|
||||
free(buffer);
|
||||
struct RClass *const rb_KernAux =
|
||||
mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||
struct RClass *const rb_KernAux_CmdlineError =
|
||||
mrb_class_get_under_id(mrb, rb_KernAux, MRB_SYM(CmdlineError));
|
||||
mrb_raise(mrb, rb_KernAux_CmdlineError, error_msg);
|
||||
}
|
||||
|
||||
mrb_value values[argc];
|
||||
for (size_t index = 0; index < argc; ++index) {
|
||||
values[index] = mrb_obj_freeze(
|
||||
mrb,
|
||||
mrb_str_cat_cstr(mrb, mrb_str_new_lit(mrb, ""), argv[index])
|
||||
);
|
||||
}
|
||||
free(argv);
|
||||
free(buffer);
|
||||
return mrb_obj_freeze(mrb, mrb_ary_new_from_values(mrb, argc, values));
|
||||
}
|
||||
|
||||
#endif // KERNAUX_VERSION_WITH_CMDLINE
|
|
@ -1,45 +0,0 @@
|
|||
#include "dynarg.h"
|
||||
|
||||
struct DynArg DynArg_create()
|
||||
{
|
||||
struct DynArg dynarg;
|
||||
DynArg_init(&dynarg);
|
||||
return dynarg;
|
||||
}
|
||||
|
||||
void DynArg_init(struct DynArg *const dynarg)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->dbl = 0.0;
|
||||
dynarg->arg.str = "";
|
||||
}
|
||||
|
||||
void DynArg_use_char(struct DynArg *const dynarg, const char chr)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.chr = chr;
|
||||
}
|
||||
|
||||
void DynArg_use_double(struct DynArg *const dynarg, const double dbl)
|
||||
{
|
||||
dynarg->use_dbl = true;
|
||||
dynarg->dbl = dbl;
|
||||
}
|
||||
|
||||
void DynArg_use_long_long(struct DynArg *const dynarg, const long long ll)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.ll = ll;
|
||||
}
|
||||
|
||||
void DynArg_use_str(struct DynArg *const dynarg, const char *const str)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.str = str;
|
||||
}
|
||||
|
||||
void DynArg_use_unsigned_long_long(struct DynArg *const dynarg, const unsigned long long ull)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.ull = ull;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef INCLUDED_DYNARG
|
||||
#define INCLUDED_DYNARG
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <kernaux/macro.h>
|
||||
|
||||
#include <kernaux/macro/packing_start.run>
|
||||
|
||||
struct DynArg {
|
||||
bool use_dbl;
|
||||
double dbl;
|
||||
// TODO: check if this will work on different endianness.
|
||||
union {
|
||||
char chr;
|
||||
long long ll;
|
||||
const char *str;
|
||||
unsigned long long ull;
|
||||
} KERNAUX_PACKED arg;
|
||||
}
|
||||
KERNAUX_PACKED;
|
||||
|
||||
#include <kernaux/macro/packing_end.run>
|
||||
|
||||
struct DynArg DynArg_create();
|
||||
void DynArg_init(struct DynArg *dynarg);
|
||||
|
||||
void DynArg_use_char(struct DynArg *dynarg, char chr);
|
||||
void DynArg_use_double(struct DynArg *dynarg, double dbl);
|
||||
void DynArg_use_long_long(struct DynArg *dynarg, long long ll);
|
||||
void DynArg_use_str(struct DynArg *dynarg, const char *str);
|
||||
void DynArg_use_unsigned_long_long(struct DynArg *dynarg, unsigned long long ull);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <mruby/presym.h>
|
||||
|
||||
#define MRB_STACK_SIZE 100
|
||||
|
||||
// TODO: implement locking
|
||||
// TODO: replace assertions with actual abort
|
||||
static size_t mrb_stack_count = 0;
|
||||
static mrb_state *mrb_stack[MRB_STACK_SIZE];
|
||||
|
||||
void mrb_mruby_kernaux_gem_final(mrb_state *const mrb) {}
|
||||
|
||||
void mrb_mruby_kernaux_gem_init(mrb_state *const mrb)
|
||||
{
|
||||
for (size_t index = mrb_stack_count; index < MRB_STACK_SIZE; ++index) {
|
||||
mrb_stack[index] = NULL;
|
||||
}
|
||||
|
||||
struct RClass *const rb_KernAux =
|
||||
mrb_define_module_id(mrb, MRB_SYM(KernAux));
|
||||
mrb_define_class_under_id(mrb, rb_KernAux, MRB_SYM(Error), E_RUNTIME_ERROR);
|
||||
|
||||
init_assert(mrb);
|
||||
init_version(mrb);
|
||||
|
||||
#ifdef KERNAUX_VERSION_WITH_CMDLINE
|
||||
init_cmdline(mrb);
|
||||
#endif // KERNAUX_VERSION_WITH_CMDLINE
|
||||
#ifdef KERNAUX_VERSION_WITH_NTOA
|
||||
init_ntoa(mrb);
|
||||
#endif // KERNAUX_VERSION_WITH_NTOA
|
||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||
init_printf(mrb);
|
||||
#endif // KERNAUX_VERSION_WITH_PRINTF
|
||||
}
|
||||
|
||||
void current_mrb_start(mrb_state *const mrb)
|
||||
{
|
||||
mrb_assert(mrb_stack_count < MRB_STACK_SIZE - 1);
|
||||
mrb_assert(mrb_stack[mrb_stack_count] == NULL);
|
||||
mrb_assert(mrb != NULL);
|
||||
|
||||
mrb_stack[mrb_stack_count++] = mrb;
|
||||
}
|
||||
|
||||
void current_mrb_finish(mrb_state *const mrb)
|
||||
{
|
||||
mrb_assert(mrb_stack_count > 0);
|
||||
mrb_assert(mrb_stack[mrb_stack_count - 1] != NULL);
|
||||
mrb_assert(mrb_stack[mrb_stack_count - 1] == mrb);
|
||||
|
||||
mrb_stack[--mrb_stack_count] = NULL;
|
||||
}
|
||||
|
||||
mrb_state *current_mrb_get()
|
||||
{
|
||||
mrb_assert(mrb_stack_count > 0);
|
||||
mrb_assert(mrb_stack[mrb_stack_count - 1] != NULL);
|
||||
|
||||
return mrb_stack[mrb_stack_count - 1];
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef __MAIN_H__
|
||||
#define __MAIN_H__
|
||||
|
||||
#include <kernaux.h>
|
||||
#include <mruby.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void current_mrb_start(mrb_state *mrb);
|
||||
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_WITH_CMDLINE
|
||||
void init_cmdline(mrb_state *mrb);
|
||||
#endif // KERNAUX_VERSION_WITH_CMDLINE
|
||||
#ifdef KERNAUX_VERSION_WITH_NTOA
|
||||
void init_ntoa(mrb_state *mrb);
|
||||
#endif // KERNAUX_VERSION_WITH_NTOA
|
||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||
void init_printf(mrb_state *mrb);
|
||||
#endif // KERNAUX_VERSION_WITH_PRINTF
|
||||
|
||||
#endif
|
|
@ -1,298 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/presym.h>
|
||||
#include <mruby/string.h>
|
||||
|
||||
#ifdef KERNAUX_VERSION_WITH_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);
|
||||
|
||||
static mrb_value rb_KernAux_utoa2(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_itoa2(mrb_state *mrb, mrb_value self);
|
||||
|
||||
static mrb_value rb_KernAux_utoa8(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_itoa8(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_utoa16(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_itoa16(mrb_state *mrb, mrb_value self);
|
||||
|
||||
static int convert_base(mrb_state *mrb, mrb_value base);
|
||||
|
||||
void init_ntoa(mrb_state *const mrb)
|
||||
{
|
||||
struct RClass *const rb_KernAux = mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||
struct RClass *const rb_KernAux_Error =
|
||||
mrb_class_get_under_id(mrb, rb_KernAux, MRB_SYM(Error));
|
||||
|
||||
mrb_define_class_under_id(mrb, rb_KernAux, MRB_SYM(InvalidNtoaBaseError),
|
||||
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",
|
||||
rb_KernAux_utoa, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
|
||||
mrb_define_class_method(mrb, rb_KernAux, "itoa",
|
||||
rb_KernAux_itoa, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
|
||||
|
||||
mrb_define_class_method(mrb, rb_KernAux, "utoa2",
|
||||
rb_KernAux_utoa2, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, rb_KernAux, "itoa2",
|
||||
rb_KernAux_itoa2, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_define_class_method(mrb, rb_KernAux, "utoa8",
|
||||
rb_KernAux_utoa8, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, rb_KernAux, "itoa8",
|
||||
rb_KernAux_itoa8, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_define_class_method(mrb, rb_KernAux, "utoa10",
|
||||
rb_KernAux_utoa10, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, rb_KernAux, "itoa10",
|
||||
rb_KernAux_itoa10, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_define_class_method(mrb, rb_KernAux, "utoa16",
|
||||
rb_KernAux_utoa16, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, rb_KernAux, "itoa16",
|
||||
rb_KernAux_itoa16, MRB_ARGS_REQ(1));
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_utoa(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_value base;
|
||||
const char *prefix = NULL;
|
||||
mrb_int prefix_len = 0;
|
||||
mrb_get_args(mrb, "io|s!", &value, &base, &prefix, &prefix_len);
|
||||
|
||||
if (value < 0) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR,
|
||||
"can't convert negative number to uint64_t");
|
||||
}
|
||||
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
char buffer[KERNAUX_UTOA_MIN_BUFFER_SIZE + prefix_len];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_utoa(value, buffer, convert_base(mrb, base), prefix);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_value base;
|
||||
const char *prefix = NULL;
|
||||
mrb_int prefix_len = 0;
|
||||
mrb_get_args(mrb, "io|s!", &value, &base, &prefix, &prefix_len);
|
||||
|
||||
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
char buffer[KERNAUX_ITOA_MIN_BUFFER_SIZE + prefix_len];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_itoa(value, buffer, convert_base(mrb, base), prefix);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_utoa2(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
if (value < 0) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR,
|
||||
"can't convert negative number to uint64_t");
|
||||
}
|
||||
|
||||
char buffer[KERNAUX_UTOA2_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_utoa2(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_itoa2(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
char buffer[KERNAUX_ITOA2_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_itoa2(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_utoa8(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
if (value < 0) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR,
|
||||
"can't convert negative number to uint64_t");
|
||||
}
|
||||
|
||||
char buffer[KERNAUX_UTOA8_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_utoa8(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_itoa8(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
char buffer[KERNAUX_ITOA8_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_itoa8(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_utoa10(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
if (value < 0) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR,
|
||||
"can't convert negative number to uint64_t");
|
||||
}
|
||||
|
||||
char buffer[KERNAUX_UTOA10_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_utoa10(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_itoa10(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
char buffer[KERNAUX_ITOA10_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_itoa10(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_utoa16(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
if (value < 0) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR,
|
||||
"can't convert negative number to uint64_t");
|
||||
}
|
||||
|
||||
char buffer[KERNAUX_UTOA16_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_utoa16(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_itoa16(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
char buffer[KERNAUX_ITOA16_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_itoa16(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
int convert_base(mrb_state *mrb, mrb_value base_rb)
|
||||
{
|
||||
if (mrb_obj_is_kind_of(mrb, base_rb, mrb->symbol_class)) {
|
||||
mrb_sym base_sym = mrb_obj_to_sym(mrb, base_rb);
|
||||
switch (base_sym) {
|
||||
case MRB_SYM(b): return 'b';
|
||||
case MRB_SYM(B): return 'B';
|
||||
case MRB_SYM(h): return 'h';
|
||||
case MRB_SYM(H): return 'H';
|
||||
case MRB_SYM(o): return 'o';
|
||||
case MRB_SYM(O): return 'O';
|
||||
case MRB_SYM(d): return 'd';
|
||||
case MRB_SYM(D): return 'D';
|
||||
case MRB_SYM(x): return 'x';
|
||||
case MRB_SYM(X): return 'X';
|
||||
default:
|
||||
{
|
||||
struct RClass *const rb_KernAux =
|
||||
mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||
struct RClass *const rb_KernAux_Error =
|
||||
mrb_class_get_under_id(mrb, rb_KernAux, MRB_SYM(Error));
|
||||
mrb_raise(mrb, rb_KernAux_Error, "invalid base");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return mrb_integer(base_rb);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // KERNAUX_VERSION_WITH_NTOA
|
|
@ -1,144 +0,0 @@
|
|||
#include "main.h"
|
||||
#include "dynarg.h"
|
||||
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/error.h>
|
||||
#include <mruby/presym.h>
|
||||
#include <mruby/string.h>
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||
|
||||
static mrb_value rb_KernAux_sprintf(mrb_state *mrb, mrb_value self);
|
||||
|
||||
void init_printf(mrb_state *const mrb)
|
||||
{
|
||||
struct RClass *const rb_KernAux = mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||
|
||||
mrb_define_class_method(mrb, rb_KernAux, "sprintf", rb_KernAux_sprintf,
|
||||
MRB_ARGS_REQ(1) | MRB_ARGS_REST());
|
||||
}
|
||||
|
||||
#define TAKE_ARG \
|
||||
if (arg_index >= argc) { \
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"); \
|
||||
} \
|
||||
mrb_value arg_rb = args[arg_index++]; \
|
||||
do {} while (0)
|
||||
|
||||
mrb_value rb_KernAux_sprintf(mrb_state *const mrb, mrb_value self)
|
||||
{
|
||||
const char *format;
|
||||
mrb_value *args;
|
||||
mrb_int argc;
|
||||
mrb_get_args(mrb, "z*", &format, &args, &argc);
|
||||
|
||||
int arg_index = 0;
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
|
||||
while (*format) {
|
||||
if (*format != '%') {
|
||||
mrb_str_cat(mrb, result, format, 1);
|
||||
++format;
|
||||
continue;
|
||||
}
|
||||
|
||||
++format;
|
||||
struct KernAux_PrintfFmt_Spec spec =
|
||||
KernAux_PrintfFmt_Spec_create_out(&format);
|
||||
|
||||
if (spec.set_width) {
|
||||
TAKE_ARG;
|
||||
KernAux_PrintfFmt_Spec_set_width(&spec, mrb_integer(arg_rb));
|
||||
}
|
||||
if (spec.set_precision) {
|
||||
TAKE_ARG;
|
||||
KernAux_PrintfFmt_Spec_set_precision(&spec, mrb_integer(arg_rb));
|
||||
}
|
||||
|
||||
struct DynArg dynarg = DynArg_create();
|
||||
|
||||
if (spec.type == KERNAUX_PRINTF_FMT_TYPE_INT) {
|
||||
TAKE_ARG;
|
||||
mrb_ensure_int_type(mrb, arg_rb);
|
||||
DynArg_use_long_long(&dynarg, mrb_integer(arg_rb));
|
||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_UINT) {
|
||||
TAKE_ARG;
|
||||
mrb_ensure_int_type(mrb, arg_rb);
|
||||
DynArg_use_unsigned_long_long(&dynarg, mrb_integer(arg_rb));
|
||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_FLOAT ||
|
||||
spec.type == KERNAUX_PRINTF_FMT_TYPE_EXP)
|
||||
{
|
||||
TAKE_ARG;
|
||||
mrb_ensure_float_type(mrb, arg_rb);
|
||||
DynArg_use_double(&dynarg, mrb_float(arg_rb));
|
||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_CHAR) {
|
||||
TAKE_ARG;
|
||||
mrb_ensure_string_type(mrb, arg_rb);
|
||||
DynArg_use_char(&dynarg, *RSTRING_PTR(arg_rb));
|
||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_STR) {
|
||||
TAKE_ARG;
|
||||
mrb_ensure_string_type(mrb, arg_rb);
|
||||
DynArg_use_str(&dynarg, RSTRING_CSTR(mrb, arg_rb));
|
||||
}
|
||||
|
||||
// 1 additional byte for the '%' character.
|
||||
// 1 additional byte for the terminating '\0' character.
|
||||
char old_format[2 + spec.format_limit - spec.format_start];
|
||||
memset(old_format, '\0', sizeof(old_format));
|
||||
old_format[0] = '%';
|
||||
strncpy(&old_format[1], spec.format_start, sizeof(old_format) - 2);
|
||||
|
||||
char buffer[BUFFER_SIZE];
|
||||
int slen;
|
||||
|
||||
if (spec.set_width) {
|
||||
if (spec.set_precision) {
|
||||
if (dynarg.use_dbl) {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.width, spec.precision,
|
||||
dynarg.dbl);
|
||||
} else {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.width, spec.precision,
|
||||
dynarg.arg);
|
||||
}
|
||||
} else {
|
||||
if (dynarg.use_dbl) {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.width, dynarg.dbl);
|
||||
} else {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.width, dynarg.arg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (spec.set_precision) {
|
||||
if (dynarg.use_dbl) {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.precision, dynarg.dbl);
|
||||
} else {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.precision, dynarg.arg);
|
||||
}
|
||||
} else {
|
||||
if (dynarg.use_dbl) {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.dbl);
|
||||
} else {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mrb_str_cat(mrb, result, buffer, slen);
|
||||
}
|
||||
|
||||
if (arg_index < argc) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "too many arguments");
|
||||
}
|
||||
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
#endif // KERNAUX_VERSION_WITH_PRINTF
|
|
@ -1,49 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <mruby/presym.h>
|
||||
#include <mruby/value.h>
|
||||
|
||||
static mrb_value rb_KernAux_Version_with_cmdlineQN(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_Version_with_ntoaQN(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_Version_with_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, "with_cmdline?",
|
||||
rb_KernAux_Version_with_cmdlineQN, MRB_ARGS_REQ(0));
|
||||
mrb_define_class_method(mrb, rb_KernAux_Version, "with_ntoa?",
|
||||
rb_KernAux_Version_with_ntoaQN, MRB_ARGS_REQ(0));
|
||||
mrb_define_class_method(mrb, rb_KernAux_Version, "with_printf?",
|
||||
rb_KernAux_Version_with_printfQN, MRB_ARGS_REQ(0));
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_Version_with_cmdlineQN(mrb_state *const mrb, const mrb_value self)
|
||||
{
|
||||
#ifdef KERNAUX_VERSION_WITH_CMDLINE
|
||||
return mrb_true_value();
|
||||
#else
|
||||
return mrb_false_value();
|
||||
#endif
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_Version_with_ntoaQN(mrb_state *const mrb, const mrb_value self)
|
||||
{
|
||||
#ifdef KERNAUX_VERSION_WITH_NTOA
|
||||
return mrb_true_value();
|
||||
#else
|
||||
return mrb_false_value();
|
||||
#endif
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_Version_with_printfQN(mrb_state *const mrb, const mrb_value self)
|
||||
{
|
||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||
return mrb_true_value();
|
||||
#else
|
||||
return mrb_false_value();
|
||||
#endif
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
assert 'KernAux.assert_cb is set by default' do
|
||||
assert_equal KernAux::DEFAULT_ASSERT_CB, KernAux.assert_cb
|
||||
end
|
||||
|
||||
assert 'we can set KernAux.assert_cb' do
|
||||
KernAux.assert_cb = nil
|
||||
assert_equal nil, KernAux.assert_cb
|
||||
|
||||
KernAux.assert_cb = 123
|
||||
assert_equal 123, KernAux.assert_cb
|
||||
|
||||
KernAux.assert_cb = KernAux::DEFAULT_ASSERT_CB
|
||||
assert_equal KernAux::DEFAULT_ASSERT_CB, KernAux.assert_cb
|
||||
end
|
||||
|
||||
assert 'KernAux::DEFAULT_ASSERT_CB raises' do
|
||||
assert_raise KernAux::AssertError, 'foo.rb:123:bar' do
|
||||
KernAux::DEFAULT_ASSERT_CB.call 'foo.rb', 123, 'bar'
|
||||
end
|
||||
end
|
||||
|
||||
assert 'KernAux.assert_do raises' do
|
||||
assert_raise KernAux::AssertError, 'foo.rb:123:hello' do
|
||||
KernAux.assert_do 'foo.rb', 123, 'hello'
|
||||
end
|
||||
end
|
|
@ -1,93 +0,0 @@
|
|||
def test_cmdline(str, expected)
|
||||
result = KernAux.cmdline str
|
||||
|
||||
assert_true result.instance_of? Array
|
||||
assert_true result.frozen?
|
||||
result.each do |item|
|
||||
assert_true item.instance_of? String
|
||||
assert_true item.frozen?
|
||||
end
|
||||
|
||||
assert_equal result, expected
|
||||
end
|
||||
|
||||
if KernAux::Version.with_cmdline?
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
assert 'when str has EOL after backslash' do
|
||||
assert_raise KernAux::CmdlineError, 'EOL after backslash' do
|
||||
KernAux.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, 'EOF or buffer overflow' do
|
||||
KernAux.cmdline 'a' * 4096
|
||||
end
|
||||
end
|
||||
|
||||
assert 'usign fixtures' do
|
||||
cmdline_yml = File.expand_path('../../../../fixtures/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']
|
||||
arg_count_max = test['arg_count_max']
|
||||
buffer_size = test['buffer_size']
|
||||
result = test['result']&.map(&escape_str)
|
||||
|
||||
next unless arg_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
|
|
@ -1,348 +0,0 @@
|
|||
def common_assert(expected, result)
|
||||
assert_true result.instance_of? String
|
||||
assert_true result.frozen?
|
||||
assert_equal expected, result
|
||||
end
|
||||
|
||||
def test_utoa(number, base, expected)
|
||||
common_assert expected, KernAux.utoa(number, base)
|
||||
common_assert expected, KernAux.utoa(number, base, nil)
|
||||
common_assert expected, KernAux.utoa(number, base, '')
|
||||
end
|
||||
|
||||
def test_itoa(number, base, expected)
|
||||
common_assert expected, KernAux.itoa(number, base)
|
||||
common_assert expected, KernAux.itoa(number, base, nil)
|
||||
common_assert expected, KernAux.itoa(number, base, '')
|
||||
end
|
||||
|
||||
def test_utoax(number, base, prefix, expected)
|
||||
common_assert expected, KernAux.utoa(number, base, prefix)
|
||||
end
|
||||
|
||||
def test_itoax(number, base, prefix, expected)
|
||||
common_assert expected, KernAux.itoa(number, base, prefix)
|
||||
end
|
||||
|
||||
def test_utoa2(number, expected)
|
||||
common_assert expected, KernAux.utoa2(number)
|
||||
end
|
||||
|
||||
def test_itoa2(number, expected)
|
||||
common_assert expected, KernAux.itoa2(number)
|
||||
end
|
||||
|
||||
def test_utoa8(number, expected)
|
||||
common_assert expected, KernAux.utoa8(number)
|
||||
end
|
||||
|
||||
def test_itoa8(number, expected)
|
||||
common_assert expected, KernAux.itoa8(number)
|
||||
end
|
||||
|
||||
def test_utoa10(number, expected)
|
||||
common_assert expected, KernAux.utoa10(number)
|
||||
end
|
||||
|
||||
def test_itoa10(number, expected)
|
||||
common_assert expected, KernAux.itoa10(number)
|
||||
end
|
||||
|
||||
def test_utoa16(number, expected)
|
||||
common_assert expected, KernAux.utoa16(number)
|
||||
end
|
||||
|
||||
def test_itoa16(number, expected)
|
||||
common_assert expected, KernAux.itoa16(number)
|
||||
end
|
||||
|
||||
if KernAux::Version.with_ntoa?
|
||||
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
|
||||
number = Random.rand(2**32 - 1)
|
||||
base = 2 + Random.rand(36 - 2)
|
||||
prefix = 'a' * 101
|
||||
KernAux.utoa(number, base, prefix)
|
||||
end
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**32 - 1).to_s
|
||||
KernAux.utoa(number.to_s)
|
||||
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
|
||||
number = Random.rand(2**31 - 1) * [1, -1].sample
|
||||
base = 2 + Random.rand(36 - 2)
|
||||
prefix = 'a' * 101
|
||||
KernAux.itoa(number, base, prefix)
|
||||
end
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**31 - 1) * [1, -1].sample
|
||||
KernAux.itoa(number.to_s)
|
||||
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
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**32 - 1).to_s
|
||||
KernAux.utoa2(number.to_s)
|
||||
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)}")
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**31 - 1) * [1, -1].sample
|
||||
KernAux.itoa2(number.to_s)
|
||||
end
|
||||
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
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**32 - 1).to_s
|
||||
KernAux.utoa8(number.to_s)
|
||||
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)}")
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**31 - 1) * [1, -1].sample
|
||||
KernAux.itoa8(number.to_s)
|
||||
end
|
||||
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
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**32 - 1).to_s
|
||||
KernAux.utoa10(number.to_s)
|
||||
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)
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**31 - 1) * [1, -1].sample
|
||||
KernAux.itoa10(number.to_s)
|
||||
end
|
||||
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
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**32 - 1).to_s
|
||||
KernAux.utoa16(number.to_s)
|
||||
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)}")
|
||||
|
||||
assert_raise TypeError, 'no implicit conversion from string' do
|
||||
number = Random.rand(2**31 - 1) * [1, -1].sample
|
||||
KernAux.itoa16(number.to_s)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,113 +0,0 @@
|
|||
if KernAux::Version.with_printf?
|
||||
assert 'KernAux.sprintf' do
|
||||
assert 'integers' do
|
||||
assert_equal 'i:0', KernAux.sprintf('i:%i', 0)
|
||||
assert_equal 'u:0', KernAux.sprintf('u:%u', 0)
|
||||
assert_equal 'i:1', KernAux.sprintf('i:%i', 1)
|
||||
assert_equal 'u:1', KernAux.sprintf('u:%u', 1)
|
||||
assert_equal 'i:10', KernAux.sprintf('i:%i', 10)
|
||||
assert_equal 'u:10', KernAux.sprintf('u:%u', 10)
|
||||
assert_equal 'i:100', KernAux.sprintf('i:%i', 100)
|
||||
assert_equal 'u:100', KernAux.sprintf('u:%u', 100)
|
||||
assert_equal 'i:1000', KernAux.sprintf('i:%i', 1000)
|
||||
assert_equal 'u:1000', KernAux.sprintf('u:%u', 1000)
|
||||
assert_equal 'i:10000', KernAux.sprintf('i:%i', 10_000)
|
||||
assert_equal 'u:10000', KernAux.sprintf('u:%u', 10_000)
|
||||
assert_equal 'i:100000', KernAux.sprintf('i:%i', 100_000)
|
||||
assert_equal 'u:100000', KernAux.sprintf('u:%u', 100_000)
|
||||
assert_equal 'i:1000000', KernAux.sprintf('i:%i', 1_000_000)
|
||||
assert_equal 'u:1000000', KernAux.sprintf('u:%u', 1_000_000)
|
||||
assert_equal 'i:10000000', KernAux.sprintf('i:%i', 10_000_000)
|
||||
assert_equal 'u:10000000', KernAux.sprintf('u:%u', 10_000_000)
|
||||
assert_equal 'i:100000000', KernAux.sprintf('i:%i', 10**8)
|
||||
assert_equal 'u:100000000', KernAux.sprintf('u:%u', 10**8)
|
||||
assert_equal 'i:1000000000', KernAux.sprintf('i:%i', 10**9)
|
||||
assert_equal 'u:1000000000', KernAux.sprintf('u:%u', 10**9)
|
||||
assert_equal 'i:2147483647', KernAux.sprintf('i:%i', 2**31 - 1)
|
||||
assert_equal 'u:2147483647', KernAux.sprintf('u:%u', 2**31 - 1)
|
||||
end
|
||||
|
||||
# TODO: test with different boxing
|
||||
# assert 'integer overflows' do
|
||||
# assert_equal 'i:-2147483648', KernAux.sprintf('i:%i', 2**31)
|
||||
# assert_equal 'u: 2147483648', KernAux.sprintf('u: %u', 2**31)
|
||||
# assert_equal 'i:-2147483647', KernAux.sprintf('i:%i', 2**31 + 1)
|
||||
# assert_equal 'u: 2147483649', KernAux.sprintf('u: %u', 2**31 + 1)
|
||||
# assert_equal 'i:-1', KernAux.sprintf('i:%i', 2**32 - 1)
|
||||
# assert_equal 'u: 4294967295', KernAux.sprintf('u: %u', 2**32 - 1)
|
||||
# assert_equal 'i: 0', KernAux.sprintf('i: %i', 2**32)
|
||||
# assert_equal 'u: 0', KernAux.sprintf('u: %u', 2**32)
|
||||
# end
|
||||
|
||||
assert 'when there are too many arguments' do
|
||||
[
|
||||
['Hello!', 'World!'],
|
||||
['Hello, %s!', 'World', 'Alex'],
|
||||
].each do |args|
|
||||
assert_raise ArgumentError, 'too many arguments' do
|
||||
KernAux.sprintf(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assert 'when there are too few arguments' do
|
||||
[
|
||||
[],
|
||||
['Hello, %s!'],
|
||||
['Hello, %*s!', 20],
|
||||
['Hello, %.*s!', 20],
|
||||
['Hello, %*.*s!', 20, 20],
|
||||
].each do |args|
|
||||
assert_raise ArgumentError, 'too few arguments' do
|
||||
KernAux.sprintf(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
[
|
||||
['', 'using regular fixtures'],
|
||||
['_orig', 'using original fixtures'],
|
||||
].each do |(suffix, description)|
|
||||
assert description do
|
||||
printf_yml =
|
||||
File.expand_path("../../../../fixtures/printf#{suffix}.yml", __FILE__)
|
||||
|
||||
YAML.load(File.read(printf_yml)).each do |test|
|
||||
expected = test['result']
|
||||
|
||||
format = ''
|
||||
args = []
|
||||
|
||||
test['args'].each do |arg|
|
||||
if arg.is_a? String
|
||||
format += arg
|
||||
else
|
||||
format += arg[0]
|
||||
is_int_format = %w[i d u x X o b].any? { |s| arg[0].include? s }
|
||||
arg[1..].each do |item|
|
||||
if item.is_a? Array
|
||||
if item.length == 1
|
||||
args << item[0]
|
||||
elsif item[0] == 'long long'
|
||||
args << item[1]
|
||||
else
|
||||
raise "Unknown format: #{args.inspect}"
|
||||
end
|
||||
elsif is_int_format && item.is_a?(Float)
|
||||
args << item.round
|
||||
else
|
||||
args << item
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assert "transforms (#{format.inspect}, #{args.inspect[1...-1]}) " \
|
||||
"to #{expected.inspect}" do
|
||||
assert_equal expected, KernAux.sprintf(format, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
2
bindings/python/.gitignore
vendored
2
bindings/python/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
/dist/
|
||||
/src/kernaux.egg-info/
|
|
@ -1,5 +0,0 @@
|
|||
kernaux
|
||||
=======
|
||||
|
||||
Binding to [libkernaux](https://github.com/tailix/libkernaux) - auxiliary
|
||||
library for kernel development.
|
|
@ -1,6 +0,0 @@
|
|||
[build-system]
|
||||
requires = [
|
||||
"setuptools>=42",
|
||||
"wheel"
|
||||
]
|
||||
build-backend = "setuptools.build_meta"
|
|
@ -1,24 +0,0 @@
|
|||
[metadata]
|
||||
name = kernaux
|
||||
version = 0.0.0
|
||||
author = Alex Kotov
|
||||
author_email = kotovalexarian@gmail.com
|
||||
description = Binding to libkernaux - auxiliary library for kernel development
|
||||
long_description = file: README.md
|
||||
long_description_content_type = text/markdown
|
||||
url = https://github.com/tailix/libkernaux/tree/master/bindings/python
|
||||
project_urls =
|
||||
Bug Tracker = https://github.com/tailix/libkernaux/issues
|
||||
classifiers =
|
||||
Programming Language :: Python :: 3
|
||||
License :: OSI Approved :: MIT License
|
||||
Operating System :: POSIX
|
||||
|
||||
[options]
|
||||
package_dir =
|
||||
= src
|
||||
packages = find:
|
||||
python_requires = >=3.8
|
||||
|
||||
[options.packages.find]
|
||||
where = src
|
|
@ -1,2 +0,0 @@
|
|||
def add_one(number):
|
||||
return number + 1
|
44
bindings/ruby/.gitignore
vendored
44
bindings/ruby/.gitignore
vendored
|
@ -1,44 +0,0 @@
|
|||
*.gem
|
||||
*.rbc
|
||||
*.so
|
||||
|
||||
/.byebug_history
|
||||
/.config/
|
||||
/.rake_tasks~
|
||||
/InstalledFiles/
|
||||
/pkg/
|
||||
/tmp/
|
||||
|
||||
# Used by dotenv library to load environment variables.
|
||||
/.env
|
||||
|
||||
# RSpec configuration and generated files.
|
||||
/.rspec
|
||||
/coverage/
|
||||
/spec/examples.txt
|
||||
/spec/reports/
|
||||
/test/tmp/
|
||||
/test/version_tmp/
|
||||
|
||||
# Documentation cache and generated files.
|
||||
/.yardoc/
|
||||
/_yardoc/
|
||||
/doc/
|
||||
/rdoc/
|
||||
|
||||
# Environment normalization.
|
||||
/.bundle/
|
||||
/vendor/bundle/
|
||||
/lib/bundler/man/
|
||||
|
||||
# For a library or gem, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in.
|
||||
/Gemfile.lock
|
||||
/.ruby-version
|
||||
/.ruby-gemset
|
||||
|
||||
# Unless supporting rvm < 1.11.0 or doing something fancy, ignore this.
|
||||
/.rvmrc
|
||||
|
||||
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
|
||||
/.rubocop-https?--*
|
|
@ -1,79 +0,0 @@
|
|||
require:
|
||||
- rubocop-performance
|
||||
- rubocop-rake
|
||||
- rubocop-rspec
|
||||
|
||||
AllCops:
|
||||
TargetRubyVersion: 3.0
|
||||
DisplayCopNames: true
|
||||
NewCops: enable
|
||||
|
||||
Layout/AccessModifierIndentation:
|
||||
EnforcedStyle: outdent
|
||||
|
||||
Layout/LineLength:
|
||||
Max: 80
|
||||
|
||||
Lint/AmbiguousOperatorPrecedence:
|
||||
Enabled: false
|
||||
|
||||
Lint/ReturnInVoidContext:
|
||||
Enabled: false
|
||||
|
||||
Metrics/BlockLength:
|
||||
Exclude:
|
||||
- '*.gemspec'
|
||||
- 'Rakefile'
|
||||
- 'spec/**/*_spec.rb'
|
||||
|
||||
RSpec/ContextWording:
|
||||
Prefixes:
|
||||
- 'and'
|
||||
- 'for'
|
||||
- 'using'
|
||||
- 'when'
|
||||
- 'with'
|
||||
- 'without'
|
||||
|
||||
RSpec/FilePath:
|
||||
CustomTransform:
|
||||
KernAux: kernaux
|
||||
|
||||
RSpec/ExampleLength:
|
||||
CountAsOne: ['array', 'hash', 'heredoc']
|
||||
|
||||
Security/Eval:
|
||||
Exclude:
|
||||
- 'spec/**/*_spec.rb'
|
||||
|
||||
Style/AndOr:
|
||||
EnforcedStyle: conditionals
|
||||
|
||||
Style/Documentation:
|
||||
Exclude:
|
||||
- 'Rakefile'
|
||||
|
||||
Style/DoubleNegation:
|
||||
Enabled: false
|
||||
|
||||
Style/GlobalVars:
|
||||
Exclude:
|
||||
- 'ext/*/extconf.rb'
|
||||
|
||||
Style/HashAsLastArrayItem:
|
||||
Enabled: false
|
||||
|
||||
Style/PerlBackrefs:
|
||||
Enabled: false
|
||||
|
||||
Style/TrailingCommaInArguments:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/TrailingCommaInArrayLiteral:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/TrailingCommaInHashLiteral:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/VariableInterpolation:
|
||||
Enabled: false
|
|
@ -1,9 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if ENV['SKIP_COVERAGE'].to_s.empty?
|
||||
SimpleCov.start do
|
||||
minimum_coverage 95
|
||||
|
||||
add_filter '/spec/'
|
||||
end
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
--markup markdown
|
||||
--readme README.md
|
||||
--protected
|
||||
--private
|
|
@ -1,8 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
# Specify your gem's dependencies in kernaux.gemspec
|
||||
gemspec
|
||||
|
||||
gem 'simplecov', require: false
|
|
@ -1,29 +0,0 @@
|
|||
::KernAux
|
||||
=========
|
||||
|
||||
[![Build status](https://github.com/tailix/libkernaux/actions/workflows/ruby.yml/badge.svg)](https://github.com/tailix/libkernaux/actions/workflows/ruby.yml)
|
||||
[![Build status (FreeBSD)](https://api.cirrus-ci.com/github/tailix/libkernaux.svg?task=Ruby%20(FreeBSD))](https://cirrus-ci.com/github/tailix/libkernaux)
|
||||
|
||||
Binding to [libkernaux](https://github.com/tailix/libkernaux) - auxiliary
|
||||
library for kernel development.
|
||||
|
||||
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
Add the following to your `Gemfile`:
|
||||
|
||||
```ruby
|
||||
gem 'kernaux', '~> 0.7.0'
|
||||
```
|
||||
|
||||
Or add the following to your `*.gemspec`:
|
||||
|
||||
```ruby
|
||||
Gem::Specification.new do |spec|
|
||||
# ...
|
||||
spec.add_runtime_dependency 'kernaux', '~> 0.7.0'
|
||||
# ...
|
||||
end
|
||||
```
|
|
@ -1,92 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'bundler/gem_tasks'
|
||||
|
||||
module Bundler
|
||||
class GemHelper
|
||||
def tag_version(*)
|
||||
yield if block_given?
|
||||
end
|
||||
|
||||
def git_push(*); end
|
||||
|
||||
def perform_git_push(*); end
|
||||
end
|
||||
end
|
||||
|
||||
CLEAN << '.yardoc'
|
||||
CLEAN << 'coverage'
|
||||
CLEAN << 'doc'
|
||||
CLEAN << 'spec/examples.txt'
|
||||
|
||||
desc 'Run default checks'
|
||||
task default: %i[test lint]
|
||||
|
||||
desc 'Run tests'
|
||||
task test: :spec
|
||||
|
||||
desc 'Run code analysis tools'
|
||||
task lint: %i[rubocop cppcheck yard:cov]
|
||||
|
||||
desc 'Fix code style (rubocop --auto-correct)'
|
||||
task fix: 'rubocop:auto_correct'
|
||||
|
||||
begin
|
||||
require 'rspec/core/rake_task'
|
||||
RSpec::Core::RakeTask.new
|
||||
rescue LoadError
|
||||
nil
|
||||
end
|
||||
|
||||
begin
|
||||
require 'rubocop/rake_task'
|
||||
RuboCop::RakeTask.new
|
||||
rescue LoadError
|
||||
nil
|
||||
end
|
||||
|
||||
begin
|
||||
require 'yard'
|
||||
YARD::Rake::YardocTask.new
|
||||
rescue LoadError
|
||||
nil
|
||||
end
|
||||
|
||||
begin
|
||||
require 'rake/extensiontask'
|
||||
Rake::ExtensionTask.new 'default' do |ext|
|
||||
ext.lib_dir = 'lib/kernaux'
|
||||
end
|
||||
rescue LoadError
|
||||
nil
|
||||
end
|
||||
|
||||
desc 'Open development console'
|
||||
task :console do
|
||||
sh 'bundle', 'exec', File.expand_path(File.join('bin', 'console'), __dir__)
|
||||
end
|
||||
|
||||
desc 'Run cppcheck'
|
||||
task :cppcheck do
|
||||
sh(
|
||||
'cppcheck',
|
||||
'--quiet',
|
||||
'--error-exitcode=1',
|
||||
'--std=c99',
|
||||
'--enable=warning,style,performance,portability',
|
||||
__dir__,
|
||||
)
|
||||
end
|
||||
|
||||
namespace :yard do
|
||||
desc 'Measure documentation coverage'
|
||||
task :cov do
|
||||
result = `bundle exec yard stats`.lines.last.strip.freeze
|
||||
m = result.match(/\A(\d+(\.\d+)?)% documented\z/)
|
||||
raise 'Invalid result' if m.nil?
|
||||
|
||||
coverage = m[1].to_f.round(2)
|
||||
puts "Documentation coverage: #{coverage}%"
|
||||
raise 'Not fully documented!' if coverage != 100
|
||||
end
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'bundler/setup'
|
||||
require 'kernaux'
|
||||
require 'pry'
|
||||
|
||||
Pry.start
|
|
@ -1,7 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eux
|
||||
|
||||
bundle install
|
||||
|
||||
# Do any other automated setup that you need to do here
|
|
@ -1,55 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
static void assert_cb(const char *file, int line, const char *msg);
|
||||
|
||||
static VALUE rb_KernAux_assert_cb(VALUE self);
|
||||
static VALUE rb_KernAux_assert_cb_EQ(VALUE self, VALUE assert_cb);
|
||||
static
|
||||
VALUE rb_KernAux_assert_do(VALUE self, VALUE file, VALUE line, VALUE msg);
|
||||
|
||||
void init_assert()
|
||||
{
|
||||
kernaux_assert_cb = assert_cb;
|
||||
|
||||
rb_define_singleton_method(rb_KernAux, "assert_cb",
|
||||
rb_KernAux_assert_cb, 0);
|
||||
rb_define_singleton_method(rb_KernAux, "assert_cb=",
|
||||
rb_KernAux_assert_cb_EQ, 1);
|
||||
rb_define_singleton_method(rb_KernAux, "assert_do",
|
||||
rb_KernAux_assert_do, 3);
|
||||
}
|
||||
|
||||
void assert_cb(const char *const file, const int line, const char *const msg)
|
||||
{
|
||||
const VALUE assert_cb_rb = rb_iv_get(rb_KernAux, "@assert_cb");
|
||||
if (assert_cb_rb == Qnil) return;
|
||||
const VALUE file_rb = rb_str_new2(file);
|
||||
const VALUE line_rb = INT2FIX(line);
|
||||
const VALUE msg_rb = rb_str_new2(msg);
|
||||
rb_funcall(assert_cb_rb, rb_intern_call, 3, file_rb, line_rb, msg_rb);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_assert_cb(const VALUE self)
|
||||
{
|
||||
return rb_iv_get(self, "@assert_cb");
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_assert_cb_EQ(const VALUE self, const VALUE assert_cb_rb)
|
||||
{
|
||||
return rb_iv_set(self, "@assert_cb", assert_cb_rb);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_assert_do(
|
||||
const VALUE self_rb KERNAUX_UNUSED,
|
||||
VALUE file_rb,
|
||||
const VALUE line_rb,
|
||||
VALUE msg_rb
|
||||
) {
|
||||
const char *const file = StringValueCStr(file_rb);
|
||||
const int line = FIX2INT(line_rb);
|
||||
const char *const msg = StringValueCStr(msg_rb);
|
||||
|
||||
kernaux_assert_do(file, line, msg);
|
||||
|
||||
return Qnil;
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
#ifdef KERNAUX_VERSION_WITH_CMDLINE
|
||||
|
||||
#define ARG_COUNT_MAX 256
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
struct Data {
|
||||
char error_msg[KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX];
|
||||
char *argv[ARG_COUNT_MAX];
|
||||
char buffer[BUFFER_SIZE];
|
||||
};
|
||||
|
||||
static VALUE rb_ANON_Data_ALLOC(VALUE klass);
|
||||
static VALUE rb_KernAux_cmdline(VALUE self, VALUE cmdline);
|
||||
|
||||
static const struct rb_data_type_struct info = {
|
||||
.wrap_struct_name = "cmdline",
|
||||
.function = {
|
||||
.dmark = NULL,
|
||||
.dfree = RUBY_DEFAULT_FREE,
|
||||
.dsize = NULL,
|
||||
.dcompact = NULL,
|
||||
.reserved = { 0 },
|
||||
},
|
||||
.parent = NULL,
|
||||
.data = NULL,
|
||||
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
||||
};
|
||||
|
||||
static VALUE rb_KernAux_CmdlineError = Qnil;
|
||||
static VALUE rb_ANON_Data = Qnil;
|
||||
|
||||
void init_cmdline()
|
||||
{
|
||||
rb_gc_register_mark_object(rb_KernAux_CmdlineError =
|
||||
rb_define_class_under(rb_KernAux, "CmdlineError", rb_KernAux_Error));
|
||||
rb_gc_register_mark_object(rb_ANON_Data =
|
||||
rb_funcall(rb_cClass, rb_intern_new, 1, rb_cObject));
|
||||
|
||||
rb_define_alloc_func(rb_ANON_Data, rb_ANON_Data_ALLOC);
|
||||
rb_define_singleton_method(rb_KernAux, "cmdline", rb_KernAux_cmdline, 1);
|
||||
}
|
||||
|
||||
VALUE rb_ANON_Data_ALLOC(const VALUE klass)
|
||||
{
|
||||
struct Data *data;
|
||||
return TypedData_Make_Struct(klass, struct Data, &info, data);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_cmdline(const VALUE self_rb, VALUE cmdline_rb)
|
||||
{
|
||||
const char *const cmdline = StringValueCStr(cmdline_rb);
|
||||
size_t argc;
|
||||
|
||||
const VALUE data_rb = rb_funcall(rb_ANON_Data, rb_intern_new, 0);
|
||||
struct Data *data;
|
||||
TypedData_Get_Struct(data_rb, struct Data, &info, data);
|
||||
if (!data) rb_raise(rb_KernAux_CmdlineError, "internal error");
|
||||
|
||||
const bool result = kernaux_cmdline(
|
||||
cmdline,
|
||||
data->error_msg,
|
||||
&argc,
|
||||
data->argv,
|
||||
data->buffer,
|
||||
ARG_COUNT_MAX,
|
||||
BUFFER_SIZE
|
||||
);
|
||||
|
||||
if (!result) rb_raise(rb_KernAux_CmdlineError, "%s", data->error_msg);
|
||||
|
||||
VALUE result_rb = rb_ary_new2(argc);
|
||||
for (size_t index = 0; index < argc; ++index) {
|
||||
rb_ary_push(
|
||||
result_rb,
|
||||
rb_funcall(rb_str_new2(data->argv[index]), rb_intern_freeze, 0)
|
||||
);
|
||||
}
|
||||
return rb_funcall(result_rb, rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
#endif // KERNAUX_VERSION_WITH_CMDLINE
|
|
@ -1,45 +0,0 @@
|
|||
#include "dynarg.h"
|
||||
|
||||
struct DynArg DynArg_create()
|
||||
{
|
||||
struct DynArg dynarg;
|
||||
DynArg_init(&dynarg);
|
||||
return dynarg;
|
||||
}
|
||||
|
||||
void DynArg_init(struct DynArg *const dynarg)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->dbl = 0.0;
|
||||
dynarg->arg.str = "";
|
||||
}
|
||||
|
||||
void DynArg_use_char(struct DynArg *const dynarg, const char chr)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.chr = chr;
|
||||
}
|
||||
|
||||
void DynArg_use_double(struct DynArg *const dynarg, const double dbl)
|
||||
{
|
||||
dynarg->use_dbl = true;
|
||||
dynarg->dbl = dbl;
|
||||
}
|
||||
|
||||
void DynArg_use_long_long(struct DynArg *const dynarg, const long long ll)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.ll = ll;
|
||||
}
|
||||
|
||||
void DynArg_use_str(struct DynArg *const dynarg, const char *const str)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.str = str;
|
||||
}
|
||||
|
||||
void DynArg_use_unsigned_long_long(struct DynArg *const dynarg, const unsigned long long ull)
|
||||
{
|
||||
dynarg->use_dbl = false;
|
||||
dynarg->arg.ull = ull;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef INCLUDED_DYNARG
|
||||
#define INCLUDED_DYNARG
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <kernaux/macro.h>
|
||||
|
||||
#include <kernaux/macro/packing_start.run>
|
||||
|
||||
struct DynArg {
|
||||
bool use_dbl;
|
||||
double dbl;
|
||||
// TODO: check if this will work on different endianness.
|
||||
union {
|
||||
char chr;
|
||||
long long ll;
|
||||
const char *str;
|
||||
unsigned long long ull;
|
||||
} KERNAUX_PACKED arg;
|
||||
}
|
||||
KERNAUX_PACKED;
|
||||
|
||||
#include <kernaux/macro/packing_end.run>
|
||||
|
||||
struct DynArg DynArg_create();
|
||||
void DynArg_init(struct DynArg *dynarg);
|
||||
|
||||
void DynArg_use_char(struct DynArg *dynarg, char chr);
|
||||
void DynArg_use_double(struct DynArg *dynarg, double dbl);
|
||||
void DynArg_use_long_long(struct DynArg *dynarg, long long ll);
|
||||
void DynArg_use_str(struct DynArg *dynarg, const char *str);
|
||||
void DynArg_use_unsigned_long_long(struct DynArg *dynarg, unsigned long long ull);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'mkmf'
|
||||
|
||||
$CFLAGS += ' -pedantic -Wall -Wextra'
|
||||
|
||||
raise 'libkernaux not found' unless have_library 'kernaux'
|
||||
|
||||
raise 'kernaux_assert_do not found' unless have_func 'kernaux_assert_do'
|
||||
unless have_var 'kernaux_assert_cb', 'kernaux.h'
|
||||
raise 'kernaux_assert_cb not found'
|
||||
end
|
||||
|
||||
raise 'can\'t create Makefile' unless create_makefile 'kernaux/default'
|
|
@ -1,34 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
ID rb_intern_call = Qnil;
|
||||
ID rb_intern_freeze = Qnil;
|
||||
ID rb_intern_LESS = Qnil;
|
||||
ID rb_intern_new = Qnil;
|
||||
|
||||
VALUE rb_KernAux = Qnil;
|
||||
VALUE rb_KernAux_Error = Qnil;
|
||||
|
||||
void Init_default()
|
||||
{
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_call = rb_intern("call")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_freeze = rb_intern("freeze")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_LESS = rb_intern("<")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_new = rb_intern("new")));
|
||||
|
||||
rb_gc_register_mark_object(rb_KernAux = rb_define_module("KernAux"));
|
||||
rb_gc_register_mark_object(rb_KernAux_Error =
|
||||
rb_define_class_under(rb_KernAux, "Error", rb_eRuntimeError));
|
||||
|
||||
init_version();
|
||||
init_assert();
|
||||
|
||||
#ifdef KERNAUX_VERSION_WITH_CMDLINE
|
||||
init_cmdline();
|
||||
#endif // KERNAUX_VERSION_WITH_CMDLINE
|
||||
#ifdef KERNAUX_VERSION_WITH_NTOA
|
||||
init_ntoa();
|
||||
#endif // KERNAUX_VERSION_WITH_NTOA
|
||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||
init_printf();
|
||||
#endif // KERNAUX_VERSION_WITH_PRINTF
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef __MAIN_H__
|
||||
#define __MAIN_H__
|
||||
|
||||
#include <kernaux.h>
|
||||
#include <ruby.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern ID rb_intern_call;
|
||||
extern ID rb_intern_freeze;
|
||||
extern ID rb_intern_LESS;
|
||||
extern ID rb_intern_new;
|
||||
|
||||
extern VALUE rb_KernAux;
|
||||
extern VALUE rb_KernAux_Error;
|
||||
|
||||
void init_version();
|
||||
void init_assert();
|
||||
|
||||
#ifdef KERNAUX_VERSION_WITH_CMDLINE
|
||||
void init_cmdline();
|
||||
#endif // KERNAUX_VERSION_WITH_CMDLINE
|
||||
#ifdef KERNAUX_VERSION_WITH_NTOA
|
||||
void init_ntoa();
|
||||
#endif // KERNAUX_VERSION_WITH_NTOA
|
||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||
void init_printf();
|
||||
#endif // KERNAUX_VERSION_WITH_PRINTF
|
||||
|
||||
#endif
|
|
@ -1,254 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
#ifdef KERNAUX_VERSION_WITH_NTOA
|
||||
|
||||
static VALUE rb_KernAux_utoa(int argc, const VALUE *argv, VALUE self);
|
||||
static VALUE rb_KernAux_itoa(int argc, const VALUE *argv, VALUE self);
|
||||
static VALUE rb_KernAux_utoa2(VALUE self, VALUE number);
|
||||
static VALUE rb_KernAux_itoa2(VALUE self, VALUE number);
|
||||
static VALUE rb_KernAux_utoa8(VALUE self, VALUE number);
|
||||
static VALUE rb_KernAux_itoa8(VALUE self, VALUE number);
|
||||
static VALUE rb_KernAux_utoa10(VALUE self, VALUE number);
|
||||
static VALUE rb_KernAux_itoa10(VALUE self, VALUE number);
|
||||
static VALUE rb_KernAux_utoa16(VALUE self, VALUE number);
|
||||
static VALUE rb_KernAux_itoa16(VALUE self, VALUE number);
|
||||
|
||||
static ID rb_intern_b = Qnil;
|
||||
static ID rb_intern_B = Qnil;
|
||||
static ID rb_intern_h = Qnil;
|
||||
static ID rb_intern_H = Qnil;
|
||||
static ID rb_intern_o = Qnil;
|
||||
static ID rb_intern_O = Qnil;
|
||||
static ID rb_intern_d = Qnil;
|
||||
static ID rb_intern_D = Qnil;
|
||||
static ID rb_intern_x = Qnil;
|
||||
static ID rb_intern_X = Qnil;
|
||||
|
||||
static VALUE rb_KernAux_InvalidNtoaBaseError = Qnil;
|
||||
static VALUE rb_KernAux_TooLongNtoaPrefixError = Qnil;
|
||||
|
||||
static int convert_base(VALUE base);
|
||||
|
||||
void init_ntoa()
|
||||
{
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_b = rb_intern("b")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_B = rb_intern("B")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_h = rb_intern("h")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_H = rb_intern("H")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_o = rb_intern("o")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_O = rb_intern("O")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_d = rb_intern("d")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_D = rb_intern("D")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_x = rb_intern("x")));
|
||||
rb_gc_register_mark_object(ID2SYM(rb_intern_X = rb_intern("X")));
|
||||
|
||||
rb_gc_register_mark_object(rb_KernAux_InvalidNtoaBaseError =
|
||||
rb_define_class_under(rb_KernAux, "InvalidNtoaBaseError",
|
||||
rb_KernAux_Error));
|
||||
rb_gc_register_mark_object(rb_KernAux_TooLongNtoaPrefixError =
|
||||
rb_define_class_under(rb_KernAux, "TooLongNtoaPrefixError",
|
||||
rb_KernAux_Error));
|
||||
|
||||
rb_define_singleton_method(rb_KernAux, "utoa", rb_KernAux_utoa, -1);
|
||||
rb_define_singleton_method(rb_KernAux, "itoa", rb_KernAux_itoa, -1);
|
||||
rb_define_singleton_method(rb_KernAux, "utoa2", rb_KernAux_utoa2, 1);
|
||||
rb_define_singleton_method(rb_KernAux, "itoa2", rb_KernAux_itoa2, 1);
|
||||
rb_define_singleton_method(rb_KernAux, "utoa8", rb_KernAux_utoa8, 1);
|
||||
rb_define_singleton_method(rb_KernAux, "itoa8", rb_KernAux_itoa8, 1);
|
||||
rb_define_singleton_method(rb_KernAux, "utoa10", rb_KernAux_utoa10, 1);
|
||||
rb_define_singleton_method(rb_KernAux, "itoa10", rb_KernAux_itoa10, 1);
|
||||
rb_define_singleton_method(rb_KernAux, "utoa16", rb_KernAux_utoa16, 1);
|
||||
rb_define_singleton_method(rb_KernAux, "itoa16", rb_KernAux_itoa16, 1);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_utoa(const int argc, const VALUE *argv, const VALUE self)
|
||||
{
|
||||
if (argc < 2 || argc > 3) {
|
||||
rb_raise(
|
||||
rb_eArgError,
|
||||
"wrong number of arguments (given %d, expected 2..3)",
|
||||
argc
|
||||
);
|
||||
}
|
||||
|
||||
VALUE number_rb = argv[0];
|
||||
VALUE base_rb = argv[1];
|
||||
VALUE prefix_rb = argc == 3 ? argv[2] : Qnil;
|
||||
|
||||
const uint64_t number = NUM2ULL(number_rb);
|
||||
|
||||
if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) {
|
||||
rb_raise(rb_eRangeError, "can't convert negative number to uint64_t");
|
||||
}
|
||||
|
||||
const char *prefix = NULL;
|
||||
long prefix_len = 0;
|
||||
if (!NIL_P(prefix_rb)) {
|
||||
prefix = StringValueCStr(prefix_rb);
|
||||
prefix_len = RSTRING_LEN(prefix_rb);
|
||||
|
||||
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
rb_raise(
|
||||
rb_KernAux_TooLongNtoaPrefixError,
|
||||
"prefix length %ld is too long",
|
||||
prefix_len
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
char buffer[KERNAUX_UTOA_MIN_BUFFER_SIZE + prefix_len];
|
||||
kernaux_utoa(number, buffer, convert_base(base_rb), prefix);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_itoa(const int argc, const VALUE *argv, const VALUE self)
|
||||
{
|
||||
if (argc < 2 || argc > 3) {
|
||||
rb_raise(
|
||||
rb_eArgError,
|
||||
"wrong number of arguments (given %d, expected 2..3)",
|
||||
argc
|
||||
);
|
||||
}
|
||||
|
||||
VALUE number_rb = argv[0];
|
||||
VALUE base_rb = argv[1];
|
||||
VALUE prefix_rb = argc == 3 ? argv[2] : Qnil;
|
||||
|
||||
const int64_t number = NUM2LL(number_rb);
|
||||
|
||||
const char *prefix = NULL;
|
||||
long prefix_len = 0;
|
||||
if (!NIL_P(prefix_rb)) {
|
||||
prefix = StringValueCStr(prefix_rb);
|
||||
prefix_len = RSTRING_LEN(prefix_rb);
|
||||
|
||||
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
rb_raise(
|
||||
rb_KernAux_TooLongNtoaPrefixError,
|
||||
"prefix length %ld is too long",
|
||||
prefix_len
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
char buffer[KERNAUX_ITOA_MIN_BUFFER_SIZE + prefix_len];
|
||||
kernaux_itoa(number, buffer, convert_base(base_rb), prefix);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_utoa2(
|
||||
const VALUE self_rb KERNAUX_UNUSED,
|
||||
const VALUE number_rb
|
||||
) {
|
||||
const uint64_t number = NUM2ULL(number_rb);
|
||||
if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) {
|
||||
rb_raise(rb_eRangeError, "can't convert negative number to uint64_t");
|
||||
}
|
||||
char buffer[KERNAUX_UTOA2_BUFFER_SIZE];
|
||||
kernaux_utoa2(number, buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_itoa2(
|
||||
const VALUE self_rb KERNAUX_UNUSED,
|
||||
const VALUE number_rb
|
||||
) {
|
||||
const int64_t number = NUM2LL(number_rb);
|
||||
char buffer[KERNAUX_ITOA2_BUFFER_SIZE];
|
||||
kernaux_itoa2(number, buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_utoa8(
|
||||
const VALUE self_rb KERNAUX_UNUSED,
|
||||
const VALUE number_rb
|
||||
) {
|
||||
const uint64_t number = NUM2ULL(number_rb);
|
||||
if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) {
|
||||
rb_raise(rb_eRangeError, "can't convert negative number to uint64_t");
|
||||
}
|
||||
char buffer[KERNAUX_UTOA8_BUFFER_SIZE];
|
||||
kernaux_utoa8(number, buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_itoa8(
|
||||
const VALUE self_rb KERNAUX_UNUSED,
|
||||
const VALUE number_rb
|
||||
) {
|
||||
const int64_t number = NUM2LL(number_rb);
|
||||
char buffer[KERNAUX_ITOA8_BUFFER_SIZE];
|
||||
kernaux_itoa8(number, buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_utoa10(
|
||||
const VALUE self_rb KERNAUX_UNUSED,
|
||||
const VALUE number_rb
|
||||
) {
|
||||
const uint64_t number = NUM2ULL(number_rb);
|
||||
if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) {
|
||||
rb_raise(rb_eRangeError, "can't convert negative number to uint64_t");
|
||||
}
|
||||
char buffer[KERNAUX_UTOA10_BUFFER_SIZE];
|
||||
kernaux_utoa10(number, buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_itoa10(
|
||||
const VALUE self_rb KERNAUX_UNUSED,
|
||||
const VALUE number_rb
|
||||
) {
|
||||
const int64_t number = NUM2LL(number_rb);
|
||||
char buffer[KERNAUX_ITOA10_BUFFER_SIZE];
|
||||
kernaux_itoa10(number, buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_utoa16(
|
||||
const VALUE self_rb KERNAUX_UNUSED,
|
||||
const VALUE number_rb
|
||||
) {
|
||||
const uint64_t number = NUM2ULL(number_rb);
|
||||
if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) {
|
||||
rb_raise(rb_eRangeError, "can't convert negative number to uint64_t");
|
||||
}
|
||||
char buffer[KERNAUX_UTOA16_BUFFER_SIZE];
|
||||
kernaux_utoa16(number, buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_itoa16(
|
||||
const VALUE self_rb KERNAUX_UNUSED,
|
||||
const VALUE number_rb
|
||||
) {
|
||||
const int64_t number = NUM2LL(number_rb);
|
||||
char buffer[KERNAUX_ITOA16_BUFFER_SIZE];
|
||||
kernaux_itoa16(number, buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
int convert_base(const VALUE base_rb)
|
||||
{
|
||||
if (TYPE(base_rb) == T_SYMBOL) {
|
||||
const ID base_id = SYM2ID(base_rb);
|
||||
if (base_id == rb_intern_b) return 'b';
|
||||
else if (base_id == rb_intern_B) return 'B';
|
||||
else if (base_id == rb_intern_h) return 'h';
|
||||
else if (base_id == rb_intern_H) return 'H';
|
||||
else if (base_id == rb_intern_o) return 'o';
|
||||
else if (base_id == rb_intern_O) return 'O';
|
||||
else if (base_id == rb_intern_d) return 'd';
|
||||
else if (base_id == rb_intern_D) return 'D';
|
||||
else if (base_id == rb_intern_x) return 'x';
|
||||
else if (base_id == rb_intern_X) return 'X';
|
||||
else {
|
||||
rb_raise(rb_KernAux_InvalidNtoaBaseError, "invalid base");
|
||||
}
|
||||
} else {
|
||||
return NUM2INT(base_rb);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // KERNAUX_VERSION_WITH_NTOA
|
|
@ -1,137 +0,0 @@
|
|||
#include "main.h"
|
||||
#include "dynarg.h"
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||
|
||||
/**
|
||||
* Typical `printf`.
|
||||
*
|
||||
* @param format [String] format string
|
||||
* @return [String] formatted output
|
||||
*
|
||||
* @example
|
||||
* KernAux.sprintf 'foo%*scar%d', 5, 'bar', 123
|
||||
* #=> "foo barcar123"
|
||||
*/
|
||||
static VALUE rb_KernAux_sprintf(int argc, VALUE *argv, VALUE self);
|
||||
|
||||
void init_printf()
|
||||
{
|
||||
rb_define_singleton_method(rb_KernAux, "sprintf", rb_KernAux_sprintf, -1);
|
||||
}
|
||||
|
||||
#define TAKE_ARG \
|
||||
if (arg_index >= argc) rb_raise(rb_eArgError, "too few arguments"); \
|
||||
VALUE arg_rb = argv[arg_index++]; \
|
||||
do {} while (0)
|
||||
|
||||
VALUE rb_KernAux_sprintf(const int argc, VALUE *const argv, VALUE self)
|
||||
{
|
||||
if (argc == 0) rb_raise(rb_eArgError, "too few arguments");
|
||||
|
||||
const char *format = StringValueCStr(argv[0]);
|
||||
int arg_index = 1;
|
||||
VALUE result = rb_str_new_literal("");
|
||||
|
||||
while (*format) {
|
||||
if (*format != '%') {
|
||||
rb_str_cat(result, format, 1);
|
||||
++format;
|
||||
continue;
|
||||
}
|
||||
|
||||
++format;
|
||||
struct KernAux_PrintfFmt_Spec spec =
|
||||
KernAux_PrintfFmt_Spec_create_out(&format);
|
||||
|
||||
if (spec.set_width) {
|
||||
TAKE_ARG;
|
||||
KernAux_PrintfFmt_Spec_set_width(&spec, NUM2INT(arg_rb));
|
||||
}
|
||||
if (spec.set_precision) {
|
||||
TAKE_ARG;
|
||||
KernAux_PrintfFmt_Spec_set_precision(&spec, NUM2INT(arg_rb));
|
||||
}
|
||||
|
||||
struct DynArg dynarg = DynArg_create();
|
||||
|
||||
if (spec.type == KERNAUX_PRINTF_FMT_TYPE_INT) {
|
||||
TAKE_ARG;
|
||||
DynArg_use_long_long(&dynarg, NUM2LL(arg_rb));
|
||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_UINT) {
|
||||
TAKE_ARG;
|
||||
DynArg_use_unsigned_long_long(&dynarg, NUM2ULL(arg_rb));
|
||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_FLOAT ||
|
||||
spec.type == KERNAUX_PRINTF_FMT_TYPE_EXP)
|
||||
{
|
||||
TAKE_ARG;
|
||||
DynArg_use_double(&dynarg, NUM2DBL(arg_rb));
|
||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_CHAR) {
|
||||
TAKE_ARG;
|
||||
Check_Type(arg_rb, T_STRING);
|
||||
DynArg_use_char(&dynarg, *StringValuePtr(arg_rb));
|
||||
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_STR) {
|
||||
TAKE_ARG;
|
||||
Check_Type(arg_rb, T_STRING);
|
||||
DynArg_use_str(&dynarg, StringValueCStr(arg_rb));
|
||||
}
|
||||
|
||||
// 1 additional byte for the '%' character.
|
||||
// 1 additional byte for the terminating '\0' character.
|
||||
char old_format[2 + spec.format_limit - spec.format_start];
|
||||
memset(old_format, '\0', sizeof(old_format));
|
||||
old_format[0] = '%';
|
||||
strncpy(&old_format[1], spec.format_start, sizeof(old_format) - 2);
|
||||
|
||||
char buffer[BUFFER_SIZE];
|
||||
int slen;
|
||||
|
||||
if (spec.set_width) {
|
||||
if (spec.set_precision) {
|
||||
if (dynarg.use_dbl) {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.width, spec.precision,
|
||||
dynarg.dbl);
|
||||
} else {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.width, spec.precision,
|
||||
dynarg.arg);
|
||||
}
|
||||
} else {
|
||||
if (dynarg.use_dbl) {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.width, dynarg.dbl);
|
||||
} else {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.width, dynarg.arg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (spec.set_precision) {
|
||||
if (dynarg.use_dbl) {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.precision, dynarg.dbl);
|
||||
} else {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
||||
spec.precision, dynarg.arg);
|
||||
}
|
||||
} else {
|
||||
if (dynarg.use_dbl) {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.dbl);
|
||||
} else {
|
||||
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rb_str_cat(result, buffer, slen);
|
||||
}
|
||||
|
||||
if (arg_index < argc) rb_raise(rb_eArgError, "too many arguments");
|
||||
|
||||
return rb_funcall(result, rb_intern_freeze, 0);
|
||||
}
|
||||
|
||||
#endif // KERNAUX_VERSION_WITH_PRINTF
|
|
@ -1,47 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
static VALUE rb_KernAux_Version_with_cmdlineQN(VALUE self);
|
||||
static VALUE rb_KernAux_Version_with_ntoaQN(VALUE self);
|
||||
static VALUE rb_KernAux_Version_with_printfQN(VALUE self);
|
||||
|
||||
static VALUE rb_KernAux_Version = Qnil;
|
||||
|
||||
void init_version()
|
||||
{
|
||||
rb_gc_register_mark_object(rb_KernAux_Version =
|
||||
rb_define_module_under(rb_KernAux, "Version"));
|
||||
|
||||
rb_define_singleton_method(rb_KernAux_Version, "with_cmdline?",
|
||||
rb_KernAux_Version_with_cmdlineQN, 0);
|
||||
rb_define_singleton_method(rb_KernAux_Version, "with_ntoa?",
|
||||
rb_KernAux_Version_with_ntoaQN, 0);
|
||||
rb_define_singleton_method(rb_KernAux_Version, "with_printf?",
|
||||
rb_KernAux_Version_with_printfQN, 0);
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_Version_with_cmdlineQN(VALUE self)
|
||||
{
|
||||
#ifdef KERNAUX_VERSION_WITH_CMDLINE
|
||||
return Qtrue;
|
||||
#else
|
||||
return Qfalse;
|
||||
#endif
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_Version_with_ntoaQN(VALUE self)
|
||||
{
|
||||
#ifdef KERNAUX_VERSION_WITH_NTOA
|
||||
return Qtrue;
|
||||
#else
|
||||
return Qfalse;
|
||||
#endif
|
||||
}
|
||||
|
||||
VALUE rb_KernAux_Version_with_printfQN(VALUE self)
|
||||
{
|
||||
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
||||
return Qtrue;
|
||||
#else
|
||||
return Qfalse;
|
||||
#endif
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'lib/kernaux/version'
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
repo = 'https://github.com/tailix/libkernaux'
|
||||
home = "#{repo}/tree/master/bindings/ruby"
|
||||
bugs = "#{repo}/issues"
|
||||
docs = "https://www.rubydoc.info/gems/kernaux/#{KernAux::VERSION}"
|
||||
|
||||
spec.name = 'kernaux'
|
||||
spec.version = KernAux::VERSION
|
||||
spec.license = 'MIT'
|
||||
spec.homepage = home
|
||||
spec.platform = Gem::Platform::RUBY
|
||||
|
||||
spec.required_ruby_version = '~> 3.0'
|
||||
|
||||
spec.authors = ['Alex Kotov']
|
||||
spec.email = %w[kotovalexarian@gmail.com]
|
||||
|
||||
spec.summary =
|
||||
'Binding to libkernaux - auxiliary library for kernel development'
|
||||
|
||||
spec.description = <<~DESCRIPTION.split("\n").map(&:strip).join ' '
|
||||
Binding to libkernaux - auxiliary library for kernel development.
|
||||
DESCRIPTION
|
||||
|
||||
spec.metadata['rubygems_mfa_required'] = 'true'
|
||||
spec.metadata['homepage_uri'] = home
|
||||
spec.metadata['source_code_uri'] = home
|
||||
spec.metadata['bug_tracker_uri'] = bugs
|
||||
spec.metadata['documentation_uri'] = docs
|
||||
|
||||
spec.bindir = 'exe'
|
||||
spec.require_paths = ['lib']
|
||||
|
||||
spec.files = Dir.chdir File.expand_path __dir__ do
|
||||
`git ls-files -z`.split("\x0").reject do |f|
|
||||
f.match %r{\A(?:test|spec|features)/}
|
||||
end
|
||||
end
|
||||
|
||||
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename f }
|
||||
|
||||
spec.extensions << 'ext/default/extconf.rb'
|
||||
|
||||
spec.add_development_dependency 'bundler', '~> 2.2'
|
||||
spec.add_development_dependency 'pry', '~> 0.14'
|
||||
spec.add_development_dependency 'rake', '~> 13.0'
|
||||
spec.add_development_dependency 'rake-compiler', '~> 1.1'
|
||||
spec.add_development_dependency 'rspec', '~> 3.10'
|
||||
spec.add_development_dependency 'rubocop', '~> 1.25'
|
||||
spec.add_development_dependency 'rubocop-performance', '~> 1.13'
|
||||
spec.add_development_dependency 'rubocop-rake', '~> 0.6'
|
||||
spec.add_development_dependency 'rubocop-rspec', '~> 2.7'
|
||||
spec.add_development_dependency 'simplecov', '~> 0.21'
|
||||
spec.add_development_dependency 'yard', '~> 0.9'
|
||||
end
|
|
@ -1,19 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
##
|
||||
# Binding to [libkernaux](https://github.com/tailix/libkernaux) - auxiliary
|
||||
# library for kernel development.
|
||||
#
|
||||
module KernAux
|
||||
end
|
||||
|
||||
require_relative 'kernaux/version'
|
||||
|
||||
# Native extensions
|
||||
require_relative 'kernaux/default'
|
||||
|
||||
# Non-standard directory structure
|
||||
require_relative 'kernaux/assert'
|
||||
require_relative 'kernaux/cmdline'
|
||||
require_relative 'kernaux/errors'
|
||||
require_relative 'kernaux/ntoa'
|
|
@ -1,58 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop:disable Style/Documentation
|
||||
begin; end
|
||||
|
||||
module KernAux
|
||||
# Default callback for assertions.
|
||||
# @see .assert_cb
|
||||
DEFAULT_ASSERT_CB = @assert_cb = lambda { |file, line, msg|
|
||||
raise AssertError, "#{file}:#{line}:#{msg}"
|
||||
}
|
||||
|
||||
# @!scope class
|
||||
|
||||
##
|
||||
# @!attribute [rw] assert_cb
|
||||
# Panic callback.
|
||||
#
|
||||
# @return [Proc]
|
||||
#
|
||||
# @api unsafe
|
||||
#
|
||||
# @see .panic
|
||||
# @see .assert_do
|
||||
##
|
||||
|
||||
##
|
||||
# Raise assertion with implicit file and line, retrieved from `caller`, and
|
||||
# explicit message.
|
||||
#
|
||||
# @param msg [String] any message
|
||||
# @return [nil]
|
||||
#
|
||||
# @raise [AssertError] if {.assert_cb} have not been changed
|
||||
#
|
||||
# @see .assert_do Explicit file and line.
|
||||
#
|
||||
def self.panic(msg)
|
||||
file, line = caller(1..1).first.split(':')[0..1]
|
||||
assert_do file, Integer(line), msg
|
||||
end
|
||||
|
||||
##
|
||||
# @!method assert_do(file, line, msg)
|
||||
# Raise assertion with explicit file, line and message.
|
||||
#
|
||||
# @param file [String] file name, usually from `__FILE__`
|
||||
# @param line [Integer] line number, usually from `__LINE__`
|
||||
# @param msg [String] any message
|
||||
# @return [nil]
|
||||
#
|
||||
# @raise [AssertError] if {.assert_cb} have not been changed
|
||||
#
|
||||
# @see .panic Implicit file and line
|
||||
##
|
||||
end
|
||||
|
||||
# rubocop:enable Style/Documentation
|
|
@ -1,20 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop:disable Style/Documentation
|
||||
begin; end
|
||||
|
||||
module KernAux
|
||||
# @!scope class
|
||||
|
||||
##
|
||||
# @!method cmdline(str)
|
||||
# Parse command line.
|
||||
#
|
||||
# @param str [String] command line string
|
||||
# @return [Array<String>] command line arguments
|
||||
#
|
||||
# @raise [CmdlineError] syntax is invalid
|
||||
##
|
||||
end
|
||||
|
||||
# rubocop:enable Style/Documentation
|
|
@ -1,39 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module KernAux
|
||||
##
|
||||
# Our base class for runtime errors.
|
||||
#
|
||||
class Error < RuntimeError; end
|
||||
|
||||
##
|
||||
# Raised when assertion has failed or panic has been called.
|
||||
#
|
||||
# @see .panic
|
||||
# @see .assert_do
|
||||
#
|
||||
class AssertError < Error; end
|
||||
|
||||
##
|
||||
# Raised when command line parsing goes wrong.
|
||||
#
|
||||
# @see .cmdline
|
||||
#
|
||||
class CmdlineError < Error; end
|
||||
|
||||
##
|
||||
# Raised when integer base is invalid.
|
||||
#
|
||||
# @see .utoa
|
||||
# @see .itoa
|
||||
#
|
||||
class InvalidNtoaBaseError < Error; end
|
||||
|
||||
##
|
||||
# Raised when prefix is too long.
|
||||
#
|
||||
# @see .utoa
|
||||
# @see .itoa
|
||||
#
|
||||
class TooLongNtoaPrefixError < Error; end
|
||||
end
|
|
@ -1,136 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop:disable Style/Documentation
|
||||
begin; end
|
||||
|
||||
module KernAux
|
||||
# @!scope class
|
||||
|
||||
##
|
||||
# @!method utoa(number, base, prefix)
|
||||
# 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
|
||||
# which is an alias to a valid integer value. Positive integers and lowercase
|
||||
# symbols mean lowercase output when base is greater than 10. Negative
|
||||
# integers and uppercase symbols mean uppercase output when base is greater
|
||||
# than 10. Aliases are: `:b`, `:B` - 2; `:o`, `:O` - 8; `:d`, `:D` - 10; `:h`,
|
||||
# `:x` - 16 (lowercase); `:H`, `:X` - -10 (uppercase).
|
||||
#
|
||||
# @param number [Integer] a number between 0 and `UINT64_MAX`
|
||||
# @param base [Integer, Symbol] base of a numeral system
|
||||
# @param prefix [nil, String] string to put before a number
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
# @raise [InvalidNtoaBaseError] base is invalid
|
||||
# @raise [TooLongNtoaPrefixError] prefix is too long
|
||||
#
|
||||
# @see .itoa Convert signed integers
|
||||
##
|
||||
|
||||
##
|
||||
# @!method itoa(number, base, prefix)
|
||||
# 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
|
||||
# which is an alias to a valid integer value. Positive integers and lowercase
|
||||
# symbols mean lowercase output when base is greater than 10. Negative
|
||||
# integers and uppercase symbols mean uppercase output when base is greater
|
||||
# than 10. Aliases are: `:b`, `:B` - 2; `:o`, `:O` - 8; `:d`, `:D` - 10; `:h`,
|
||||
# `:x` - 16 (lowercase); `:H`, `:X` - -10 (uppercase).
|
||||
#
|
||||
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
|
||||
# @param base [Integer, Symbol] base of a numeral system
|
||||
# @param prefix [nil, String] string to put between a sign and a number
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
# @raise [InvalidNtoaBaseError] base is invalid
|
||||
# @raise [TooLongNtoaPrefixError] prefix is too long
|
||||
#
|
||||
# @see .utoa Convert unsigned integers
|
||||
##
|
||||
|
||||
##
|
||||
# @!method utoa2(number)
|
||||
# Convert `uint64_t` to a binary string.
|
||||
#
|
||||
# @param number [Integer] a number between 0 and `UINT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
|
||||
##
|
||||
# @!method itoa2(number)
|
||||
# Convert `int64_t` to a binary string.
|
||||
#
|
||||
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
|
||||
##
|
||||
# @!method utoa8(number)
|
||||
# Convert `uint64_t` to a octal string.
|
||||
#
|
||||
# @param number [Integer] a number between 0 and `UINT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
|
||||
##
|
||||
# @!method itoa8(number)
|
||||
# Convert `int64_t` to a octal string.
|
||||
#
|
||||
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
|
||||
##
|
||||
# @!method utoa10(number)
|
||||
# Convert `uint64_t` to a decimal string.
|
||||
#
|
||||
# @param number [Integer] a number between 0 and `UINT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
|
||||
##
|
||||
# @!method itoa10(number)
|
||||
# Convert `int64_t` to a decimal string.
|
||||
#
|
||||
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
|
||||
##
|
||||
# @!method utoa16(number)
|
||||
# Convert `uint64_t` to a hexadecimal string.
|
||||
#
|
||||
# @param number [Integer] a number between 0 and `UINT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
|
||||
##
|
||||
# @!method itoa16(number)
|
||||
# Convert `int64_t` to a hexadecimal string.
|
||||
#
|
||||
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
end
|
||||
|
||||
# rubocop:enable Style/Documentation
|
|
@ -1,13 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module KernAux
|
||||
# Gem version.
|
||||
VERSION = '0.7.0'
|
||||
|
||||
##
|
||||
# This module includes functions to determine if specific features are
|
||||
# supported by the library.
|
||||
#
|
||||
module Version
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe KernAux, '.panic' do
|
||||
subject(:panic) { described_class.panic msg }
|
||||
|
||||
let(:msg) { 'Hello, World!' }
|
||||
|
||||
specify do
|
||||
expect { panic }.to \
|
||||
raise_error described_class::AssertError, /\A#{__FILE__}:\d+:#{msg}\z/
|
||||
end
|
||||
|
||||
context 'when custom assertion callback has beed set' do
|
||||
around do |example|
|
||||
described_class.assert_cb = lambda { |file, line, msg|
|
||||
raise "file: #{file.inspect}, line: #{line}, msg: #{msg.inspect}"
|
||||
}
|
||||
example.run
|
||||
ensure
|
||||
described_class.assert_cb = described_class::DEFAULT_ASSERT_CB
|
||||
end
|
||||
|
||||
specify do
|
||||
expect { panic }.to raise_error(
|
||||
RuntimeError,
|
||||
/\Afile: #{__FILE__.inspect}, line: \d+, msg: #{msg.inspect}\z/,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,115 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_cmdline? and RSpec.describe KernAux, '.cmdline' do
|
||||
subject(:cmdline) { described_class.cmdline str }
|
||||
|
||||
let(:str) { 'foo bar\\ baz "car cdr"' }
|
||||
|
||||
it { is_expected.to be_instance_of Array }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to all be_instance_of String }
|
||||
it { is_expected.to all be_frozen }
|
||||
it { is_expected.to eq ['foo', 'bar baz', 'car cdr'] }
|
||||
|
||||
context 'when str is empty' do
|
||||
let(:str) { '' }
|
||||
|
||||
it { is_expected.to eq [] }
|
||||
end
|
||||
|
||||
context 'when str has invalid type' do
|
||||
let(:str) { 123 }
|
||||
|
||||
specify { expect { cmdline }.to raise_error TypeError }
|
||||
end
|
||||
|
||||
context 'when str has EOL after backslash' do
|
||||
let(:str) { '\\' }
|
||||
|
||||
specify do
|
||||
expect { cmdline }.to \
|
||||
raise_error described_class::CmdlineError, 'EOL after backslash'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when str has EOL after backslash inside quote' do
|
||||
let(:str) { '"\\' }
|
||||
|
||||
specify do
|
||||
expect { cmdline }.to raise_error \
|
||||
described_class::CmdlineError, 'EOL after backslash inside quote'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when str has unescaped quotation mark' do
|
||||
let(:str) { 'foo"' }
|
||||
|
||||
specify do
|
||||
expect { cmdline }.to \
|
||||
raise_error described_class::CmdlineError, 'unescaped quotation mark'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when str has EOL inside quote' do
|
||||
let(:str) { '"' }
|
||||
|
||||
specify do
|
||||
expect { cmdline }.to \
|
||||
raise_error described_class::CmdlineError, 'EOL inside quote'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are not too many args' do
|
||||
let(:str) { 'a ' * 256 }
|
||||
|
||||
it { is_expected.to eq ['a'] * 256 }
|
||||
end
|
||||
|
||||
context 'when there are too many args' do
|
||||
let(:str) { 'a ' * 257 }
|
||||
|
||||
specify do
|
||||
expect { cmdline }.to \
|
||||
raise_error described_class::CmdlineError, 'too many args'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when args don\'t cause buffer overflow' do
|
||||
let(:str) { 'a' * 4095 }
|
||||
|
||||
it { is_expected.to eq ['a' * 4095] }
|
||||
end
|
||||
|
||||
context 'when args cause buffer overflow' do
|
||||
let(:str) { 'a' * 4096 }
|
||||
|
||||
specify do
|
||||
expect { cmdline }.to \
|
||||
raise_error described_class::CmdlineError, 'EOF or buffer overflow'
|
||||
end
|
||||
end
|
||||
|
||||
context 'using fixtures' do
|
||||
cmdline_yml =
|
||||
File.expand_path('../../../../../fixtures/cmdline.yml', __dir__)
|
||||
|
||||
YAML.safe_load_file(cmdline_yml).each do |test|
|
||||
escape_str = lambda do |str|
|
||||
eval "\"#{str}\"", binding, __FILE__, __LINE__ # "str"
|
||||
end
|
||||
|
||||
cmdline = escape_str.call test['cmdline']
|
||||
arg_count_max = test['arg_count_max']
|
||||
buffer_size = test['buffer_size']
|
||||
result = test['result']&.map(&escape_str)
|
||||
|
||||
next unless arg_count_max.nil? && buffer_size.nil? && !result.nil?
|
||||
|
||||
it "transforms #{cmdline.inspect} to #{result.inspect}" do
|
||||
expect(described_class.cmdline(cmdline)).to eq result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,70 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa10' do
|
||||
subject(:itoa10) { described_class.itoa10 number }
|
||||
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)) }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0' }
|
||||
end
|
||||
|
||||
context 'when number is 1' do
|
||||
let(:number) { 1 }
|
||||
|
||||
it { is_expected.to eq '1' }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
it { is_expected.to eq '-1' }
|
||||
end
|
||||
|
||||
context 'when number is min int64_t' do
|
||||
let(:number) { -2**63 }
|
||||
|
||||
it { is_expected.to eq number.to_s }
|
||||
end
|
||||
|
||||
context 'when number is max int64_t' do
|
||||
let(:number) { 2**63 - 1 }
|
||||
|
||||
it { is_expected.to eq number.to_s }
|
||||
end
|
||||
|
||||
context 'when number is lesser than min uint64_t' do
|
||||
let(:number) { -2**63 - 1 }
|
||||
|
||||
specify do
|
||||
expect { itoa10 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**63 }
|
||||
|
||||
specify do
|
||||
expect { itoa10 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { itoa10 }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,72 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa16' do
|
||||
subject(:itoa16) { described_class.itoa16 number }
|
||||
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)) }
|
||||
|
||||
def sign = number < 0 ? '-' : ''
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "#{sign}0x#{number.abs.to_s(16)}" }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0x0' }
|
||||
end
|
||||
|
||||
context 'when number is 1' do
|
||||
let(:number) { 1 }
|
||||
|
||||
it { is_expected.to eq '0x1' }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
it { is_expected.to eq '-0x1' }
|
||||
end
|
||||
|
||||
context 'when number is min int64_t' do
|
||||
let(:number) { -2**63 }
|
||||
|
||||
it { is_expected.to eq "-0x#{number.abs.to_s(16)}" }
|
||||
end
|
||||
|
||||
context 'when number is max int64_t' do
|
||||
let(:number) { 2**63 - 1 }
|
||||
|
||||
it { is_expected.to eq "0x#{number.to_s(16)}" }
|
||||
end
|
||||
|
||||
context 'when number is lesser than min uint64_t' do
|
||||
let(:number) { -2**63 - 1 }
|
||||
|
||||
specify do
|
||||
expect { itoa16 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**63 }
|
||||
|
||||
specify do
|
||||
expect { itoa16 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { itoa16 }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,72 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa2' do
|
||||
subject(:itoa2) { described_class.itoa2 number }
|
||||
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)) }
|
||||
|
||||
def sign = number < 0 ? '-' : ''
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "#{sign}0b#{number.abs.to_s(2)}" }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0b0' }
|
||||
end
|
||||
|
||||
context 'when number is 1' do
|
||||
let(:number) { 1 }
|
||||
|
||||
it { is_expected.to eq '0b1' }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
it { is_expected.to eq '-0b1' }
|
||||
end
|
||||
|
||||
context 'when number is min int64_t' do
|
||||
let(:number) { -2**63 }
|
||||
|
||||
it { is_expected.to eq "-0b#{number.abs.to_s(2)}" }
|
||||
end
|
||||
|
||||
context 'when number is max int64_t' do
|
||||
let(:number) { 2**63 - 1 }
|
||||
|
||||
it { is_expected.to eq "0b#{number.to_s(2)}" }
|
||||
end
|
||||
|
||||
context 'when number is lesser than min uint64_t' do
|
||||
let(:number) { -2**63 - 1 }
|
||||
|
||||
specify do
|
||||
expect { itoa2 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**63 }
|
||||
|
||||
specify do
|
||||
expect { itoa2 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { itoa2 }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,72 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa8' do
|
||||
subject(:itoa8) { described_class.itoa8 number }
|
||||
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)) }
|
||||
|
||||
def sign = number < 0 ? '-' : ''
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "#{sign}0o#{number.abs.to_s(8)}" }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0o0' }
|
||||
end
|
||||
|
||||
context 'when number is 1' do
|
||||
let(:number) { 1 }
|
||||
|
||||
it { is_expected.to eq '0o1' }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
it { is_expected.to eq '-0o1' }
|
||||
end
|
||||
|
||||
context 'when number is min int64_t' do
|
||||
let(:number) { -2**63 }
|
||||
|
||||
it { is_expected.to eq "-0o#{number.abs.to_s(8)}" }
|
||||
end
|
||||
|
||||
context 'when number is max int64_t' do
|
||||
let(:number) { 2**63 - 1 }
|
||||
|
||||
it { is_expected.to eq "0o#{number.to_s(8)}" }
|
||||
end
|
||||
|
||||
context 'when number is lesser than min uint64_t' do
|
||||
let(:number) { -2**63 - 1 }
|
||||
|
||||
specify do
|
||||
expect { itoa8 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**63 }
|
||||
|
||||
specify do
|
||||
expect { itoa8 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { itoa8 }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,245 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa' do
|
||||
subject(:itoa) { described_class.itoa number, base, prefix }
|
||||
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)) }
|
||||
let(:base) { rand 2..36 }
|
||||
let(:prefix) { [nil, ''].sample }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq '0' }
|
||||
end
|
||||
|
||||
context 'when number is 1' do
|
||||
let(:number) { 1 }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq '1' }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq '-1' }
|
||||
end
|
||||
|
||||
context 'when number is min int64_t' do
|
||||
let(:number) { -2**63 }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
end
|
||||
|
||||
context 'when number is max int64_t' do
|
||||
let(:number) { 2**63 - 1 }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
end
|
||||
|
||||
context 'when number is lesser than min uint64_t' do
|
||||
let(:number) { -2**63 - 1 }
|
||||
|
||||
specify do
|
||||
expect { itoa }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**63 }
|
||||
|
||||
specify do
|
||||
expect { itoa }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { itoa }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when base is negative' do
|
||||
let(:base) { -rand(2..36) }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s(-base).upcase }
|
||||
end
|
||||
|
||||
context 'when base is :b' do
|
||||
let(:base) { :b }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 2 }
|
||||
end
|
||||
|
||||
context 'when base is :B:' do
|
||||
let(:base) { :B }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 2 }
|
||||
end
|
||||
|
||||
context 'when base is :o' do
|
||||
let(:base) { :o }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 8 }
|
||||
end
|
||||
|
||||
context 'when base is :O' do
|
||||
let(:base) { :O }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 8 }
|
||||
end
|
||||
|
||||
context 'when base is :d' do
|
||||
let(:base) { :d }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s }
|
||||
end
|
||||
|
||||
context 'when base is :D' do
|
||||
let(:base) { :D }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s }
|
||||
end
|
||||
|
||||
context 'when base is :h' do
|
||||
let(:base) { :h }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 16 }
|
||||
end
|
||||
|
||||
context 'when base is :x' do
|
||||
let(:base) { :x }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 16 }
|
||||
end
|
||||
|
||||
context 'when base is :H' do
|
||||
let(:base) { :H }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s(16).upcase }
|
||||
end
|
||||
|
||||
context 'when base is :X' do
|
||||
let(:base) { :X }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s(16).upcase }
|
||||
end
|
||||
|
||||
context 'when base is an invalid symbol' do
|
||||
let(:base) { :foo }
|
||||
|
||||
specify do
|
||||
expect { itoa }.to \
|
||||
raise_error described_class::InvalidNtoaBaseError, 'invalid base'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no prefix is given' do
|
||||
subject(:itoa) { described_class.itoa number, base }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
end
|
||||
|
||||
context 'when prefix is nil' do
|
||||
let(:prefix) { nil }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
end
|
||||
|
||||
context 'when prefix is empty' do
|
||||
let(:prefix) { '' }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
end
|
||||
|
||||
context 'when prefix is present' do
|
||||
let(:prefix) { 'foo' }
|
||||
|
||||
def sign = number < 0 ? '-' : ''
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "#{sign}foo#{number.abs.to_s(base)}" }
|
||||
end
|
||||
|
||||
context 'when prefix is not a string' do
|
||||
let(:prefix) { 123 }
|
||||
|
||||
specify do
|
||||
expect { itoa }.to raise_error(
|
||||
TypeError,
|
||||
"no implicit conversion of #{prefix.class} into String",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when prefix has max length' do
|
||||
let(:prefix) { 'a' * 100 }
|
||||
|
||||
def sign = number < 0 ? '-' : ''
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "#{sign}#{prefix}#{number.abs.to_s(base)}" }
|
||||
end
|
||||
|
||||
context 'when prefix is too long' do
|
||||
let(:prefix) { 'a' * 101 }
|
||||
|
||||
specify do
|
||||
expect { itoa }.to raise_error(
|
||||
described_class::TooLongNtoaPrefixError,
|
||||
"prefix length #{prefix.length} is too long",
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,52 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa10' do
|
||||
subject(:utoa10) { described_class.utoa10 number }
|
||||
|
||||
let(:number) { rand 0..(2**64 - 1) }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0' }
|
||||
end
|
||||
|
||||
context 'when number is max uint64_t' do
|
||||
let(:number) { 2**64 - 1 }
|
||||
|
||||
it { is_expected.to eq number.to_s }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
specify do
|
||||
expect { utoa10 }.to \
|
||||
raise_error RangeError, 'can\'t convert negative number to uint64_t'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**64 }
|
||||
|
||||
specify do
|
||||
expect { utoa10 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `unsigned long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand(0..(2**64 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { utoa10 }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,52 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa16' do
|
||||
subject(:utoa16) { described_class.utoa16 number }
|
||||
|
||||
let(:number) { rand 0..(2**64 - 1) }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "0x#{number.to_s(16)}" }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0x0' }
|
||||
end
|
||||
|
||||
context 'when number is max uint64_t' do
|
||||
let(:number) { 2**64 - 1 }
|
||||
|
||||
it { is_expected.to eq "0x#{number.to_s(16)}" }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
specify do
|
||||
expect { utoa16 }.to \
|
||||
raise_error RangeError, 'can\'t convert negative number to uint64_t'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**64 }
|
||||
|
||||
specify do
|
||||
expect { utoa16 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `unsigned long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand(0..(2**64 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { utoa16 }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,52 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa2' do
|
||||
subject(:utoa2) { described_class.utoa2 number }
|
||||
|
||||
let(:number) { rand 0..(2**64 - 1) }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "0b#{number.to_s(2)}" }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0b0' }
|
||||
end
|
||||
|
||||
context 'when number is max uint64_t' do
|
||||
let(:number) { 2**64 - 1 }
|
||||
|
||||
it { is_expected.to eq "0b#{number.to_s(2)}" }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
specify do
|
||||
expect { utoa2 }.to \
|
||||
raise_error RangeError, 'can\'t convert negative number to uint64_t'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**64 }
|
||||
|
||||
specify do
|
||||
expect { utoa2 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `unsigned long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand(0..(2**64 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { utoa2 }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,52 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa8' do
|
||||
subject(:utoa8) { described_class.utoa8 number }
|
||||
|
||||
let(:number) { rand 0..(2**64 - 1) }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "0o#{number.to_s(8)}" }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0o0' }
|
||||
end
|
||||
|
||||
context 'when number is max uint64_t' do
|
||||
let(:number) { 2**64 - 1 }
|
||||
|
||||
it { is_expected.to eq "0o#{number.to_s(8)}" }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
specify do
|
||||
expect { utoa8 }.to \
|
||||
raise_error RangeError, 'can\'t convert negative number to uint64_t'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**64 }
|
||||
|
||||
specify do
|
||||
expect { utoa8 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `unsigned long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand(0..(2**64 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { utoa8 }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,217 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa' do
|
||||
subject(:utoa) { described_class.utoa number, base, prefix }
|
||||
|
||||
let(:number) { rand 0..(2**64 - 1) }
|
||||
let(:base) { rand 2..36 }
|
||||
let(:prefix) { [nil, ''].sample }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq '0' }
|
||||
end
|
||||
|
||||
context 'when number is max uint64_t' do
|
||||
let(:number) { 2**64 - 1 }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
specify do
|
||||
expect { utoa }.to \
|
||||
raise_error RangeError, 'can\'t convert negative number to uint64_t'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**64 }
|
||||
|
||||
specify do
|
||||
expect { utoa }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `unsigned long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is not numeric' do
|
||||
let(:number) { rand(0..(2**64 - 1)).to_s }
|
||||
|
||||
specify do
|
||||
expect { utoa }.to raise_error \
|
||||
TypeError, 'no implicit conversion from string'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when base is negative' do
|
||||
let(:base) { -rand(2..36) }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s(-base).upcase }
|
||||
end
|
||||
|
||||
context 'when base is :b' do
|
||||
let(:base) { :b }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 2 }
|
||||
end
|
||||
|
||||
context 'when base is :B:' do
|
||||
let(:base) { :B }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 2 }
|
||||
end
|
||||
|
||||
context 'when base is :o' do
|
||||
let(:base) { :o }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 8 }
|
||||
end
|
||||
|
||||
context 'when base is :O' do
|
||||
let(:base) { :O }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 8 }
|
||||
end
|
||||
|
||||
context 'when base is :d' do
|
||||
let(:base) { :d }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s }
|
||||
end
|
||||
|
||||
context 'when base is :D' do
|
||||
let(:base) { :D }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s }
|
||||
end
|
||||
|
||||
context 'when base is :h' do
|
||||
let(:base) { :h }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 16 }
|
||||
end
|
||||
|
||||
context 'when base is :x' do
|
||||
let(:base) { :x }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s 16 }
|
||||
end
|
||||
|
||||
context 'when base is :H' do
|
||||
let(:base) { :H }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s(16).upcase }
|
||||
end
|
||||
|
||||
context 'when base is :X' do
|
||||
let(:base) { :X }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s(16).upcase }
|
||||
end
|
||||
|
||||
context 'when base is an invalid symbol' do
|
||||
let(:base) { :foo }
|
||||
|
||||
specify do
|
||||
expect { utoa }.to \
|
||||
raise_error described_class::InvalidNtoaBaseError, 'invalid base'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no prefix is given' do
|
||||
subject(:utoa) { described_class.utoa number, base }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
end
|
||||
|
||||
context 'when prefix is nil' do
|
||||
let(:prefix) { nil }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
end
|
||||
|
||||
context 'when prefix is empty' do
|
||||
let(:prefix) { '' }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq number.to_s base }
|
||||
end
|
||||
|
||||
context 'when prefix is present' do
|
||||
let(:prefix) { 'foo' }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "#{prefix}#{number.to_s(base)}" }
|
||||
end
|
||||
|
||||
context 'when prefix is not a string' do
|
||||
let(:prefix) { 123 }
|
||||
|
||||
specify do
|
||||
expect { utoa }.to raise_error(
|
||||
TypeError,
|
||||
"no implicit conversion of #{prefix.class} into String",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when prefix has max length' do
|
||||
let(:prefix) { 'a' * 100 }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "#{prefix}#{number.to_s(base)}" }
|
||||
end
|
||||
|
||||
context 'when prefix is too long' do
|
||||
let(:prefix) { 'a' * 101 }
|
||||
|
||||
specify do
|
||||
expect { utoa }.to raise_error(
|
||||
described_class::TooLongNtoaPrefixError,
|
||||
"prefix length #{prefix.length} is too long",
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,85 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
KernAux::Version.with_printf? and RSpec.describe KernAux, '.sprintf' do
|
||||
subject :sprintf do
|
||||
described_class.sprintf 'Hello, %s!', 'World'
|
||||
end
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq 'Hello, World!' }
|
||||
|
||||
context 'when there are too many arguments' do
|
||||
[
|
||||
['Hello!', 'World!'],
|
||||
['Hello, %s!', 'World', 'Alex'],
|
||||
].each do |args|
|
||||
it "raises on #{args.inspect}" do
|
||||
expect { described_class.sprintf(*args) }.to \
|
||||
raise_error ArgumentError, 'too many arguments'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are too few arguments' do
|
||||
[
|
||||
[],
|
||||
['Hello, %s!'],
|
||||
['Hello, %*s!', 20],
|
||||
['Hello, %.*s!', 20],
|
||||
['Hello, %*.*s!', 20, 20],
|
||||
].each do |args|
|
||||
it "raises on #{args.inspect}" do
|
||||
expect { described_class.sprintf(*args) }.to \
|
||||
raise_error ArgumentError, 'too few arguments'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
[
|
||||
['', 'using regular fixtures'],
|
||||
['_orig', 'using original fixtures'],
|
||||
].each do |(suffix, description)|
|
||||
context description do
|
||||
printf_yml = File.expand_path(
|
||||
"../../../../../fixtures/printf#{suffix}.yml",
|
||||
__dir__,
|
||||
)
|
||||
|
||||
YAML.safe_load_file(printf_yml).each do |test|
|
||||
expected = test['result']
|
||||
|
||||
format = ''
|
||||
args = []
|
||||
|
||||
test['args'].each do |arg|
|
||||
if arg.is_a? String
|
||||
format += arg
|
||||
else
|
||||
format += arg[0]
|
||||
arg[1..].each do |item|
|
||||
if item.is_a? Array
|
||||
if item.length == 1
|
||||
args << item[0]
|
||||
elsif item[0] == 'long long'
|
||||
args << item[1]
|
||||
else
|
||||
raise "Unknown format: #{args.inspect}"
|
||||
end
|
||||
else
|
||||
args << item
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "transforms (#{format.inspect}, #{args.inspect[1...-1]}) " \
|
||||
"to #{expected.inspect}" do
|
||||
expect(described_class.sprintf(format, *args)).to eq expected
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,11 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe KernAux do
|
||||
describe '::VERSION' do
|
||||
specify do
|
||||
expect(described_class::VERSION).to match(/\A\d+\.\d+\.\d+\z/)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,106 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This should be on the top of the file.
|
||||
require 'simplecov'
|
||||
|
||||
# This file was generated by the `rspec --init` command. Conventionally, all
|
||||
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
||||
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
||||
# this file to always be loaded, without a need to explicitly require it in any
|
||||
# files.
|
||||
#
|
||||
# Given that it is always loaded, you are encouraged to keep this file as
|
||||
# light-weight as possible. Requiring heavyweight dependencies from this file
|
||||
# will add to the boot time of your test suite on EVERY test run, even for an
|
||||
# individual file that may not need all of that loaded. Instead, consider making
|
||||
# a separate helper file that requires the additional dependencies and performs
|
||||
# the additional setup, and require it from the spec files that actually need
|
||||
# it.
|
||||
#
|
||||
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
||||
|
||||
require 'kernaux'
|
||||
|
||||
require 'yaml'
|
||||
|
||||
RSpec.configure do |config|
|
||||
# rspec-expectations config goes here. You can use an alternate
|
||||
# assertion/expectation library such as wrong or the stdlib/minitest
|
||||
# assertions if you prefer.
|
||||
config.expect_with :rspec do |expectations|
|
||||
# This option will default to `true` in RSpec 4. It makes the `description`
|
||||
# and `failure_message` of custom matchers include text for helper methods
|
||||
# defined using `chain`, e.g.:
|
||||
# be_bigger_than(2).and_smaller_than(4).description
|
||||
# # => "be bigger than 2 and smaller than 4"
|
||||
# ...rather than:
|
||||
# # => "be bigger than 2"
|
||||
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
||||
end
|
||||
|
||||
# rspec-mocks config goes here. You can use an alternate test double
|
||||
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
||||
config.mock_with :rspec do |mocks|
|
||||
# Prevents you from mocking or stubbing a method that does not exist on
|
||||
# a real object. This is generally recommended, and will default to
|
||||
# `true` in RSpec 4.
|
||||
mocks.verify_partial_doubles = true
|
||||
end
|
||||
|
||||
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will
|
||||
# have no way to turn it off -- the option exists only for backwards
|
||||
# compatibility in RSpec 3). It causes shared context metadata to be
|
||||
# inherited by the metadata hash of host groups and examples, rather than
|
||||
# triggering implicit auto-inclusion in groups with matching metadata.
|
||||
config.shared_context_metadata_behavior = :apply_to_host_groups
|
||||
|
||||
# This allows you to limit a spec run to individual examples or groups
|
||||
# you care about by tagging them with `:focus` metadata. When nothing
|
||||
# is tagged with `:focus`, all examples get run. RSpec also provides
|
||||
# aliases for `it`, `describe`, and `context` that include `:focus`
|
||||
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
||||
config.filter_run_when_matching :focus
|
||||
|
||||
# Allows RSpec to persist some state between runs in order to support
|
||||
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
||||
# you configure your source control system to ignore this file.
|
||||
config.example_status_persistence_file_path = 'spec/examples.txt'
|
||||
|
||||
# Limits the available syntax to the non-monkey patched syntax that is
|
||||
# recommended. For more details, see:
|
||||
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
||||
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
||||
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
||||
config.disable_monkey_patching!
|
||||
|
||||
# This setting enables warnings. It's recommended, but in some cases may
|
||||
# be too noisy due to issues in dependencies.
|
||||
config.warnings = true
|
||||
|
||||
# Many RSpec users commonly either run the entire suite or an individual
|
||||
# file, and it's useful to allow more verbose output when running an
|
||||
# individual spec file.
|
||||
if config.files_to_run.one?
|
||||
# Use the documentation formatter for detailed output,
|
||||
# unless a formatter has already been configured
|
||||
# (e.g. via a command-line flag).
|
||||
config.default_formatter = 'doc'
|
||||
end
|
||||
|
||||
# Print the 10 slowest examples and example groups at the
|
||||
# end of the spec run, to help surface which specs are running
|
||||
# particularly slow.
|
||||
config.profile_examples = 10
|
||||
|
||||
# Run specs in random order to surface order dependencies. If you find an
|
||||
# order dependency and want to debug it, you can fix the order by providing
|
||||
# the seed, which is printed after each run.
|
||||
# --seed 1234
|
||||
config.order = :random
|
||||
|
||||
# Seed global randomization in this process using the `--seed` CLI option.
|
||||
# Setting this allows you to use `--seed` to deterministically reproduce
|
||||
# test failures related to randomization by passing the same `--seed` value
|
||||
# as the one that triggered the failure.
|
||||
Kernel.srand config.seed
|
||||
end
|
2
bindings/rust/.gitignore
vendored
2
bindings/rust/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
/Cargo.lock
|
||||
/target/
|
|
@ -1,5 +0,0 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"kernaux",
|
||||
"kernaux-sys",
|
||||
]
|
|
@ -1,23 +0,0 @@
|
|||
[package]
|
||||
name = "kernaux-sys"
|
||||
version = "0.7.0"
|
||||
authors = ["Alex Kotov <kotovalexarian@gmail.com>"]
|
||||
edition = "2021"
|
||||
description = "Unsafe no-std binding to libkernaux - auxiliary library for kernel development"
|
||||
readme = true
|
||||
homepage = "https://github.com/tailix/libkernaux/tree/master/bindings/rust"
|
||||
repository = "https://github.com/tailix/libkernaux/tree/master/bindings/rust"
|
||||
license = "MIT"
|
||||
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
|
||||
features = ["extra_traits"]
|
|
@ -1,8 +0,0 @@
|
|||
kernaux_sys
|
||||
===========
|
||||
|
||||
[![Build status](https://github.com/tailix/libkernaux/actions/workflows/rust.yml/badge.svg)](https://github.com/tailix/libkernaux/actions/workflows/rust.yml)
|
||||
[![Build status (FreeBSD)](https://api.cirrus-ci.com/github/tailix/libkernaux.svg?task=Rust%20(FreeBSD))](https://cirrus-ci.com/github/tailix/libkernaux)
|
||||
|
||||
Unsafe no-std binding to [libkernaux](https://github.com/tailix/libkernaux) -
|
||||
auxiliary library for kernel development.
|
|
@ -1,67 +0,0 @@
|
|||
use libc::{c_char, c_int};
|
||||
|
||||
pub type AssertCB = unsafe extern "C" fn(*const c_char, c_int, *const c_char);
|
||||
|
||||
#[link(name = "kernaux")]
|
||||
extern "C" {
|
||||
#[link_name = "kernaux_assert_do"]
|
||||
pub fn assert_do(file: *const c_char, line: c_int, msg: *const c_char);
|
||||
|
||||
#[link_name = "kernaux_assert_cb"]
|
||||
pub static mut assert_cb: Option<AssertCB>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ptr::null;
|
||||
|
||||
static mut LAST_FILE: *const c_char = null();
|
||||
static mut LAST_LINE: c_int = 0;
|
||||
static mut LAST_MSG: *const c_char = null();
|
||||
|
||||
unsafe extern "C" fn some_assert_cb(
|
||||
file: *const c_char,
|
||||
line: c_int,
|
||||
msg: *const c_char,
|
||||
) {
|
||||
LAST_FILE = file;
|
||||
LAST_LINE = line;
|
||||
LAST_MSG = msg;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default() {
|
||||
unsafe {
|
||||
assert_cb = None;
|
||||
assert!(assert_cb.is_none());
|
||||
|
||||
assert_cb = Some(some_assert_cb);
|
||||
match assert_cb {
|
||||
None => panic!(),
|
||||
Some(actual_assert_cb) => {
|
||||
assert!(actual_assert_cb == some_assert_cb)
|
||||
}
|
||||
}
|
||||
|
||||
let file_cstr = CString::new("foo.rs").unwrap();
|
||||
let msg_cstr = CString::new("bar").unwrap();
|
||||
|
||||
assert_do(
|
||||
file_cstr.as_ptr() as *const c_char,
|
||||
123,
|
||||
msg_cstr.as_ptr() as *const c_char,
|
||||
);
|
||||
|
||||
let file = CStr::from_ptr(LAST_FILE).to_str().unwrap();
|
||||
let line = LAST_LINE;
|
||||
let msg = CStr::from_ptr(LAST_MSG).to_str().unwrap();
|
||||
|
||||
assert_eq!(file, "foo.rs");
|
||||
assert_eq!(line, 123);
|
||||
assert_eq!(msg, "bar");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
use libc::{c_char, size_t};
|
||||
|
||||
pub const ERROR_MSG_SIZE_MAX: usize = 256;
|
||||
pub const ERROR_MSG_SLEN_MAX: usize = ERROR_MSG_SIZE_MAX - 1;
|
||||
|
||||
#[link(name = "kernaux")]
|
||||
extern "C" {
|
||||
#[link_name = "kernaux_cmdline"]
|
||||
// TODO: Rust's "bool" is not guaranteed to be compatible with C's one
|
||||
pub fn cmdline(
|
||||
cmdline: *const c_char,
|
||||
error_msg: *mut c_char,
|
||||
argc: *mut size_t,
|
||||
argv: *mut *mut c_char,
|
||||
buffer: *mut c_char,
|
||||
arg_count_max: size_t,
|
||||
buffer_size: size_t,
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
const ARG_COUNT_MAX: usize = 100;
|
||||
const BUFFER_SIZE: usize = 4096;
|
||||
|
||||
#[test]
|
||||
fn default() {
|
||||
let cmdline = CString::new("foo bar\\ baz \"car cdr\"").unwrap();
|
||||
|
||||
let mut error_msg: [c_char; ERROR_MSG_SIZE_MAX] =
|
||||
[0; ERROR_MSG_SIZE_MAX];
|
||||
let mut argc: size_t = 0;
|
||||
let mut argv: [*mut c_char; ARG_COUNT_MAX] =
|
||||
[0 as *mut c_char; ARG_COUNT_MAX];
|
||||
let mut buffer: [c_char; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||
|
||||
unsafe {
|
||||
assert!(super::cmdline(
|
||||
cmdline.as_ptr(),
|
||||
error_msg.as_mut_ptr(),
|
||||
&mut argc,
|
||||
argv.as_mut_ptr(),
|
||||
buffer.as_mut_ptr(),
|
||||
ARG_COUNT_MAX,
|
||||
BUFFER_SIZE,
|
||||
));
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
unsafe { CStr::from_ptr(error_msg.as_ptr()) }
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
"",
|
||||
);
|
||||
assert_eq!(argc, 3);
|
||||
assert_eq!(unsafe { CStr::from_ptr(argv[0]) }.to_str().unwrap(), "foo");
|
||||
assert_eq!(
|
||||
unsafe { CStr::from_ptr(argv[1]) }.to_str().unwrap(),
|
||||
"bar baz",
|
||||
);
|
||||
assert_eq!(
|
||||
unsafe { CStr::from_ptr(argv[2]) }.to_str().unwrap(),
|
||||
"car cdr",
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#![no_std]
|
||||
|
||||
#[cfg(test)]
|
||||
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, *};
|
|
@ -1,266 +0,0 @@
|
|||
use libc::{c_char, c_int};
|
||||
|
||||
pub const MAX_PREFIX_LEN: usize = 100;
|
||||
|
||||
pub const UTOA_MIN_BUFFER_SIZE: usize = 64 + 1;
|
||||
pub const ITOA_MIN_BUFFER_SIZE: usize = 65 + 1;
|
||||
|
||||
pub const UTOA2_BUFFER_SIZE: usize = 64 + 2 + 1;
|
||||
pub const ITOA2_BUFFER_SIZE: usize = 65 + 2 + 1;
|
||||
pub const UTOA8_BUFFER_SIZE: usize = 21 + 2 + 1;
|
||||
pub const ITOA8_BUFFER_SIZE: usize = 22 + 2 + 1;
|
||||
pub const UTOA10_BUFFER_SIZE: usize = 20 + 1;
|
||||
pub const ITOA10_BUFFER_SIZE: usize = 20 + 1;
|
||||
pub const UTOA16_BUFFER_SIZE: usize = 16 + 2 + 1;
|
||||
pub const ITOA16_BUFFER_SIZE: usize = 17 + 2 + 1;
|
||||
|
||||
#[link(name = "kernaux")]
|
||||
extern "C" {
|
||||
#[link_name = "kernaux_utoa"]
|
||||
pub fn utoa(
|
||||
value: u64,
|
||||
buffer: *mut c_char,
|
||||
base: c_int,
|
||||
prefix: *const c_char,
|
||||
) -> *mut c_char;
|
||||
#[link_name = "kernaux_itoa"]
|
||||
pub fn itoa(
|
||||
value: i64,
|
||||
buffer: *mut c_char,
|
||||
base: c_int,
|
||||
prefix: *const c_char,
|
||||
) -> *mut c_char;
|
||||
|
||||
#[link_name = "kernaux_utoa2"]
|
||||
pub fn utoa2(value: u64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_itoa2"]
|
||||
pub fn itoa2(value: i64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_utoa8"]
|
||||
pub fn utoa8(value: u64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_itoa8"]
|
||||
pub fn itoa8(value: i64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_utoa10"]
|
||||
pub fn utoa10(value: u64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_itoa10"]
|
||||
pub fn itoa10(value: i64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_utoa16"]
|
||||
pub fn utoa16(value: u64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_itoa16"]
|
||||
pub fn itoa16(value: i64, buffer: *mut c_char) -> *mut c_char;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ptr::null;
|
||||
|
||||
fn empty_prefix() -> CString {
|
||||
CString::new("").unwrap()
|
||||
}
|
||||
|
||||
fn foo_prefix() -> CString {
|
||||
CString::new("foo").unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa() {
|
||||
let mut buffer: [i8; UTOA_MIN_BUFFER_SIZE + 3] =
|
||||
[0; UTOA_MIN_BUFFER_SIZE + 3];
|
||||
|
||||
let empty_pfx = empty_prefix();
|
||||
let foo_pfx = foo_prefix();
|
||||
|
||||
let end: *mut c_char =
|
||||
unsafe { utoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, null()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
||||
|
||||
let end: *mut c_char = unsafe {
|
||||
utoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, empty_pfx.as_ptr())
|
||||
};
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
||||
|
||||
let end: *mut c_char = unsafe {
|
||||
utoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, foo_pfx.as_ptr())
|
||||
};
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "foo123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(6) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa() {
|
||||
let mut buffer: [i8; ITOA_MIN_BUFFER_SIZE + 3] =
|
||||
[0; ITOA_MIN_BUFFER_SIZE + 3];
|
||||
|
||||
let empty_pfx = empty_prefix();
|
||||
let foo_pfx = foo_prefix();
|
||||
|
||||
let end: *mut c_char =
|
||||
unsafe { itoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, null()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
||||
|
||||
let end: *mut c_char = unsafe {
|
||||
itoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, empty_pfx.as_ptr())
|
||||
};
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
||||
|
||||
let end: *mut c_char = unsafe {
|
||||
itoa(0x123, buffer.as_mut_ptr(), 'x' as c_int, foo_pfx.as_ptr())
|
||||
};
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "foo123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(6) });
|
||||
|
||||
let end: *mut c_char =
|
||||
unsafe { itoa(-0x123, buffer.as_mut_ptr(), 'x' as c_int, null()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "-123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(4) });
|
||||
|
||||
let end: *mut c_char = unsafe {
|
||||
itoa(
|
||||
-0x123,
|
||||
buffer.as_mut_ptr(),
|
||||
'x' as c_int,
|
||||
empty_pfx.as_ptr(),
|
||||
)
|
||||
};
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "-123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(4) });
|
||||
|
||||
let end: *mut c_char = unsafe {
|
||||
itoa(-0x123, buffer.as_mut_ptr(), 'x' as c_int, foo_pfx.as_ptr())
|
||||
};
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "-foo123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(7) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa2() {
|
||||
let mut buffer: [i8; UTOA2_BUFFER_SIZE] = [0; UTOA2_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { utoa2(123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "0b1111011");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(9) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa2() {
|
||||
let mut buffer: [i8; ITOA2_BUFFER_SIZE] = [0; ITOA2_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa2(123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "0b1111011");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(9) });
|
||||
|
||||
let mut buffer: [i8; ITOA2_BUFFER_SIZE] = [0; ITOA2_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa2(-123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "-0b1111011");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(10) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa8() {
|
||||
let mut buffer: [i8; UTOA8_BUFFER_SIZE] = [0; UTOA8_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { utoa8(0o123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "0o123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(5) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa8() {
|
||||
let mut buffer: [i8; ITOA8_BUFFER_SIZE] = [0; ITOA8_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa8(0o123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "0o123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(5) });
|
||||
|
||||
let mut buffer: [i8; ITOA8_BUFFER_SIZE] = [0; ITOA8_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa8(-0o123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "-0o123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(6) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa10() {
|
||||
let mut buffer: [i8; UTOA10_BUFFER_SIZE] = [0; UTOA10_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { utoa10(123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa10() {
|
||||
let mut buffer: [i8; ITOA10_BUFFER_SIZE] = [0; ITOA10_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa10(123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(3) });
|
||||
|
||||
let mut buffer: [i8; ITOA10_BUFFER_SIZE] = [0; ITOA10_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa10(-123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "-123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(4) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa16() {
|
||||
let mut buffer: [i8; UTOA16_BUFFER_SIZE] = [0; UTOA16_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { utoa16(0x123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "0x123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(5) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa16() {
|
||||
let mut buffer: [i8; ITOA16_BUFFER_SIZE] = [0; ITOA16_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa16(0x123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "0x123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(5) });
|
||||
|
||||
let mut buffer: [i8; ITOA16_BUFFER_SIZE] = [0; ITOA16_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa16(-0x123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "-0x123");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(6) });
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
pub fn with_cmdline() -> bool {
|
||||
cfg!(feature = "cmdline")
|
||||
}
|
||||
|
||||
pub fn with_ntoa() -> bool {
|
||||
cfg!(feature = "ntoa")
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
[package]
|
||||
name = "kernaux"
|
||||
version = "0.7.0"
|
||||
authors = ["Alex Kotov <kotovalexarian@gmail.com>"]
|
||||
edition = "2021"
|
||||
description = "Safe binding to libkernaux - auxiliary library for kernel development"
|
||||
readme = true
|
||||
homepage = "https://github.com/tailix/libkernaux/tree/master/bindings/rust"
|
||||
repository = "https://github.com/tailix/libkernaux/tree/master/bindings/rust"
|
||||
license = "MIT"
|
||||
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.7.0"
|
||||
default-features = false
|
||||
path = "../kernaux-sys"
|
||||
|
||||
[dependencies.libc]
|
||||
version = "0.2.113"
|
||||
default-features = false
|
|
@ -1,8 +0,0 @@
|
|||
kernaux
|
||||
=======
|
||||
|
||||
[![Build status](https://github.com/tailix/libkernaux/actions/workflows/rust.yml/badge.svg)](https://github.com/tailix/libkernaux/actions/workflows/rust.yml)
|
||||
[![Build status (FreeBSD)](https://api.cirrus-ci.com/github/tailix/libkernaux.svg?task=Rust%20(FreeBSD))](https://cirrus-ci.com/github/tailix/libkernaux)
|
||||
|
||||
Safe binding to [libkernaux](https://github.com/tailix/libkernaux) - auxiliary
|
||||
library for kernel development.
|
|
@ -1,33 +0,0 @@
|
|||
use ctor::ctor;
|
||||
use libc::{c_char, c_int};
|
||||
use std::ffi::CStr;
|
||||
|
||||
#[ctor]
|
||||
unsafe fn ctor() {
|
||||
kernaux_sys::assert_cb = Some(assert_cb);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn assert_cb(
|
||||
file: *const c_char,
|
||||
line: c_int,
|
||||
msg: *const c_char,
|
||||
) {
|
||||
let file = CStr::from_ptr(file).to_str().unwrap();
|
||||
let msg = CStr::from_ptr(msg).to_str().unwrap();
|
||||
|
||||
panic!("{}:{}:{}", file, line, msg);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::ffi::CString;
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "foo.rs:123:bar")]
|
||||
fn default() {
|
||||
let file = CString::new("foo.rs").unwrap();
|
||||
let msg = CString::new("bar").unwrap();
|
||||
|
||||
unsafe { kernaux_sys::assert_do(file.as_ptr(), 123, msg.as_ptr()) }
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
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);
|
||||
assert_eq!(NtoaConfig::try_from('x'), NtoaConfig::try_from(16));
|
||||
assert_eq!(NtoaConfig::try_from('X'), NtoaConfig::try_from(-16));
|
||||
|
||||
assert_eq!(utoa(123, Default::default(), None), Ok("123".into()));
|
||||
assert_eq!(itoa(123, Default::default(), None), Ok("123".into()));
|
||||
assert_eq!(itoa(-123, Default::default(), None), Ok("-123".into()));
|
||||
|
||||
assert_eq!(
|
||||
utoa(123, Default::default(), Some("foo")),
|
||||
Ok("foo123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(123, Default::default(), Some("foo")),
|
||||
Ok("foo123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(-123, Default::default(), Some("foo")),
|
||||
Ok("-foo123".into()),
|
||||
);
|
||||
|
||||
assert_eq!(utoa2(123), "0b1111011");
|
||||
assert_eq!(itoa2(123), "0b1111011");
|
||||
assert_eq!(utoa8(0o123), "0o123");
|
||||
assert_eq!(itoa8(0o123), "0o123");
|
||||
assert_eq!(utoa10(123), "123");
|
||||
assert_eq!(itoa10(123), "123");
|
||||
assert_eq!(utoa16(0x123), "0x123");
|
||||
assert_eq!(itoa16(0x123), "0x123");
|
||||
}
|
||||
}
|
|
@ -1,771 +0,0 @@
|
|||
use kernaux_sys::ntoa::{
|
||||
itoa as kernaux_itoa, itoa10 as kernaux_itoa10, itoa16 as kernaux_itoa16,
|
||||
itoa2 as kernaux_itoa2, itoa8 as kernaux_itoa8, utoa as kernaux_utoa,
|
||||
utoa10 as kernaux_utoa10, utoa16 as kernaux_utoa16, utoa2 as kernaux_utoa2,
|
||||
utoa8 as kernaux_utoa8, ITOA10_BUFFER_SIZE, ITOA16_BUFFER_SIZE,
|
||||
ITOA2_BUFFER_SIZE, ITOA8_BUFFER_SIZE, ITOA_MIN_BUFFER_SIZE, MAX_PREFIX_LEN,
|
||||
UTOA10_BUFFER_SIZE, UTOA16_BUFFER_SIZE, UTOA2_BUFFER_SIZE,
|
||||
UTOA8_BUFFER_SIZE, UTOA_MIN_BUFFER_SIZE,
|
||||
};
|
||||
|
||||
use std::ffi::{CStr, CString, NulError};
|
||||
use std::ptr::null;
|
||||
use std::str::Utf8Error;
|
||||
|
||||
use libc::c_int;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct Config {
|
||||
base: u8,
|
||||
uppercase: bool,
|
||||
}
|
||||
|
||||
pub type Result = std::result::Result<String, Error>;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Error {
|
||||
PrefixTooLong(usize),
|
||||
PrefixIncludesNull(NulError),
|
||||
Utf8(Utf8Error),
|
||||
}
|
||||
|
||||
pub fn utoa(value: u64, config: Config, prefix: Option<&str>) -> Result {
|
||||
let prefix = if let Some(prefix) = prefix {
|
||||
if prefix.len() > MAX_PREFIX_LEN {
|
||||
return Err(Error::PrefixTooLong(prefix.len()));
|
||||
}
|
||||
Some(CString::new(prefix)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
utoac(value, config, prefix)
|
||||
}
|
||||
|
||||
pub fn itoa(value: i64, config: Config, prefix: Option<&str>) -> Result {
|
||||
let prefix = if let Some(prefix) = prefix {
|
||||
if prefix.len() > MAX_PREFIX_LEN {
|
||||
return Err(Error::PrefixTooLong(prefix.len()));
|
||||
}
|
||||
Some(CString::new(prefix)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
itoac(value, config, prefix)
|
||||
}
|
||||
|
||||
fn utoac(value: u64, config: Config, prefix: Option<CString>) -> Result {
|
||||
let mut buffer: [i8; UTOA_MIN_BUFFER_SIZE + MAX_PREFIX_LEN] =
|
||||
[0; UTOA_MIN_BUFFER_SIZE + MAX_PREFIX_LEN];
|
||||
|
||||
unsafe {
|
||||
kernaux_utoa(
|
||||
value,
|
||||
buffer.as_mut_ptr(),
|
||||
config.to_c_int(),
|
||||
prefix
|
||||
.as_ref()
|
||||
.map(|prefix| prefix.as_ptr())
|
||||
.unwrap_or(null()),
|
||||
);
|
||||
};
|
||||
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str()?;
|
||||
Ok(String::from(result))
|
||||
}
|
||||
|
||||
fn itoac(value: i64, config: Config, prefix: Option<CString>) -> Result {
|
||||
let mut buffer: [i8; ITOA_MIN_BUFFER_SIZE + MAX_PREFIX_LEN] =
|
||||
[0; ITOA_MIN_BUFFER_SIZE + MAX_PREFIX_LEN];
|
||||
|
||||
unsafe {
|
||||
kernaux_itoa(
|
||||
value,
|
||||
buffer.as_mut_ptr(),
|
||||
config.to_c_int(),
|
||||
prefix
|
||||
.as_ref()
|
||||
.map(|prefix| prefix.as_ptr())
|
||||
.unwrap_or(null()),
|
||||
);
|
||||
};
|
||||
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str()?;
|
||||
Ok(String::from(result))
|
||||
}
|
||||
|
||||
pub fn utoa2(value: u64) -> String {
|
||||
let mut buffer: [i8; UTOA2_BUFFER_SIZE] = [0; UTOA2_BUFFER_SIZE];
|
||||
unsafe { kernaux_utoa2(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
pub fn itoa2(value: i64) -> String {
|
||||
let mut buffer: [i8; ITOA2_BUFFER_SIZE] = [0; ITOA2_BUFFER_SIZE];
|
||||
unsafe { kernaux_itoa2(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
pub fn utoa8(value: u64) -> String {
|
||||
let mut buffer: [i8; UTOA8_BUFFER_SIZE] = [0; UTOA8_BUFFER_SIZE];
|
||||
unsafe { kernaux_utoa8(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
pub fn itoa8(value: i64) -> String {
|
||||
let mut buffer: [i8; ITOA8_BUFFER_SIZE] = [0; ITOA8_BUFFER_SIZE];
|
||||
unsafe { kernaux_itoa8(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
pub fn utoa10(value: u64) -> String {
|
||||
let mut buffer: [i8; UTOA10_BUFFER_SIZE] = [0; UTOA10_BUFFER_SIZE];
|
||||
unsafe { kernaux_utoa10(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
pub fn itoa10(value: i64) -> String {
|
||||
let mut buffer: [i8; ITOA10_BUFFER_SIZE] = [0; ITOA10_BUFFER_SIZE];
|
||||
unsafe { kernaux_itoa10(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
pub fn utoa16(value: u64) -> String {
|
||||
let mut buffer: [i8; UTOA16_BUFFER_SIZE] = [0; UTOA16_BUFFER_SIZE];
|
||||
unsafe { kernaux_utoa16(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
pub fn itoa16(value: i64) -> String {
|
||||
let mut buffer: [i8; ITOA16_BUFFER_SIZE] = [0; ITOA16_BUFFER_SIZE];
|
||||
unsafe { kernaux_itoa16(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base: 10,
|
||||
uppercase: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn base(&self) -> u8 {
|
||||
self.base
|
||||
}
|
||||
|
||||
pub fn uppercase(&self) -> bool {
|
||||
self.uppercase
|
||||
}
|
||||
|
||||
fn to_c_int(self) -> c_int {
|
||||
if self.uppercase {
|
||||
(-(self.base as i8)).into()
|
||||
} else {
|
||||
self.base.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NulError> for Error {
|
||||
fn from(nul_error: NulError) -> Self {
|
||||
Self::PrefixIncludesNull(nul_error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Utf8Error> for Error {
|
||||
fn from(utf8_error: Utf8Error) -> Self {
|
||||
Self::Utf8(utf8_error)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<char> for Config {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: char) -> std::result::Result<Self, Self::Error> {
|
||||
let base: i64 = match value {
|
||||
'b' | 'B' => 2,
|
||||
'o' | 'O' => 8,
|
||||
'd' | 'D' => 10,
|
||||
'h' | 'x' => 16,
|
||||
'H' | 'X' => -16,
|
||||
_ => return Err(()),
|
||||
};
|
||||
|
||||
base.try_into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u64> for Config {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u64) -> std::result::Result<Self, Self::Error> {
|
||||
if (2..=36).contains(&value) {
|
||||
Ok(Self {
|
||||
base: value as u8,
|
||||
uppercase: false,
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<i64> for Config {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: i64) -> std::result::Result<Self, Self::Error> {
|
||||
let uppercase = value < 0;
|
||||
let value = if value < 0 { -value } else { value };
|
||||
|
||||
if (2..=36).contains(&value) {
|
||||
Ok(Self {
|
||||
base: value as u8,
|
||||
uppercase,
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for Config {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u32) -> std::result::Result<Self, Self::Error> {
|
||||
Self::try_from(value as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<i32> for Config {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: i32) -> std::result::Result<Self, Self::Error> {
|
||||
Self::try_from(value as i64)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u16> for Config {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u16) -> std::result::Result<Self, Self::Error> {
|
||||
Self::try_from(value as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<i16> for Config {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: i16) -> std::result::Result<Self, Self::Error> {
|
||||
Self::try_from(value as i64)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for Config {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u8) -> std::result::Result<Self, Self::Error> {
|
||||
Self::try_from(value as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<i8> for Config {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: i8) -> std::result::Result<Self, Self::Error> {
|
||||
Self::try_from(value as i64)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_utoa_prefix() {
|
||||
assert_eq!(
|
||||
utoa(123, Default::default(), Some("foo")),
|
||||
Ok("foo123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(
|
||||
123,
|
||||
Default::default(),
|
||||
Some("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
|
||||
),
|
||||
Ok("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(
|
||||
123,
|
||||
Default::default(),
|
||||
Some("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
|
||||
),
|
||||
Err(Error::PrefixTooLong(101)),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa_prefix() {
|
||||
assert_eq!(
|
||||
itoa(123, Default::default(), Some("foo")),
|
||||
Ok("foo123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(-123, Default::default(), Some("foo")),
|
||||
Ok("-foo123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(
|
||||
123,
|
||||
Default::default(),
|
||||
Some("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
|
||||
),
|
||||
Ok("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(
|
||||
123,
|
||||
Default::default(),
|
||||
Some("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
|
||||
),
|
||||
Err(Error::PrefixTooLong(101)),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa() {
|
||||
// binary
|
||||
assert_eq!(
|
||||
utoa(0b10110, 'b'.try_into().unwrap(), None),
|
||||
Ok("10110".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(0b10110, 'B'.try_into().unwrap(), None),
|
||||
Ok("10110".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(0b10110, 2.try_into().unwrap(), None),
|
||||
Ok("10110".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(0b10110, (-2).try_into().unwrap(), None),
|
||||
Ok("10110".into()),
|
||||
);
|
||||
|
||||
// octal
|
||||
assert_eq!(
|
||||
utoa(0o123, 'o'.try_into().unwrap(), None),
|
||||
Ok("123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(0o123, 'O'.try_into().unwrap(), None),
|
||||
Ok("123".into()),
|
||||
);
|
||||
assert_eq!(utoa(0o123, 8.try_into().unwrap(), None), Ok("123".into()));
|
||||
assert_eq!(
|
||||
utoa(0o123, (-8).try_into().unwrap(), None),
|
||||
Ok("123".into()),
|
||||
);
|
||||
|
||||
// decimal
|
||||
assert_eq!(utoa(123, Default::default(), None), Ok("123".into()));
|
||||
assert_eq!(utoa(123, 'd'.try_into().unwrap(), None), Ok("123".into()));
|
||||
assert_eq!(utoa(123, 'D'.try_into().unwrap(), None), Ok("123".into()));
|
||||
assert_eq!(utoa(123, 10.try_into().unwrap(), None), Ok("123".into()));
|
||||
assert_eq!(
|
||||
utoa(123, (-10).try_into().unwrap(), None),
|
||||
Ok("123".into()),
|
||||
);
|
||||
|
||||
// hexadecimal
|
||||
assert_eq!(
|
||||
utoa(0x123cafe, 'x'.try_into().unwrap(), None),
|
||||
Ok("123cafe".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(0x123cafe, 16.try_into().unwrap(), None),
|
||||
Ok("123cafe".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(0x123cafe, 'X'.try_into().unwrap(), None),
|
||||
Ok("123CAFE".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(0x123cafe, (-16).try_into().unwrap(), None),
|
||||
Ok("123CAFE".into()),
|
||||
);
|
||||
|
||||
// random base: 14
|
||||
assert_eq!(
|
||||
utoa(123456, 14.try_into().unwrap(), None),
|
||||
Ok("32dc4".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
utoa(123456, (-14).try_into().unwrap(), None),
|
||||
Ok("32DC4".into()),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa() {
|
||||
// binary
|
||||
assert_eq!(
|
||||
itoa(0b10110, 'b'.try_into().unwrap(), None),
|
||||
Ok("10110".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(-0b10110, 'B'.try_into().unwrap(), None),
|
||||
Ok("-10110".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(-0b10110, 2.try_into().unwrap(), None),
|
||||
Ok("-10110".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(0b10110, (-2).try_into().unwrap(), None),
|
||||
Ok("10110".into()),
|
||||
);
|
||||
|
||||
// octal
|
||||
assert_eq!(
|
||||
itoa(-0o123, 'o'.try_into().unwrap(), None),
|
||||
Ok("-123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(0o123, 'O'.try_into().unwrap(), None),
|
||||
Ok("123".into()),
|
||||
);
|
||||
assert_eq!(itoa(0o123, 8.try_into().unwrap(), None), Ok("123".into()));
|
||||
assert_eq!(
|
||||
itoa(-0o123, (-8).try_into().unwrap(), None),
|
||||
Ok("-123".into()),
|
||||
);
|
||||
|
||||
// decimal
|
||||
assert_eq!(itoa(123, Default::default(), None), Ok("123".into()));
|
||||
assert_eq!(
|
||||
itoa(-123, 'd'.try_into().unwrap(), None),
|
||||
Ok("-123".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(-123, 'D'.try_into().unwrap(), None),
|
||||
Ok("-123".into()),
|
||||
);
|
||||
assert_eq!(itoa(123, 10.try_into().unwrap(), None), Ok("123".into()));
|
||||
assert_eq!(
|
||||
itoa(123, (-10).try_into().unwrap(), None),
|
||||
Ok("123".into()),
|
||||
);
|
||||
|
||||
// hexadecimal
|
||||
assert_eq!(
|
||||
itoa(-0x123cafe, 'x'.try_into().unwrap(), None),
|
||||
Ok("-123cafe".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(0x123cafe, 16.try_into().unwrap(), None),
|
||||
Ok("123cafe".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(0x123cafe, 'X'.try_into().unwrap(), None),
|
||||
Ok("123CAFE".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(-0x123cafe, (-16).try_into().unwrap(), None),
|
||||
Ok("-123CAFE".into()),
|
||||
);
|
||||
|
||||
// random base: 14
|
||||
assert_eq!(
|
||||
itoa(123456, 14.try_into().unwrap(), None),
|
||||
Ok("32dc4".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(-123456, (-14).try_into().unwrap(), None),
|
||||
Ok("-32DC4".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(-123456, 14.try_into().unwrap(), None),
|
||||
Ok("-32dc4".into()),
|
||||
);
|
||||
assert_eq!(
|
||||
itoa(123456, (-14).try_into().unwrap(), None),
|
||||
Ok("32DC4".into()),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa2() {
|
||||
assert_eq!(utoa2(0), "0b0");
|
||||
assert_eq!(utoa2(1), "0b1");
|
||||
assert_eq!(utoa2(123), "0b1111011");
|
||||
assert_eq!(
|
||||
utoa2(u64::MAX),
|
||||
"0b1111111111111111111111111111111111111111111111111111111111111111",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa2() {
|
||||
assert_eq!(itoa2(0), "0b0");
|
||||
assert_eq!(itoa2(1), "0b1");
|
||||
assert_eq!(itoa2(-1), "-0b1");
|
||||
assert_eq!(itoa2(123), "0b1111011");
|
||||
assert_eq!(itoa2(-123), "-0b1111011");
|
||||
assert_eq!(
|
||||
itoa2(i64::MAX),
|
||||
"0b111111111111111111111111111111111111111111111111111111111111111",
|
||||
);
|
||||
assert_eq!(
|
||||
itoa2(i64::MIN),
|
||||
"-0b1000000000000000000000000000000000000000000000000000000000000000",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa8() {
|
||||
assert_eq!(utoa8(0), "0o0");
|
||||
assert_eq!(utoa8(1), "0o1");
|
||||
assert_eq!(utoa8(0o123), "0o123");
|
||||
assert_eq!(utoa8(u64::MAX), "0o1777777777777777777777");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa8() {
|
||||
assert_eq!(itoa8(0), "0o0");
|
||||
assert_eq!(itoa8(1), "0o1");
|
||||
assert_eq!(itoa8(-1), "-0o1");
|
||||
assert_eq!(itoa8(0o123), "0o123");
|
||||
assert_eq!(itoa8(-0o123), "-0o123");
|
||||
assert_eq!(itoa8(i64::MAX), "0o777777777777777777777");
|
||||
assert_eq!(itoa8(i64::MIN), "-0o1000000000000000000000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa10() {
|
||||
assert_eq!(utoa10(0), "0");
|
||||
assert_eq!(utoa10(1), "1");
|
||||
assert_eq!(utoa10(123), "123");
|
||||
assert_eq!(utoa10(u64::MAX), "18446744073709551615");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa10() {
|
||||
assert_eq!(itoa10(0), "0");
|
||||
assert_eq!(itoa10(1), "1");
|
||||
assert_eq!(itoa10(-1), "-1");
|
||||
assert_eq!(itoa10(123), "123");
|
||||
assert_eq!(itoa10(-123), "-123");
|
||||
assert_eq!(itoa10(i64::MAX), "9223372036854775807");
|
||||
assert_eq!(itoa10(i64::MIN), "-9223372036854775808");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa16() {
|
||||
assert_eq!(utoa16(0), "0x0");
|
||||
assert_eq!(utoa16(1), "0x1");
|
||||
assert_eq!(utoa16(0x123), "0x123");
|
||||
assert_eq!(utoa16(u64::MAX), "0xffffffffffffffff");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa16() {
|
||||
assert_eq!(itoa16(0), "0x0");
|
||||
assert_eq!(itoa16(1), "0x1");
|
||||
assert_eq!(itoa16(-1), "-0x1");
|
||||
assert_eq!(itoa16(0x123), "0x123");
|
||||
assert_eq!(itoa16(-0x123), "-0x123");
|
||||
assert_eq!(itoa16(i64::MAX), "0x7fffffffffffffff");
|
||||
assert_eq!(itoa16(i64::MIN), "-0x8000000000000000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_config_default() {
|
||||
assert_eq!(
|
||||
Config::default(),
|
||||
Config {
|
||||
base: 10,
|
||||
uppercase: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_config_from_unsigned() {
|
||||
assert_eq!(Config::try_from(12u8), Config::try_from(12u64));
|
||||
assert_eq!(Config::try_from(12i8), Config::try_from(12i64));
|
||||
assert_eq!(Config::try_from(12u16), Config::try_from(12u64));
|
||||
assert_eq!(Config::try_from(12i16), Config::try_from(12i64));
|
||||
assert_eq!(Config::try_from(12u32), Config::try_from(12u64));
|
||||
assert_eq!(Config::try_from(12i32), Config::try_from(12i64));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_config_from_u64() {
|
||||
assert_eq!(Config::try_from(0u64), Err(()));
|
||||
assert_eq!(Config::try_from(1u64), Err(()));
|
||||
assert_eq!(Config::try_from(37u64), Err(()));
|
||||
assert_eq!(
|
||||
Config::try_from(2u64),
|
||||
Ok(Config {
|
||||
base: 2,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from(10u64),
|
||||
Ok(Config {
|
||||
base: 10,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from(36u64),
|
||||
Ok(Config {
|
||||
base: 36,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_config_from_i64() {
|
||||
assert_eq!(Config::try_from(0i64), Err(()));
|
||||
assert_eq!(Config::try_from(1i64), Err(()));
|
||||
assert_eq!(Config::try_from(-1i64), Err(()));
|
||||
assert_eq!(Config::try_from(37i64), Err(()));
|
||||
assert_eq!(Config::try_from(-37i64), Err(()));
|
||||
assert_eq!(
|
||||
Config::try_from(2i64),
|
||||
Ok(Config {
|
||||
base: 2,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from(-2i64),
|
||||
Ok(Config {
|
||||
base: 2,
|
||||
uppercase: true,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from(10i64),
|
||||
Ok(Config {
|
||||
base: 10,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from(-10i64),
|
||||
Ok(Config {
|
||||
base: 10,
|
||||
uppercase: true,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from(36i64),
|
||||
Ok(Config {
|
||||
base: 36,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from(-36i64),
|
||||
Ok(Config {
|
||||
base: 36,
|
||||
uppercase: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_config_from_char() {
|
||||
assert_eq!(Config::try_from('a'), Err(()));
|
||||
assert_eq!(Config::try_from('A'), Err(()));
|
||||
assert_eq!(Config::try_from('z'), Err(()));
|
||||
assert_eq!(Config::try_from('Z'), Err(()));
|
||||
assert_eq!(
|
||||
Config::try_from('b'),
|
||||
Ok(Config {
|
||||
base: 2,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from('B'),
|
||||
Ok(Config {
|
||||
base: 2,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from('o'),
|
||||
Ok(Config {
|
||||
base: 8,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from('O'),
|
||||
Ok(Config {
|
||||
base: 8,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from('d'),
|
||||
Ok(Config {
|
||||
base: 10,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from('D'),
|
||||
Ok(Config {
|
||||
base: 10,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from('h'),
|
||||
Ok(Config {
|
||||
base: 16,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from('H'),
|
||||
Ok(Config {
|
||||
base: 16,
|
||||
uppercase: true,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from('x'),
|
||||
Ok(Config {
|
||||
base: 16,
|
||||
uppercase: false,
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
Config::try_from('X'),
|
||||
Ok(Config {
|
||||
base: 16,
|
||||
uppercase: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
../../kernaux-sys/src/version.rs
|
|
@ -1 +0,0 @@
|
|||
max_width = 80
|
Loading…
Reference in a new issue