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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35403cb6b05ff5261a51180f48e16840860e28e8e49e6ce7f58fc5bd005a280e
4
- data.tar.gz: fd7fe644f7d76dadc0780f98f6871fe6b08e31dad97ae5e3ef03877753c88bfd
3
+ metadata.gz: 21ad918ab6294134e9518f00a5668eafc8589d2bd434cd151544407cf771ed1f
4
+ data.tar.gz: 50f52442cef28318a12c87a14c7d4d4ce1d61b086e898811ff038995f4202018
5
5
  SHA512:
6
- metadata.gz: b408f3e40e812c8d420bf03749a0fd07136a1a8849af5011a855464602163cf7e2bc3a824c0b7565e410c856b0078d8ee01ccee744f65ca8c68b7d425eaa3a83
7
- data.tar.gz: ea0811bf28ad00219a1218a3c915248526f1b01707bda152a289ddd6c78aa368a06ae073bbeb90dd1dd31c4301cca1f27cb62eefb643e494d096ded65bb6a12c
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 = 'extconf_dev.rb'
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 list log strbuf syntax].map do |w|
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.6.3'
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'
@@ -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, cstr: '%s'\n", len, cstr);
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
- struct list_elem *rb_altprintf_make_list(const wchar_t *fmt, VALUE *argv, long *argi, VALUE *hash) {
56
- struct list_elem *le_cur;
57
- struct list_elem *le_start;
58
- struct list_elem *le_prev;
59
- /* create a dummy element as the head */
60
- le_start = le_prev = list_elem_create();
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
- VALUE entry, symbol;
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
- long int *tmp_int;
65
- wint_t *tmp_char;
66
- double *tmp_double;
67
- const wchar_t *tmp_str;
74
+ LOG("getting from hash\n");
68
75
 
69
- char *cstr;
70
- size_t len;
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
- int mode = 0;
73
- long argc = rb_array_len(*argv);
74
- int use_hash = 0;
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
- const wchar_t *end = &fmt[wcslen(fmt)];
107
+ head = f = parsef(&fmt);
77
108
 
78
- for (;fmt<end;fmt++) {
79
- LOG("checking char '%lc', lvl: '%d'\n", (wint_t)(*fmt), mode);
80
- if (mode == 0) {
81
- switch(*fmt) {
82
- case FS_START: mode = 1;
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
- switch (*fmt) {
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
- no_more_args:
181
- if (le_start->next == NULL) return le_start;
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
- /* set cur to the 2nd element and destroy the first one */
184
- le_cur = le_start->next;
185
- le_start->next = NULL;
186
- list_elem_destroy(le_start);
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
- return le_cur;
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
- struct list_elem *ap;
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
- long argi = 0;
209
- while (passes > 0) {
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 = altsprintf(wfmt, ap);
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
- VALUE mod = rb_define_module(MODNAME);
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
  }
@@ -1,42 +1,5 @@
1
- #ifndef ALTPRINTF_H
2
- #define ALTPRINTF_H
3
-
4
- #ifndef _XOPEN_SOURCE
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