kernaux 0.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of kernaux might be problematic. Click here for more details.

@@ -0,0 +1,191 @@
1
+ #include <kernaux.h>
2
+ #include <ruby.h>
3
+
4
+ #ifdef HAVE_KERNAUX_UTOA
5
+ static VALUE rb_KernAux_utoa(VALUE self, VALUE number, VALUE base);
6
+ #endif
7
+ #ifdef HAVE_KERNAUX_ITOA
8
+ static VALUE rb_KernAux_itoa(VALUE self, VALUE number, VALUE base);
9
+ #endif
10
+ #ifdef HAVE_KERNAUX_UTOA10
11
+ static VALUE rb_KernAux_utoa10(VALUE self, VALUE number);
12
+ #endif
13
+ #ifdef HAVE_KERNAUX_ITOA10
14
+ static VALUE rb_KernAux_itoa10(VALUE self, VALUE number);
15
+ #endif
16
+ #ifdef HAVE_KERNAUX_UTOA16
17
+ static VALUE rb_KernAux_utoa16(VALUE self, VALUE number);
18
+ #endif
19
+ #ifdef HAVE_KERNAUX_ITOA16
20
+ static VALUE rb_KernAux_itoa16(VALUE self, VALUE number);
21
+ #endif
22
+
23
+ static ID rb_intern_LESS = Qnil;
24
+ static ID rb_intern_b = Qnil;
25
+ static ID rb_intern_B = Qnil;
26
+ static ID rb_intern_freeze = Qnil;
27
+ static ID rb_intern_h = Qnil;
28
+ static ID rb_intern_H = Qnil;
29
+ static ID rb_intern_o = Qnil;
30
+ static ID rb_intern_O = Qnil;
31
+ static ID rb_intern_d = Qnil;
32
+ static ID rb_intern_D = Qnil;
33
+ static ID rb_intern_x = Qnil;
34
+ static ID rb_intern_X = Qnil;
35
+
36
+ static VALUE rb_KernAux = Qnil;
37
+ static VALUE rb_KernAux_Error = Qnil;
38
+ static VALUE rb_KernAux_InvalidNtoaBaseError = Qnil;
39
+
40
+ #if defined(HAVE_KERNAUX_UTOA) || defined(HAVE_KERNAUX_ITOA)
41
+ static int convert_base(VALUE base);
42
+ #endif
43
+
44
+ void init_ntoa()
45
+ {
46
+ rb_gc_register_mark_object(ID2SYM(rb_intern_LESS = rb_intern("<")));
47
+ rb_gc_register_mark_object(ID2SYM(rb_intern_b = rb_intern("b")));
48
+ rb_gc_register_mark_object(ID2SYM(rb_intern_B = rb_intern("B")));
49
+ rb_gc_register_mark_object(ID2SYM(rb_intern_freeze = rb_intern("freeze")));
50
+ rb_gc_register_mark_object(ID2SYM(rb_intern_h = rb_intern("h")));
51
+ rb_gc_register_mark_object(ID2SYM(rb_intern_H = rb_intern("H")));
52
+ rb_gc_register_mark_object(ID2SYM(rb_intern_o = rb_intern("o")));
53
+ rb_gc_register_mark_object(ID2SYM(rb_intern_O = rb_intern("O")));
54
+ rb_gc_register_mark_object(ID2SYM(rb_intern_d = rb_intern("d")));
55
+ rb_gc_register_mark_object(ID2SYM(rb_intern_D = rb_intern("D")));
56
+ rb_gc_register_mark_object(ID2SYM(rb_intern_x = rb_intern("x")));
57
+ rb_gc_register_mark_object(ID2SYM(rb_intern_X = rb_intern("X")));
58
+
59
+ rb_gc_register_mark_object(rb_KernAux = rb_define_module("KernAux"));
60
+ rb_gc_register_mark_object(rb_KernAux_Error =
61
+ rb_define_class_under(rb_KernAux, "Error", rb_eRuntimeError));
62
+ rb_gc_register_mark_object(rb_KernAux_InvalidNtoaBaseError =
63
+ rb_define_class_under(rb_KernAux, "InvalidNtoaBaseError",
64
+ rb_KernAux_Error));
65
+
66
+ #ifdef HAVE_KERNAUX_UTOA
67
+ rb_define_singleton_method(rb_KernAux, "utoa", rb_KernAux_utoa, 2);
68
+ #endif
69
+ #ifdef HAVE_KERNAUX_ITOA
70
+ rb_define_singleton_method(rb_KernAux, "itoa", rb_KernAux_itoa, 2);
71
+ #endif
72
+ #ifdef HAVE_KERNAUX_UTOA10
73
+ rb_define_singleton_method(rb_KernAux, "utoa10", rb_KernAux_utoa10, 1);
74
+ #endif
75
+ #ifdef HAVE_KERNAUX_ITOA10
76
+ rb_define_singleton_method(rb_KernAux, "itoa10", rb_KernAux_itoa10, 1);
77
+ #endif
78
+ #ifdef HAVE_KERNAUX_UTOA16
79
+ rb_define_singleton_method(rb_KernAux, "utoa16", rb_KernAux_utoa16, 1);
80
+ #endif
81
+ #ifdef HAVE_KERNAUX_ITOA16
82
+ rb_define_singleton_method(rb_KernAux, "itoa16", rb_KernAux_itoa16, 1);
83
+ #endif
84
+ }
85
+
86
+ #ifdef HAVE_KERNAUX_UTOA
87
+ VALUE rb_KernAux_utoa(
88
+ const VALUE self_rb __attribute__((unused)),
89
+ const VALUE number_rb,
90
+ const VALUE base_rb
91
+ ) {
92
+ RB_INTEGER_TYPE_P(number_rb);
93
+ if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) {
94
+ rb_raise(rb_eRangeError, "can't convert negative number to uint64_t");
95
+ }
96
+ char buffer[KERNAUX_UTOA_BUFFER_SIZE];
97
+ kernaux_utoa(NUM2ULL(number_rb), buffer, convert_base(base_rb));
98
+ return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
99
+ }
100
+ #endif
101
+
102
+ #ifdef HAVE_KERNAUX_ITOA
103
+ VALUE rb_KernAux_itoa(
104
+ const VALUE self_rb __attribute__((unused)),
105
+ const VALUE number_rb,
106
+ const VALUE base_rb
107
+ ) {
108
+ RB_INTEGER_TYPE_P(number_rb);
109
+ char buffer[KERNAUX_ITOA_BUFFER_SIZE];
110
+ kernaux_itoa(NUM2LL(number_rb), buffer, convert_base(base_rb));
111
+ return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
112
+ }
113
+ #endif
114
+
115
+ #ifdef HAVE_KERNAUX_UTOA10
116
+ VALUE rb_KernAux_utoa10(
117
+ const VALUE self_rb __attribute__((unused)),
118
+ const VALUE number_rb
119
+ ) {
120
+ RB_INTEGER_TYPE_P(number_rb);
121
+ if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) {
122
+ rb_raise(rb_eRangeError, "can't convert negative number to uint64_t");
123
+ }
124
+ char buffer[KERNAUX_UTOA10_BUFFER_SIZE];
125
+ kernaux_utoa10(NUM2ULL(number_rb), buffer);
126
+ return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
127
+ }
128
+ #endif
129
+
130
+ #ifdef HAVE_KERNAUX_ITOA10
131
+ VALUE rb_KernAux_itoa10(
132
+ const VALUE self_rb __attribute__((unused)),
133
+ const VALUE number_rb
134
+ ) {
135
+ RB_INTEGER_TYPE_P(number_rb);
136
+ char buffer[KERNAUX_ITOA10_BUFFER_SIZE];
137
+ kernaux_itoa10(NUM2LL(number_rb), buffer);
138
+ return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
139
+ }
140
+ #endif
141
+
142
+ #ifdef HAVE_KERNAUX_UTOA16
143
+ VALUE rb_KernAux_utoa16(
144
+ const VALUE self_rb __attribute__((unused)),
145
+ const VALUE number_rb
146
+ ) {
147
+ RB_INTEGER_TYPE_P(number_rb);
148
+ if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) {
149
+ rb_raise(rb_eRangeError, "can't convert negative number to uint64_t");
150
+ }
151
+ char buffer[KERNAUX_UTOA16_BUFFER_SIZE];
152
+ kernaux_utoa16(NUM2ULL(number_rb), buffer);
153
+ return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
154
+ }
155
+ #endif
156
+
157
+ #ifdef HAVE_KERNAUX_ITOA16
158
+ VALUE rb_KernAux_itoa16(
159
+ const VALUE self_rb __attribute__((unused)),
160
+ const VALUE number_rb
161
+ ) {
162
+ RB_INTEGER_TYPE_P(number_rb);
163
+ char buffer[KERNAUX_ITOA16_BUFFER_SIZE];
164
+ kernaux_itoa16(NUM2LL(number_rb), buffer);
165
+ return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
166
+ }
167
+ #endif
168
+
169
+ #if defined(HAVE_KERNAUX_UTOA) || defined(HAVE_KERNAUX_ITOA)
170
+ int convert_base(const VALUE base_rb)
171
+ {
172
+ if (TYPE(base_rb) == T_SYMBOL) {
173
+ const ID base_id = SYM2ID(base_rb);
174
+ if (base_id == rb_intern_b) return 'b';
175
+ else if (base_id == rb_intern_B) return 'B';
176
+ else if (base_id == rb_intern_h) return 'h';
177
+ else if (base_id == rb_intern_H) return 'H';
178
+ else if (base_id == rb_intern_o) return 'o';
179
+ else if (base_id == rb_intern_O) return 'O';
180
+ else if (base_id == rb_intern_d) return 'd';
181
+ else if (base_id == rb_intern_D) return 'D';
182
+ else if (base_id == rb_intern_x) return 'x';
183
+ else if (base_id == rb_intern_X) return 'X';
184
+ else {
185
+ rb_raise(rb_KernAux_InvalidNtoaBaseError, "invalid base");
186
+ }
187
+ } else {
188
+ return NUM2INT(base_rb);
189
+ }
190
+ }
191
+ #endif
@@ -0,0 +1,120 @@
1
+ #include <kernaux.h>
2
+ #include <ruby.h>
3
+
4
+ #include "dynarg.h"
5
+
6
+ #ifdef HAVE_KERNAUX_SNPRINTF
7
+
8
+ static VALUE rb_KernAux_snprintf1(int argc, const VALUE *argv, VALUE self);
9
+
10
+ static ID rb_intern_freeze = Qnil;
11
+ static VALUE rb_KernAux = Qnil;
12
+
13
+ void init_printf()
14
+ {
15
+ rb_gc_register_mark_object(ID2SYM(rb_intern_freeze = rb_intern("freeze")));
16
+ rb_gc_register_mark_object(rb_KernAux = rb_define_module("KernAux"));
17
+
18
+ rb_define_singleton_method(rb_KernAux, "snprintf1",
19
+ rb_KernAux_snprintf1, -1);
20
+ }
21
+
22
+ // TODO: is this implementation correct?
23
+ // FIXME: rewrite to ensure no memory leak on exception.
24
+ VALUE rb_KernAux_snprintf1(
25
+ const int argc,
26
+ const VALUE *const argv_rb,
27
+ const VALUE self __attribute__((unused))
28
+ ) {
29
+ if (argc < 2 || argc > 5) rb_raise(rb_eArgError, "expected 2, 3, 4 or 5 args");
30
+
31
+ const VALUE size_rb = argv_rb[0];
32
+ VALUE format_rb = argv_rb[1];
33
+
34
+ const int size = NUM2INT(size_rb);
35
+ const char *const format = StringValueCStr(format_rb);
36
+
37
+ if (size < 0) rb_raise(rb_eRangeError, "expected non-negative size");
38
+
39
+ const char *fmt = format;
40
+
41
+ while (*fmt && *fmt != '%') ++fmt;
42
+ if (*(fmt++) != '%') rb_raise(rb_eArgError, "invalid format");
43
+
44
+ struct KernAux_PrintfFmt_Spec spec = KernAux_PrintfFmt_Spec_create();
45
+
46
+ fmt = KernAux_PrintfFmt_Spec_parse(&spec, fmt);
47
+
48
+ while (*fmt) {
49
+ if (*(fmt++) == '%') rb_raise(rb_eArgError, "invalid format");
50
+ }
51
+
52
+ int arg_index = 2;
53
+ if (spec.set_width && argc > arg_index) {
54
+ KernAux_PrintfFmt_Spec_set_width(&spec, NUM2INT(argv_rb[arg_index++]));
55
+ }
56
+ if (spec.set_precision && argc > arg_index) {
57
+ KernAux_PrintfFmt_Spec_set_precision(&spec, NUM2INT(argv_rb[arg_index++]));
58
+ }
59
+
60
+ struct DynArg dynarg = DynArg_create();
61
+ if (argc > arg_index) {
62
+ VALUE arg_rb = argv_rb[arg_index];
63
+
64
+ if (spec.type == KERNAUX_PRINTF_FMT_TYPE_INT) {
65
+ RB_INTEGER_TYPE_P(arg_rb);
66
+ DynArg_use_long_long(&dynarg, NUM2LL(arg_rb));
67
+ } else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_UINT) {
68
+ RB_INTEGER_TYPE_P(arg_rb);
69
+ DynArg_use_unsigned_long_long(&dynarg, NUM2ULL(arg_rb));
70
+ } else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_FLOAT ||
71
+ spec.type == KERNAUX_PRINTF_FMT_TYPE_EXP)
72
+ {
73
+ RB_FLOAT_TYPE_P(arg_rb);
74
+ DynArg_use_double(&dynarg, NUM2DBL(arg_rb));
75
+ } else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_CHAR) {
76
+ Check_Type(arg_rb, T_STRING);
77
+ DynArg_use_char(&dynarg, *StringValuePtr(arg_rb));
78
+ } else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_STR) {
79
+ Check_Type(arg_rb, T_STRING);
80
+ DynArg_use_str(&dynarg, StringValueCStr(arg_rb));
81
+ }
82
+ }
83
+
84
+ char *const str = malloc(size);
85
+ if (!str) rb_raise(rb_eNoMemError, "snprintf1 buffer malloc");
86
+
87
+ int slen;
88
+ if (spec.set_width) {
89
+ if (spec.set_precision) {
90
+ slen = dynarg.use_dbl
91
+ ? kernaux_snprintf(str, size, format, spec.width, spec.precision, dynarg.dbl)
92
+ : kernaux_snprintf(str, size, format, spec.width, spec.precision, dynarg.arg);
93
+ } else {
94
+ slen = dynarg.use_dbl
95
+ ? kernaux_snprintf(str, size, format, spec.width, dynarg.dbl)
96
+ : kernaux_snprintf(str, size, format, spec.width, dynarg.arg);
97
+ }
98
+ } else {
99
+ if (spec.set_precision) {
100
+ slen = dynarg.use_dbl
101
+ ? kernaux_snprintf(str, size, format, spec.precision, dynarg.dbl)
102
+ : kernaux_snprintf(str, size, format, spec.precision, dynarg.arg);
103
+ } else {
104
+ slen = dynarg.use_dbl
105
+ ? kernaux_snprintf(str, size, format, dynarg.dbl)
106
+ : kernaux_snprintf(str, size, format, dynarg.arg);
107
+ }
108
+ }
109
+
110
+ const VALUE output_rb =
111
+ rb_funcall(rb_str_new2(str), rb_intern_freeze, 0);
112
+ free(str);
113
+
114
+ const VALUE result_rb = rb_ary_new2(2);
115
+ rb_ary_push(result_rb, output_rb);
116
+ rb_ary_push(result_rb, INT2NUM(slen));
117
+ return rb_funcall(result_rb, rb_intern_freeze, 0);
118
+ }
119
+
120
+ #endif // HAVE_KERNAUX_SNPRINTF
data/kernaux.gemspec ADDED
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/kernaux/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ repo = 'https://github.com/tailix/libkernaux'
7
+ home = "#{repo}/tree/master/pkgs/ruby"
8
+ bugs = "#{repo}/issues"
9
+
10
+ spec.name = 'kernaux'
11
+ spec.version = KernAux::VERSION
12
+ spec.license = 'MIT'
13
+ spec.homepage = home
14
+ spec.platform = Gem::Platform::RUBY
15
+
16
+ spec.required_ruby_version = '~> 3.0'
17
+
18
+ spec.authors = ['Alex Kotov']
19
+ spec.email = %w[kotovalexarian@gmail.com]
20
+
21
+ spec.summary =
22
+ 'Binding to libkernaux - auxiliary library for kernel development'
23
+
24
+ spec.description = <<~DESCRIPTION.split("\n").map(&:strip).join ' '
25
+ Binding to libkernaux - auxiliary library for kernel development.
26
+ DESCRIPTION
27
+
28
+ spec.metadata['homepage_uri'] = home
29
+ spec.metadata['source_code_uri'] = home
30
+ spec.metadata['bug_tracker_uri'] = bugs
31
+ spec.metadata['rubygems_mfa_required'] = 'true'
32
+
33
+ spec.bindir = 'exe'
34
+ spec.require_paths = ['lib']
35
+
36
+ spec.files = Dir.chdir File.expand_path __dir__ do
37
+ `git ls-files -z`.split("\x0").reject do |f|
38
+ f.match %r{\A(?:test|spec|features)/}
39
+ end
40
+ end
41
+
42
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename f }
43
+
44
+ spec.extensions << 'ext/default/extconf.rb'
45
+
46
+ spec.add_development_dependency 'bundler', '~> 2.2'
47
+ spec.add_development_dependency 'pry', '~> 0.14'
48
+ spec.add_development_dependency 'rake', '~> 13.0'
49
+ spec.add_development_dependency 'rake-compiler', '~> 1.1'
50
+ spec.add_development_dependency 'rspec', '~> 3.10'
51
+ spec.add_development_dependency 'rubocop', '~> 1.25'
52
+ spec.add_development_dependency 'rubocop-performance', '~> 1.13'
53
+ spec.add_development_dependency 'rubocop-rake', '~> 0.6'
54
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.7'
55
+ spec.add_development_dependency 'simplecov', '~> 0.21'
56
+ spec.add_development_dependency 'yard', '~> 0.9'
57
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KernAux
4
+ # Gem version.
5
+ VERSION = '0.3.0'
6
+ end
data/lib/kernaux.rb ADDED
@@ -0,0 +1,238 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'kernaux/version'
4
+
5
+ # Native extensions
6
+ require_relative 'kernaux/default'
7
+
8
+ ##
9
+ # Binding to [libkernaux](https://github.com/tailix/libkernaux) - auxiliary
10
+ # library for kernel development.
11
+ #
12
+ module KernAux
13
+ # Default callback for assertions.
14
+ # @see .assert_cb
15
+ DEFAULT_ASSERT_CB = @assert_cb = lambda { |file, line, msg|
16
+ raise AssertError, "#{file}:#{line}:#{msg}"
17
+ }
18
+
19
+ # Buffer size for {.sprintf1}.
20
+ # @todo Make it dynamic.
21
+ SPRINTF1_BUFFER_SIZE = 10_000
22
+
23
+ # @!scope class
24
+
25
+ ##
26
+ # @!attribute [rw] assert_cb
27
+ # Panic callback.
28
+ #
29
+ # @see .panic
30
+ # @see .assert_do
31
+ ##
32
+
33
+ ##
34
+ # Raise assertion with implicit file and line, retrieved from `caller`, and
35
+ # explicit message.
36
+ #
37
+ # @param msg [String] any message
38
+ # @return [nil]
39
+ #
40
+ # @raise [AssertError] if {.assert_cb} have not been changed
41
+ #
42
+ # @see .assert_do Explicit file and line.
43
+ #
44
+ def self.panic(msg)
45
+ file, line = caller(1..1).first.split(':')[0..1]
46
+ assert_do file, Integer(line), msg
47
+ end
48
+
49
+ ##
50
+ # @!method assert_do(file, line, msg)
51
+ # Raise assertion with explicit file, line and message.
52
+ #
53
+ # @param file [String] file name, usually from `__FILE__`
54
+ # @param line [Integer] line number, usually from `__LINE__`
55
+ # @param msg [String] any message
56
+ # @return [nil]
57
+ #
58
+ # @raise [AssertError] if {.assert_cb} have not been changed
59
+ #
60
+ # @see .panic Implicit file and line
61
+
62
+ # @!parse [ruby]
63
+
64
+ if singleton_class.method_defined? :snprintf1
65
+ ##
66
+ # Typical `printf`.
67
+ #
68
+ # @param args [Array<String,
69
+ # Array<(String, Object)>,
70
+ # Array<(String, Integer, Object)>>]
71
+ # @return [String] formatted output
72
+ #
73
+ # @example
74
+ # KernAux.sprintf 'foo', ['%*s', 5, 'bar'], 'car', ['%d', 123]
75
+ # #=> "foo barcar123"
76
+ #
77
+ def self.sprintf(*args)
78
+ args.map do |arg|
79
+ if arg.is_a? Array
80
+ sprintf1(*arg)
81
+ else
82
+ arg
83
+ end
84
+ end.join.freeze
85
+ end
86
+
87
+ ##
88
+ # `printf` for single formatting parameter.
89
+ #
90
+ # @param format [String] formatting string
91
+ # @return [String] formatted output
92
+ #
93
+ # @see .sprintf Multiple formatting parameters
94
+ #
95
+ # @example
96
+ # KernAux.sprintf1 '%%' #=> "%"
97
+ # KernAux.sprintf1 '%s', 'foo' #=> "foo"
98
+ # KernAux.sprintf1 '%5s', 'foo' #=> " foo"
99
+ # KernAux.sprintf1 '%*s', 5, 'foo' #=> " foo"
100
+ #
101
+ def self.sprintf1(format, *args)
102
+ snprintf1(SPRINTF1_BUFFER_SIZE, format, *args).first
103
+ end
104
+
105
+ ##
106
+ # @!method snprintf1(buffer_size, format, ...)
107
+ # `printf` for single formatting parameter with manual buffer size.
108
+ #
109
+ # @param buffer_size [Integer] buffer size (including terminating null
110
+ # character)
111
+ # @param format [String] formatting string
112
+ # @return [Array<(String, Integer)>] formatted output and it's size
113
+ #
114
+ # @see .sprintf1 Automatic buffer size
115
+ ##
116
+ end
117
+
118
+ ##
119
+ # @!method cmdline(str)
120
+ # Parse command line.
121
+ #
122
+ # @param str [String] command line string
123
+ # @return [Array<String>] command line arguments
124
+ #
125
+ # @raise [CmdlineError] syntax is invalid
126
+
127
+ # @!parse [ruby]
128
+
129
+ ##
130
+ # @!method utoa(number, base)
131
+ # Convert `uint64_t` to a string in multiple numeral systems.
132
+ #
133
+ # Base can be a positive or negative integer between 2 and 36, or a symbol
134
+ # which is an alias to a valid integer value. Positive integers and lowercase
135
+ # symbols mean lowercase output when base is greater than 10. Negative
136
+ # integers and uppercase symbols mean uppercase output when base is greater
137
+ # than 10. Aliases are: `:b`, `:B` - 2; `:o`, `:O` - 8; `:d`, `:D` - 10; `:h`,
138
+ # `:x` - 16 (lowercase); `:H`, `:X` - -10 (uppercase).
139
+ #
140
+ # @param number [Integer] a number between 0 and `UINT64_MAX`
141
+ # @param base [Integer, Symbol] base of a numeral system
142
+ # @return [String]
143
+ #
144
+ # @raise [RangeError] number is out of range
145
+ # @raise [InvalidNtoaBaseError] base is invalid
146
+ #
147
+ # @see .itoa Convert signed integers
148
+ ##
149
+
150
+ ##
151
+ # @!method itoa(number, base)
152
+ # Convert `int64_t` to a string in multiple numeral systems.
153
+ #
154
+ # Base can be a positive or negative integer between 2 and 36, or a symbol
155
+ # which is an alias to a valid integer value. Positive integers and lowercase
156
+ # symbols mean lowercase output when base is greater than 10. Negative
157
+ # integers and uppercase symbols mean uppercase output when base is greater
158
+ # than 10. Aliases are: `:b`, `:B` - 2; `:o`, `:O` - 8; `:d`, `:D` - 10; `:h`,
159
+ # `:x` - 16 (lowercase); `:H`, `:X` - -10 (uppercase).
160
+ #
161
+ # @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
162
+ # @param base [Integer, Symbol] base of a numeral system
163
+ # @return [String]
164
+ #
165
+ # @raise [RangeError] number is out of range
166
+ # @raise [InvalidNtoaBaseError] base is invalid
167
+ #
168
+ # @see .utoa Convert unsigned integers
169
+ ##
170
+
171
+ ##
172
+ # @!method utoa10(number)
173
+ # Convert `uint64_t` to a decimal string.
174
+ #
175
+ # @param number [Integer] a number between 0 and `UINT64_MAX`
176
+ # @return [String]
177
+ #
178
+ # @raise [RangeError] number is out of range
179
+ ##
180
+
181
+ ##
182
+ # @!method itoa10(number)
183
+ # Convert `int64_t` to a decimal string.
184
+ #
185
+ # @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
186
+ # @return [String]
187
+ #
188
+ # @raise [RangeError] number is out of range
189
+ ##
190
+
191
+ ##
192
+ # @!method utoa16(number)
193
+ # Convert `uint64_t` to a hexadecimal string.
194
+ #
195
+ # @param number [Integer] a number between 0 and `UINT64_MAX`
196
+ # @return [String]
197
+ #
198
+ # @raise [RangeError] number is out of range
199
+ ##
200
+
201
+ ##
202
+ # @!method itoa16(number)
203
+ # Convert `int64_t` to a hexadecimal string.
204
+ #
205
+ # @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
206
+ # @return [String]
207
+ #
208
+ # @raise [RangeError] number is out of range
209
+ ##
210
+
211
+ ##
212
+ # Our base class for runtime errors.
213
+ #
214
+ class Error < RuntimeError; end
215
+
216
+ ##
217
+ # Raised when assertion has failed or panic has been called.
218
+ #
219
+ # @see .panic
220
+ # @see .assert_do
221
+ #
222
+ class AssertError < Error; end
223
+
224
+ ##
225
+ # Raised when command line parsing goes wrong.
226
+ #
227
+ # @see .cmdline
228
+ #
229
+ class CmdlineError < Error; end
230
+
231
+ ##
232
+ # Raised when integer base is invalid.
233
+ #
234
+ # @see .utoa
235
+ # @see .itoa
236
+ #
237
+ class InvalidNtoaBaseError < Error; end
238
+ end