fjson 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.
- data/CHANGES +0 -3
- data/Rakefile +43 -41
- data/ext/extensions/array_ext/array_ext.c +13 -81
- data/ext/extensions/array_ext/array_ext.h +4 -8
- data/ext/extensions/array_ext/extconf.mkmf.rb +3 -0
- data/ext/extensions/enumerable/enumerable.c +70 -0
- data/ext/extensions/enumerable/enumerable.h +9 -0
- data/ext/extensions/hash_ext/extconf.mkmf.rb +3 -0
- data/ext/extensions/hash_ext/hash_ext.c +13 -81
- data/ext/extensions/hash_ext/hash_ext.h +3 -8
- data/ext/json_ext/json_ext.c +12 -13
- data/ext/json_ext/json_ext.h +2 -0
- data/ext/state_ext/state_ext.c +16 -85
- data/ext/state_ext/state_ext.h +3 -7
- data/ext/state_ext/state_lib.c +107 -0
- data/ext/state_ext/state_lib.h +15 -0
- data/hash_benchmark.rb +0 -2
- data/hash_benchmark_action_support.rb +4 -0
- data/hash_benchmark_fjson.rb +3 -0
- data/hash_benchmark_json.rb +4 -0
- data/lib/json/editor.rb +1 -1
- data/mkmf_tasks.rb +99 -0
- data/rake_helper.rb +1 -1
- data/spec/array_spec.rb +12 -2
- data/spec/false_class_spec.rb +1 -1
- data/spec/float_spec.rb +1 -1
- data/spec/hash_spec.rb +13 -0
- data/spec/integer_spec.rb +1 -1
- data/spec/mkmf_tasks_spec.rb +110 -0
- data/spec/nil_class_spec.rb +1 -1
- data/spec/object_spec.rb +1 -1
- data/spec/spec_helper.rb +10 -0
- data/spec/spec_suite.rb +3 -8
- data/spec/state_spec.rb +10 -11
- data/spec/string_spec.rb +1 -1
- data/spec/string_when_not_supporting_unicode_and_kcode_is_not_utf8_json_spec.rb +1 -1
- data/spec/string_when_supporting_unicode_and_kcode_is_not_utf8_json_spec.rb +1 -1
- data/spec/string_with_latin1_character_set_json_spec.rb +15 -15
- data/spec/string_with_utf8_values_when_supporting_unicode_json_spec.rb +12 -12
- data/spec/true_class_spec.rb +1 -1
- metadata +58 -53
- data/mkmf_rake_builder.rb +0 -170
- data/spec/mkmf_rake_builder_spec.rb +0 -217
- data/spec/rake_helper_spec.rb +0 -9
@@ -1,13 +1,8 @@
|
|
1
1
|
#include "ruby.h"
|
2
2
|
#include <string.h>
|
3
|
-
#include "
|
4
|
-
#include "
|
3
|
+
#include "state_lib.h"
|
4
|
+
#include "enumerable.h"
|
5
5
|
|
6
|
-
static VALUE json_shift(VALUE, VALUE, VALUE, VALUE);
|
7
6
|
static VALUE generate_key_value_json(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
|
8
|
-
static VALUE process_internal_json(VALUE, VALUE, VALUE, VALUE, VALUE);
|
9
7
|
static VALUE json_transform(VALUE, VALUE, VALUE);
|
10
|
-
static VALUE
|
11
|
-
static VALUE json_check_circular_and_transform_ensure(VALUE);
|
12
|
-
static VALUE json_check_circular_and_transform(VALUE, VALUE, VALUE);
|
13
|
-
static VALUE to_json(int, VALUE*, VALUE);
|
8
|
+
static VALUE process_internal_json(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
|
data/ext/json_ext/json_ext.c
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#include "json_ext.h"
|
2
2
|
|
3
|
-
static VALUE mJSON;
|
4
3
|
static VALUE mJSONModuleMethods;
|
5
4
|
static VALUE cStandardError;
|
6
5
|
static VALUE cJSONError;
|
@@ -9,8 +8,8 @@ static VALUE cUnparserError;
|
|
9
8
|
static VALUE cCircularDatastructure;
|
10
9
|
|
11
10
|
void Init_json_ext() {
|
12
|
-
|
13
|
-
mJSONModuleMethods = rb_define_module_under(
|
11
|
+
rb_cJSON = rb_define_module("JSON");
|
12
|
+
mJSONModuleMethods = rb_define_module_under(rb_cJSON, "ModuleMethods");
|
14
13
|
|
15
14
|
_begin_setup_iconv();
|
16
15
|
|
@@ -21,22 +20,22 @@ void Init_json_ext() {
|
|
21
20
|
/**
|
22
21
|
* The base exception for JSON errors.
|
23
22
|
*/
|
24
|
-
cJSONError = rb_define_class_under(
|
23
|
+
cJSONError = rb_define_class_under(rb_cJSON, "JSONError", cStandardError);
|
25
24
|
|
26
25
|
/**
|
27
26
|
* This exception is raise, if a parser error occurs.
|
28
27
|
*/
|
29
|
-
cParserError = rb_define_class_under(
|
28
|
+
cParserError = rb_define_class_under(rb_cJSON, "ParserError", cJSONError);
|
30
29
|
|
31
30
|
/**
|
32
31
|
* This exception is raise, if a unparser error occurs.
|
33
32
|
*/
|
34
|
-
cUnparserError = rb_define_class_under(
|
33
|
+
cUnparserError = rb_define_class_under(rb_cJSON, "UnparserError", cJSONError);
|
35
34
|
|
36
35
|
/**
|
37
36
|
* If a circular data structure is encountered while unparsing this exception is raised.
|
38
37
|
*/
|
39
|
-
cCircularDatastructure = rb_define_class_under(
|
38
|
+
cCircularDatastructure = rb_define_class_under(rb_cJSON, "CircularDatastructure", cUnparserError);
|
40
39
|
}
|
41
40
|
|
42
41
|
/**
|
@@ -45,7 +44,7 @@ void Init_json_ext() {
|
|
45
44
|
static VALUE utf8_to_utf16(self, string)
|
46
45
|
VALUE self, string;
|
47
46
|
{
|
48
|
-
VALUE mUTF8toUTF16 = rb_const_get(
|
47
|
+
VALUE mUTF8toUTF16 = rb_const_get(rb_cJSON, rb_intern("UTF8toUTF16"));
|
49
48
|
VALUE packed_bytes = rb_funcall(mUTF8toUTF16, rb_intern("iconv"), 1, string);
|
50
49
|
VALUE unpacked_bytes = rb_funcall(packed_bytes, rb_intern("unpack"), 1, rb_str_new2("H*"));
|
51
50
|
return rb_ary_entry(unpacked_bytes, 0);
|
@@ -64,7 +63,7 @@ static VALUE utf8_to_json(self, input)
|
|
64
63
|
|
65
64
|
VALUE supports_utf8 = Qfalse;
|
66
65
|
if(
|
67
|
-
rb_funcall(
|
66
|
+
rb_funcall(rb_cJSON, rb_intern("support_unicode?"), 0) == Qtrue &&
|
68
67
|
rb_equal(rb_gv_get("KCODE"), rb_str_new2("UTF8"))
|
69
68
|
) {
|
70
69
|
supports_utf8 = Qtrue;
|
@@ -86,14 +85,14 @@ static void _begin_setup_iconv() {
|
|
86
85
|
|
87
86
|
VALUE mUTF8toUTF16 = rb_funcall(mIconv, rb_intern("new"), 2, rb_str_new2("utf-8"), rb_str_new2("utf-16be"));
|
88
87
|
rb_const_set(
|
89
|
-
|
88
|
+
rb_cJSON,
|
90
89
|
rb_intern("UTF16toUTF8"),
|
91
90
|
mUTF8toUTF16
|
92
91
|
);
|
93
92
|
|
94
93
|
VALUE mUTF16toUTF8 = rb_funcall(mIconv, rb_intern("new"), 2, rb_str_new2("utf-16be"), rb_str_new2("utf-8"));
|
95
94
|
rb_const_set(
|
96
|
-
|
95
|
+
rb_cJSON,
|
97
96
|
rb_intern("UTF8toUTF16"),
|
98
97
|
mUTF16toUTF8
|
99
98
|
);
|
@@ -170,7 +169,7 @@ static long _convert_utf8_char(input, i, result, supports_utf8)
|
|
170
169
|
}
|
171
170
|
else {
|
172
171
|
char* error_message = "Encountered unknown UTF-8 byte: ";
|
173
|
-
error_message
|
172
|
+
append(error_message, c_current);
|
174
173
|
strcat(error_message, "!");
|
175
174
|
rb_raise(rb_eRuntimeError, error_message);
|
176
175
|
}
|
@@ -184,7 +183,7 @@ static VALUE _convert_utf_8_string_part(result, input, i, length)
|
|
184
183
|
{
|
185
184
|
rb_str_cat2(result, "\\u");
|
186
185
|
VALUE utf_header = rb_funcall(input, rb_intern("[]"), 2, LONG2NUM(i), LONG2NUM(length));
|
187
|
-
rb_str_append(result, utf8_to_utf16(
|
186
|
+
rb_str_append(result, utf8_to_utf16(rb_cJSON, utf_header));
|
188
187
|
|
189
188
|
return Qnil;
|
190
189
|
}
|
data/ext/json_ext/json_ext.h
CHANGED
data/ext/state_ext/state_ext.c
CHANGED
@@ -1,61 +1,42 @@
|
|
1
1
|
#include "state_ext.h"
|
2
2
|
|
3
|
-
static VALUE cState;
|
4
|
-
static VALUE mClassMethods;
|
5
|
-
static VALUE mJSON;
|
6
|
-
|
7
3
|
/**
|
8
4
|
* This class is used to create State instances, that are used to hold data
|
9
5
|
* while unparsing a Ruby data structure into a JSON string.
|
10
6
|
*/
|
11
7
|
void Init_state_ext() {
|
12
|
-
mJSON = rb_const_get(rb_cObject, rb_intern("JSON"));
|
13
|
-
|
14
|
-
mClassMethods = rb_define_module_under(
|
8
|
+
VALUE mJSON = rb_const_get(rb_cObject, rb_intern("JSON"));
|
9
|
+
rb_cJsonState = rb_define_class_under(mJSON, "State", rb_cObject);
|
10
|
+
VALUE mClassMethods = rb_define_module_under(rb_cJsonState, "ClassMethods");
|
15
11
|
|
16
|
-
rb_define_method(mClassMethods, "from_state",
|
17
|
-
rb_extend_object(
|
12
|
+
rb_define_method(mClassMethods, "from_state", rb_json_from_state, 1);
|
13
|
+
rb_extend_object(rb_cJsonState, mClassMethods);
|
18
14
|
|
19
|
-
rb_define_method(
|
20
|
-
rb_define_method(
|
21
|
-
rb_define_method(
|
22
|
-
rb_define_method(
|
15
|
+
rb_define_method(rb_cJsonState, "initialize", initialize, -1);
|
16
|
+
rb_define_method(rb_cJsonState, "seen?", rb_json_state_seen, 1);
|
17
|
+
rb_define_method(rb_cJsonState, "remember", rb_json_state_remember, 1);
|
18
|
+
rb_define_method(rb_cJsonState, "forget", rb_json_state_forget, 1);
|
23
19
|
|
24
20
|
/*
|
25
21
|
* This string is used to indent levels in the JSON string.
|
26
22
|
*/
|
27
|
-
rb_define_method(
|
28
|
-
rb_define_method(
|
23
|
+
rb_define_method(rb_cJsonState, "indent", rb_json_state_get_intent, 0);
|
24
|
+
rb_define_method(rb_cJsonState, "indent=", rb_json_state_set_intent, 1);
|
29
25
|
|
30
26
|
/*
|
31
27
|
* This string is used to include a space between the tokens in a JSON string.
|
32
28
|
*/
|
33
|
-
rb_define_attr(
|
29
|
+
rb_define_attr(rb_cJsonState, "space", 1, 1);
|
34
30
|
|
35
31
|
/*
|
36
32
|
* This string is put at the end of a line that holds a JSON object (or Hash).
|
37
33
|
*/
|
38
|
-
rb_define_attr(
|
34
|
+
rb_define_attr(rb_cJsonState, "object_nl", 1, 1);
|
39
35
|
|
40
36
|
/*
|
41
37
|
* This string is put at the end of a line that holds a JSON array.
|
42
38
|
*/
|
43
|
-
rb_define_attr(
|
44
|
-
}
|
45
|
-
|
46
|
-
void rb_json_state_indent(state, json, depth)
|
47
|
-
VALUE state, json;
|
48
|
-
long depth;
|
49
|
-
{
|
50
|
-
VALUE indent = rb_funcall(state, rb_intern("indent"), 0);
|
51
|
-
char* c_indent = StringValueCStr(indent);
|
52
|
-
// Incrementing the depth
|
53
|
-
char* full_indent;
|
54
|
-
long i;
|
55
|
-
for(i=0; i<depth; i++) {
|
56
|
-
strcat(full_indent, c_indent);
|
57
|
-
}
|
58
|
-
rb_str_cat2(json, full_indent);
|
39
|
+
rb_define_attr(rb_cJsonState, "array_nl", 1, 1);
|
59
40
|
}
|
60
41
|
|
61
42
|
/** Static **/
|
@@ -92,68 +73,18 @@ static VALUE initialize(argc, argv, self)
|
|
92
73
|
rb_ivar_set(self, rb_intern("@seen"), rb_hash_new());
|
93
74
|
}
|
94
75
|
|
95
|
-
static VALUE
|
76
|
+
static VALUE rb_json_state_get_intent(self)
|
96
77
|
VALUE self;
|
97
78
|
{
|
98
79
|
return rb_ivar_get(self, rb_intern("@indent"));
|
99
80
|
}
|
100
81
|
|
101
|
-
static VALUE
|
82
|
+
static VALUE rb_json_state_set_intent(self, indent)
|
102
83
|
VALUE self, indent;
|
103
84
|
{
|
104
85
|
rb_ivar_set(self, rb_intern("@indent"), indent);
|
105
86
|
}
|
106
87
|
|
107
|
-
/**
|
108
|
-
* Creates a State object from _opts_, which ought to be Hash to create a
|
109
|
-
* new State instance configured by opts, something else to create an
|
110
|
-
* unconfigured instance. If _opts_ is a State object, it is just returned.
|
111
|
-
*/
|
112
|
-
static VALUE from_state(self, opts)
|
113
|
-
VALUE self, opts;
|
114
|
-
{
|
115
|
-
if(rb_obj_is_kind_of(opts, cState)) {
|
116
|
-
return opts;
|
117
|
-
}
|
118
|
-
else if(rb_obj_is_kind_of(opts, rb_cHash)) {
|
119
|
-
return rb_funcall(self, rb_intern("new"), 1, opts);
|
120
|
-
}
|
121
|
-
else {
|
122
|
-
return rb_funcall(self, rb_intern("new"), 0);
|
123
|
-
}
|
124
|
-
}
|
125
|
-
|
126
|
-
/**
|
127
|
-
* Returns _true_, if _object_ was already seen during this Unparsing run.
|
128
|
-
*/
|
129
|
-
static VALUE seen(self, object)
|
130
|
-
VALUE self, object;
|
131
|
-
{
|
132
|
-
VALUE seen_ivar = rb_ivar_get(self, rb_intern("@seen"));
|
133
|
-
return rb_hash_aref(seen_ivar, rb_obj_id(object));
|
134
|
-
}
|
135
|
-
|
136
|
-
/**
|
137
|
-
* Remember _object_, to find out if it was already encountered (to find out
|
138
|
-
* if a cyclic data structure is unparsed).
|
139
|
-
*/
|
140
|
-
static VALUE remember(self, object)
|
141
|
-
VALUE self, object;
|
142
|
-
{
|
143
|
-
VALUE seen_ivar = rb_ivar_get(self, rb_intern("@seen"));
|
144
|
-
rb_hash_aset(seen_ivar, rb_obj_id(object), Qtrue);
|
145
|
-
}
|
146
|
-
|
147
|
-
/**
|
148
|
-
* Forget _object_ for this Unparsing run.
|
149
|
-
*/
|
150
|
-
static VALUE forget(self, object)
|
151
|
-
VALUE self, object;
|
152
|
-
{
|
153
|
-
VALUE seen_ivar = rb_ivar_get(self, rb_intern("@seen"));
|
154
|
-
rb_hash_delete(seen_ivar, rb_obj_id(object));
|
155
|
-
}
|
156
|
-
|
157
88
|
/** private **/
|
158
89
|
static VALUE hash_value_or_empty_string_default(hash, cKey)
|
159
90
|
VALUE hash;
|
data/ext/state_ext/state_ext.h
CHANGED
@@ -1,14 +1,10 @@
|
|
1
1
|
#include "ruby.h"
|
2
|
+
#include "state_lib.h"
|
2
3
|
#include <string.h>
|
3
4
|
|
4
5
|
static VALUE initialize(int, VALUE*, VALUE);
|
5
6
|
static VALUE state_allocate(VALUE);
|
6
|
-
static VALUE from_state(VALUE, VALUE);
|
7
7
|
static VALUE hash_value_or_empty_string_default(VALUE, const char*);
|
8
|
-
static VALUE seen(VALUE, VALUE);
|
9
|
-
static VALUE remember(VALUE, VALUE);
|
10
|
-
static VALUE forget(VALUE, VALUE);
|
11
8
|
|
12
|
-
static VALUE
|
13
|
-
static VALUE
|
14
|
-
void rb_json_state_indent(VALUE, VALUE, long);
|
9
|
+
static VALUE rb_json_state_get_intent(VALUE);
|
10
|
+
static VALUE rb_json_state_set_intent(VALUE, VALUE);
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#include "state_lib.h"
|
2
|
+
|
3
|
+
void rb_json_state_indent(state, json, depth)
|
4
|
+
VALUE state, json;
|
5
|
+
long depth;
|
6
|
+
{
|
7
|
+
VALUE indent = rb_json_state_get_intent(state);
|
8
|
+
char* c_indent = StringValueCStr(indent);
|
9
|
+
// Incrementing the depth
|
10
|
+
char* full_indent;
|
11
|
+
long i;
|
12
|
+
for(i=0; i<depth; i++) {
|
13
|
+
strcat(full_indent, c_indent);
|
14
|
+
}
|
15
|
+
rb_str_cat2(json, full_indent);
|
16
|
+
}
|
17
|
+
|
18
|
+
VALUE rb_to_json(rb_target, rb_state, rb_indent)
|
19
|
+
VALUE rb_target, rb_state, rb_indent;
|
20
|
+
{
|
21
|
+
VALUE args = rb_ary_new2(3);
|
22
|
+
rb_ary_store (args, 0, rb_target);
|
23
|
+
rb_ary_store (args, 1, rb_state);
|
24
|
+
rb_ary_store (args, 2, rb_indent);
|
25
|
+
return rb_rescue(call_to_json, args, to_json_exception, rb_target);
|
26
|
+
}
|
27
|
+
|
28
|
+
VALUE rb_json_should_shift(state, object_nl)
|
29
|
+
VALUE state, object_nl;
|
30
|
+
{
|
31
|
+
if(state == Qnil) return Qfalse;
|
32
|
+
if(RSTRING(object_nl)->len == 0) return Qfalse;
|
33
|
+
return Qtrue;
|
34
|
+
}
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Creates a State object from _opts_, which ought to be Hash to create a
|
38
|
+
* new State instance configured by opts, something else to create an
|
39
|
+
* unconfigured instance. If _opts_ is a State object, it is just returned.
|
40
|
+
*/
|
41
|
+
VALUE rb_json_from_state(self, opts)
|
42
|
+
VALUE self, opts;
|
43
|
+
{
|
44
|
+
if(rb_obj_is_kind_of(opts, rb_cJsonState)) {
|
45
|
+
return opts;
|
46
|
+
}
|
47
|
+
else if(rb_obj_is_kind_of(opts, rb_cHash)) {
|
48
|
+
return rb_funcall(self, rb_intern("new"), 1, opts);
|
49
|
+
}
|
50
|
+
else {
|
51
|
+
return rb_funcall(self, rb_intern("new"), 0);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* Returns _true_, if _object_ was already seen during this Unparsing run.
|
57
|
+
*/
|
58
|
+
VALUE rb_json_state_seen(self, object)
|
59
|
+
VALUE self, object;
|
60
|
+
{
|
61
|
+
VALUE seen_ivar = rb_ivar_get(self, rb_intern("@seen"));
|
62
|
+
return rb_hash_aref(seen_ivar, rb_obj_id(object));
|
63
|
+
}
|
64
|
+
|
65
|
+
/**
|
66
|
+
* Remember _object_, to find out if it was already encountered (to find out
|
67
|
+
* if a cyclic data structure is unparsed).
|
68
|
+
*/
|
69
|
+
VALUE rb_json_state_remember(self, object)
|
70
|
+
VALUE self, object;
|
71
|
+
{
|
72
|
+
VALUE seen_ivar = rb_ivar_get(self, rb_intern("@seen"));
|
73
|
+
rb_hash_aset(seen_ivar, rb_obj_id(object), Qtrue);
|
74
|
+
}
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Forget _object_ for this Unparsing run.
|
78
|
+
*/
|
79
|
+
VALUE rb_json_state_forget(self, object)
|
80
|
+
VALUE self, object;
|
81
|
+
{
|
82
|
+
VALUE seen_ivar = rb_ivar_get(self, rb_intern("@seen"));
|
83
|
+
rb_hash_delete(seen_ivar, rb_obj_id(object));
|
84
|
+
}
|
85
|
+
|
86
|
+
/** Static **/
|
87
|
+
|
88
|
+
static VALUE call_to_json(args)
|
89
|
+
VALUE args;
|
90
|
+
{
|
91
|
+
VALUE rb_target = rb_ary_entry(args, 0);
|
92
|
+
VALUE rb_state = rb_ary_entry(args, 1);
|
93
|
+
VALUE rb_indent = rb_ary_entry(args, 2);
|
94
|
+
return rb_funcall(rb_target, rb_intern("to_json"), 2, rb_state, rb_indent);
|
95
|
+
}
|
96
|
+
|
97
|
+
static VALUE to_json_exception(rb_target, rb_error)
|
98
|
+
VALUE rb_target, rb_error;
|
99
|
+
{
|
100
|
+
VALUE rb_error_class = rb_obj_class(rb_error);
|
101
|
+
if(rb_error_class == rb_eArgError) {
|
102
|
+
return rb_funcall(rb_target, rb_intern("to_json"), 0);
|
103
|
+
}
|
104
|
+
else {
|
105
|
+
rb_exc_raise(rb_error);
|
106
|
+
}
|
107
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include <string.h>
|
3
|
+
|
4
|
+
VALUE rb_json_from_state(VALUE, VALUE);
|
5
|
+
VALUE rb_json_state_seen(VALUE, VALUE);
|
6
|
+
VALUE rb_json_state_remember(VALUE, VALUE);
|
7
|
+
VALUE rb_json_state_forget(VALUE, VALUE);
|
8
|
+
VALUE rb_json_should_shift(VALUE, VALUE);
|
9
|
+
VALUE rb_to_json(VALUE, VALUE, VALUE);
|
10
|
+
void rb_json_state_indent(VALUE, VALUE, long);
|
11
|
+
|
12
|
+
static VALUE call_to_json(VALUE);
|
13
|
+
static VALUE to_json_exception(VALUE, VALUE);
|
14
|
+
|
15
|
+
VALUE rb_cJsonState;
|
data/hash_benchmark.rb
CHANGED
data/lib/json/editor.rb
CHANGED
data/mkmf_tasks.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
class MkmfTasks
|
2
|
+
attr_writer :extconf_file_name,
|
3
|
+
:project_dir,
|
4
|
+
:file_extension,
|
5
|
+
:extension_paths,
|
6
|
+
:extconf_arguments
|
7
|
+
|
8
|
+
def initialize(actor)
|
9
|
+
@actor = actor
|
10
|
+
end
|
11
|
+
|
12
|
+
def default
|
13
|
+
compile
|
14
|
+
end
|
15
|
+
|
16
|
+
def compile
|
17
|
+
@extension_paths.each do |extension|
|
18
|
+
dir = "ext/#{extension}"
|
19
|
+
extconf dir
|
20
|
+
make dir
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def spec
|
25
|
+
compile
|
26
|
+
install
|
27
|
+
dir = @project_dir
|
28
|
+
require File.expand_path("#{dir}/spec/spec_suite")
|
29
|
+
end
|
30
|
+
|
31
|
+
def lib
|
32
|
+
directory "lib"
|
33
|
+
end
|
34
|
+
|
35
|
+
def install
|
36
|
+
@extension_paths.each do |extension_path|
|
37
|
+
build_path = build_path(extension_path)
|
38
|
+
raise "File #{build_path} does not exist" unless File.exists?(build_path)
|
39
|
+
cp build_path, library_path(extension_path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def cleanup
|
44
|
+
@extension_paths.each do |extension_path|
|
45
|
+
library_path = library_path(extension_path)
|
46
|
+
rm library_path if library_path && File.exists?(library_path)
|
47
|
+
|
48
|
+
build_file_path = build_path(extension_path)
|
49
|
+
rm build_file_path if build_file_path && File.exists?(build_file_path)
|
50
|
+
|
51
|
+
build_object_path = "#{build_path_without_file_extension(extension_path)}.o"
|
52
|
+
rm build_object_path if build_object_path && File.exists?(build_object_path)
|
53
|
+
|
54
|
+
build_dir = build_dir(extension_path)
|
55
|
+
make_file_path = "#{build_dir}/Makefile"
|
56
|
+
rm make_file_path if make_file_path && File.exists?(make_file_path)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
def extconf(dir)
|
62
|
+
Dir.chdir(dir) do
|
63
|
+
sh("ruby #{@extconf_arguments} #{@extconf_file_name}")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def make(makedir)
|
68
|
+
Dir.chdir(makedir) do
|
69
|
+
sh("make")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def build_dir(relative_extension_path)
|
74
|
+
"#{@project_dir}/ext/#{relative_extension_path}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def build_path(relative_extension_path)
|
78
|
+
basename = build_path_without_file_extension(relative_extension_path)
|
79
|
+
"#{basename}.#{@file_extension}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def build_path_without_file_extension(relative_extension_path)
|
83
|
+
"#{build_dir(relative_extension_path)}/#{File.basename(relative_extension_path)}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def library_path(relative_extension_path)
|
87
|
+
library_directory_path = File.expand_path("#{@project_dir}/lib/#{File.dirname(relative_extension_path)}")
|
88
|
+
binary_name = "#{File.basename(relative_extension_path)}.#{@file_extension}"
|
89
|
+
"#{library_directory_path}/#{binary_name}"
|
90
|
+
end
|
91
|
+
|
92
|
+
def rm(path)
|
93
|
+
@actor.__send__ :rm, path
|
94
|
+
end
|
95
|
+
|
96
|
+
def sh(cmd)
|
97
|
+
@actor.__send__ :sh, cmd
|
98
|
+
end
|
99
|
+
end
|