alt_printf 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|