edn_turbo 0.1.0 → 0.1.1

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.
@@ -2,7 +2,7 @@
2
2
  #define EDN_RUBY_EXT_PARSER_H
3
3
 
4
4
  #include <string>
5
- #include <strstream>
5
+ #include <sstream>
6
6
  #include <rice/Object.hpp>
7
7
  #include <rice/to_from_ruby.hpp>
8
8
 
@@ -21,17 +21,18 @@ namespace edn
21
21
 
22
22
  Rice::Object parse(const char* s, std::size_t len);
23
23
 
24
- const char* EDN_parse_decimal(const char *p, const char *pe, Rice::Object& o);
25
- const char* EDN_parse_integer(const char *p, const char *pe, Rice::Object& o);
26
- const char* EDN_parse_keyword(const char *p, const char *pe, Rice::Object& o);
27
- const char* EDN_parse_tagged (const char *p, const char *pe, Rice::Object& o, bool& dicard);
28
- const char* EDN_parse_string (const char *p, const char *pe, Rice::Object& o);
29
- const char* EDN_parse_value (const char *p, const char *pe, Rice::Object& o);
30
- const char* EDN_parse_vector (const char *p, const char *pe, Rice::Object& o);
31
- const char* EDN_parse_map (const char *p, const char *pe, Rice::Object& o);
32
- const char* EDN_parse_list (const char *p, const char *pe, Rice::Object& o);
24
+ const char* parse_decimal(const char *p, const char *pe, Rice::Object& o);
25
+ const char* parse_integer(const char *p, const char *pe, Rice::Object& o);
26
+ const char* parse_keyword(const char *p, const char *pe, Rice::Object& o);
27
+ const char* parse_tagged (const char *p, const char *pe, Rice::Object& o, bool& dicard);
28
+ const char* parse_string (const char *p, const char *pe, Rice::Object& o);
29
+ const char* parse_value (const char *p, const char *pe, Rice::Object& o);
30
+ const char* parse_vector (const char *p, const char *pe, Rice::Object& o);
31
+ const char* parse_map (const char *p, const char *pe, Rice::Object& o);
32
+ const char* parse_list (const char *p, const char *pe, Rice::Object& o);
33
33
 
34
- bool EDN_parse_byte_stream (const char *p, const char *pe, Rice::String& s);
34
+ static bool parse_byte_stream(const char *p, const char *pe, Rice::String& s);
35
+ static bool unicode_to_utf8(const char *s, std::size_t len, std::string& rslt);
35
36
 
36
37
  void error(const std::string& err, char c) const;
37
38
  void error(char err_c) const { error("", err_c); }
@@ -52,9 +53,6 @@ namespace edn
52
53
 
53
54
  Rice::Object process(const std::string& data) { return parse(data.c_str(), data.length()); }
54
55
 
55
- // handle file read from the c-side
56
- Rice::Object open(const std::string& file);
57
-
58
56
  }; // Engine
59
57
 
60
58
  } // namespace
@@ -1,9 +1,6 @@
1
1
  #include <iostream>
2
2
  #include <string>
3
3
 
4
- #include <ruby/ruby.h>
5
- #include <ruby/encoding.h>
6
-
7
4
  #include <rice/Hash.hpp>
8
5
  #include <rice/Array.hpp>
9
6
  #include <rice/to_from_ruby.hpp>
@@ -13,6 +10,10 @@
13
10
  //
14
11
  // EDN spec at: https://github.com/edn-format/edn
15
12
  //
13
+ //
14
+ // many thanks to Florian Frank for json-ruby which was essential in
15
+ // helping me learn about ragel
16
+ //
16
17
 
17
18
  %%{
18
19
  machine EDN_common;
@@ -67,21 +68,21 @@
67
68
  }
68
69
 
69
70
  action parse_keyword {
70
- const char *np = EDN_parse_keyword(fpc, pe, o);
71
+ const char *np = parse_keyword(fpc, pe, o);
71
72
  if (np == NULL) { fhold; fbreak; } else fexec np;
72
73
  }
73
74
 
74
75
  action parse_string {
75
- const char *np = EDN_parse_string(fpc, pe, o);
76
+ const char *np = parse_string(fpc, pe, o);
76
77
  if (np == NULL) { fhold; fbreak; } else fexec np;
77
78
  }
78
79
 
79
80
  action parse_number {
80
81
  // try to parse a decimal first
81
- const char *np = EDN_parse_decimal(fpc, pe, o);
82
+ const char *np = parse_decimal(fpc, pe, o);
82
83
  if (np == NULL) {
83
84
  // if we can't, try to parse it as an int
84
- np = EDN_parse_integer(fpc, pe, o);
85
+ np = parse_integer(fpc, pe, o);
85
86
  }
86
87
 
87
88
  if (np) {
@@ -96,17 +97,17 @@
96
97
  }
97
98
 
98
99
  action parse_vector {
99
- const char *np = EDN_parse_vector(fpc, pe, o);
100
+ const char *np = parse_vector(fpc, pe, o);
100
101
  if (np == NULL) { fhold; fbreak; } else fexec np;
101
102
  }
102
103
 
103
104
  action parse_list {
104
- const char *np = EDN_parse_list(fpc, pe, o);
105
+ const char *np = parse_list(fpc, pe, o);
105
106
  if (np == NULL) { fhold; fbreak; } else fexec np;
106
107
  }
107
108
 
108
109
  action parse_map {
109
- const char *np = EDN_parse_map(fpc, pe, o);
110
+ const char *np = parse_map(fpc, pe, o);
110
111
  if (np == NULL) { fhold; fbreak; } else fexec np;
111
112
  }
112
113
 
@@ -126,7 +127,7 @@
126
127
  }%%
127
128
 
128
129
 
129
- const char *edn::Parser::EDN_parse_value(const char *p, const char *pe, Rice::Object& o)
130
+ const char *edn::Parser::parse_value(const char *p, const char *pe, Rice::Object& o)
130
131
  {
131
132
  int cs;
132
133
 
@@ -145,80 +146,6 @@ const char *edn::Parser::EDN_parse_value(const char *p, const char *pe, Rice::Ob
145
146
  }
146
147
 
147
148
 
148
- // ============================================================
149
- // tagged element parsing - any of #uuid, #inst, #{, #(some symbol)
150
- // discard (#_ <ident>) is handled by the top-level machine
151
- //
152
- %%{
153
- machine EDN_dispatch;
154
- include EDN_common;
155
-
156
- begin_discard = '_';
157
- begin_set = '{';
158
- end_set = '}';
159
-
160
- write data;
161
-
162
- action exit { fhold; fbreak; }
163
-
164
- main := begin_dispatch (
165
- (begin_discard (space)? ([a-zA-Z0-9\-\.]*)) |
166
- ('inst ' string_delim ([0-9\-+:\.TZ])* string_delim) |
167
- ('uuid ' string_delim ([a-f0-9\-]* string_delim))
168
- )
169
- (^[a-zA-Z0-9:\.\-+ ]* @exit);
170
- }%%
171
-
172
-
173
- const char* edn::Parser::EDN_parse_tagged(const char *p, const char *pe, Rice::Object& o, bool& discard)
174
- {
175
- int cs;
176
- Rice::String str;
177
-
178
- %% write init;
179
- p_save = p;
180
- %% write exec;
181
-
182
- if (cs >= EDN_dispatch_first_final) {
183
-
184
- //is it a discard? if so, just drop the following token
185
- if (*(p_save + 1) == '_')
186
- {
187
- discard = true;
188
- return p + 1;
189
- }
190
-
191
- std::size_t len = p - p_save;
192
- std::string buf;
193
- buf.reserve(len);
194
-
195
- if (len > 10)
196
- {
197
- // there's enough room to be #inst or #uuid, copy the
198
- // string portion
199
- if (std::strncmp(p_save + 1, "inst", 4) == 0) {
200
- buf.append(p_save + 7, len - 8);
201
- } else if (std::strncmp(p_save + 1, "uuid", 4) == 0) {
202
- buf.append(p_save + 7, len - 8);
203
- }
204
-
205
- o = Rice::String(buf);
206
- return p;
207
- }
208
-
209
- // tagged element
210
- o = Rice::String(buf);
211
- return p;
212
- }
213
- else if (cs == EDN_dispatch_error) {
214
- error(*p);
215
- return pe;
216
- }
217
- else if (cs == EDN_dispatch_en_main) {} // silence ragel warning
218
- return NULL;
219
- }
220
-
221
-
222
149
 
223
150
  // ============================================================
224
151
  // keyword parsing
@@ -237,7 +164,7 @@ const char* edn::Parser::EDN_parse_tagged(const char *p, const char *pe, Rice::O
237
164
  }%%
238
165
 
239
166
 
240
- const char* edn::Parser::EDN_parse_keyword(const char *p, const char *pe, Rice::Object& o)
167
+ const char* edn::Parser::parse_keyword(const char *p, const char *pe, Rice::Object& o)
241
168
  {
242
169
  int cs;
243
170
 
@@ -272,7 +199,7 @@ const char* edn::Parser::EDN_parse_keyword(const char *p, const char *pe, Rice::
272
199
  write data;
273
200
 
274
201
  action parse_string {
275
- if (!EDN_parse_byte_stream(p_save + 1, p, s)) {
202
+ if (!parse_byte_stream(p_save + 1, p, s)) {
276
203
  fhold;
277
204
  fbreak;
278
205
  } else {
@@ -292,82 +219,7 @@ const char* edn::Parser::EDN_parse_keyword(const char *p, const char *pe, Rice::
292
219
  }%%
293
220
 
294
221
 
295
- //
296
- // copies the string data, unescaping any present values that need to be replaced
297
- //
298
- bool edn::Parser::EDN_parse_byte_stream(const char *p, const char *pe, Rice::String& s)
299
- {
300
- if (pe > p) {
301
- std::string buf;
302
- std::size_t len = pe - p;
303
-
304
- // pre-allocate storage needed
305
- buf.reserve(len);
306
-
307
- const char* cp = p;
308
- std::size_t pos = 0;
309
- char c, replacement;
310
-
311
- while (cp < pe)
312
- {
313
- // append any other character that is not the escaping slash
314
- if (*cp != '\\') {
315
- buf.replace(pos++, 1, 1, *cp++);
316
- continue;
317
- }
318
-
319
- // looking at a '\' - check what it escapes if there's a
320
- // following character
321
- if (++cp == pe)
322
- break;
323
-
324
- c = *cp++;
325
- replacement = '?';
326
-
327
- switch (c)
328
- {
329
- case 't':
330
- replacement = '\t';
331
- break;
332
- case 'n':
333
- replacement = '\n';
334
- break;
335
- case 'r':
336
- replacement = '\r';
337
- break;
338
- case '\"':
339
- replacement = '\"';
340
- break;
341
- case '\\':
342
- replacement = '\\';
343
- break;
344
- /* TODO: add support for this!
345
- case 'u':
346
- replacement = '\u';
347
- break;
348
- */
349
- default:
350
- std::cerr << "value must be unescaped but case is unhandled: '" << c << "'" << std::endl;
351
- break;
352
- }
353
-
354
- // substitute the escaped walue
355
- if (replacement != '?')
356
- buf.replace(pos++, 1, 1, replacement);
357
- }
358
-
359
- // utf-8 encode
360
- VALUE vs = Rice::protect( rb_str_new2, buf.c_str() );
361
- VALUE s_utf8 = Rice::protect( rb_enc_associate, vs, rb_utf8_encoding() );
362
- s = Rice::String(s_utf8);
363
- return true;
364
- }
365
-
366
- return false;
367
- }
368
-
369
-
370
- const char* edn::Parser::EDN_parse_string(const char *p, const char *pe, Rice::Object& o)
222
+ const char* edn::Parser::parse_string(const char *p, const char *pe, Rice::Object& o)
371
223
  {
372
224
  static const char* EDN_TYPE = "string";
373
225
  int cs;
@@ -410,7 +262,7 @@ const char* edn::Parser::EDN_parse_string(const char *p, const char *pe, Rice::O
410
262
  }%%
411
263
 
412
264
 
413
- const char* edn::Parser::EDN_parse_decimal(const char *p, const char *pe, Rice::Object& o)
265
+ const char* edn::Parser::parse_decimal(const char *p, const char *pe, Rice::Object& o)
414
266
  {
415
267
  int cs;
416
268
 
@@ -441,7 +293,7 @@ const char* edn::Parser::EDN_parse_decimal(const char *p, const char *pe, Rice::
441
293
  main := '-'? ('0' | [1-9][0-9]* [M]?) (^[0-9M]? @exit);
442
294
  }%%
443
295
 
444
- const char* edn::Parser::EDN_parse_integer(const char *p, const char *pe, Rice::Object& o)
296
+ const char* edn::Parser::parse_integer(const char *p, const char *pe, Rice::Object& o)
445
297
  {
446
298
  int cs;
447
299
 
@@ -469,7 +321,7 @@ const char* edn::Parser::EDN_parse_integer(const char *p, const char *pe, Rice::
469
321
 
470
322
  action parse_value {
471
323
  Rice::Object v;
472
- const char *np = EDN_parse_value(fpc, pe, v);
324
+ const char *np = parse_value(fpc, pe, v);
473
325
  if (np == NULL) {
474
326
  fhold; fbreak;
475
327
  } else {
@@ -481,7 +333,7 @@ const char* edn::Parser::EDN_parse_integer(const char *p, const char *pe, Rice::
481
333
  action parse_dispatch {
482
334
  bool discard = false;
483
335
  Rice::Object v;
484
- const char *np = EDN_parse_tagged(fpc, pe, v, discard);
336
+ const char *np = parse_tagged(fpc, pe, v, discard);
485
337
  if (np == NULL) {
486
338
  fhold; fbreak;
487
339
  } else {
@@ -520,7 +372,7 @@ const char* edn::Parser::EDN_parse_integer(const char *p, const char *pe, Rice::
520
372
  //
521
373
  // vector parsing
522
374
  //
523
- const char* edn::Parser::EDN_parse_vector(const char *p, const char *pe, Rice::Object& o)
375
+ const char* edn::Parser::parse_vector(const char *p, const char *pe, Rice::Object& o)
524
376
  {
525
377
  static const char* EDN_TYPE = "vector";
526
378
 
@@ -563,7 +415,7 @@ const char* edn::Parser::EDN_parse_vector(const char *p, const char *pe, Rice::O
563
415
  //
564
416
  // list parsing
565
417
  //
566
- const char* edn::Parser::EDN_parse_list(const char *p, const char *pe, Rice::Object& o)
418
+ const char* edn::Parser::parse_list(const char *p, const char *pe, Rice::Object& o)
567
419
  {
568
420
  static const char* EDN_TYPE = "list";
569
421
 
@@ -597,7 +449,7 @@ const char* edn::Parser::EDN_parse_list(const char *p, const char *pe, Rice::Obj
597
449
  write data;
598
450
 
599
451
  action parse_key {
600
- const char *np = EDN_parse_value(fpc, pe, k);
452
+ const char *np = parse_value(fpc, pe, k);
601
453
  if (np == NULL) {
602
454
  fhold; fbreak;
603
455
  } else {
@@ -606,7 +458,7 @@ const char* edn::Parser::EDN_parse_list(const char *p, const char *pe, Rice::Obj
606
458
  }
607
459
 
608
460
  action parse_value {
609
- const char *np = EDN_parse_value(fpc, pe, v);
461
+ const char *np = parse_value(fpc, pe, v);
610
462
  if (np == NULL) {
611
463
  fhold; fbreak;
612
464
  } else {
@@ -634,7 +486,7 @@ const char* edn::Parser::EDN_parse_list(const char *p, const char *pe, Rice::Obj
634
486
  }%%
635
487
 
636
488
 
637
- const char* edn::Parser::EDN_parse_map(const char *p, const char *pe, Rice::Object& o)
489
+ const char* edn::Parser::parse_map(const char *p, const char *pe, Rice::Object& o)
638
490
  {
639
491
  static const char* EDN_TYPE = "map";
640
492
 
@@ -659,6 +511,82 @@ const char* edn::Parser::EDN_parse_map(const char *p, const char *pe, Rice::Obje
659
511
 
660
512
 
661
513
 
514
+ // ============================================================
515
+ // tagged element parsing - any of #uuid, #inst, #{, #(some symbol)
516
+ // discard (#_ <ident>) is handled by the top-level machine
517
+ //
518
+ // NOTE: this is not fully implemented yet
519
+ //
520
+ %%{
521
+ machine EDN_dispatch;
522
+ include EDN_common;
523
+
524
+ begin_discard = '_';
525
+ begin_set = '{';
526
+ end_set = '}';
527
+
528
+ write data;
529
+
530
+ action exit { fhold; fbreak; }
531
+
532
+ main := begin_dispatch (
533
+ (begin_discard (space)? ([a-zA-Z0-9\-\.]*)) |
534
+ ('inst ' string_delim ([0-9\-+:\.TZ])* string_delim) |
535
+ ('uuid ' string_delim ([a-f0-9\-]* string_delim))
536
+ )
537
+ (^[a-zA-Z0-9:\.\-+ ]* @exit);
538
+ }%%
539
+
540
+
541
+ const char* edn::Parser::parse_tagged(const char *p, const char *pe, Rice::Object& o, bool& discard)
542
+ {
543
+ int cs;
544
+ Rice::String str;
545
+
546
+ %% write init;
547
+ p_save = p;
548
+ %% write exec;
549
+
550
+ if (cs >= EDN_dispatch_first_final) {
551
+
552
+ //is it a discard? if so, just drop the following token
553
+ if (*(p_save + 1) == '_')
554
+ {
555
+ discard = true;
556
+ return p + 1;
557
+ }
558
+
559
+ std::size_t len = p - p_save;
560
+ std::string buf;
561
+ buf.reserve(len);
562
+
563
+ if (len > 10)
564
+ {
565
+ // there's enough room to be #inst or #uuid, copy the
566
+ // string portion
567
+ if (std::strncmp(p_save + 1, "inst", 4) == 0) {
568
+ buf.append(p_save + 7, len - 8);
569
+ } else if (std::strncmp(p_save + 1, "uuid", 4) == 0) {
570
+ buf.append(p_save + 7, len - 8);
571
+ }
572
+
573
+ o = Rice::String(buf);
574
+ return p;
575
+ }
576
+
577
+ // tagged element
578
+ o = Rice::String(buf);
579
+ return p;
580
+ }
581
+ else if (cs == EDN_dispatch_error) {
582
+ error(*p);
583
+ return pe;
584
+ }
585
+ else if (cs == EDN_dispatch_en_main) {} // silence ragel warning
586
+ return NULL;
587
+ }
588
+
589
+
662
590
  // ============================================================
663
591
  // main parsing machine
664
592
  //
@@ -669,17 +597,17 @@ const char* edn::Parser::EDN_parse_map(const char *p, const char *pe, Rice::Obje
669
597
  write data nofinal;
670
598
 
671
599
  action parse_vector {
672
- const char* np = EDN_parse_vector(fpc, pe, result);
600
+ const char* np = parse_vector(fpc, pe, result);
673
601
  if (np == NULL) { fhold; fbreak; } else fexec np;
674
602
  }
675
603
 
676
604
  action parse_map {
677
- const char *np = EDN_parse_map(fpc, pe, result);
605
+ const char *np = parse_map(fpc, pe, result);
678
606
  if (np == NULL) { fhold; fbreak; } else fexec np;
679
607
  }
680
608
 
681
609
  action parse_list {
682
- const char *np = EDN_parse_list(fpc, pe, result);
610
+ const char *np = parse_list(fpc, pe, result);
683
611
  if (np == NULL) { fhold; fbreak; } else fexec np;
684
612
  }
685
613
 
@@ -1,41 +1,39 @@
1
1
  #include <iostream>
2
2
  #include <string>
3
3
  #include <fstream>
4
+
4
5
  #include <rice/Object.hpp>
5
6
 
7
+ #include <ruby/ruby.h>
8
+ #include <ruby/encoding.h>
9
+
6
10
  #include "edn_parser.h"
7
11
 
8
12
  namespace edn
9
13
  {
10
- // ============================================================
11
- // reads the contents of a file and begins the parsing process
12
14
  //
13
- Rice::Object Parser::open(const std::string& file)
15
+ // copies the string data, unescaping any present values that need to be replaced
16
+ //
17
+ bool Parser::parse_byte_stream(const char *p_start, const char *p_end, Rice::String& s)
14
18
  {
15
- Rice::Object rslt = Qnil;
16
-
17
- std::ifstream f(file);
18
-
19
- if (f.is_open())
20
- {
21
- // determine the length of the file
22
- f.seekg(0, f.end);
23
- long len = f.tellg();
24
- f.seekg(0, f.beg);
25
-
26
- // read its contents
27
- char* buf = new char[len];
28
- f.read(buf, len);
29
- f.close();
30
-
31
- // parse the buffer
32
- rslt = parse(buf, len);
33
-
34
- delete [] buf;
19
+ if (p_end > p_start) {
20
+ std::string buf;
21
+ std::size_t len = p_end - p_start;
22
+
23
+ if (unicode_to_utf8(p_start, len, buf))
24
+ {
25
+ // utf-8 encode
26
+ VALUE vs = Rice::protect( rb_str_new2, buf.c_str() );
27
+ VALUE s_utf8 = Rice::protect( rb_enc_associate, vs, rb_utf8_encoding() );
28
+ s = Rice::String(s_utf8);
29
+ return true;
30
+ }
35
31
  }
36
- return rslt;
32
+
33
+ return false;
37
34
  }
38
35
 
36
+
39
37
  //
40
38
  // error reporting
41
39
  void Parser::error(const std::string& err, char c) const
@@ -0,0 +1,29 @@
1
+ #include <string>
2
+
3
+ //
4
+ // needed to define this in its own file because icu and ruby have
5
+ // differing definitions for Uchar and the compiler complains
6
+ //
7
+ #include <unicode/utypes.h>
8
+ #include <unicode/ustring.h>
9
+ #include <unicode/ucnv.h>
10
+
11
+ #include "edn_parser.h"
12
+
13
+ namespace edn
14
+ {
15
+ //
16
+ // unescapes any values that need to be replaced, saves it to utf8
17
+ //
18
+ bool Parser::unicode_to_utf8(const char *s, std::size_t len, std::string& rslt)
19
+ {
20
+ icu::UnicodeString ustr(s, len);
21
+
22
+ if (ustr.isBogus()) {
23
+ return false;
24
+ }
25
+
26
+ ustr.unescape().toUTF8String(rslt);
27
+ return true;
28
+ }
29
+ }
@@ -1,3 +1,26 @@
1
1
  require 'mkmf-rice'
2
2
 
3
+ HEADER_DIRS = [
4
+ '/usr/local/include',
5
+ '/usr/local/opt/icu4c/include',
6
+ '/usr/include'
7
+ ]
8
+
9
+ LIB_DIRS = [
10
+ '/usr/local/lib', # must be the first entry; add others after it
11
+ '/usr/local/opt/icu4c/lib'
12
+ ]
13
+
14
+ unless find_header('unicode/uversion.h', *HEADER_DIRS)
15
+ abort "icu4c headers missing"
16
+ end
17
+
18
+ # haven't figured out how this ever works so..
19
+ #unless have_library('icuuc', 'uconv_close', *LIB_DIRS)
20
+ # abort "ic4c lib missing"
21
+ #end
22
+
23
+ # do this instead. sigh
24
+ $LOCAL_LIBS="-L#{LIB_DIRS[1]} -licuuc"
25
+
3
26
  create_makefile("edn_turbo/edn_turbo")
@@ -41,7 +41,6 @@ void Init_edn_turbo(void)
41
41
  Rice::define_class_under<edn::Parser>(rb_mEDNT, "Parser")
42
42
  .define_constructor(Rice::Constructor<edn::Parser>())
43
43
  .define_method("ext_read", &edn::Parser::process, (Rice::Arg("data")))
44
- .define_method("ext_open", &edn::Parser::open, (Rice::Arg("file")))
45
44
  ;
46
45
 
47
46
  // import whatever else we've defined in the ruby side
@@ -1,3 +1,3 @@
1
1
  module EDNT
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -38,6 +38,15 @@ class EDNT_Test < Minitest::Test
38
38
  )
39
39
  end
40
40
 
41
+ def test_unicode
42
+
43
+ check_file('test/unicode.edn',
44
+ [:text,
45
+ "Page \u0018, October 2009 TechTIPS",
46
+ "This should be an unfilled star: ☆"]
47
+ )
48
+ end
49
+
41
50
  def test_vector
42
51
 
43
52
  check_file('test/vector_1.edn',
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: edn_turbo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ed Porras
@@ -70,6 +70,7 @@ files:
70
70
  - ext/edn_turbo/edn_parser.h
71
71
  - ext/edn_turbo/edn_parser.rl
72
72
  - ext/edn_turbo/edn_parser_def.cc
73
+ - ext/edn_turbo/edn_parser_unicode.cc
73
74
  - ext/edn_turbo/extconf.rb
74
75
  - ext/edn_turbo/main.cc
75
76
  - lib/edn_turbo.rb