alt_printf 0.1.3 → 0.1.4
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/Rakefile +8 -2
- data/alt_printf.gemspec +1 -1
- data/ext/alt_printf/alt_printf.c +135 -147
- data/ext/alt_printf/altprintf.h +4 -41
- data/ext/alt_printf/enums.h +6 -0
- data/ext/alt_printf/extconf.h +1 -0
- data/ext/alt_printf/extconf.rb +2 -3
- data/ext/alt_printf/extconf_debug.rb +4 -0
- data/ext/alt_printf/extconf_dev.rb +2 -7
- data/ext/alt_printf/extconf_helper.rb +35 -0
- data/ext/alt_printf/fmt.c +174 -0
- data/ext/alt_printf/fmt.h +8 -0
- data/ext/alt_printf/fmte.c +92 -0
- data/ext/alt_printf/fmte.h +37 -0
- data/ext/alt_printf/log.h +2 -1
- data/ext/alt_printf/parsef.c +125 -0
- data/ext/alt_printf/parsef.h +10 -0
- data/ext/alt_printf/strbuf.c +44 -26
- data/ext/alt_printf/strbuf.h +12 -3
- data/ext/alt_printf/syntax.h +8 -5
- data/lib/alt_printf/alt_printf.so +0 -0
- data/lib/alt_printf/version.rb +1 -1
- metadata +12 -6
- data/ext/alt_printf/altprintf.c +0 -250
- data/ext/alt_printf/list.c +0 -81
- data/ext/alt_printf/list.h +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21ad918ab6294134e9518f00a5668eafc8589d2bd434cd151544407cf771ed1f
|
4
|
+
data.tar.gz: 50f52442cef28318a12c87a14c7d4d4ce1d61b086e898811ff038995f4202018
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6a76f53245ab159d89fed59ef4c2026c813a0a3fbde2fdc6ee4508238f1ce7b634641a582fdba85f929f3d882914ebebc812cb33adfcdb767ba3aaaf22d8858
|
7
|
+
data.tar.gz: d049337a26d25eace4667bda2a040cad2066bd51d09a7e22aa3d36b8e39dbd1364e3b34940d0c731b206e7c379a2a58b3cb39476c7c22e31f6a2ddfffa4c7e8d
|
data/Rakefile
CHANGED
@@ -7,7 +7,13 @@ SRC_DIR = File.join(__dir__, '../src')
|
|
7
7
|
|
8
8
|
Rake::ExtensionTask.new('alt_printf') do |ext|
|
9
9
|
ext.lib_dir = 'lib/alt_printf'
|
10
|
-
ext.config_script =
|
10
|
+
ext.config_script =
|
11
|
+
case ENV['GEM_DEBUG']
|
12
|
+
when nil
|
13
|
+
'extconf_dev.rb'
|
14
|
+
else
|
15
|
+
'extconf_debug.rb'
|
16
|
+
end
|
11
17
|
end
|
12
18
|
|
13
19
|
desc 'copy necessary C files from ../src and build the resulting gem'
|
@@ -31,7 +37,7 @@ task :build_gem do
|
|
31
37
|
end
|
32
38
|
|
33
39
|
FileUtils.cp_r(
|
34
|
-
%w[altprintf
|
40
|
+
%w[altprintf fmt fmte parsef strbuf enums log syntax].map do |w|
|
35
41
|
%w[h c].map { |e| File.join(SRC_DIR, "#{w}.#{e}") }
|
36
42
|
.select { |f| File.exist?(f) }
|
37
43
|
end.flatten,
|
data/alt_printf.gemspec
CHANGED
@@ -17,7 +17,7 @@ AltPrintf::SPEC = Gem::Specification.new do |s|
|
|
17
17
|
s.extensions = Dir["ext/**/extconf.rb"]
|
18
18
|
s.require_paths = ['lib']
|
19
19
|
|
20
|
-
s.required_ruby_version = '>= 2.
|
20
|
+
s.required_ruby_version = '>= 2.5.5'
|
21
21
|
|
22
22
|
s.add_development_dependency 'rake-compiler', '~> 1.0'
|
23
23
|
s.add_development_dependency 'rake', '~> 12.3'
|
data/ext/alt_printf/alt_printf.c
CHANGED
@@ -1,19 +1,16 @@
|
|
1
|
+
#ifdef _FORTIFY_SOURCE
|
2
|
+
#undef _FORTIFY_SOURCE
|
3
|
+
#endif
|
4
|
+
|
5
|
+
#include "extconf.h"
|
1
6
|
#include <stdio.h>
|
2
7
|
#include <locale.h>
|
3
8
|
#include <wchar.h>
|
4
9
|
#include <ruby.h>
|
5
10
|
#include <ruby/encoding.h>
|
6
|
-
#include "extconf.h"
|
7
|
-
#include "list.h"
|
8
11
|
#include "altprintf.h"
|
9
12
|
#include "log.h"
|
10
13
|
|
11
|
-
#define CHECKARG \
|
12
|
-
if (!use_hash) { \
|
13
|
-
if (*argi >= argc) goto no_more_args; \
|
14
|
-
entry = rb_ary_entry(*argv, *argi); \
|
15
|
-
}
|
16
|
-
|
17
14
|
#define MODNAME "AltPrintf"
|
18
15
|
|
19
16
|
rb_encoding *enc;
|
@@ -40,11 +37,18 @@ VALUE wcstorbs(const wchar_t *wstr) {
|
|
40
37
|
char *cstr;
|
41
38
|
VALUE str;
|
42
39
|
|
40
|
+
LOG("converting wcs to rbs\n");
|
41
|
+
LOG("wcs: '%ls'\n\n", wstr);
|
42
|
+
|
43
43
|
len = wcsrtombs(NULL, &wstr, 0, NULL);
|
44
|
+
LOG("len: %d\n", len);
|
44
45
|
cstr = calloc(len, sizeof(wchar_t));
|
45
46
|
wcsrtombs(cstr, &wstr, len, NULL);
|
47
|
+
LOG("cstr: '%s'\n", cstr);
|
46
48
|
|
47
|
-
LOG("wcs to rbs, len: %d,
|
49
|
+
LOG("wcs to rbs, len: %d, wcs: %ls, mbs: '%s'\n", len, wstr, cstr);
|
50
|
+
|
51
|
+
if (len == (size_t)-1) return Qnil;
|
48
52
|
|
49
53
|
str = rb_external_str_new_with_enc(cstr, len, enc);
|
50
54
|
free(cstr);
|
@@ -52,147 +56,134 @@ VALUE wcstorbs(const wchar_t *wstr) {
|
|
52
56
|
return str;
|
53
57
|
}
|
54
58
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
VALUE get_entry(struct fmte *f, VALUE *argv, long *argi, VALUE *hash) {
|
60
|
+
VALUE sym, entry;
|
61
|
+
size_t len;
|
62
|
+
const wchar_t *tmpw;
|
63
|
+
char *cstr;
|
64
|
+
|
65
|
+
LOG("getting entry\n");
|
61
66
|
|
62
|
-
|
67
|
+
if (f->anglearg_len == 0) {
|
68
|
+
LOG("getting from argv[%ld]\n", *argi);
|
69
|
+
entry = rb_ary_entry(*argv, *argi);
|
70
|
+
(*argi)++;
|
71
|
+
return entry;
|
72
|
+
}
|
63
73
|
|
64
|
-
|
65
|
-
wint_t *tmp_char;
|
66
|
-
double *tmp_double;
|
67
|
-
const wchar_t *tmp_str;
|
74
|
+
LOG("getting from hash\n");
|
68
75
|
|
69
|
-
|
70
|
-
|
76
|
+
//fmte_inspect(f);
|
77
|
+
|
78
|
+
tmpw = f->anglearg_start;
|
79
|
+
len = wcsnrtombs(NULL, &tmpw, f->anglearg_len, 0, NULL);
|
80
|
+
LOG("allocating %d, maxlen %d\n", len, f->anglearg_len);
|
81
|
+
|
82
|
+
cstr = calloc(len + 1, sizeof(char));
|
83
|
+
wcsnrtombs(cstr, &tmpw, f->anglearg_len, len, NULL);
|
84
|
+
LOG("wrote cstr %s\n", cstr);
|
85
|
+
|
86
|
+
LOG("symbol | cstr: '%s', len %d\n", cstr, len);
|
71
87
|
|
72
|
-
|
73
|
-
|
74
|
-
|
88
|
+
sym = rb_check_symbol_cstr(cstr, len, enc);
|
89
|
+
entry = rb_hash_lookup2(*hash, sym, Qnil);
|
90
|
+
if (entry == Qnil) rb_raise(rb_eKeyError, "missing key :%s", cstr);
|
91
|
+
free(cstr);
|
92
|
+
|
93
|
+
return entry;
|
94
|
+
}
|
95
|
+
|
96
|
+
wchar_t *rb_apformat(wchar_t *fmt, VALUE *argv, long *argi, VALUE *hash) {
|
97
|
+
struct fmte *f, *head;
|
98
|
+
wchar_t *final;
|
99
|
+
int loop = 1;
|
100
|
+
long *tmpi;
|
101
|
+
wint_t *tmpc;
|
102
|
+
wchar_t *tmps;
|
103
|
+
double *tmpd;
|
104
|
+
void *tmp;
|
105
|
+
VALUE entry;
|
75
106
|
|
76
|
-
|
107
|
+
head = f = parsef(&fmt);
|
77
108
|
|
78
|
-
|
79
|
-
LOG("
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
break;
|
84
|
-
}
|
109
|
+
while (loop) {
|
110
|
+
LOG("scanned type: %d\n", f->type);
|
111
|
+
|
112
|
+
if (f->type != FEnd && f->type != FRaw) {
|
113
|
+
entry = get_entry(f, argv, argi, hash);
|
85
114
|
} else {
|
86
|
-
|
87
|
-
case FS_A_CHARARG:
|
88
|
-
fmt++;
|
89
|
-
break;
|
90
|
-
case FS_A_RBHASHSTART:
|
91
|
-
tmp_str = fmt + 1;
|
92
|
-
|
93
|
-
use_hash = -1;
|
94
|
-
while (fmt < end && *fmt != FS_A_RBHASHEND) {
|
95
|
-
fmt++;
|
96
|
-
use_hash++;
|
97
|
-
}
|
98
|
-
|
99
|
-
LOG("use_hash: %d\n", use_hash);
|
100
|
-
len = wcsnrtombs(NULL, &tmp_str, use_hash, 0, NULL);
|
101
|
-
|
102
|
-
cstr = calloc(len + 1, sizeof(char));
|
103
|
-
wcsnrtombs(cstr, &tmp_str, use_hash, len, NULL);
|
104
|
-
|
105
|
-
LOG("symbol | cstr: '%s', len %d\n", cstr, len);
|
106
|
-
|
107
|
-
symbol = rb_check_symbol_cstr(cstr, len, enc);
|
108
|
-
entry = rb_hash_lookup2(*hash, symbol, Qnil);
|
109
|
-
|
110
|
-
if (entry == Qnil) {
|
111
|
-
rb_raise(
|
112
|
-
rb_eKeyError,
|
113
|
-
"no such key :%s",
|
114
|
-
cstr
|
115
|
-
);
|
116
|
-
free(cstr);
|
117
|
-
}
|
118
|
-
|
119
|
-
use_hash = 1;
|
120
|
-
|
121
|
-
break;
|
122
|
-
case FS_A_STRINGSTART:
|
123
|
-
while (fmt < end && *fmt != FS_A_STRINGEND) fmt++;
|
124
|
-
break;
|
125
|
-
case FS_T_STRING:
|
126
|
-
CHECKARG;
|
127
|
-
|
128
|
-
tmp_str = rbstowcs(entry);
|
129
|
-
le_cur = list_elem_ini(tmp_str, String);
|
130
|
-
goto match;
|
131
|
-
case FS_T_TERN:
|
132
|
-
CHECKARG;
|
133
|
-
tmp_int = malloc(sizeof(long int));
|
134
|
-
if (entry == Qfalse || entry == Qnil) {
|
135
|
-
*tmp_int = 0;
|
136
|
-
} else {
|
137
|
-
*tmp_int = 1;
|
138
|
-
}
|
139
|
-
LOG("got bool %ld\n", *tmp_int);
|
140
|
-
le_cur = list_elem_ini(tmp_int, Int);
|
141
|
-
|
142
|
-
goto match;
|
143
|
-
case FS_T_MUL:
|
144
|
-
case FS_T_ALIGN:
|
145
|
-
case FS_T_INT:
|
146
|
-
CHECKARG;
|
147
|
-
|
148
|
-
tmp_int = malloc(sizeof(long int));
|
149
|
-
*tmp_int = FIX2LONG(entry);
|
150
|
-
LOG("got int %ld\n", *tmp_int);
|
151
|
-
le_cur = list_elem_ini(tmp_int, Int);
|
152
|
-
goto match;
|
153
|
-
case FS_T_CHAR:
|
154
|
-
CHECKARG;
|
155
|
-
|
156
|
-
tmp_char = malloc(sizeof(wint_t));
|
157
|
-
tmp_str = rbstowcs(entry);
|
158
|
-
*tmp_char = btowc(tmp_str[0]);
|
159
|
-
le_cur = list_elem_ini(tmp_char, Char);
|
160
|
-
goto match;
|
161
|
-
case FS_T_DOUBLE:
|
162
|
-
CHECKARG;
|
163
|
-
|
164
|
-
tmp_double = malloc(sizeof(double));
|
165
|
-
*tmp_double = RFLOAT_VALUE(entry);
|
166
|
-
le_cur = list_elem_ini(tmp_double, Double);
|
167
|
-
goto match;
|
168
|
-
match: le_prev->next = le_cur;
|
169
|
-
le_prev = le_cur;
|
170
|
-
mode = 0;
|
171
|
-
(*argi)++;
|
172
|
-
break;
|
173
|
-
case FS_START:
|
174
|
-
mode = 0;
|
175
|
-
break;
|
176
|
-
}
|
115
|
+
entry = Qnil;
|
177
116
|
}
|
178
|
-
}
|
179
117
|
|
180
|
-
|
181
|
-
|
118
|
+
switch (f->type) {
|
119
|
+
case FString:
|
120
|
+
Check_Type(entry, T_STRING);
|
121
|
+
|
122
|
+
tmp = rbstowcs(entry);
|
123
|
+
goto match;
|
124
|
+
case FTern:
|
125
|
+
tmpi = malloc(sizeof(long));
|
126
|
+
|
127
|
+
*tmpi = (entry == Qfalse || entry == Qnil) ? 0 : 1;
|
128
|
+
|
129
|
+
tmp = tmpi;
|
130
|
+
goto match;
|
131
|
+
case FMul:
|
132
|
+
case FAlign:
|
133
|
+
case FInt:
|
134
|
+
Check_Type(entry, T_FIXNUM);
|
135
|
+
|
136
|
+
tmpi = malloc(sizeof(long int));
|
137
|
+
*tmpi = FIX2LONG(entry);
|
138
|
+
tmp = tmpi;
|
139
|
+
goto match;
|
140
|
+
case FChar:
|
141
|
+
Check_Type(entry, T_STRING);
|
142
|
+
|
143
|
+
tmpc = malloc(sizeof(wint_t));
|
144
|
+
tmps = rbstowcs(entry);
|
145
|
+
*tmpc = btowc(tmps[0]);
|
146
|
+
tmp = tmpc;
|
147
|
+
goto match;
|
148
|
+
case FDouble:
|
149
|
+
Check_Type(entry, T_FLOAT);
|
150
|
+
|
151
|
+
tmpd = malloc(sizeof(double));
|
152
|
+
*tmpd = RFLOAT_VALUE(entry);
|
153
|
+
tmp = tmpd;
|
154
|
+
match:
|
155
|
+
f->value = tmp;
|
156
|
+
break;
|
157
|
+
case FRaw:
|
158
|
+
break;
|
159
|
+
case FEnd:
|
160
|
+
LOG("EOS (end of string)\n");
|
161
|
+
loop = 0;
|
162
|
+
break;
|
163
|
+
case FNone:
|
164
|
+
LOG("error! shouldn' t be none\n");
|
165
|
+
break;
|
166
|
+
}
|
182
167
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
168
|
+
LOG("pushing fmt\n");
|
169
|
+
#ifdef DEBUG
|
170
|
+
fmte_inspect(f);
|
171
|
+
#endif
|
172
|
+
fmte_push(head, f);
|
173
|
+
if (loop) f = parsef(&fmt);
|
174
|
+
}
|
187
175
|
|
188
|
-
|
176
|
+
LOG("got all fmt elements\n");
|
177
|
+
final = assemble_fmt(head);
|
178
|
+
fmte_destroy(head);
|
179
|
+
return final;
|
189
180
|
}
|
190
181
|
|
191
182
|
VALUE rb_alt_printf(long passes, size_t argc, VALUE *argv, VALUE self) {
|
192
183
|
VALUE fmt, args, hash, final;
|
193
184
|
wchar_t *wfmt;
|
194
185
|
wchar_t *formatted;
|
195
|
-
|
186
|
+
long argi;
|
196
187
|
|
197
188
|
rb_scan_args(argc, argv, "1*:", &fmt, &args, &hash);
|
198
189
|
|
@@ -204,24 +195,22 @@ VALUE rb_alt_printf(long passes, size_t argc, VALUE *argv, VALUE self) {
|
|
204
195
|
if (passes == 0) return fmt;
|
205
196
|
|
206
197
|
wfmt = rbstowcs(fmt);
|
198
|
+
formatted = NULL;
|
207
199
|
|
208
|
-
|
209
|
-
|
210
|
-
ap = rb_altprintf_make_list(wfmt, &args, &argi, &hash);
|
211
|
-
|
212
|
-
//list_elem_inspect_all(ap);
|
200
|
+
argi = 0;
|
201
|
+
for (; passes > 0; passes--) {
|
213
202
|
LOG("wfmt: %ls\n", wfmt);
|
214
203
|
|
215
|
-
formatted =
|
204
|
+
formatted = rb_apformat(wfmt, &args, &argi, &hash);
|
205
|
+
|
216
206
|
LOG("formatted result: '%ls'\n", formatted);
|
217
207
|
|
218
208
|
free(wfmt);
|
219
|
-
list_elem_destroy(ap);
|
220
|
-
|
221
209
|
wfmt = formatted;
|
222
|
-
passes--;
|
223
210
|
}
|
224
211
|
|
212
|
+
|
213
|
+
LOG("final: '%ls'\n", formatted);
|
225
214
|
final = wcstorbs(formatted);
|
226
215
|
|
227
216
|
free(formatted);
|
@@ -230,8 +219,6 @@ VALUE rb_alt_printf(long passes, size_t argc, VALUE *argv, VALUE self) {
|
|
230
219
|
}
|
231
220
|
|
232
221
|
VALUE rb_alt_printf_single_pass(size_t argc, VALUE *argv, VALUE self) {
|
233
|
-
VALUE fmt, args, hash, final;
|
234
|
-
|
235
222
|
return rb_alt_printf(1, argc, argv, self);
|
236
223
|
}
|
237
224
|
|
@@ -250,10 +237,11 @@ VALUE rb_alt_printf_multi_pass(size_t argc, VALUE *argv, VALUE self) {
|
|
250
237
|
return rb_alt_printf(passes, argc - 1, &argv[1], self);
|
251
238
|
}
|
252
239
|
|
253
|
-
void Init_alt_printf()
|
254
|
-
|
240
|
+
void Init_alt_printf() {
|
241
|
+
VALUE mod;
|
242
|
+
|
255
243
|
enc = rb_enc_find("UTF-8");
|
256
|
-
|
244
|
+
mod = rb_define_module(MODNAME);
|
257
245
|
rb_define_module_function(mod, "fmt", rb_alt_printf_single_pass, -1);
|
258
246
|
rb_define_module_function(mod, "fmtm", rb_alt_printf_multi_pass, -1);
|
259
247
|
}
|
data/ext/alt_printf/altprintf.h
CHANGED
@@ -1,42 +1,5 @@
|
|
1
|
-
#ifndef
|
2
|
-
#define
|
3
|
-
|
4
|
-
#
|
5
|
-
#define _XOPEN_SOURCE
|
6
|
-
#endif
|
7
|
-
|
8
|
-
#include <stdio.h>
|
9
|
-
#include <stdlib.h>
|
10
|
-
#include <stdarg.h>
|
11
|
-
#include <string.h>
|
12
|
-
#include <math.h>
|
13
|
-
#include <limits.h>
|
14
|
-
#include <wchar.h>
|
15
|
-
#include "strbuf.h"
|
16
|
-
#include "list.h"
|
17
|
-
#include "syntax.h"
|
18
|
-
|
19
|
-
wchar_t *altsprintf(wchar_t *fmt, struct list_elem *le);
|
20
|
-
|
21
|
-
enum align {
|
22
|
-
Left,
|
23
|
-
Right,
|
24
|
-
Center
|
25
|
-
};
|
26
|
-
|
27
|
-
struct width {
|
28
|
-
long int prec;
|
29
|
-
long int pad;
|
30
|
-
};
|
31
|
-
|
32
|
-
struct format {
|
33
|
-
wchar_t *stringarg_start;
|
34
|
-
wchar_t *stringarg_end;
|
35
|
-
wint_t chararg;
|
36
|
-
wint_t padchar;
|
37
|
-
enum align align;
|
38
|
-
struct width width;
|
39
|
-
struct list_elem *le;
|
40
|
-
};
|
41
|
-
|
1
|
+
#ifndef ALTPRINTF_H_
|
2
|
+
#define ALTPRINTF_H_
|
3
|
+
#include "parsef.h"
|
4
|
+
#include "fmt.h"
|
42
5
|
#endif
|