edn_turbo 0.5.7 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }