cauterize 0.0.1.pre5 → 0.0.1.pre7

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 (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