kernaux 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/Rakefile +14 -2
- data/ext/default/main.h +6 -0
- data/ext/default/printf.c +95 -166
- data/lib/kernaux/version.rb +1 -1
- data/lib/kernaux.rb +0 -1
- metadata +3 -4
- data/lib/kernaux/printf.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 575d6442a1d63f0c17a1679006ebcc61aa65174d1ff9a9feecd873fb0ed23077
|
4
|
+
data.tar.gz: 0dd0cb5e521520974de0eca0e7f3cf536d5557d6386094faf885575c0453f392
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e4c2dffb8776d91a701e3a2d10135a6dbaa459ec9208d921067e13fefee8a4ac368319c3e62003731f7dcfb6367c48d785ce1d0d2341dda7fdbaba5aaa99a31
|
7
|
+
data.tar.gz: 5ba213e81e45bca750c2a07062cf5db89650b5a49b4106909b285977c965ae90748c57527d5d851276c8f3e8ae21a6128f55c62adfd7300feb71caeecc6d8955
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ Install
|
|
15
15
|
Add the following to your `Gemfile`:
|
16
16
|
|
17
17
|
```ruby
|
18
|
-
gem 'kernaux', '~> 0.
|
18
|
+
gem 'kernaux', '~> 0.7.0'
|
19
19
|
```
|
20
20
|
|
21
21
|
Or add the following to your `*.gemspec`:
|
@@ -23,7 +23,7 @@ Or add the following to your `*.gemspec`:
|
|
23
23
|
```ruby
|
24
24
|
Gem::Specification.new do |spec|
|
25
25
|
# ...
|
26
|
-
spec.add_runtime_dependency 'kernaux', '~> 0.
|
26
|
+
spec.add_runtime_dependency 'kernaux', '~> 0.7.0'
|
27
27
|
# ...
|
28
28
|
end
|
29
29
|
```
|
data/Rakefile
CHANGED
@@ -20,13 +20,13 @@ CLEAN << 'doc'
|
|
20
20
|
CLEAN << 'spec/examples.txt'
|
21
21
|
|
22
22
|
desc 'Run default checks'
|
23
|
-
task default: %i[test lint
|
23
|
+
task default: %i[test lint]
|
24
24
|
|
25
25
|
desc 'Run tests'
|
26
26
|
task test: :spec
|
27
27
|
|
28
28
|
desc 'Run code analysis tools'
|
29
|
-
task lint: :
|
29
|
+
task lint: %i[rubocop cppcheck yard:cov]
|
30
30
|
|
31
31
|
desc 'Fix code style (rubocop --auto-correct)'
|
32
32
|
task fix: 'rubocop:auto_correct'
|
@@ -66,6 +66,18 @@ task :console do
|
|
66
66
|
sh 'bundle', 'exec', File.expand_path(File.join('bin', 'console'), __dir__)
|
67
67
|
end
|
68
68
|
|
69
|
+
desc 'Run cppcheck'
|
70
|
+
task :cppcheck do
|
71
|
+
sh(
|
72
|
+
'cppcheck',
|
73
|
+
'--quiet',
|
74
|
+
'--error-exitcode=1',
|
75
|
+
'--std=c99',
|
76
|
+
'--enable=warning,style,performance,portability',
|
77
|
+
__dir__,
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
69
81
|
namespace :yard do
|
70
82
|
desc 'Measure documentation coverage'
|
71
83
|
task :cov do
|
data/ext/default/main.h
CHANGED
data/ext/default/printf.c
CHANGED
@@ -1,208 +1,137 @@
|
|
1
1
|
#include "main.h"
|
2
|
-
|
3
2
|
#include "dynarg.h"
|
4
3
|
|
5
|
-
#
|
6
|
-
#include <stdlib.h>
|
4
|
+
#define BUFFER_SIZE 4096
|
7
5
|
|
8
6
|
#ifdef KERNAUX_VERSION_WITH_PRINTF
|
9
7
|
|
10
|
-
|
11
|
-
*
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
static VALUE rb_KernAux_Snprintf1 = Qnil;
|
23
|
-
|
24
|
-
static size_t rb_KernAux_Snprintf1_DSIZE(const void *ptr);
|
25
|
-
|
26
|
-
const rb_data_type_t rb_KernAux_Snprintf1_DTYPE = {
|
27
|
-
.wrap_struct_name = "KernAux::Snprintf1",
|
28
|
-
.parent = NULL,
|
29
|
-
.data = NULL,
|
30
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
31
|
-
.function = {
|
32
|
-
.dfree = RUBY_DEFAULT_FREE,
|
33
|
-
.dsize = rb_KernAux_Snprintf1_DSIZE,
|
34
|
-
.dmark = NULL,
|
35
|
-
.dcompact = NULL,
|
36
|
-
.reserved = { 0 },
|
37
|
-
},
|
38
|
-
};
|
39
|
-
|
40
|
-
struct rb_KernAux_Snprintf1_DATA {
|
41
|
-
const struct KernAux_PrintfFmt_Spec *spec;
|
42
|
-
const struct DynArg *dynarg;
|
43
|
-
int size;
|
44
|
-
const char *format;
|
45
|
-
char *str;
|
46
|
-
};
|
47
|
-
|
48
|
-
/********
|
49
|
-
* Main *
|
50
|
-
********/
|
8
|
+
/**
|
9
|
+
* Typical `printf`.
|
10
|
+
*
|
11
|
+
* @param format [String] format string
|
12
|
+
* @return [String] formatted output
|
13
|
+
*
|
14
|
+
* @example
|
15
|
+
* KernAux.sprintf 'foo%*scar%d', 5, 'bar', 123
|
16
|
+
* #=> "foo barcar123"
|
17
|
+
*/
|
18
|
+
static VALUE rb_KernAux_sprintf(int argc, VALUE *argv, VALUE self);
|
51
19
|
|
52
20
|
void init_printf()
|
53
21
|
{
|
54
|
-
|
55
|
-
rb_KernAux_Snprintf1 =
|
56
|
-
// @api private
|
57
|
-
rb_define_class_under(rb_KernAux, "Snprintf1", rb_cObject));
|
58
|
-
rb_funcall(rb_KernAux, rb_intern("private_constant"), 1, ID2SYM(rb_intern("Snprintf1")));
|
59
|
-
|
60
|
-
rb_define_singleton_method(rb_KernAux, "snprintf1",
|
61
|
-
rb_KernAux_snprintf1, -1);
|
22
|
+
rb_define_singleton_method(rb_KernAux, "sprintf", rb_KernAux_sprintf, -1);
|
62
23
|
}
|
63
24
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
VALUE rb_KernAux_snprintf1(
|
69
|
-
const int argc,
|
70
|
-
const VALUE *const argv_rb,
|
71
|
-
const VALUE self KERNAUX_UNUSED
|
72
|
-
) {
|
73
|
-
if (argc < 2 || argc > 5) rb_raise(rb_eArgError, "expected 2, 3, 4 or 5 args");
|
25
|
+
#define TAKE_ARG \
|
26
|
+
if (arg_index >= argc) rb_raise(rb_eArgError, "too few arguments"); \
|
27
|
+
VALUE arg_rb = argv[arg_index++]; \
|
28
|
+
do {} while (0)
|
74
29
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
const int size = NUM2INT(size_rb);
|
79
|
-
const char *const format = StringValueCStr(format_rb);
|
80
|
-
|
81
|
-
if (size < 0) rb_raise(rb_eRangeError, "expected non-negative size");
|
30
|
+
VALUE rb_KernAux_sprintf(const int argc, VALUE *const argv, VALUE self)
|
31
|
+
{
|
32
|
+
if (argc == 0) rb_raise(rb_eArgError, "too few arguments");
|
82
33
|
|
83
|
-
const char *
|
34
|
+
const char *format = StringValueCStr(argv[0]);
|
35
|
+
int arg_index = 1;
|
36
|
+
VALUE result = rb_str_new_literal("");
|
84
37
|
|
85
|
-
while (*
|
86
|
-
|
38
|
+
while (*format) {
|
39
|
+
if (*format != '%') {
|
40
|
+
rb_str_cat(result, format, 1);
|
41
|
+
++format;
|
42
|
+
continue;
|
43
|
+
}
|
87
44
|
|
88
|
-
|
45
|
+
++format;
|
46
|
+
struct KernAux_PrintfFmt_Spec spec =
|
47
|
+
KernAux_PrintfFmt_Spec_create_out(&format);
|
89
48
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
if (spec.set_precision && argc > arg_index) {
|
99
|
-
KernAux_PrintfFmt_Spec_set_precision(&spec, NUM2INT(argv_rb[arg_index++]));
|
100
|
-
}
|
49
|
+
if (spec.set_width) {
|
50
|
+
TAKE_ARG;
|
51
|
+
KernAux_PrintfFmt_Spec_set_width(&spec, NUM2INT(arg_rb));
|
52
|
+
}
|
53
|
+
if (spec.set_precision) {
|
54
|
+
TAKE_ARG;
|
55
|
+
KernAux_PrintfFmt_Spec_set_precision(&spec, NUM2INT(arg_rb));
|
56
|
+
}
|
101
57
|
|
102
|
-
|
103
|
-
if (argc > arg_index) {
|
104
|
-
VALUE arg_rb = argv_rb[arg_index];
|
58
|
+
struct DynArg dynarg = DynArg_create();
|
105
59
|
|
106
60
|
if (spec.type == KERNAUX_PRINTF_FMT_TYPE_INT) {
|
61
|
+
TAKE_ARG;
|
107
62
|
DynArg_use_long_long(&dynarg, NUM2LL(arg_rb));
|
108
63
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_UINT) {
|
64
|
+
TAKE_ARG;
|
109
65
|
DynArg_use_unsigned_long_long(&dynarg, NUM2ULL(arg_rb));
|
110
66
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_FLOAT ||
|
111
67
|
spec.type == KERNAUX_PRINTF_FMT_TYPE_EXP)
|
112
68
|
{
|
69
|
+
TAKE_ARG;
|
113
70
|
DynArg_use_double(&dynarg, NUM2DBL(arg_rb));
|
114
71
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_CHAR) {
|
72
|
+
TAKE_ARG;
|
115
73
|
Check_Type(arg_rb, T_STRING);
|
116
74
|
DynArg_use_char(&dynarg, *StringValuePtr(arg_rb));
|
117
75
|
} else if (spec.type == KERNAUX_PRINTF_FMT_TYPE_STR) {
|
76
|
+
TAKE_ARG;
|
118
77
|
Check_Type(arg_rb, T_STRING);
|
119
78
|
DynArg_use_str(&dynarg, StringValueCStr(arg_rb));
|
120
79
|
}
|
121
|
-
}
|
122
|
-
|
123
|
-
char *const str = malloc(size);
|
124
|
-
if (!str) rb_raise(rb_eNoMemError, "snprintf1 buffer malloc");
|
125
|
-
|
126
|
-
struct rb_KernAux_Snprintf1_DATA *userdata;
|
127
|
-
VALUE userdata_rb = TypedData_Make_Struct(
|
128
|
-
rb_KernAux_Snprintf1,
|
129
|
-
struct rb_KernAux_Snprintf1_DATA,
|
130
|
-
&rb_KernAux_Snprintf1_DTYPE,
|
131
|
-
userdata
|
132
|
-
);
|
133
|
-
if (NIL_P(userdata_rb) || userdata == NULL) {
|
134
|
-
free(str);
|
135
|
-
rb_raise(rb_eNoMemError, "snprintf1 userdata alloc");
|
136
|
-
}
|
137
|
-
|
138
|
-
userdata->spec = &spec;
|
139
|
-
userdata->dynarg = &dynarg;
|
140
|
-
userdata->size = size;
|
141
|
-
userdata->format = format;
|
142
|
-
userdata->str = str;
|
143
|
-
|
144
|
-
int state = 0;
|
145
|
-
VALUE result =
|
146
|
-
rb_protect(rb_KernAux_snprintf1_PROTECT, userdata_rb, &state);
|
147
|
-
|
148
|
-
free(str);
|
149
|
-
|
150
|
-
if (state == 0) {
|
151
|
-
return result;
|
152
|
-
} else {
|
153
|
-
rb_jump_tag(state);
|
154
|
-
}
|
155
|
-
}
|
156
80
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
81
|
+
// 1 additional byte for the '%' character.
|
82
|
+
// 1 additional byte for the terminating '\0' character.
|
83
|
+
char old_format[2 + spec.format_limit - spec.format_start];
|
84
|
+
memset(old_format, '\0', sizeof(old_format));
|
85
|
+
old_format[0] = '%';
|
86
|
+
strncpy(&old_format[1], spec.format_start, sizeof(old_format) - 2);
|
87
|
+
|
88
|
+
char buffer[BUFFER_SIZE];
|
89
|
+
int slen;
|
90
|
+
|
91
|
+
if (spec.set_width) {
|
92
|
+
if (spec.set_precision) {
|
93
|
+
if (dynarg.use_dbl) {
|
94
|
+
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
95
|
+
spec.width, spec.precision,
|
96
|
+
dynarg.dbl);
|
97
|
+
} else {
|
98
|
+
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
99
|
+
spec.width, spec.precision,
|
100
|
+
dynarg.arg);
|
101
|
+
}
|
102
|
+
} else {
|
103
|
+
if (dynarg.use_dbl) {
|
104
|
+
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
105
|
+
spec.width, dynarg.dbl);
|
106
|
+
} else {
|
107
|
+
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
108
|
+
spec.width, dynarg.arg);
|
109
|
+
}
|
110
|
+
}
|
173
111
|
} else {
|
174
|
-
|
175
|
-
|
176
|
-
|
112
|
+
if (spec.set_precision) {
|
113
|
+
if (dynarg.use_dbl) {
|
114
|
+
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
115
|
+
spec.precision, dynarg.dbl);
|
116
|
+
} else {
|
117
|
+
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format,
|
118
|
+
spec.precision, dynarg.arg);
|
119
|
+
}
|
120
|
+
} else {
|
121
|
+
if (dynarg.use_dbl) {
|
122
|
+
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.dbl);
|
123
|
+
} else {
|
124
|
+
slen = kernaux_snprintf(buffer, BUFFER_SIZE, old_format, dynarg.arg);
|
125
|
+
}
|
126
|
+
}
|
177
127
|
}
|
178
|
-
} else {
|
179
|
-
if (userdata->spec->set_precision) {
|
180
|
-
slen = userdata->dynarg->use_dbl
|
181
|
-
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->precision, userdata->dynarg->dbl)
|
182
|
-
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->spec->precision, userdata->dynarg->arg);
|
183
|
-
} else {
|
184
|
-
slen = userdata->dynarg->use_dbl
|
185
|
-
? kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->dynarg->dbl)
|
186
|
-
: kernaux_snprintf(userdata->str, userdata->size, userdata->format, userdata->dynarg->arg);
|
187
|
-
}
|
188
|
-
}
|
189
128
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
const VALUE result_rb = rb_ary_new2(2);
|
194
|
-
rb_ary_push(result_rb, output_rb);
|
195
|
-
rb_ary_push(result_rb, INT2NUM(slen));
|
196
|
-
return rb_funcall(result_rb, rb_intern_freeze, 0);
|
197
|
-
}
|
129
|
+
rb_str_cat(result, buffer, slen);
|
130
|
+
}
|
198
131
|
|
199
|
-
|
200
|
-
* ::KernAux::Snprintf1 *
|
201
|
-
************************/
|
132
|
+
if (arg_index < argc) rb_raise(rb_eArgError, "too many arguments");
|
202
133
|
|
203
|
-
|
204
|
-
{
|
205
|
-
return sizeof(struct rb_KernAux_Snprintf1_DATA);
|
134
|
+
return rb_funcall(result, rb_intern_freeze, 0);
|
206
135
|
}
|
207
136
|
|
208
137
|
#endif // KERNAUX_VERSION_WITH_PRINTF
|
data/lib/kernaux/version.rb
CHANGED
data/lib/kernaux.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kernaux
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Kotov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -197,7 +197,6 @@ files:
|
|
197
197
|
- lib/kernaux/cmdline.rb
|
198
198
|
- lib/kernaux/errors.rb
|
199
199
|
- lib/kernaux/ntoa.rb
|
200
|
-
- lib/kernaux/printf.rb
|
201
200
|
- lib/kernaux/version.rb
|
202
201
|
homepage: https://github.com/tailix/libkernaux/tree/master/bindings/ruby
|
203
202
|
licenses:
|
@@ -207,7 +206,7 @@ metadata:
|
|
207
206
|
homepage_uri: https://github.com/tailix/libkernaux/tree/master/bindings/ruby
|
208
207
|
source_code_uri: https://github.com/tailix/libkernaux/tree/master/bindings/ruby
|
209
208
|
bug_tracker_uri: https://github.com/tailix/libkernaux/issues
|
210
|
-
documentation_uri: https://www.rubydoc.info/gems/kernaux/0.
|
209
|
+
documentation_uri: https://www.rubydoc.info/gems/kernaux/0.7.0
|
211
210
|
post_install_message:
|
212
211
|
rdoc_options: []
|
213
212
|
require_paths:
|
data/lib/kernaux/printf.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# rubocop:disable Style/Documentation
|
4
|
-
begin; end
|
5
|
-
|
6
|
-
module KernAux
|
7
|
-
# Buffer size for {.sprintf1}.
|
8
|
-
# @todo Make it dynamic.
|
9
|
-
SPRINTF1_BUFFER_SIZE = 10_000
|
10
|
-
|
11
|
-
# @!scope class
|
12
|
-
|
13
|
-
# @!parse [ruby]
|
14
|
-
|
15
|
-
if Version.with_printf?
|
16
|
-
##
|
17
|
-
# Typical `printf`.
|
18
|
-
#
|
19
|
-
# @param args [Array<String,
|
20
|
-
# Array<(String, Object)>,
|
21
|
-
# Array<(String, Integer, Object)>>]
|
22
|
-
# @return [String] formatted output
|
23
|
-
#
|
24
|
-
# @example
|
25
|
-
# KernAux.sprintf 'foo', ['%*s', 5, 'bar'], 'car', ['%d', 123]
|
26
|
-
# #=> "foo barcar123"
|
27
|
-
#
|
28
|
-
def self.sprintf(*args)
|
29
|
-
args.map do |arg|
|
30
|
-
if arg.is_a? Array
|
31
|
-
sprintf1(*arg)
|
32
|
-
else
|
33
|
-
arg
|
34
|
-
end
|
35
|
-
end.join.freeze
|
36
|
-
end
|
37
|
-
|
38
|
-
##
|
39
|
-
# `printf` for single formatting parameter.
|
40
|
-
#
|
41
|
-
# @param format [String] formatting string
|
42
|
-
# @return [String] formatted output
|
43
|
-
#
|
44
|
-
# @see .sprintf Multiple formatting parameters
|
45
|
-
#
|
46
|
-
# @example
|
47
|
-
# KernAux.sprintf1 '%%' #=> "%"
|
48
|
-
# KernAux.sprintf1 '%s', 'foo' #=> "foo"
|
49
|
-
# KernAux.sprintf1 '%5s', 'foo' #=> " foo"
|
50
|
-
# KernAux.sprintf1 '%*s', 5, 'foo' #=> " foo"
|
51
|
-
#
|
52
|
-
def self.sprintf1(format, *args)
|
53
|
-
snprintf1(SPRINTF1_BUFFER_SIZE, format, *args).first
|
54
|
-
end
|
55
|
-
|
56
|
-
##
|
57
|
-
# @!method snprintf1(buffer_size, format, ...)
|
58
|
-
# `printf` for single formatting parameter with manual buffer size.
|
59
|
-
#
|
60
|
-
# @param buffer_size [Integer] buffer size (including terminating null
|
61
|
-
# character)
|
62
|
-
# @param format [String] formatting string
|
63
|
-
# @return [Array<(String, Integer)>] formatted output and it's size
|
64
|
-
#
|
65
|
-
# @see .sprintf1 Automatic buffer size
|
66
|
-
##
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# rubocop:enable Style/Documentation
|