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.
- data/README.md +9 -0
- data/Rakefile +1 -1
- data/bin/cauterize +1 -1
- data/cauterize.gemspec +1 -0
- data/example/Cauterize +15 -9
- data/example/build.sh +3 -0
- data/example/doc_cauterize_output/example_project.txt +124 -0
- data/example/ruby_ex.rb +14 -0
- data/lib/cauterize.rb +117 -0
- data/lib/cauterize/base_type.rb +3 -2
- data/lib/cauterize/builders.rb +18 -2
- data/lib/cauterize/builders/c/group.rb +2 -3
- data/lib/cauterize/builders/cs/group.rb +2 -3
- data/lib/cauterize/builders/doc/buildable.rb +30 -0
- data/lib/cauterize/builders/doc/builtin.rb +21 -0
- data/lib/cauterize/builders/doc/composite.rb +23 -0
- data/lib/cauterize/builders/doc/enumeration.rb +24 -0
- data/lib/cauterize/builders/doc/fixed_array.rb +26 -0
- data/lib/cauterize/builders/doc/group.rb +29 -0
- data/lib/cauterize/builders/doc/scalar.rb +21 -0
- data/lib/cauterize/builders/doc/variable_array.rb +26 -0
- data/lib/cauterize/builtin.rb +2 -2
- data/lib/cauterize/c_builder.rb +5 -0
- data/lib/cauterize/cauterize.rb +7 -2
- data/lib/cauterize/composite.rb +8 -7
- data/lib/cauterize/cs_builder.rb +8 -5
- data/lib/cauterize/doc_builder.rb +34 -0
- data/lib/cauterize/enumeration.rb +5 -5
- data/lib/cauterize/fixed_array.rb +3 -3
- data/lib/cauterize/group.rb +18 -8
- data/lib/cauterize/scalar.rb +3 -3
- data/lib/cauterize/variable_array.rb +3 -3
- data/lib/cauterize/version.rb +1 -1
- data/spec/base_type_spec.rb +10 -0
- data/spec/builders/c/group_spec.rb +2 -2
- data/spec/builders/cs/group_spec.rb +1 -1
- data/spec/builders/doc/buildable_spec.rb +25 -0
- data/spec/builders_spec.rb +4 -2
- data/spec/builtin_spec.rb +2 -0
- data/spec/c_builder_spec.rb +12 -3
- data/spec/composite_spec.rb +11 -0
- data/spec/cs_builder_spec.rb +6 -2
- data/spec/doc_builder_spec.rb +247 -0
- data/spec/enumeration_spec.rb +2 -0
- data/spec/fixed_array_spec.rb +2 -0
- data/spec/group_spec.rb +4 -2
- data/spec/scalar_spec.rb +2 -0
- data/spec/spec_helper.rb +4 -0
- data/support/c/src/cauterize.h +1 -1
- data/support/cs/src/CauterizeFormatter.cs +7 -5
- data/support/cs/src/CauterizeTypes.cs +45 -5
- 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
|
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.
|
55
|
-
g.
|
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
@@ -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
|
data/example/ruby_ex.rb
ADDED
@@ -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
|
+
|
data/lib/cauterize/base_type.rb
CHANGED
@@ -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
|
data/lib/cauterize/builders.rb
CHANGED
@@ -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
|
-
|
21
|
-
|
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
|
-
|
88
|
-
|
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
|
-
|
20
|
-
if b
|
19
|
+
if field.type
|
21
20
|
formatter << "[Order(#{i+1})]"
|
22
|
-
|
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
|