edn_turbo 0.5.7 → 0.6.0

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.
@@ -1,3 +1,25 @@
1
+ // The MIT License (MIT)
2
+
3
+ // Copyright (c) 2015-2019 Ed Porras
4
+
5
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ // of this software and associated documentation files (the "Software"), to deal
7
+ // in the Software without restriction, including without limitation the rights
8
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ // copies of the Software, and to permit persons to whom the Software is
10
+ // furnished to do so, subject to the following conditions:
11
+
12
+ // The above copyright notice and this permission notice shall be included in
13
+ // all copies or substantial portions of the Software.
14
+
15
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ // THE SOFTWARE.
22
+
1
23
  #include <iostream>
2
24
  #include <string>
3
25
  #include <sstream>
@@ -71,20 +93,20 @@
71
93
  action parse_val_string {
72
94
  // string types within double-quotes
73
95
  const char *np = parse_string(fpc, pe, v);
74
- if (np == NULL) { fhold; fbreak; } else fexec np;
96
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
75
97
  }
76
98
 
77
99
  action parse_val_keyword {
78
100
  // tokens with a leading ':'
79
101
  const char *np = parse_keyword(fpc, pe, v);
80
- if (np == NULL) { fhold; fbreak; } else fexec np;
102
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
81
103
  }
82
104
 
83
105
  action parse_val_number {
84
106
  // tokens w/ leading digits: non-negative integers & decimals.
85
107
  // try to parse a decimal first
86
108
  const char *np = parse_decimal(fpc, pe, v);
87
- if (np == NULL) {
109
+ if (np == nullptr) {
88
110
  // if we can't, try to parse it as an int
89
111
  np = parse_integer(fpc, pe, v);
90
112
  }
@@ -103,20 +125,20 @@
103
125
  action parse_val_operator {
104
126
  // stand-alone operators *, +, -, etc.
105
127
  const char *np = parse_operator(fpc, pe, v);
106
- if (np == NULL) { fhold; fbreak; } else fexec np;
128
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
107
129
  }
108
130
 
109
131
  action parse_val_char {
110
132
  // tokens w/ leading \ (escaped characters \newline, \c, etc.)
111
133
  const char *np = parse_esc_char(fpc, pe, v);
112
- if (np == NULL) { fhold; fbreak; } else fexec np;
134
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
113
135
  }
114
136
 
115
137
  action parse_val_symbol {
116
138
  // user identifiers and reserved keywords (true, false, nil)
117
139
  VALUE sym = Qnil;
118
140
  const char *np = parse_symbol(fpc, pe, sym);
119
- if (np == NULL) { fexec pe; } else {
141
+ if (np == nullptr) { fexec pe; } else {
120
142
  // parse_symbol will make 'sym' a ruby string
121
143
  if (std::strcmp(RSTRING_PTR(sym), "true") == 0) { v = Qtrue; }
122
144
  else if (std::strcmp(RSTRING_PTR(sym), "false") == 0) { v = Qfalse; }
@@ -131,31 +153,31 @@
131
153
  action parse_val_vector {
132
154
  // [
133
155
  const char *np = parse_vector(fpc, pe, v);
134
- if (np == NULL) { fhold; fbreak; } else fexec np;
156
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
135
157
  }
136
158
 
137
159
  action parse_val_list {
138
160
  // (
139
161
  const char *np = parse_list(fpc, pe, v);
140
- if (np == NULL) { fhold; fbreak; } else fexec np;
162
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
141
163
  }
142
164
 
143
165
  action parse_val_map {
144
166
  // {
145
167
  const char *np = parse_map(fpc, pe, v);
146
- if (np == NULL) { fhold; fbreak; } else fexec np;
168
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
147
169
  }
148
170
 
149
171
  action parse_val_meta {
150
172
  // ^
151
173
  const char *np = parse_meta(fpc, pe);
152
- if (np == NULL) { fhold; fbreak; } else fexec np;
174
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
153
175
  }
154
176
 
155
177
  action parse_val_dispatch {
156
178
  // handles tokens w/ leading # ("#_", "#{", and tagged elems)
157
179
  const char *np = parse_dispatch(fpc + 1, pe, v);
158
- if (np == NULL) { fhold; fbreak; } else fexec np;
180
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
159
181
  }
160
182
 
161
183
 
@@ -191,7 +213,7 @@ const char *edn::Parser::parse_value(const char *p, const char *pe, VALUE& v)
191
213
  return pe;
192
214
  }
193
215
  else if (cs == EDN_value_en_main) {} // silence ragel warning
194
- return NULL;
216
+ return nullptr;
195
217
  }
196
218
 
197
219
 
@@ -247,7 +269,7 @@ const char* edn::Parser::parse_string(const char *p, const char *pe, VALUE& v)
247
269
  return pe;
248
270
  }
249
271
  else if (cs == EDN_string_en_main) {} // silence ragel warning
250
- return NULL;
272
+ return nullptr;
251
273
  }
252
274
 
253
275
 
@@ -293,7 +315,7 @@ const char* edn::Parser::parse_keyword(const char *p, const char *pe, VALUE& v)
293
315
  return pe;
294
316
  }
295
317
  else if (cs == EDN_keyword_en_main) {} // silence ragel warning
296
- return NULL;
318
+ return nullptr;
297
319
  }
298
320
 
299
321
 
@@ -328,7 +350,7 @@ const char* edn::Parser::parse_decimal(const char *p, const char *pe, VALUE& v)
328
350
  return p + 1;
329
351
  }
330
352
  else if (cs == EDN_decimal_en_main) {} // silence ragel warning
331
- return NULL;
353
+ return nullptr;
332
354
  }
333
355
 
334
356
 
@@ -360,7 +382,7 @@ const char* edn::Parser::parse_integer(const char *p, const char *pe, VALUE& v)
360
382
  return p + 1;
361
383
  }
362
384
  else if (cs == EDN_integer_en_main) {} // silence ragel warning
363
- return NULL;
385
+ return nullptr;
364
386
  }
365
387
 
366
388
 
@@ -382,7 +404,7 @@ const char* edn::Parser::parse_integer(const char *p, const char *pe, VALUE& v)
382
404
  // parse a symbol including the leading operator (-, +, .)
383
405
  VALUE sym = Qnil;
384
406
  const char *np = parse_symbol(p_save, pe, sym);
385
- if (np == NULL) { fexec pe; } else {
407
+ if (np == nullptr) { fexec pe; } else {
386
408
  if (sym != Qnil)
387
409
  v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
388
410
  fexec np;
@@ -396,7 +418,7 @@ const char* edn::Parser::parse_integer(const char *p, const char *pe, VALUE& v)
396
418
  //
397
419
  // try to parse a decimal first
398
420
  const char *np = parse_decimal(p_save, pe, v);
399
- if (np == NULL) {
421
+ if (np == nullptr) {
400
422
  // if we can't, try to parse it as an int
401
423
  np = parse_integer(p_save, pe, v);
402
424
  }
@@ -447,7 +469,7 @@ const char* edn::Parser::parse_operator(const char *p, const char *pe, VALUE& v)
447
469
  return pe;
448
470
  }
449
471
  else if (cs == EDN_operator_en_main) {} // silence ragel warning
450
- return NULL;
472
+ return nullptr;
451
473
  }
452
474
 
453
475
 
@@ -491,7 +513,7 @@ const char* edn::Parser::parse_esc_char(const char *p, const char *pe, VALUE& v)
491
513
  return pe;
492
514
  }
493
515
  else if (cs == EDN_escaped_char_en_main) {} // silence ragel warning
494
- return NULL;
516
+ return nullptr;
495
517
  }
496
518
 
497
519
 
@@ -551,7 +573,7 @@ const char* edn::Parser::parse_symbol(const char *p, const char *pe, VALUE& s)
551
573
  error(__FUNCTION__, "invalid symbol sequence", *p);
552
574
  }
553
575
  else if (cs == EDN_symbol_en_main) {} // silence ragel warning
554
- return NULL;
576
+ return nullptr;
555
577
  }
556
578
 
557
579
 
@@ -589,7 +611,7 @@ const char* edn::Parser::parse_symbol(const char *p, const char *pe, VALUE& s)
589
611
  VALUE e;
590
612
  std::size_t meta_sz = meta_size();
591
613
  const char *np = parse_value(fpc, pe, e);
592
- if (np == NULL) { fhold; fbreak; } else {
614
+ if (np == nullptr) { fhold; fbreak; } else {
593
615
  // if there's an entry in the discard list, the current
594
616
  // object is not meant to be kept due to a #_ so don't
595
617
  // push it into the list of elements
@@ -657,7 +679,7 @@ const char* edn::Parser::parse_vector(const char *p, const char *pe, VALUE& v)
657
679
  return pe;
658
680
  }
659
681
  else if (cs == EDN_vector_en_main) {} // silence ragel warning
660
- return NULL;
682
+ return nullptr;
661
683
  }
662
684
 
663
685
 
@@ -702,7 +724,7 @@ const char* edn::Parser::parse_list(const char *p, const char *pe, VALUE& v)
702
724
  return pe;
703
725
  }
704
726
  else if (cs == EDN_list_en_main) {} // silence ragel warning
705
- return NULL;
727
+ return nullptr;
706
728
  }
707
729
 
708
730
 
@@ -760,7 +782,7 @@ const char* edn::Parser::parse_map(const char *p, const char *pe, VALUE& v)
760
782
  return pe;
761
783
  }
762
784
  else if (cs == EDN_map_en_main) {} // silence ragel warning
763
- return NULL;
785
+ return nullptr;
764
786
  }
765
787
 
766
788
 
@@ -779,19 +801,19 @@ const char* edn::Parser::parse_map(const char *p, const char *pe, VALUE& v)
779
801
  action parse_disp_set {
780
802
  // #{ }
781
803
  const char *np = parse_set(fpc, pe, v);
782
- if (np == NULL) { fhold; fbreak; } else fexec np;
804
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
783
805
  }
784
806
 
785
807
  action parse_disp_discard {
786
808
  // discard token #_
787
809
  const char *np = parse_discard(fpc, pe);
788
- if (np == NULL) { fhold; fbreak; } else fexec np;
810
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
789
811
  }
790
812
 
791
813
  action parse_disp_tagged {
792
814
  // #inst, #uuid, or #user/tag
793
815
  const char *np = parse_tagged(fpc, pe, v);
794
- if (np == NULL) { fhold; fbreak; } else fexec np;
816
+ if (np == nullptr) { fhold; fbreak; } else fexec np;
795
817
  }
796
818
 
797
819
 
@@ -819,7 +841,7 @@ const char* edn::Parser::parse_dispatch(const char *p, const char *pe, VALUE& v)
819
841
  }
820
842
  else if (cs == EDN_dispatch_en_main) {} // silence ragel warning
821
843
 
822
- return NULL;
844
+ return nullptr;
823
845
  }
824
846
 
825
847
 
@@ -863,7 +885,7 @@ const char* edn::Parser::parse_set(const char *p, const char *pe, VALUE& v)
863
885
  return pe;
864
886
  }
865
887
  else if (cs == EDN_set_en_main) {} // silence ragel warning
866
- return NULL;
888
+ return nullptr;
867
889
  }
868
890
 
869
891
 
@@ -883,7 +905,7 @@ const char* edn::Parser::parse_set(const char *p, const char *pe, VALUE& v)
883
905
 
884
906
  action discard_value {
885
907
  const char *np = parse_value(fpc, pe, v);
886
- if (np == NULL) { fhold; fbreak; } else {
908
+ if (np == nullptr) { fhold; fbreak; } else {
887
909
  // this token is to be discarded so store it in the
888
910
  // discard stack - we really don't need to save it so this
889
911
  // could be simplified
@@ -922,7 +944,7 @@ const char* edn::Parser::parse_discard(const char *p, const char *pe)
922
944
  }
923
945
  else if (cs == EDN_discard_en_main) {} // silence ragel warning
924
946
 
925
- return NULL;
947
+ return nullptr;
926
948
  }
927
949
 
928
950
 
@@ -962,7 +984,7 @@ const char* edn::Parser::parse_discard(const char *p, const char *pe)
962
984
  action parse_tag {
963
985
  // parses the symbol portion of the pair
964
986
  const char *np = parse_symbol(fpc, pe, sym_name);
965
- if (np == NULL) { fhold; fbreak; } else {
987
+ if (np == nullptr) { fhold; fbreak; } else {
966
988
  sym_ok = true;
967
989
  fexec np;
968
990
  }
@@ -970,7 +992,7 @@ const char* edn::Parser::parse_discard(const char *p, const char *pe)
970
992
  action parse_data {
971
993
  // parses the value portion
972
994
  const char *np = parse_value(fpc, pe, data);
973
- if (np == NULL) { fhold; fbreak; } else {
995
+ if (np == nullptr) { fhold; fbreak; } else {
974
996
  data_ok = true;
975
997
  fexec np;
976
998
  }
@@ -1001,7 +1023,7 @@ const char* edn::Parser::parse_tagged(const char *p, const char *pe, VALUE& v)
1001
1023
  if (!sym_ok || !data_ok) {
1002
1024
  error(__FUNCTION__, "tagged element symbol error", *p);
1003
1025
  v = EDN_EOF_CONST;
1004
- return NULL;
1026
+ return nullptr;
1005
1027
  }
1006
1028
 
1007
1029
  try {
@@ -1019,7 +1041,7 @@ const char* edn::Parser::parse_tagged(const char *p, const char *pe, VALUE& v)
1019
1041
  }
1020
1042
  else if (cs == EDN_tagged_en_main) {} // silence ragel warning
1021
1043
  v = EDN_EOF_CONST;
1022
- return NULL;
1044
+ return nullptr;
1023
1045
  }
1024
1046
 
1025
1047
 
@@ -1038,7 +1060,7 @@ const char* edn::Parser::parse_tagged(const char *p, const char *pe, VALUE& v)
1038
1060
 
1039
1061
  action parse_data {
1040
1062
  const char *np = parse_value(fpc, pe, v);
1041
- if (np == NULL) { fhold; fbreak; } else { fexec np; }
1063
+ if (np == nullptr) { fhold; fbreak; } else { fexec np; }
1042
1064
  }
1043
1065
 
1044
1066
  main := begin_meta (
@@ -1065,7 +1087,7 @@ const char* edn::Parser::parse_meta(const char *p, const char *pe)
1065
1087
  }
1066
1088
  else if (cs == EDN_meta_en_main) {} // silence ragel warning
1067
1089
 
1068
- return NULL;
1090
+ return nullptr;
1069
1091
  }
1070
1092
 
1071
1093
 
@@ -1086,7 +1108,7 @@ const char* edn::Parser::parse_meta(const char *p, const char *pe)
1086
1108
  // an actual data item
1087
1109
  std::size_t meta_sz = meta_size();
1088
1110
  const char* np = parse_value(fpc, pe, result);
1089
- if (np == NULL) { fexec pe; fbreak; } else {
1111
+ if (np == nullptr) { fexec pe; fbreak; } else {
1090
1112
  // if we have metadata saved and it matches the count we
1091
1113
  // saved before we parsed a value, then we must bind the
1092
1114
  // metadata sequence to it
@@ -1120,7 +1142,7 @@ VALUE edn::Parser::parse(const char* src, std::size_t len)
1120
1142
  return EDN_EOF_CONST;
1121
1143
  }
1122
1144
  else if (cs == EDN_parser_first_final) {
1123
- p = pe = eof = NULL;
1145
+ p = pe = eof = nullptr;
1124
1146
  }
1125
1147
  else if (cs == EDN_parser_en_main) {} // silence ragel warning
1126
1148
  return result;
@@ -1144,7 +1166,7 @@ VALUE edn::Parser::parse(const char* src, std::size_t len)
1144
1166
  meta_sz = meta_size();
1145
1167
 
1146
1168
  const char* np = parse_value(fpc, pe, value);
1147
- if (np == NULL) { fhold; fbreak; } else {
1169
+ if (np == nullptr) { fhold; fbreak; } else {
1148
1170
  if (!meta_empty()) {
1149
1171
  // was an additional metadata entry read? if so, don't
1150
1172
  // return a value
@@ -1,5 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # The MIT License (MIT)
4
+
5
+ # Copyright (c) 2015-2019 Ed Porras
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
3
25
  require 'mkmf'
4
26
 
5
27
  header_dirs =
@@ -38,7 +60,8 @@ lib_dirs =
38
60
  dir_config('icuuc', header_dirs, lib_dirs)
39
61
 
40
62
  # feels very hackish to do this but the new icu4c needs it on MacOS
41
- $CXXFLAGS << ' -stdlib=libc++ -std=c++11' if RUBY_PLATFORM.match?(/darwin/)
63
+ $CXXFLAGS << ' -stdlib=libc++ -Wno-deprecated-register' if RUBY_PLATFORM =~ /darwin/
64
+ $CXXFLAGS << ' -std=c++11 -std=gnu++11'
42
65
 
43
66
  abort "\n>> failed to find icu4c headers - is icu4c installed?\n\n" unless
44
67
  find_header('unicode/uversion.h')
@@ -1,3 +1,25 @@
1
+ // The MIT License (MIT)
2
+
3
+ // Copyright (c) 2015-2019 Ed Porras
4
+
5
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ // of this software and associated documentation files (the "Software"), to deal
7
+ // in the Software without restriction, including without limitation the rights
8
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ // copies of the Software, and to permit persons to whom the Software is
10
+ // furnished to do so, subject to the following conditions:
11
+
12
+ // The above copyright notice and this permission notice shall be included in
13
+ // all copies or substantial portions of the Software.
14
+
15
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ // THE SOFTWARE.
22
+
1
23
  #include <signal.h>
2
24
  #include <iostream>
3
25
  #include <clocale>
@@ -10,150 +32,147 @@
10
32
 
11
33
  namespace edn {
12
34
 
13
- VALUE rb_mEDN;
14
- VALUE rb_mEDNT;
15
-
16
- // Symbols used to call into the ruby world.
17
- VALUE EDN_MAKE_SYMBOL_METHOD = Qnil;
18
- VALUE EDN_MAKE_LIST_METHOD = Qnil;
19
- VALUE EDN_MAKE_SET_METHOD = Qnil;
20
- VALUE EDN_MAKE_BIG_DECIMAL_METHOD = Qnil;
21
- VALUE EDN_TAGGED_ELEM_METHOD = Qnil;
22
- VALUE EDNT_EXTENDED_VALUE_METHOD = Qnil;
23
-
24
- VALUE RUBY_STRING_TO_I_METHOD = Qnil;
25
- VALUE RUBY_STRING_TO_F_METHOD = Qnil;
26
- VALUE RUBY_READ_METHOD = Qnil;
27
-
28
- // returned when EOF - defined as a constant in EDN module
29
- VALUE EDN_EOF_CONST = Qnil;
30
-
31
- //
32
- // Wrappers to hook the class w/ the C-api.
33
- static void delete_parser(void* p_ptr) {
34
- delete reinterpret_cast<edn::Parser*>(p_ptr);
35
- }
36
-
37
- static const rb_data_type_t parser_data_type = {
38
- "edn_turbo::Parser",
39
- {0, delete_parser, 0, {0}},
40
- 0, 0,
41
- RUBY_TYPED_FREE_IMMEDIATELY,
42
- };
43
-
44
- static VALUE wrap_parser_ptr(VALUE klass, edn::Parser* ptr) {
45
- return TypedData_Wrap_Struct(klass, &parser_data_type, ptr);
46
- }
47
-
48
- static VALUE alloc_obj(VALUE self){
49
- return wrap_parser_ptr(self, new Parser());
50
- }
51
-
52
- static inline Parser* get_parser(VALUE self)
53
- {
54
- Parser *p;
55
- TypedData_Get_Struct( self, edn::Parser, &parser_data_type, p );
56
- return p;
57
- }
58
- static VALUE set_source(VALUE self, VALUE data);
59
-
60
- //
61
- // Called by the constructor - sets the source if passed.
62
- static VALUE initialize(int argc, VALUE* argv, VALUE self)
63
- {
64
- if (argc > 0) {
65
- set_source( self, argv[0] );
66
- }
67
- return self;
68
- }
69
-
70
- //
71
- // change the input source
72
- static VALUE set_source(VALUE self, VALUE data)
73
- {
74
- Parser* p = get_parser(self);
75
-
76
- switch (TYPE(data))
77
- {
78
- case T_STRING:
79
- {
35
+ VALUE rb_mEDN;
36
+ VALUE rb_mEDNT;
37
+
38
+ // Symbols used to call into the ruby world.
39
+ VALUE EDN_MAKE_SYMBOL_METHOD = Qnil;
40
+ VALUE EDN_MAKE_LIST_METHOD = Qnil;
41
+ VALUE EDN_MAKE_SET_METHOD = Qnil;
42
+ VALUE EDN_MAKE_BIG_DECIMAL_METHOD = Qnil;
43
+ VALUE EDN_TAGGED_ELEM_METHOD = Qnil;
44
+ VALUE EDNT_EXTENDED_VALUE_METHOD = Qnil;
45
+
46
+ VALUE RUBY_STRING_TO_I_METHOD = Qnil;
47
+ VALUE RUBY_STRING_TO_F_METHOD = Qnil;
48
+ VALUE RUBY_READ_METHOD = Qnil;
49
+
50
+ // returned when EOF - defined as a constant in EDN module
51
+ VALUE EDN_EOF_CONST = Qnil;
52
+
53
+ //
54
+ // Wrappers to hook the class w/ the C-api.
55
+ static void delete_parser(void* p_ptr) {
56
+ delete reinterpret_cast<edn::Parser*>(p_ptr);
57
+ }
58
+
59
+ static const rb_data_type_t parser_data_type = {
60
+ "edn_turbo::Parser",
61
+ {0, delete_parser, 0, {0}},
62
+ 0, 0,
63
+ RUBY_TYPED_FREE_IMMEDIATELY,
64
+ };
65
+
66
+ static VALUE wrap_parser_ptr(VALUE klass, edn::Parser* ptr) {
67
+ return TypedData_Wrap_Struct(klass, &parser_data_type, ptr);
68
+ }
69
+
70
+ static VALUE alloc_obj(VALUE self){
71
+ return wrap_parser_ptr(self, new Parser());
72
+ }
73
+
74
+ static inline Parser* get_parser(VALUE self)
75
+ {
76
+ Parser *p;
77
+ TypedData_Get_Struct( self, edn::Parser, &parser_data_type, p );
78
+ return p;
79
+ }
80
+ static VALUE set_source(VALUE self, VALUE data);
81
+
82
+ //
83
+ // Called by the constructor - sets the source if passed.
84
+ static VALUE initialize(int argc, VALUE* argv, VALUE self)
85
+ {
86
+ if (argc > 0) {
87
+ set_source( self, argv[0] );
88
+ }
89
+ return self;
90
+ }
91
+
92
+ //
93
+ // change the input source
94
+ static VALUE set_source(VALUE self, VALUE data)
95
+ {
96
+ Parser* p = get_parser(self);
97
+
98
+ switch (TYPE(data))
99
+ {
100
+ case T_STRING:
101
+ {
80
102
  const char* stream = StringValueCStr(data);
81
103
  if (stream) {
82
- p->set_source( stream, std::strlen(stream) );
104
+ p->set_source( stream, std::strlen(stream) );
83
105
  }
84
106
  break;
85
- }
86
- case T_FILE:
87
- {
107
+ }
108
+ case T_FILE:
109
+ {
88
110
  // extract the stream pointer
89
111
  rb_io_t* fptr = RFILE(data)->fptr;
90
112
  if (!fptr) {
91
- rb_raise(rb_eRuntimeError, "Ruby IO - fptr is NULL");
113
+ rb_raise(rb_eRuntimeError, "Ruby IO - fptr is null");
92
114
  }
93
115
 
94
116
  rb_io_check_char_readable(fptr);
95
117
 
96
118
  FILE* fp = rb_io_stdio_file(fptr);
97
119
  if (!fp) {
98
- rb_raise(rb_eRuntimeError, "Ruby IO - fptr->fp is NULL");
120
+ rb_raise(rb_eRuntimeError, "Ruby IO - fptr->fp is null");
99
121
  }
100
122
 
101
123
  p->set_source(fp);
102
124
  break;
103
- }
104
- case T_DATA:
105
- {
106
- // StringIO or some other IO not part of the ruby core -
107
- // this is very inefficient as it'll require read()
108
- // calls from the ruby side (involves a lot of data
109
- // wrapping, etc)
125
+ }
126
+ case T_DATA:
127
+ {
128
+ // StringIO or some other IO not part of the ruby core
110
129
  if (rb_respond_to(data, RUBY_READ_METHOD)) {
111
- p->set_source(data);
112
- break;
130
+ p->set_source(data);
131
+ break;
113
132
  }
114
- }
115
- default:
116
- rb_raise(rb_eRuntimeError, "set_source expected String, core IO, or IO that responds to read()");
117
- break;
118
- }
119
-
120
- return self;
121
- }
122
-
123
- //
124
- // eof?
125
- static VALUE eof(VALUE self, VALUE data)
126
- {
127
- return get_parser(self)->is_eof();
128
- }
129
-
130
- //
131
- // parses an entire stream
132
- static VALUE read(VALUE self, VALUE data)
133
- {
134
- if (TYPE(data) != T_STRING) {
135
- rb_raise(rb_eTypeError, "Expected String data");
136
- }
137
- const char* stream = StringValueCStr(data);
138
- if (stream) {
139
- return get_parser(self)->parse(stream, std::strlen(stream) );
140
- }
141
- return Qnil;
142
- }
143
-
144
- //
145
- // gets the next token in the current stream
146
- static VALUE next(VALUE self, VALUE data)
147
- {
148
- return get_parser(self)->next();
149
- }
150
-
151
- //
152
- // signal handler
153
- static void die(int sig)
154
- {
155
- exit(-1);
156
- }
133
+ }
134
+ default:
135
+ rb_raise(rb_eArgError, "set_source expected String, core IO, or IO that responds to read()");
136
+ break;
137
+ }
138
+
139
+ return self;
140
+ }
141
+
142
+ //
143
+ // eof?
144
+ static VALUE eof(VALUE self, VALUE data)
145
+ {
146
+ return get_parser(self)->is_eof();
147
+ }
148
+
149
+ //
150
+ // parses an entire stream
151
+ static VALUE read(VALUE self, VALUE data)
152
+ {
153
+ if (TYPE(data) != T_STRING) {
154
+ rb_raise(rb_eTypeError, "Expected String data");
155
+ }
156
+ const char* stream = StringValueCStr(data);
157
+ if (stream) {
158
+ return get_parser(self)->parse(stream, std::strlen(stream) );
159
+ }
160
+ return Qnil;
161
+ }
162
+
163
+ //
164
+ // gets the next token in the current stream
165
+ static VALUE next(VALUE self, VALUE data)
166
+ {
167
+ return get_parser(self)->next();
168
+ }
169
+
170
+ //
171
+ // signal handler
172
+ [[noreturn]] static void die(int sig)
173
+ {
174
+ exit(-1);
175
+ }
157
176
  }
158
177
 
159
178
 
@@ -162,45 +181,49 @@ namespace edn {
162
181
  extern "C"
163
182
  void Init_edn_turbo(void)
164
183
  {
165
- struct sigaction a;
166
- a.sa_handler = edn::die;
167
- sigemptyset(&a.sa_mask);
168
- a.sa_flags = 0;
169
- sigaction(SIGINT, &a, NULL);
170
-
171
- // pass things back as utf-8
172
- if (!setlocale( LC_ALL, "" )) {
173
- rb_raise(rb_eRuntimeError, "Extension init error calling setlocale() - It appears your system's locale is not configured correctly.\n");
174
- }
175
-
176
- edn::rb_mEDN = rb_const_get(rb_cObject, rb_intern("EDN"));
177
- edn::rb_mEDNT = rb_define_module("EDNT");
178
-
179
- // bind the ruby Parser class to the C++ one
180
- VALUE rb_cParser = rb_define_class_under(edn::rb_mEDNT, "Parser", rb_cObject);
181
- rb_define_alloc_func(rb_cParser, edn::alloc_obj);
182
- rb_define_method(rb_cParser, "initialize", (VALUE(*)(ANYARGS)) &edn::initialize, -1 );
183
- rb_define_method(rb_cParser, "ext_eof", (VALUE(*)(ANYARGS)) &edn::eof, 0 );
184
-
185
- rb_define_method(rb_cParser, "set_input", (VALUE(*)(ANYARGS)) &edn::set_source, 1 );
186
- rb_define_method(rb_cParser, "parse", (VALUE(*)(ANYARGS)) &edn::read, 1 );
187
- rb_define_method(rb_cParser, "read", (VALUE(*)(ANYARGS)) &edn::next, 0 );
188
-
189
- // bind ruby methods we'll call - these should be defined in edn_turbo.rb
190
- edn::EDN_MAKE_SYMBOL_METHOD = rb_intern("symbol");
191
- edn::EDN_MAKE_LIST_METHOD = rb_intern("list");
192
- edn::EDN_MAKE_SET_METHOD = rb_intern("set");
193
- edn::EDN_MAKE_BIG_DECIMAL_METHOD = rb_intern("big_decimal");
194
- edn::EDN_TAGGED_ELEM_METHOD = rb_intern("tagged_element");
195
-
196
- // defined in EDNT - see edn_parser.rb
197
- edn::EDNT_EXTENDED_VALUE_METHOD = rb_intern("extend_for_meta");
198
-
199
- // ruby methods
200
- edn::RUBY_STRING_TO_I_METHOD = rb_intern("to_i");
201
- edn::RUBY_STRING_TO_F_METHOD = rb_intern("to_f");
202
- edn::RUBY_READ_METHOD = rb_intern("read");
203
-
204
- // so we can return EOF directly
205
- edn::EDN_EOF_CONST = rb_const_get(edn::rb_mEDN, rb_intern("EOF"));
184
+ struct sigaction a;
185
+ a.sa_handler = edn::die;
186
+ sigemptyset(&a.sa_mask);
187
+ a.sa_flags = 0;
188
+ sigaction(SIGINT, &a, nullptr);
189
+
190
+ // pass things back as utf-8
191
+ if (!setlocale( LC_ALL, "" )) {
192
+ rb_raise(rb_eRuntimeError, "Extension init error calling setlocale() - It appears your system's locale is not configured correctly.\n");
193
+ }
194
+
195
+ edn::rb_mEDN = rb_const_get(rb_cObject, rb_intern("EDN"));
196
+ edn::rb_mEDNT = rb_define_module("EDNT");
197
+
198
+ // bind the ruby Parser class to the C++ one
199
+ VALUE rb_cParser = rb_define_class_under(edn::rb_mEDNT, "Parser", rb_cObject);
200
+ rb_define_alloc_func(rb_cParser, edn::alloc_obj);
201
+ rb_define_method(rb_cParser, "initialize",
202
+ reinterpret_cast<VALUE(*)(ANYARGS)>(&edn::initialize), -1 );
203
+ rb_define_method(rb_cParser, "ext_eof",
204
+ reinterpret_cast<VALUE(*)(ANYARGS)>(&edn::eof), 0 );
205
+ rb_define_method(rb_cParser, "set_input",
206
+ reinterpret_cast<VALUE(*)(ANYARGS)>(&edn::set_source), 1 );
207
+ rb_define_method(rb_cParser, "parse",
208
+ reinterpret_cast<VALUE(*)(ANYARGS)>(&edn::read), 1 );
209
+ rb_define_method(rb_cParser, "read",
210
+ reinterpret_cast<VALUE(*)(ANYARGS)>(&edn::next), 0 );
211
+
212
+ // bind ruby methods we'll call - these should be defined in edn_turbo.rb
213
+ edn::EDN_MAKE_SYMBOL_METHOD = rb_intern("symbol");
214
+ edn::EDN_MAKE_LIST_METHOD = rb_intern("list");
215
+ edn::EDN_MAKE_SET_METHOD = rb_intern("set");
216
+ edn::EDN_MAKE_BIG_DECIMAL_METHOD = rb_intern("big_decimal");
217
+ edn::EDN_TAGGED_ELEM_METHOD = rb_intern("tagged_element");
218
+
219
+ // defined in EDNT - see edn_parser.rb
220
+ edn::EDNT_EXTENDED_VALUE_METHOD = rb_intern("extend_for_meta");
221
+
222
+ // ruby methods
223
+ edn::RUBY_STRING_TO_I_METHOD = rb_intern("to_i");
224
+ edn::RUBY_STRING_TO_F_METHOD = rb_intern("to_f");
225
+ edn::RUBY_READ_METHOD = rb_intern("read");
226
+
227
+ // so we can return EOF directly
228
+ edn::EDN_EOF_CONST = rb_const_get(edn::rb_mEDN, rb_intern("EOF"));
206
229
  }