cauterize 0.0.1.pre5 → 0.0.1.pre7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/README.md +9 -0
  2. data/Rakefile +1 -1
  3. data/bin/cauterize +1 -1
  4. data/cauterize.gemspec +1 -0
  5. data/example/Cauterize +15 -9
  6. data/example/build.sh +3 -0
  7. data/example/doc_cauterize_output/example_project.txt +124 -0
  8. data/example/ruby_ex.rb +14 -0
  9. data/lib/cauterize.rb +117 -0
  10. data/lib/cauterize/base_type.rb +3 -2
  11. data/lib/cauterize/builders.rb +18 -2
  12. data/lib/cauterize/builders/c/group.rb +2 -3
  13. data/lib/cauterize/builders/cs/group.rb +2 -3
  14. data/lib/cauterize/builders/doc/buildable.rb +30 -0
  15. data/lib/cauterize/builders/doc/builtin.rb +21 -0
  16. data/lib/cauterize/builders/doc/composite.rb +23 -0
  17. data/lib/cauterize/builders/doc/enumeration.rb +24 -0
  18. data/lib/cauterize/builders/doc/fixed_array.rb +26 -0
  19. data/lib/cauterize/builders/doc/group.rb +29 -0
  20. data/lib/cauterize/builders/doc/scalar.rb +21 -0
  21. data/lib/cauterize/builders/doc/variable_array.rb +26 -0
  22. data/lib/cauterize/builtin.rb +2 -2
  23. data/lib/cauterize/c_builder.rb +5 -0
  24. data/lib/cauterize/cauterize.rb +7 -2
  25. data/lib/cauterize/composite.rb +8 -7
  26. data/lib/cauterize/cs_builder.rb +8 -5
  27. data/lib/cauterize/doc_builder.rb +34 -0
  28. data/lib/cauterize/enumeration.rb +5 -5
  29. data/lib/cauterize/fixed_array.rb +3 -3
  30. data/lib/cauterize/group.rb +18 -8
  31. data/lib/cauterize/scalar.rb +3 -3
  32. data/lib/cauterize/variable_array.rb +3 -3
  33. data/lib/cauterize/version.rb +1 -1
  34. data/spec/base_type_spec.rb +10 -0
  35. data/spec/builders/c/group_spec.rb +2 -2
  36. data/spec/builders/cs/group_spec.rb +1 -1
  37. data/spec/builders/doc/buildable_spec.rb +25 -0
  38. data/spec/builders_spec.rb +4 -2
  39. data/spec/builtin_spec.rb +2 -0
  40. data/spec/c_builder_spec.rb +12 -3
  41. data/spec/composite_spec.rb +11 -0
  42. data/spec/cs_builder_spec.rb +6 -2
  43. data/spec/doc_builder_spec.rb +247 -0
  44. data/spec/enumeration_spec.rb +2 -0
  45. data/spec/fixed_array_spec.rb +2 -0
  46. data/spec/group_spec.rb +4 -2
  47. data/spec/scalar_spec.rb +2 -0
  48. data/spec/spec_helper.rb +4 -0
  49. data/support/c/src/cauterize.h +1 -1
  50. data/support/cs/src/CauterizeFormatter.cs +7 -5
  51. data/support/cs/src/CauterizeTypes.cs +45 -5
  52. metadata +50 -18
data/README.md CHANGED
@@ -148,3 +148,12 @@ group(:responses) do |g|
148
148
  c.field :delete_user, :delete_user_response
149
149
  end
150
150
  ```
151
+
152
+ Groups don't have to specify a data type in all of their fields.
153
+
154
+ ```ruby
155
+ group(:complex) do |g|
156
+ g.field :a_number, :int32
157
+ g.dataless :a_state # no associated data with this alternative
158
+ end
159
+ ```
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ task :greatest do
14
14
  test_suite_path = File.join(d, "test_suite.c")
15
15
  mk_test_suite_file(test_suite_path)
16
16
 
17
- args = "-Wall -Wextra -Werror -Isupport/c/test -Isupport/c/src -I#{d}"
17
+ args = "-pedantic -Wall -Wextra -Werror -std=c99 -Isupport/c/test -Isupport/c/src -I#{d}"
18
18
  srcs = "support/c/src/cauterize.c support/c/test/test.c"
19
19
  bin = File.join(d, "test.bin")
20
20
  sh "gcc #{args} #{srcs} -o #{bin}"
data/bin/cauterize CHANGED
@@ -30,7 +30,7 @@ class CauterizeCmdline < Thor
30
30
  end
31
31
 
32
32
  language = language.downcase
33
- if %w(c cs).include? language
33
+ if %w(c cs doc).include? language
34
34
  Cauterize.generate language, target_dir, desc_file
35
35
  else
36
36
  raise CmdLineException.new("Language '#{language}' is not supported.")
data/cauterize.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
20
20
  gem.add_dependency 'rake', '>= 0.9.2.0'
21
21
  gem.add_dependency 'thor', '>= 0.16.0'
22
22
  gem.add_dependency 'require_all', '>= 1.2.1'
23
+ gem.add_dependency 'bindata', '>= 1.5'
23
24
 
24
25
  gem.add_development_dependency 'rspec', '>= 2.12.0'
25
26
  gem.add_development_dependency 'mocha', '>= 0.13.0'
data/example/Cauterize CHANGED
@@ -15,21 +15,21 @@ enumeration(:large_value) do |e|
15
15
  e.value :positive, 500
16
16
  end
17
17
 
18
- composite(:weirdness) do |c|
19
- c.field :val, :large_value
20
- c.field :num, :int8
21
- end
22
-
23
18
  fixed_array(:color_list) do |a|
24
19
  a.array_type :color
25
- a.array_size 4
20
+ a.array_size 41
26
21
  end
27
22
 
23
+ composite(:weirdness) do |c|
24
+ c.field :val, :large_value
25
+ c.field :num, :int8
26
+ end
27
+
28
28
  fixed_array(:color_list_list) do |a|
29
29
  a.array_type :color_list
30
30
  a.array_size 4
31
31
  end
32
-
32
+
33
33
  variable_array(:numbers) do |a|
34
34
  a.size_type :usmallint
35
35
  a.array_type :bigint
@@ -51,6 +51,12 @@ end
51
51
  group(:insanity) do |g|
52
52
  g.field :nonsensical, :nonsensical
53
53
  g.field :crazy, :crazy
54
- g.field :any_empty_entry
55
- g.field :another_empty
54
+ g.dataless :any_empty_entry
55
+ g.dataless :another_empty
56
+ end
57
+
58
+ group(:wat) do |g|
59
+ g.field :arrrr, :color_list_list
60
+ g.field :coooo, :color
61
+ g.dataless :ohnoes
56
62
  end
data/example/build.sh CHANGED
@@ -1,5 +1,8 @@
1
1
  #!/bin/sh
2
2
 
3
+ rm -rf doc_cauterize_output
4
+ ../bin/cauterize generate doc doc_cauterize_output
5
+
3
6
  rm -rf c_cauterize_output
4
7
  ../bin/cauterize generate c c_cauterize_output
5
8
 
@@ -0,0 +1,124 @@
1
+ Type Name: int8
2
+ Cauterize Class: built-in
3
+ Description: <none>
4
+ data - size: 1 bytes
5
+
6
+ Type Name: int16
7
+ Cauterize Class: built-in
8
+ Description: <none>
9
+ data - size: 2 bytes
10
+
11
+ Type Name: int32
12
+ Cauterize Class: built-in
13
+ Description: <none>
14
+ data - size: 4 bytes
15
+
16
+ Type Name: int64
17
+ Cauterize Class: built-in
18
+ Description: <none>
19
+ data - size: 8 bytes
20
+
21
+ Type Name: uint8
22
+ Cauterize Class: built-in
23
+ Description: <none>
24
+ data - size: 1 bytes
25
+
26
+ Type Name: uint16
27
+ Cauterize Class: built-in
28
+ Description: <none>
29
+ data - size: 2 bytes
30
+
31
+ Type Name: uint32
32
+ Cauterize Class: built-in
33
+ Description: <none>
34
+ data - size: 4 bytes
35
+
36
+ Type Name: uint64
37
+ Cauterize Class: built-in
38
+ Description: <none>
39
+ data - size: 8 bytes
40
+
41
+ Type Name: bigint
42
+ Cauterize Class: scalar
43
+ Description: <none>
44
+ data - type: int32
45
+
46
+ Type Name: usmallint
47
+ Cauterize Class: scalar
48
+ Description: <none>
49
+ data - type: uint8
50
+
51
+ Type Name: color
52
+ Cauterize Class: enumeration
53
+ Description: <none>
54
+ Encoding: int8
55
+ red = 0
56
+ blue = 1
57
+ green = 2
58
+
59
+ Type Name: large_value
60
+ Cauterize Class: enumeration
61
+ Description: <none>
62
+ Encoding: int16
63
+ negative = -500
64
+ positive = 500
65
+
66
+ Type Name: weirdness
67
+ Cauterize Class: composite
68
+ Description: <none>
69
+ val - type: large_value
70
+ num - type: int8
71
+
72
+ Type Name: color_list
73
+ Cauterize Class: fixed-array
74
+ Description: <none>
75
+ Stored Type: color
76
+ Value Count: 4
77
+ data - 4 values of type color
78
+
79
+ Type Name: color_list_list
80
+ Cauterize Class: fixed-array
81
+ Description: <none>
82
+ Stored Type: color_list
83
+ Value Count: 4
84
+ data - 4 values of type color_list
85
+
86
+ Type Name: numbers
87
+ Cauterize Class: variable-array
88
+ Description: <none>
89
+ Maximum Value Count: 128
90
+ length - type usmallint
91
+ data - 0 to 128 values of type bigint
92
+
93
+ Type Name: nonsensical
94
+ Cauterize Class: composite
95
+ Description: <none>
96
+ color - type: color
97
+ color_list - type: color_list
98
+ numbers - type: numbers
99
+
100
+ Type Name: crazy
101
+ Cauterize Class: composite
102
+ Description: <none>
103
+ first_numbers - type: numbers
104
+ second_numbers - type: numbers
105
+ third_numbers - type: numbers
106
+
107
+ Type Name: insanity
108
+ Cauterize Class: group
109
+ Description: <none>
110
+ kind tag: group_insanity_type
111
+ kinds:
112
+ nonsensical - payload: nonsensical
113
+ crazy - payload: crazy
114
+ any_empty_entry - payload: <no payload>
115
+ another_empty - payload: <no payload>
116
+
117
+ Type Name: group_insanity_type
118
+ Cauterize Class: enumeration
119
+ Description: <none>
120
+ Encoding: int8
121
+ GROUP_INSANITY_TYPE_NONSENSICAL = 0
122
+ GROUP_INSANITY_TYPE_CRAZY = 1
123
+ GROUP_INSANITY_TYPE_ANY_EMPTY_ENTRY = 2
124
+ GROUP_INSANITY_TYPE_ANOTHER_EMPTY = 3
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "../lib")
2
+ require 'cauterize'
3
+ require 'bindata'
4
+
5
+
6
+ Cauterize.populate(ARGV[0])
7
+
8
+ i = Cauterize::ExampleProject::Wat.new
9
+ i.tag.representation = 0
10
+ p i.num_bytes
11
+ i.tag.representation = 1
12
+ p i.num_bytes
13
+ i.tag.representation = 2
14
+ p i.num_bytes
data/lib/cauterize.rb ADDED
@@ -0,0 +1,117 @@
1
+ require 'bindata'
2
+ require 'cauterize/snake_case'
3
+ require 'cauterize/base_type'
4
+ require 'cauterize/cauterize'
5
+
6
+ def fix(s)
7
+ s.gsub(/([[:alpha:]])_([[:digit:]])/) do |m|
8
+ $1 + $2
9
+ end
10
+ end
11
+
12
+
13
+ def populate_scalar(klass, inst)
14
+ klass.class_eval do
15
+ endian :little
16
+ send(fix(inst.type_name.name.to_s), :data)
17
+ end
18
+ end
19
+
20
+ def populate_enum(klass, inst)
21
+ klass.class_eval do
22
+ endian :little
23
+
24
+ send(fix(inst.representation.name.to_s), :representation)
25
+
26
+ enum_vals = inst.values.values.map {|v| [v.value, v.name.to_sym]}
27
+ enum_hash = Hash[enum_vals]
28
+ const_set(:ENUM_MAP, enum_hash)
29
+ inst.values.values.each do |v|
30
+ klass.const_set(v.name.upcase.to_sym, v.value)
31
+ end
32
+
33
+ def enum
34
+ self.class.const_get(:ENUM_MAP)[representation]
35
+ end
36
+ end
37
+ end
38
+
39
+ def populate_fixed_array(klass, inst)
40
+ klass.class_eval do
41
+ endian :little
42
+ array :data, { :type => fix(inst.array_type.name.to_s),
43
+ :initial_length => inst.array_size }
44
+ end
45
+ end
46
+
47
+ def populate_variable_array(klass, inst)
48
+ # TODO: Figure out what we should do with inst.array_size
49
+ klass.class_eval do
50
+ endian :little
51
+ send(fix(inst.size_type.name.to_s), :va_len, :value => lambda { data.length })
52
+ array :data, { :type => fix(inst.array_type.name.to_s),
53
+ :read_until => lambda { index == va_len - 1}}
54
+ end
55
+ end
56
+
57
+ def populate_composite(klass, inst)
58
+ klass.class_eval do
59
+ endian :little
60
+ inst.fields.values.each do |v|
61
+ send(fix(v.type.name.to_s), v.name.to_s)
62
+ end
63
+ end
64
+ end
65
+
66
+ def populate_group(klass, inst)
67
+ choices = inst.fields.values.each_with_index.map do |v, i|
68
+ [i, v.type.nil? ? :empty_data : fix(v.type.name.to_s).to_sym]
69
+ end
70
+
71
+ klass.class_eval do
72
+ endian :little
73
+ send(fix(inst.tag_enum.name.to_s), :tag)
74
+
75
+ choice :data, :selection => lambda { tag.representation },
76
+ :choices => Hash[choices]
77
+ end
78
+ end
79
+
80
+ module Cauterize
81
+ class EmptyData < BinData::Record; end
82
+
83
+ def self.populate(desc_file)
84
+ parse_dsl(desc_file)
85
+
86
+ dsl_mod = Module.new do |mod|
87
+
88
+ BaseType.all_instances.each do |inst|
89
+ next if Cauterize::BuiltIn == inst.class
90
+
91
+ n = inst.name.to_s.camel
92
+ module_eval("class #{n} < BinData::Record; end")
93
+ klass = const_get(n)
94
+
95
+ case inst
96
+ when Cauterize::Scalar
97
+ populate_scalar(klass, inst)
98
+ when Cauterize::Enumeration
99
+ populate_enum(klass, inst)
100
+ when Cauterize::FixedArray
101
+ populate_fixed_array(klass, inst)
102
+ when Cauterize::VariableArray
103
+ populate_variable_array(klass, inst)
104
+ when Cauterize::Composite
105
+ populate_composite(klass, inst)
106
+ when Cauterize::Group
107
+ populate_group(klass, inst)
108
+ else
109
+ puts "Unhandled instance: #{inst.class.name}"
110
+ end
111
+ end
112
+ end
113
+
114
+ const_set(Cauterize.get_name.camel, dsl_mod)
115
+ end
116
+ end
117
+
@@ -2,16 +2,17 @@ require 'set'
2
2
 
3
3
  module Cauterize
4
4
  class BaseType
5
- attr_reader :name, :id
5
+ attr_reader :name, :id, :description
6
6
  @@next_id = {}
7
7
  @@instances = {}
8
8
 
9
- def initialize(name)
9
+ def initialize(name, description=nil)
10
10
  if @@instances.keys.include?(name)
11
11
  raise Exception.new("A type with the name #{name} already exists. [#{@@instances[name].inspect}]")
12
12
  end
13
13
 
14
14
  @name = name
15
+ @description = description
15
16
  @id = next_id
16
17
  register_instance(self)
17
18
  end
@@ -5,6 +5,10 @@ module Cauterize
5
5
 
6
6
  module_function
7
7
 
8
+ def builders
9
+ @builders
10
+ end
11
+
8
12
  def register(language, description_class, builder_class)
9
13
  @builders ||= {}
10
14
  @builders[language] ||= {}
@@ -17,9 +21,21 @@ module Cauterize
17
21
  end
18
22
 
19
23
  def get(language, description_instance)
20
- if @builders and @builders[language] and @builders[language][description_instance.class]
21
- @builders[language][description_instance.class].new(description_instance)
24
+ unless @builders
25
+ raise UnregisteredException.new("No builders are registered.")
26
+ end
27
+
28
+ unless @builders[language]
29
+ s = "Language #{language} not registered."
30
+ raise UnregisteredException.new(s)
22
31
  end
32
+
33
+ unless @builders[language][description_instance.class]
34
+ s = "Class #{description_instance.class} not registered for #{language}."
35
+ raise UnregisteredException.new(s)
36
+ end
37
+
38
+ @builders[language][description_instance.class].new(description_instance)
23
39
  end
24
40
  end
25
41
  end
@@ -84,9 +84,8 @@ module Cauterize
84
84
  formatter << "union"
85
85
  formatter.braces do
86
86
  @blueprint.fields.values.each do |field|
87
- b = Builders.get(:c, field.type)
88
- if b
89
- b.declare(formatter, field.name)
87
+ if field.type
88
+ Builders.get(:c, field.type).declare(formatter, field.name)
90
89
  else
91
90
  formatter << "/* No data associated with '#{field.name}'. */"
92
91
  end
@@ -16,10 +16,9 @@ module Cauterize::Builders::CS
16
16
  Cauterize::Builders.get(:cs, @tag_enum).declare(formatter, "Type")
17
17
  formatter.blank_line
18
18
  @blueprint.fields.values.each_with_index do |field, i|
19
- b = Cauterize::Builders.get(:cs, field.type)
20
- if b
19
+ if field.type
21
20
  formatter << "[Order(#{i+1})]"
22
- b.declare(formatter, field.name)
21
+ Cauterize::Builders.get(:cs, field.type).declare(formatter, field.name)
23
22
  else
24
23
  formatter << "/* No data associated with '#{field.name}'. */"
25
24
  end
@@ -0,0 +1,30 @@
1
+ module Cauterize
2
+ module Builders
3
+ module Doc
4
+ REQUIRED_METHODS = [
5
+ :heading,
6
+ :body,
7
+ ]
8
+
9
+ class BuildableException < Exception; end
10
+
11
+ class Buildable
12
+ def initialize(blueprint)
13
+ @blueprint = blueprint
14
+ end
15
+
16
+ alias_method :orig_method_missing, :method_missing
17
+
18
+ def method_missing(sym, *args)
19
+ sym_required = REQUIRED_METHODS.include?(sym)
20
+
21
+ if sym_required
22
+ raise BuildableException.new("Classes deriving Buildable must implement the method #{sym}.")
23
+ else
24
+ orig_method_missing(sym, *args)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end