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 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