cauterize 0.0.1.pre9 → 0.0.1.pre10

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -21,9 +21,7 @@ Gemfile.lock
21
21
  pkg
22
22
 
23
23
  # Examples
24
- example/cauterize_output
25
- example/c_cauterize_output
26
- example/cs_cauterize_output
24
+ example/*_cauterize_output
27
25
 
28
26
  # Nunit test results
29
27
  TestResult.xml
data/example/build.sh CHANGED
@@ -18,3 +18,5 @@ rm -rf cs_cauterize_output
18
18
 
19
19
  dmcs cs_cauterize_output/*.cs -target:library -out:cs_cauterize_output/example_project.dll
20
20
 
21
+ rm -rf ruby_cauterize_output
22
+ ../bin/cauterize generate ruby ruby_cauterize_output
@@ -1,9 +1,9 @@
1
1
  require 'set'
2
+ require 'digest'
2
3
 
3
4
  module Cauterize
4
5
  class BaseType
5
- attr_reader :name, :id, :description
6
- @@next_id = {}
6
+ attr_reader :name, :description
7
7
  @@instances = {}
8
8
 
9
9
  def initialize(name, description=nil)
@@ -13,42 +13,25 @@ module Cauterize
13
13
 
14
14
  @name = name
15
15
  @description = description
16
- @id = next_id
17
16
  register_instance(self)
18
17
  end
19
18
 
20
- def type
21
- tag_part = ((tag << BaseType.id_bit_width) & BaseType.tag_bit_mask)
22
- id_part = (id & BaseType.id_bit_mask)
23
- (tag_part | id_part) & BaseType.type_bit_mask
19
+ def type_hash(digest = nil)
20
+ digest ||= BaseType.digest_class.new
21
+ digest.update(@name.to_s)
22
+ local_hash(digest)
24
23
  end
25
24
 
26
- def type_str
27
- "0x%04X" % type
28
- end
25
+ def self.all_instances; @@instances.values end
29
26
 
30
- def tag
31
- cname = self.class.name
32
- case cname
33
- when "Cauterize::Scalar"; 0
34
- when "Cauterize::Enumeration"; 1
35
- when "Cauterize::Composite"; 2
36
- when "Cauterize::FixedArray"; 3
37
- when "Cauterize::VariableArray"; 4
38
- when "Cauterize::Group"; 5
39
- else
40
- raise Exception.new("Tag not defined for #{cname}.")
41
- end
27
+ def self.model_hash
28
+ @@instances.keys.sort.map do |k|
29
+ @@instances[k]
30
+ end.inject(BaseType.digest_class.new) do |d, i|
31
+ i.type_hash(d)
32
+ end.digest
42
33
  end
43
34
 
44
- def self.tag_bit_mask; 0xE000 end
45
- def self.tag_bit_width; 3 end
46
- def self.id_bit_mask; 0x1FFF end
47
- def self.id_bit_width; 13 end
48
- def self.type_bit_mask; 0xFFFF end
49
- def self.type_bit_width; tag_bit_width + id_bit_width end
50
- def self.all_instances; @@instances.values end
51
-
52
35
  def self.find_type(name)
53
36
  @@instances[name]
54
37
  end
@@ -61,6 +44,10 @@ module Cauterize
61
44
  end
62
45
  end
63
46
 
47
+ def self.digest_class
48
+ Digest::SHA1
49
+ end
50
+
64
51
  alias :orig_method_missing :method_missing
65
52
 
66
53
  def method_missing(sym, *args)
@@ -74,6 +61,12 @@ module Cauterize
74
61
 
75
62
  protected
76
63
 
64
+ # local_hash is responsible for hashing the things in the type that
65
+ # are not known about in the BaseType parent class.
66
+ def local_hash(digest)
67
+ raise Exception.new("All instances of BaseType (including #{self.class}) must implement local_hash.")
68
+ end
69
+
77
70
  def register_instance(inst)
78
71
  if @@instances[inst.name]
79
72
  raise Exception.new("Type with name #{inst.name} already defined.")
@@ -81,14 +74,5 @@ module Cauterize
81
74
 
82
75
  @@instances[inst.name] = inst
83
76
  end
84
-
85
- def next_id
86
- cname = self.class.name
87
- @@next_id[cname] ||= 0
88
-
89
- an_id = @@next_id[cname]
90
- @@next_id[cname] += 1
91
- return an_id
92
- end
93
77
  end
94
78
  end
@@ -48,6 +48,13 @@ module Cauterize
48
48
  @byte_length
49
49
  end
50
50
  end
51
+
52
+ protected
53
+
54
+ def local_hash(digest)
55
+ digest.update(@flavor.to_s)
56
+ digest.update(@byte_length.to_s)
57
+ end
51
58
  end
52
59
 
53
60
  # Create all the builtin types.
@@ -1,4 +1,5 @@
1
1
  require 'time'
2
+ require 'digest'
2
3
 
3
4
  module Cauterize
4
5
  class CBuilder
@@ -32,6 +33,10 @@ module Cauterize
32
33
  f << "#define GEN_DATE (\"#{DateTime.now.to_s}\")"
33
34
  f.blank_line
34
35
 
36
+ f << "#define MODEL_HASH_LEN (#{BaseType.digest_class.new.length})"
37
+ f << "#define MODEL_HASH {#{BaseType.model_hash.bytes.to_a.join(", ")}}"
38
+ f.blank_line
39
+
35
40
  instances = BaseType.all_instances
36
41
  builders = instances.map {|i| Builders.get(:c, i)}
37
42
 
@@ -30,6 +30,11 @@ module Cauterize
30
30
  @type = BaseType.find_type!(type_name)
31
31
  @description = desc
32
32
  end
33
+
34
+ def field_hash(digest)
35
+ digest.update(@name.to_s)
36
+ @type.type_hash(digest)
37
+ end
33
38
  end
34
39
 
35
40
  class Composite < BaseType
@@ -47,5 +52,13 @@ module Cauterize
47
52
  @fields[name] = CompositeField.new(name, type, desc)
48
53
  end
49
54
  end
55
+
56
+ protected
57
+
58
+ def local_hash(digest)
59
+ @fields.keys.inject(digest) {|d, k|
60
+ @fields[k].field_hash(digest)
61
+ }
62
+ end
50
63
  end
51
64
  end
@@ -31,7 +31,9 @@ module Cauterize
31
31
  f.braces do
32
32
  f << "Name = \"#{@name}\","
33
33
  f << "GeneratedVersion = \"#{Cauterize.get_version}\","
34
- f << "GeneratedDate = \"#{DateTime.now.to_s}\""
34
+ f << "GeneratedDate = \"#{DateTime.now.to_s}\","
35
+ f << "ModelHashLength = #{BaseType.digest_class.new.length},"
36
+ f << "ModelHash = new byte[] {#{BaseType.model_hash.bytes.to_a.join(", ")}}"
35
37
  end
36
38
  f << ";"
37
39
  end
@@ -31,6 +31,11 @@ module Cauterize
31
31
  @name = name
32
32
  @value = value
33
33
  end
34
+
35
+ def value_hash(digest)
36
+ digest.update(@name.to_s)
37
+ digest.update(@value.to_s)
38
+ end
34
39
  end
35
40
 
36
41
  class Enumeration < BaseType
@@ -69,12 +74,21 @@ module Cauterize
69
74
  raise Exception.new("Unable to represent enumeration (#{min_val} -> #{max_val})")
70
75
  end
71
76
  end
77
+
78
+ protected
79
+
80
+ def local_hash(digest)
81
+ representation.type_hash(digest)
82
+ values.keys.sort.inject(digest) {|d, k|
83
+ values[k].value_hash(digest)
84
+ }
85
+ end
72
86
 
73
87
  private
74
88
 
75
89
  def value_id(next_id=nil)
76
90
  if next_id
77
- @value_id = next_id
91
+ @value_id = next_id.to_i
78
92
  end
79
93
 
80
94
  v = @value_id
@@ -39,5 +39,12 @@ module Cauterize
39
39
  @array_size
40
40
  end
41
41
  end
42
+
43
+ protected
44
+
45
+ def local_hash(digest)
46
+ digest.update(@array_size.to_s)
47
+ @array_type.type_hash(digest)
48
+ end
42
49
  end
43
50
  end
@@ -27,6 +27,15 @@ module Cauterize
27
27
  @type = BaseType.find_type!(type) if type
28
28
  @description = desc
29
29
  end
30
+
31
+ def field_hash(digest)
32
+ digest.update(@name.to_s)
33
+ if @type
34
+ @type.type_hash(digest)
35
+ else
36
+ digest
37
+ end
38
+ end
30
39
  end
31
40
 
32
41
  class Group < BaseType
@@ -59,5 +68,14 @@ module Cauterize
59
68
  def enum_sym(fname)
60
69
  "group_#{@name}_type_#{fname}".up_snake.to_sym
61
70
  end
71
+
72
+ protected
73
+
74
+ def local_hash(digest)
75
+ @tag_enum.type_hash(digest)
76
+ @fields.keys.inject(digest) {|d, k|
77
+ @fields[k].field_hash(digest)
78
+ }
79
+ end
62
80
  end
63
81
  end
@@ -20,6 +20,14 @@ module Cauterize
20
20
  f << "require_relative './cauterize_ruby_builtins'"
21
21
  f << ""
22
22
 
23
+ f << "CAUTERIZE_GEN_VERSION = \"#{Cauterize.get_version}\""
24
+ f << "CAUTERIZE_GEN_DATE = \"#{DateTime.now.to_s}\""
25
+ f << ""
26
+
27
+ f << "CAUTERIZE_MODEL_HASH_LEN = #{BaseType.digest_class.new.length}"
28
+ f << "CAUTERIZE_MODEL_HASH = [#{BaseType.model_hash.bytes.to_a.join(", ")}]"
29
+ f << ""
30
+
23
31
  instances = BaseType.all_instances
24
32
  builders = instances.map {|i| Builders.get(:ruby, i)}
25
33
  builders.each { |b| b.class_defn(f) }
@@ -43,5 +43,11 @@ module Cauterize
43
43
  @type_name
44
44
  end
45
45
  end
46
+
47
+ protected
48
+
49
+ def local_hash(digest)
50
+ @type_name.type_hash(digest)
51
+ end
46
52
  end
47
53
  end
@@ -52,5 +52,13 @@ module Cauterize
52
52
  @size_type
53
53
  end
54
54
  end
55
+
56
+ protected
57
+
58
+ def local_hash(digest)
59
+ digest.update(@array_size.to_s)
60
+ @array_type.type_hash(digest)
61
+ @size_type.type_hash(digest)
62
+ end
55
63
  end
56
64
  end
@@ -1,3 +1,3 @@
1
1
  module Cauterize
2
- VERSION = "0.0.1.pre9"
2
+ VERSION = "0.0.1.pre10"
3
3
  end
@@ -2,10 +2,6 @@ module Cauterize
2
2
 
3
3
  describe Cauterize do
4
4
  describe BaseType do
5
- describe :id do
6
- it { has_a_unique_id_for_each_instance(BaseType) }
7
- end
8
-
9
5
  describe :description do
10
6
  it "handles nil description" do
11
7
  BaseType.new(:foo, nil).description.should be_nil
@@ -16,62 +12,6 @@ module Cauterize
16
12
  end
17
13
  end
18
14
 
19
- describe :type_str do
20
- it "is the hexadecimal representation of type" do
21
- f = Cauterize.enumeration(:foo) do |e|
22
- e.value :a, 1
23
- end
24
-
25
- b = Cauterize.enumeration(:bar) do |e|
26
- e.value :a, 1
27
- end
28
-
29
- b.type_str.should == "0x2001"
30
- end
31
- end
32
-
33
- describe :tag do
34
- it { is_tagged_as(Scalar, 0) }
35
- it { is_tagged_as(Enumeration, 1) }
36
- it { is_tagged_as(Composite, 2) }
37
- it { is_tagged_as(FixedArray, 3) }
38
- it { is_tagged_as(VariableArray, 4) }
39
- it { is_tagged_as(Group, 5) }
40
- end
41
-
42
- describe :next_id do
43
- it "is an incrementing value starting at 0" do
44
- # the .new consumes the 0.
45
- BaseType.new(:foo).instance_exec do
46
- next_id.should == 1
47
- next_id.should == 2
48
- next_id.should == 3
49
- next_id.should == 4
50
- end
51
- end
52
-
53
- it "should not allow derived class ids to interact" do
54
- a1 = Scalar.new(:uint8_t)
55
- a2 = Scalar.new(:uint64_t)
56
- e1 = Enumeration.new(:zoop)
57
- e2 = Enumeration.new(:nih)
58
-
59
- a1.id.should == 0
60
- a2.id.should == 1
61
- e1.id.should == 0
62
- e2.id.should == 1
63
- end
64
- end
65
-
66
- describe "bit stuff" do
67
- it "is consistent" do
68
- BaseType.class_exec do
69
- (tag_bit_width + id_bit_width).should == type_bit_width
70
- (tag_bit_mask >> id_bit_width).should == 0x7
71
- end
72
- end
73
- end
74
-
75
15
  describe :register_instance do
76
16
  it "adds an instance to the instance list" do
77
17
  orig_len = BaseType.all_instances.length
@@ -122,6 +62,132 @@ module Cauterize
122
62
  end
123
63
  end
124
64
 
65
+ describe :type_hash do
66
+ it "is different for objects with different names" do
67
+ f = Cauterize.scalar(:foo) {|t| t.type_name :uint8}.type_hash
68
+ g = Cauterize.scalar(:bar) {|t| t.type_name :uint8}.type_hash
69
+
70
+ f.should_not == g
71
+ end
72
+
73
+ it "is different for objects with different types" do
74
+ f = Cauterize.scalar(:foo) {|t| t.type_name :uint8}.type_hash
75
+ reset_for_test
76
+
77
+ g = Cauterize.scalar(:foo) {|t| t.type_name :int8}.type_hash
78
+ reset_for_test
79
+
80
+ f.should_not == g
81
+ end
82
+
83
+ it "differes on enumeration value differences" do
84
+ f = Cauterize.enumeration(:foo) { |t| t.value :a, 0 }.type_hash
85
+ reset_for_test
86
+
87
+ g = Cauterize.enumeration(:foo) { |t| t.value :a, 1 }.type_hash
88
+ reset_for_test
89
+
90
+ f.should_not == g
91
+ end
92
+
93
+ it "differs on differing length in fixed arrays" do
94
+ f = Cauterize.fixed_array(:foo) { |t| t.array_type :int8; t.array_size 1 }.type_hash
95
+ reset_for_test
96
+
97
+ g = Cauterize.fixed_array(:foo) { |t| t.array_type :int8; t.array_size 2 }.type_hash
98
+ reset_for_test
99
+
100
+ f.should_not == g
101
+ end
102
+
103
+ it "differs on differing size type in variable arrays" do
104
+ f = Cauterize.variable_array(:foo) { |t| t.array_type :int8; t.array_size 2; t.size_type :uint8 }.type_hash
105
+ reset_for_test
106
+
107
+ g = Cauterize.variable_array(:foo) { |t| t.array_type :int8; t.array_size 2; t.size_type :uint16 }.type_hash
108
+ reset_for_test
109
+
110
+ f.should_not == g
111
+ end
112
+
113
+ it "differs on group field reordering" do
114
+ f = Cauterize.group(:foo) do |t|
115
+ t.field :a, :int8
116
+ t.field :b, :int8
117
+ end.type_hash
118
+ reset_for_test
119
+
120
+ g = Cauterize.group(:foo) do |t|
121
+ t.field :b, :int8
122
+ t.field :a, :int8
123
+ end.type_hash
124
+ reset_for_test
125
+
126
+ f.should_not == g
127
+ end
128
+
129
+ it "differs on composite field reordering" do
130
+ f = Cauterize.composite(:foo) do |t|
131
+ t.field :a, :int8
132
+ t.field :b, :int8
133
+ end.type_hash
134
+ reset_for_test
135
+
136
+ g = Cauterize.composite(:foo) do |t|
137
+ t.field :b, :int8
138
+ t.field :a, :int8
139
+ end.type_hash
140
+ reset_for_test
141
+
142
+ f.should_not == g
143
+ end
144
+
145
+ it "differs on changes in indirect fields" do
146
+ Cauterize.scalar(:a_thing) { |t| t.type_name :int8 }
147
+ f = Cauterize.composite(:foo) do |t|
148
+ t.field :a, :a_thing
149
+ end.type_hash
150
+ reset_for_test
151
+
152
+ Cauterize.scalar(:a_thing) { |t| t.type_name :uint8 }
153
+ g = Cauterize.composite(:foo) do |t|
154
+ t.field :a, :a_thing
155
+ end.type_hash
156
+ reset_for_test
157
+
158
+ f.should_not == g
159
+ end
160
+ end
161
+
162
+ describe :model_hash do
163
+ it "returns a SHA1 of the model" do
164
+ Cauterize.scalar(:foo) {|t| t.type_name :uint8}
165
+
166
+ h = BaseType.model_hash
167
+ h.should_not be_nil
168
+ h.length.should == 20 # length of sha1
169
+ end
170
+
171
+ it "is supported by all the types" do
172
+ gen_a_model
173
+ h = BaseType.model_hash
174
+ h.should_not be_nil
175
+ h.length.should == 20 # length of sha1
176
+ end
177
+
178
+ it "differs on different models" do
179
+ gen_a_model
180
+ a = BaseType.model_hash
181
+ reset_for_test
182
+
183
+ gen_b_model
184
+ b = BaseType.model_hash
185
+ reset_for_test
186
+
187
+ a.should_not == b
188
+ end
189
+ end
190
+
125
191
  describe :find_type do
126
192
  it "returns the instance with the provided name" do
127
193
  f = Cauterize.scalar(:foo)
data/spec/builtin_spec.rb CHANGED
@@ -14,13 +14,6 @@ module Cauterize
14
14
  end
15
15
 
16
16
  it { can_be_documented(BuiltIn) }
17
-
18
- describe :id do
19
- it "has a unique id for each builtin" do
20
- ids = Cauterize.builtins.values.map(&:id)
21
- ids.uniq.should =~ ids
22
- end
23
- end
24
17
  end
25
18
 
26
19
 
@@ -19,7 +19,6 @@ module Cauterize
19
19
  describe :initialize do
20
20
  it "Creates a fixed array." do
21
21
  @a.name.should == :foo
22
- @a.id.should_not be_nil
23
22
  end
24
23
  end
25
24
 
data/spec/scalar_spec.rb CHANGED
@@ -8,10 +8,6 @@ module Cauterize
8
8
 
9
9
  it { can_be_documented(Cauterize::Scalar) }
10
10
 
11
- describe :id do
12
- it { has_a_unique_id_for_each_instance(Scalar) }
13
- end
14
-
15
11
  describe :type_name do
16
12
  it "specifies the builtin type to alias" do
17
13
  s = Cauterize.scalar(:foo) do |t|
data/spec/spec_helper.rb CHANGED
@@ -43,12 +43,6 @@ module Cauterize
43
43
  cls.new(:foo).tag.should == tag
44
44
  end
45
45
 
46
- def has_a_unique_id_for_each_instance(cls)
47
- cls.new(:foo).id.should == 0
48
- cls.new(:bar).id.should == 1
49
- cls.new(:baz).id.should == 2
50
- end
51
-
52
46
  def creates_a_named_object(fn_sym, obj)
53
47
  fn = Cauterize.method(fn_sym)
54
48
  a = fn.call(:foo)
@@ -0,0 +1,76 @@
1
+ module Cauterize
2
+ module CauterizeHelpers
3
+ def gen_a_model
4
+ Cauterize.scalar(:foo) do |t|
5
+ t.type_name :uint8
6
+ end
7
+
8
+ Cauterize.enumeration(:color) do |e|
9
+ e.value :red
10
+ e.value :blue
11
+ e.value :green
12
+ end
13
+
14
+ Cauterize.fixed_array(:color_list) do |a|
15
+ a.array_type :color
16
+ a.array_size 41
17
+ end
18
+
19
+ Cauterize.variable_array(:int8_list) do |a|
20
+ a.size_type :uint8
21
+ a.array_type :int8
22
+ a.array_size 200
23
+ end
24
+
25
+ Cauterize.composite(:two_things) do |t|
26
+ t.field :thing_1, :uint8
27
+ t.field :thing_2, :uint16
28
+ end
29
+
30
+ Cauterize.group(:one_of_everything) do |t|
31
+ t.field :a_foo, :foo
32
+ t.field :a_color, :color
33
+ t.field :a_color_list, :color_list
34
+ t.field :an_int8_list, :int8_list
35
+ t.field :a_two_things, :two_things
36
+ end
37
+ end
38
+
39
+ def gen_b_model
40
+ Cauterize.scalar(:foo) do |t|
41
+ t.type_name :uint8
42
+ end
43
+
44
+ Cauterize.enumeration(:color) do |e|
45
+ e.value :red
46
+ e.value :blue
47
+ e.value :green
48
+ end
49
+
50
+ Cauterize.fixed_array(:color_list) do |a|
51
+ a.array_type :color
52
+ a.array_size 41
53
+ end
54
+
55
+ Cauterize.variable_array(:int8_list) do |a|
56
+ a.size_type :uint8
57
+ a.array_type :int8
58
+ a.array_size 200
59
+ end
60
+
61
+ Cauterize.composite(:two_things) do |t|
62
+ t.field :thing_1, :uint8
63
+ t.field :thing_2, :uint16
64
+ end
65
+
66
+ Cauterize.group(:one_of_everything) do |t|
67
+ t.field :a_foo, :foo
68
+ t.field :a_color, :color
69
+ t.field :a_color_list, :color_list
70
+ t.field :an_int8_list, :int8_list
71
+ t.field :a_two_things, :two_things
72
+ t.dataless :emptyness
73
+ end
74
+ end
75
+ end
76
+ end
@@ -6,6 +6,8 @@ namespace Cauterize
6
6
  public string Name;
7
7
  public string GeneratedVersion;
8
8
  public string GeneratedDate;
9
+ public int ModelHashLength;
10
+ public byte[] ModelHash;
9
11
  }
10
12
 
11
13
  public class CauterizeComposite
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cauterize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre9
4
+ version: 0.0.1.pre10
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-30 00:00:00.000000000 Z
12
+ date: 2013-07-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -212,6 +212,7 @@ files:
212
212
  - spec/support/shared_examples_for_c_buildables.rb
213
213
  - spec/support/shared_examples_for_sane_c_buildables.rb
214
214
  - spec/support/shared_examples_for_stubbed_functions.rb
215
+ - spec/support/spec_sample_model.rb
215
216
  - spec/test_main.c
216
217
  - spec/variable_array_spec.rb
217
218
  - support/c/src/cauterize.c
@@ -262,7 +263,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
262
263
  version: '0'
263
264
  segments:
264
265
  - 0
265
- hash: -966914952996441061
266
+ hash: 3445789086503525251
266
267
  required_rubygems_version: !ruby/object:Gem::Requirement
267
268
  none: false
268
269
  requirements:
@@ -310,5 +311,6 @@ test_files:
310
311
  - spec/support/shared_examples_for_c_buildables.rb
311
312
  - spec/support/shared_examples_for_sane_c_buildables.rb
312
313
  - spec/support/shared_examples_for_stubbed_functions.rb
314
+ - spec/support/spec_sample_model.rb
313
315
  - spec/test_main.c
314
316
  - spec/variable_array_spec.rb