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.
Files changed (61) hide show
  1. data/.gitignore +24 -0
  2. data/.rspec +1 -0
  3. data/.travisci.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +152 -0
  7. data/Rakefile +38 -0
  8. data/bin/cauterize +53 -0
  9. data/c/src/cauterize.c +74 -0
  10. data/c/src/cauterize.h +46 -0
  11. data/c/src/cauterize_debug.h +29 -0
  12. data/c/src/cauterize_util.h +7 -0
  13. data/c/test/greatest.h +536 -0
  14. data/c/test/test.c +166 -0
  15. data/cauterize.gemspec +26 -0
  16. data/example/Cauterize +44 -0
  17. data/example/build.sh +4 -0
  18. data/lib/cauterize/base_type.rb +96 -0
  19. data/lib/cauterize/builders.rb +27 -0
  20. data/lib/cauterize/builders/c/buildable.rb +59 -0
  21. data/lib/cauterize/builders/c/composite.rb +55 -0
  22. data/lib/cauterize/builders/c/enumeration.rb +41 -0
  23. data/lib/cauterize/builders/c/fixed_array.rb +62 -0
  24. data/lib/cauterize/builders/c/group.rb +95 -0
  25. data/lib/cauterize/builders/c/scalar.rb +31 -0
  26. data/lib/cauterize/builders/c/variable_array.rb +90 -0
  27. data/lib/cauterize/c_builder.rb +63 -0
  28. data/lib/cauterize/cauterize.rb +33 -0
  29. data/lib/cauterize/composite.rb +50 -0
  30. data/lib/cauterize/enumeration.rb +77 -0
  31. data/lib/cauterize/fixed_array.rb +43 -0
  32. data/lib/cauterize/formatter.rb +59 -0
  33. data/lib/cauterize/group.rb +56 -0
  34. data/lib/cauterize/scalar.rb +38 -0
  35. data/lib/cauterize/snake_case.rb +21 -0
  36. data/lib/cauterize/variable_array.rb +56 -0
  37. data/lib/cauterize/version.rb +3 -0
  38. data/spec/base_type_spec.rb +167 -0
  39. data/spec/builders/c/buildable_spec.rb +25 -0
  40. data/spec/builders/c/composite_spec.rb +46 -0
  41. data/spec/builders/c/enumeration_spec.rb +32 -0
  42. data/spec/builders/c/fixed_array_spec.rb +36 -0
  43. data/spec/builders/c/group_spec.rb +112 -0
  44. data/spec/builders/c/scalar_spec.rb +8 -0
  45. data/spec/builders/c/variable_array_spec.rb +50 -0
  46. data/spec/builders_spec.rb +51 -0
  47. data/spec/c_builder_spec.rb +133 -0
  48. data/spec/cauterize_spec.rb +8 -0
  49. data/spec/composite_spec.rb +62 -0
  50. data/spec/enumeration_spec.rb +104 -0
  51. data/spec/fixed_array_spec.rb +62 -0
  52. data/spec/group_spec.rb +104 -0
  53. data/spec/scalar_spec.rb +36 -0
  54. data/spec/spec_helper.rb +115 -0
  55. data/spec/support/shared_examples_for_array_buildables.rb +22 -0
  56. data/spec/support/shared_examples_for_c_buildables.rb +91 -0
  57. data/spec/support/shared_examples_for_sane_c_buildables.rb +22 -0
  58. data/spec/support/shared_examples_for_stubbed_functions.rb +18 -0
  59. data/spec/test_main.c +13 -0
  60. data/spec/variable_array_spec.rb +92 -0
  61. metadata +212 -0
@@ -0,0 +1,8 @@
1
+ describe Cauterize do
2
+ describe :set_name do
3
+ it "sets the name of the project" do
4
+ set_name("some_name")
5
+ Cauterize.get_name.should == "some_name"
6
+ end
7
+ end
8
+ end
@@ -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
@@ -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
@@ -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
@@ -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