cauterize 0.0.1.pre1
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/.gitignore +24 -0
- data/.rspec +1 -0
- data/.travisci.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +152 -0
- data/Rakefile +38 -0
- data/bin/cauterize +53 -0
- data/c/src/cauterize.c +74 -0
- data/c/src/cauterize.h +46 -0
- data/c/src/cauterize_debug.h +29 -0
- data/c/src/cauterize_util.h +7 -0
- data/c/test/greatest.h +536 -0
- data/c/test/test.c +166 -0
- data/cauterize.gemspec +26 -0
- data/example/Cauterize +44 -0
- data/example/build.sh +4 -0
- data/lib/cauterize/base_type.rb +96 -0
- data/lib/cauterize/builders.rb +27 -0
- data/lib/cauterize/builders/c/buildable.rb +59 -0
- data/lib/cauterize/builders/c/composite.rb +55 -0
- data/lib/cauterize/builders/c/enumeration.rb +41 -0
- data/lib/cauterize/builders/c/fixed_array.rb +62 -0
- data/lib/cauterize/builders/c/group.rb +95 -0
- data/lib/cauterize/builders/c/scalar.rb +31 -0
- data/lib/cauterize/builders/c/variable_array.rb +90 -0
- data/lib/cauterize/c_builder.rb +63 -0
- data/lib/cauterize/cauterize.rb +33 -0
- data/lib/cauterize/composite.rb +50 -0
- data/lib/cauterize/enumeration.rb +77 -0
- data/lib/cauterize/fixed_array.rb +43 -0
- data/lib/cauterize/formatter.rb +59 -0
- data/lib/cauterize/group.rb +56 -0
- data/lib/cauterize/scalar.rb +38 -0
- data/lib/cauterize/snake_case.rb +21 -0
- data/lib/cauterize/variable_array.rb +56 -0
- data/lib/cauterize/version.rb +3 -0
- data/spec/base_type_spec.rb +167 -0
- data/spec/builders/c/buildable_spec.rb +25 -0
- data/spec/builders/c/composite_spec.rb +46 -0
- data/spec/builders/c/enumeration_spec.rb +32 -0
- data/spec/builders/c/fixed_array_spec.rb +36 -0
- data/spec/builders/c/group_spec.rb +112 -0
- data/spec/builders/c/scalar_spec.rb +8 -0
- data/spec/builders/c/variable_array_spec.rb +50 -0
- data/spec/builders_spec.rb +51 -0
- data/spec/c_builder_spec.rb +133 -0
- data/spec/cauterize_spec.rb +8 -0
- data/spec/composite_spec.rb +62 -0
- data/spec/enumeration_spec.rb +104 -0
- data/spec/fixed_array_spec.rb +62 -0
- data/spec/group_spec.rb +104 -0
- data/spec/scalar_spec.rb +36 -0
- data/spec/spec_helper.rb +115 -0
- data/spec/support/shared_examples_for_array_buildables.rb +22 -0
- data/spec/support/shared_examples_for_c_buildables.rb +91 -0
- data/spec/support/shared_examples_for_sane_c_buildables.rb +22 -0
- data/spec/support/shared_examples_for_stubbed_functions.rb +18 -0
- data/spec/test_main.c +13 -0
- data/spec/variable_array_spec.rb +92 -0
- metadata +212 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
describe Cauterize do
|
2
|
+
before { reset_for_test }
|
3
|
+
|
4
|
+
describe CompositeField do
|
5
|
+
describe :initialize do
|
6
|
+
it "creates a new name -> type mapping" do
|
7
|
+
a = scalar(:a_type)
|
8
|
+
b = scalar(:b_type)
|
9
|
+
f = CompositeField.new(:a_name, :a_type)
|
10
|
+
f.name.should == :a_name
|
11
|
+
f.type.should be a
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Composite do
|
17
|
+
describe :initialize do
|
18
|
+
it "creates a Composite" do
|
19
|
+
c = Composite.new(:foo)
|
20
|
+
c.name.should == :foo
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe :fields do
|
25
|
+
it "defines a new field in the composite" do
|
26
|
+
a = scalar(:foo)
|
27
|
+
comp = composite(:comp) do |c|
|
28
|
+
c.field :a_foo, :foo
|
29
|
+
end
|
30
|
+
|
31
|
+
comp.fields.keys[0].should == :a_foo
|
32
|
+
comp.fields.values[0].name.should == :a_foo
|
33
|
+
comp.fields.values[0].type.should be a
|
34
|
+
end
|
35
|
+
|
36
|
+
it "errors on duplicate field names" do
|
37
|
+
a = scalar(:foo)
|
38
|
+
lambda {
|
39
|
+
composite(:comp) do |c|
|
40
|
+
c.field :a_foo, :foo
|
41
|
+
c.field :b_foo, :foo
|
42
|
+
c.field :b_foo, :foo
|
43
|
+
end
|
44
|
+
}.should raise_error /Field name b_foo already used/
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe :composite do
|
50
|
+
it { creates_a_named_object(:composite, Composite) }
|
51
|
+
it { retrieves_obj_with_identical_name(:composite) }
|
52
|
+
it { yields_the_object(:composite) }
|
53
|
+
it { adds_object_to_hash(:composite, :composites) }
|
54
|
+
end
|
55
|
+
|
56
|
+
describe :composite! do
|
57
|
+
it { creates_a_named_object(:composite!, Composite) }
|
58
|
+
it { raises_exception_with_identical_name(:composite!) }
|
59
|
+
it { yields_the_object(:composite!) }
|
60
|
+
it { adds_object_to_hash(:composite!, :composites) }
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
describe Cauterize do
|
2
|
+
before { reset_for_test }
|
3
|
+
|
4
|
+
describe EnumerationValue do
|
5
|
+
describe :initialize do
|
6
|
+
it "creates an EnumerationValue" do
|
7
|
+
e = EnumerationValue.new(:foo, 1)
|
8
|
+
e.name.should == :foo
|
9
|
+
e.value.should == 1
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Enumeration do
|
15
|
+
describe :initialize do
|
16
|
+
it "creates a new enumeration with the right name" do
|
17
|
+
Enumeration.new(:foo).name.should == :foo
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe :value do
|
22
|
+
it "adds a new value to the enumeration" do
|
23
|
+
enum = enumeration(:foo) do |e|
|
24
|
+
e.value :a
|
25
|
+
e.value :b
|
26
|
+
e.value :c
|
27
|
+
e.value :d
|
28
|
+
end
|
29
|
+
|
30
|
+
values = enum.values
|
31
|
+
values.length.should == 4
|
32
|
+
values.keys.should == [:a, :b, :c, :d]
|
33
|
+
values.values.map(&:value).should == [0, 1, 2, 3]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "accepts a fixed value" do
|
37
|
+
enum = enumeration(:foo) do |e|
|
38
|
+
e.value :a, 10
|
39
|
+
e.value :b, 20
|
40
|
+
e.value :c
|
41
|
+
end
|
42
|
+
|
43
|
+
values = enum.values
|
44
|
+
values.keys.should == [:a, :b, :c]
|
45
|
+
values.values.map(&:value).should == [10, 20, 21]
|
46
|
+
end
|
47
|
+
|
48
|
+
it "allows out-of-order values" do
|
49
|
+
lambda {
|
50
|
+
enumeration(:foo) do |e|
|
51
|
+
e.value :a, 10
|
52
|
+
e.value :b, 9
|
53
|
+
end
|
54
|
+
}.should_not raise_error
|
55
|
+
end
|
56
|
+
|
57
|
+
it "doesn't allow duplicate ids" do
|
58
|
+
lambda {
|
59
|
+
enumeration(:foo) do |e|
|
60
|
+
e.value :a, 1
|
61
|
+
e.value :b, 1
|
62
|
+
end
|
63
|
+
}.should raise_error /duplicate constant/
|
64
|
+
end
|
65
|
+
|
66
|
+
it "doesn't allow accidentally identical ids" do
|
67
|
+
en = enumeration(:foo) do |e|
|
68
|
+
e.value :a, 10
|
69
|
+
e.value :b, 9
|
70
|
+
e.value :c
|
71
|
+
end
|
72
|
+
|
73
|
+
en.values.values.map(&:value).should == [10,9,11]
|
74
|
+
end
|
75
|
+
|
76
|
+
it "errors on duplicate names" do
|
77
|
+
lambda {
|
78
|
+
enumeration(:foo) do |e|
|
79
|
+
e.value :a
|
80
|
+
e.value :a
|
81
|
+
end
|
82
|
+
}.should raise_error /duplicate name/
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe :enumeration do
|
88
|
+
it { creates_a_named_object(:enumeration, Enumeration) }
|
89
|
+
it { retrieves_obj_with_identical_name(:enumeration) }
|
90
|
+
it { yields_the_object(:enumeration) }
|
91
|
+
it { adds_object_to_hash(:enumeration, :enumerations) }
|
92
|
+
end
|
93
|
+
|
94
|
+
describe :enumeration! do
|
95
|
+
it { creates_a_named_object(:enumeration!, Enumeration) }
|
96
|
+
it { raises_exception_with_identical_name(:enumeration!) }
|
97
|
+
it { yields_the_object(:enumeration!) }
|
98
|
+
it { adds_object_to_hash(:enumeration!, :enumerations) }
|
99
|
+
end
|
100
|
+
|
101
|
+
describe :enumerations do
|
102
|
+
it { is_hash_of_created_objs(:enumeration, :enumerations) }
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
describe Cauterize do
|
2
|
+
before { reset_for_test }
|
3
|
+
|
4
|
+
describe :fixed_array do
|
5
|
+
it { creates_a_named_object(:fixed_array, FixedArray) }
|
6
|
+
it { retrieves_obj_with_identical_name(:fixed_array) }
|
7
|
+
it { yields_the_object(:fixed_array) }
|
8
|
+
it { adds_object_to_hash(:fixed_array, :fixed_arrays) }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe :fixed_array! do
|
12
|
+
it { creates_a_named_object(:fixed_array!, FixedArray) }
|
13
|
+
it { raises_exception_with_identical_name(:variable_array!) }
|
14
|
+
it { yields_the_object(:fixed_array!) }
|
15
|
+
it { adds_object_to_hash(:fixed_array!, :fixed_arrays) }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe FixedArray do
|
19
|
+
before { @a = fixed_array(:foo) }
|
20
|
+
|
21
|
+
describe :initialize do
|
22
|
+
it "Creates a fixed array." do
|
23
|
+
@a.name.should == :foo
|
24
|
+
@a.id.should_not be_nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe :array_type do
|
29
|
+
it "Defines the type of the FixedArray." do
|
30
|
+
scalar(:uint32_t)
|
31
|
+
@a.array_type :uint32_t
|
32
|
+
@a.instance_variable_get(:@array_type).name.should == :uint32_t
|
33
|
+
end
|
34
|
+
|
35
|
+
it "raises an error if type doesn't exist" do
|
36
|
+
lambda {
|
37
|
+
fixed_array(:fa) do |f|
|
38
|
+
f.array_type :lol
|
39
|
+
end
|
40
|
+
}.should raise_error /lol does not correspond/
|
41
|
+
end
|
42
|
+
|
43
|
+
it "is the defined type if no argument is passed" do
|
44
|
+
s = scalar(:uint32_t)
|
45
|
+
@a.array_type :uint32_t
|
46
|
+
@a.array_type.should be s
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe :array_size do
|
51
|
+
it "Defines the size of the FixedArray." do
|
52
|
+
@a.array_size 46
|
53
|
+
@a.instance_variable_get(:@array_size).should == 46
|
54
|
+
end
|
55
|
+
|
56
|
+
it "is the defined size if no argument is passed" do
|
57
|
+
@a.array_size 46
|
58
|
+
@a.array_size.should == 46
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/group_spec.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
describe Cauterize do
|
2
|
+
before { reset_for_test }
|
3
|
+
|
4
|
+
describe :group do
|
5
|
+
it { creates_a_named_object(:group, Group) }
|
6
|
+
it { retrieves_obj_with_identical_name(:group) }
|
7
|
+
it { yields_the_object(:group) }
|
8
|
+
it { adds_object_to_hash(:group, :groups) }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe :group! do
|
12
|
+
it { creates_a_named_object(:group!, Group) }
|
13
|
+
it { raises_exception_with_identical_name(:group!) }
|
14
|
+
it { yields_the_object(:group!) }
|
15
|
+
it { adds_object_to_hash(:group!, :groups) }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe :groups do
|
19
|
+
it "is all the defined groups" do
|
20
|
+
group(:a)
|
21
|
+
group(:b)
|
22
|
+
groups.values.map(&:name).should == [:a, :b]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe GroupField do
|
27
|
+
describe :initialize do
|
28
|
+
it "creats a GroupField" do
|
29
|
+
t = scalar(:type)
|
30
|
+
f = GroupField.new(:name, :type)
|
31
|
+
f.name.should == :name
|
32
|
+
f.type.should be t
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe Group do
|
38
|
+
describe :initialize do
|
39
|
+
it "makes a new Group" do
|
40
|
+
Group.new(:foo).name == :foo
|
41
|
+
end
|
42
|
+
|
43
|
+
it "creates the tag enum" do
|
44
|
+
e = Group.new(:foo).tag_enum
|
45
|
+
e.name.should == :group_foo_type
|
46
|
+
e.values == {}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe :field do
|
51
|
+
it "adds a field to the Group" do
|
52
|
+
a = scalar(:aaa)
|
53
|
+
b = scalar(:bbb)
|
54
|
+
grp = group(:foo) do |g|
|
55
|
+
g.field(:a, :aaa)
|
56
|
+
g.field(:b, :bbb)
|
57
|
+
end
|
58
|
+
|
59
|
+
grp.fields.values.map(&:name).should == [:a, :b]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "errors on duplicate field names" do
|
63
|
+
a = scalar(:aaa)
|
64
|
+
lambda {
|
65
|
+
grp = group(:foo) do |g|
|
66
|
+
g.field(:a, :aaa)
|
67
|
+
g.field(:a, :aaa)
|
68
|
+
end
|
69
|
+
}.should raise_error /Field name a already used/
|
70
|
+
end
|
71
|
+
|
72
|
+
it "errors on non-existant types" do
|
73
|
+
lambda {
|
74
|
+
grp = group(:foo) do |g|
|
75
|
+
g.field(:a, :aaa)
|
76
|
+
end
|
77
|
+
}.should raise_error /name aaa does not correspond to a type/
|
78
|
+
end
|
79
|
+
|
80
|
+
it "adds a new value to the enum for each field" do
|
81
|
+
a = scalar(:aaa)
|
82
|
+
b = scalar(:bbb)
|
83
|
+
grp = group(:foo) do |g|
|
84
|
+
g.field(:a, :aaa)
|
85
|
+
g.field(:b, :bbb)
|
86
|
+
end
|
87
|
+
|
88
|
+
grp.tag_enum.values.keys.should =~ [:GROUP_FOO_TYPE_A, :GROUP_FOO_TYPE_B]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe ".tag_enum" do
|
93
|
+
it "is the enumeration used for the type tag" do
|
94
|
+
Group.new(:foo).tag_enum.class.should be Cauterize::Enumeration
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "enum_sym" do
|
99
|
+
it "returns the enumeration symbol for a field name" do
|
100
|
+
group(:foo).enum_sym(:a_field).should == :GROUP_FOO_TYPE_A_FIELD
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/spec/scalar_spec.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
describe Cauterize do
|
2
|
+
before do
|
3
|
+
reset_for_test
|
4
|
+
flush_scalars
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Scalar do
|
8
|
+
describe :initialize do
|
9
|
+
it "creates an scalar" do
|
10
|
+
scalar(:foo).name.should == :foo
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe :id do
|
15
|
+
it { has_a_unique_id_for_each_instance(Scalar) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe :scalar do
|
20
|
+
it { creates_a_named_object(:scalar, Scalar) }
|
21
|
+
it { retrieves_obj_with_identical_name(:scalar) }
|
22
|
+
it { yields_the_object(:scalar) }
|
23
|
+
it { adds_object_to_hash(:scalar, :scalars) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe :scalar! do
|
27
|
+
it { creates_a_named_object(:scalar!, Scalar) }
|
28
|
+
it { raises_exception_with_identical_name(:scalar!) }
|
29
|
+
it { yields_the_object(:scalar!) }
|
30
|
+
it { adds_object_to_hash(:scalar!, :scalars) }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe :scalars do
|
34
|
+
it { is_hash_of_created_objs(:scalar, :scalars) }
|
35
|
+
end
|
36
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'mocha/api'
|
3
|
+
require 'require_all'
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
6
|
+
require 'cauterize/cauterize'
|
7
|
+
|
8
|
+
require_all Dir['spec/support/**/*.rb']
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.mock_framework = :mocha
|
12
|
+
config.before(:each) do
|
13
|
+
reset_for_test
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
###
|
18
|
+
|
19
|
+
def reset_for_test
|
20
|
+
BaseType.class_variable_set(:@@next_id, {})
|
21
|
+
BaseType.class_variable_set(:@@instances, {})
|
22
|
+
BaseType.class_variable_set(:@@used_names, Set.new)
|
23
|
+
|
24
|
+
Cauterize.module_exec do
|
25
|
+
@enumerations = {}
|
26
|
+
@groups = {}
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_tagged_as(cls, tag)
|
32
|
+
cls.new(:foo).tag.should == tag
|
33
|
+
end
|
34
|
+
|
35
|
+
def has_a_unique_id_for_each_instance(cls)
|
36
|
+
cls.new(:foo).id.should == 0
|
37
|
+
cls.new(:bar).id.should == 1
|
38
|
+
cls.new(:baz).id.should == 2
|
39
|
+
end
|
40
|
+
|
41
|
+
def creates_a_named_object(fn_sym, obj)
|
42
|
+
fn = method(fn_sym)
|
43
|
+
a = fn.call(:foo)
|
44
|
+
a.class.should == obj
|
45
|
+
a.name.should == :foo
|
46
|
+
end
|
47
|
+
|
48
|
+
def retrieves_obj_with_identical_name(fn_sym)
|
49
|
+
fn = method(fn_sym)
|
50
|
+
a = fn.call(:foo)
|
51
|
+
b = fn.call(:foo)
|
52
|
+
a.should be b
|
53
|
+
end
|
54
|
+
|
55
|
+
def raises_exception_with_identical_name(fn_sym)
|
56
|
+
fn = method(fn_sym)
|
57
|
+
fn.call(:foo)
|
58
|
+
lambda { fn.call(:foo) }.should raise_error
|
59
|
+
end
|
60
|
+
|
61
|
+
def yields_the_object(fn_sym)
|
62
|
+
fn = method(fn_sym)
|
63
|
+
called = false
|
64
|
+
yielded = nil
|
65
|
+
r = fn.call(:foo) { |a| yielded = a }
|
66
|
+
yielded.should be r
|
67
|
+
end
|
68
|
+
|
69
|
+
def adds_object_to_hash(fn_sym, hash_fn_sym)
|
70
|
+
fn = method(fn_sym)
|
71
|
+
hash_fn = method(hash_fn_sym)
|
72
|
+
|
73
|
+
f = fn.call(:foo)
|
74
|
+
b = fn.call(:bar)
|
75
|
+
|
76
|
+
hash_fn.call.keys.should == [:foo, :bar]
|
77
|
+
hash_fn.call.values[0].should be f
|
78
|
+
hash_fn.call.values[1].should be b
|
79
|
+
end
|
80
|
+
|
81
|
+
def is_hash_of_created_objs(create_fn_sym, hash_fn_sym)
|
82
|
+
create_fn = method(create_fn_sym)
|
83
|
+
hash_fn = method(hash_fn_sym)
|
84
|
+
|
85
|
+
f = create_fn.call(:foo)
|
86
|
+
b = create_fn.call(:bar)
|
87
|
+
z = create_fn.call(:zap)
|
88
|
+
|
89
|
+
vs = hash_fn.call.values
|
90
|
+
vs[0].should be f
|
91
|
+
vs[1].should be b
|
92
|
+
vs[2].should be z
|
93
|
+
hash_fn.call.keys.should == [:foo, :bar, :zap]
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
###############################################################################
|
98
|
+
|
99
|
+
def gen_test_main(sym_list)
|
100
|
+
sym_voids = sym_list.map {|s| "(void*)#{s}"}.join(", ")
|
101
|
+
str = <<-EOF
|
102
|
+
#include "testing.h"
|
103
|
+
|
104
|
+
int main(int argc, char * argv[])
|
105
|
+
{
|
106
|
+
(void)argc;
|
107
|
+
(void)argv;
|
108
|
+
|
109
|
+
void * ptr[] = {#{sym_voids}};
|
110
|
+
(void)ptr;
|
111
|
+
|
112
|
+
return 0;
|
113
|
+
}
|
114
|
+
EOF
|
115
|
+
end
|