ridl 2.2.4
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.
- checksums.yaml +7 -0
- data/LICENSE +49 -0
- data/README.rdoc +42 -0
- data/lib/idl/BiDirPolicy.pidl +28 -0
- data/lib/idl/CosNaming.idl +260 -0
- data/lib/idl/IOP.pidl +98 -0
- data/lib/idl/Messaging.pidl +152 -0
- data/lib/idl/PortableServer.pidl +371 -0
- data/lib/idl/TimeBase.pidl +40 -0
- data/lib/idl/orb.idl +200 -0
- data/lib/ridl/backend.rb +124 -0
- data/lib/ridl/delegate.rb +740 -0
- data/lib/ridl/expression.rb +276 -0
- data/lib/ridl/genfile.rb +220 -0
- data/lib/ridl/node.rb +2818 -0
- data/lib/ridl/optparse_ext.rb +357 -0
- data/lib/ridl/parser.diff +42 -0
- data/lib/ridl/parser.rb +3836 -0
- data/lib/ridl/parser.ry +933 -0
- data/lib/ridl/require.rb +18 -0
- data/lib/ridl/ridl.rb +44 -0
- data/lib/ridl/runner.rb +304 -0
- data/lib/ridl/scanner.rb +1238 -0
- data/lib/ridl/type.rb +507 -0
- data/lib/ridl/version.rb +22 -0
- metadata +74 -0
@@ -0,0 +1,276 @@
|
|
1
|
+
#--------------------------------------------------------------------
|
2
|
+
# expression.rb - IDL Expression classes
|
3
|
+
#
|
4
|
+
# Author: Martin Corino
|
5
|
+
#
|
6
|
+
# This program is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the RIDL LICENSE which is
|
8
|
+
# included with this program.
|
9
|
+
#
|
10
|
+
# Copyright (c) Remedy IT Expertise BV
|
11
|
+
# Chamber of commerce Rotterdam nr.276339, The Netherlands
|
12
|
+
#--------------------------------------------------------------------
|
13
|
+
require 'ridl/node'
|
14
|
+
|
15
|
+
module IDL
|
16
|
+
class Expression
|
17
|
+
attr_reader :idltype
|
18
|
+
attr_reader :value
|
19
|
+
def typename; @idltype.typename; end
|
20
|
+
|
21
|
+
def is_template?
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
def instantiate(_context)
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
class Value < Expression
|
30
|
+
def initialize(type, val)
|
31
|
+
@idltype = type
|
32
|
+
@value = @idltype.narrow(val)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class ScopedName < Expression
|
37
|
+
attr_reader :node
|
38
|
+
def initialize(node)
|
39
|
+
if $DEBUG
|
40
|
+
unless IDL::AST::Const === node || (IDL::AST::TemplateParam === node && node.idltype.is_a?(IDL::Type::Const))
|
41
|
+
raise RuntimeError,
|
42
|
+
"#{node.scoped_name} must be constant: #{node.class.name}."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
@node = node
|
46
|
+
@idltype = node.idltype
|
47
|
+
@value = @idltype.narrow(node.value) unless node.is_template?
|
48
|
+
end
|
49
|
+
def is_template?
|
50
|
+
@node.is_template?
|
51
|
+
end
|
52
|
+
def instantiate(_context)
|
53
|
+
if self.is_template?
|
54
|
+
cp = IDL::AST::TemplateParam.concrete_param(_context, @node)
|
55
|
+
cp.is_a?(Expression) ? cp : ScopedName.new(cp)
|
56
|
+
else
|
57
|
+
self
|
58
|
+
end
|
59
|
+
end
|
60
|
+
def is_node?(node_class)
|
61
|
+
@node.is_a?(node_class)
|
62
|
+
end
|
63
|
+
def resolved_node
|
64
|
+
@node
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Enumerator < Expression
|
69
|
+
attr_reader :node
|
70
|
+
def initialize(node)
|
71
|
+
if $DEBUG
|
72
|
+
if not IDL::AST::Enumerator === node
|
73
|
+
raise RuntimeError,
|
74
|
+
"#{node.scoped_name} must be enumerator: #{node.class.name}."
|
75
|
+
end
|
76
|
+
end
|
77
|
+
@node = node
|
78
|
+
@idltype = node.idltype
|
79
|
+
@value = node.value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class Operation < Expression
|
84
|
+
NUMBER_OF_OPERANDS = nil
|
85
|
+
|
86
|
+
attr_reader :operands
|
87
|
+
def initialize(*_operands)
|
88
|
+
n = self.class::NUMBER_OF_OPERANDS
|
89
|
+
|
90
|
+
if _operands.size != n
|
91
|
+
raise RuntimeError,
|
92
|
+
format("%s must receive %d operand%s.",
|
93
|
+
self.typename, n, if (n>1) then "s" else "" end)
|
94
|
+
end
|
95
|
+
|
96
|
+
unless _operands.any? { |o| o.is_template? }
|
97
|
+
@idltype = self.class.suite_type(*(_operands.collect{|o| o.idltype.resolved_type}))
|
98
|
+
@value = calculate(*(_operands.collect{|o| o.value}))
|
99
|
+
else
|
100
|
+
@idltype = nil
|
101
|
+
@value = nil
|
102
|
+
end
|
103
|
+
@operands = _operands
|
104
|
+
self.set_type
|
105
|
+
end
|
106
|
+
|
107
|
+
def is_template?
|
108
|
+
@operands.any? { |o| o.is_template? }
|
109
|
+
end
|
110
|
+
|
111
|
+
def instantiate(_context)
|
112
|
+
self.is_template? ? self.class.new(*@operands.collect { |o| o.instantiate(_context) }) : self
|
113
|
+
end
|
114
|
+
|
115
|
+
def Operation.suite_type(*types)
|
116
|
+
types.each do |t|
|
117
|
+
if not self::Applicable.include? t.class
|
118
|
+
raise RuntimeError,
|
119
|
+
"#{self.name} cannot be applicable for #{t.typename}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
ret = nil
|
124
|
+
types = types.collect {|t| t.class }
|
125
|
+
self::Applicable.each do |t|
|
126
|
+
if types.include? t
|
127
|
+
ret = t
|
128
|
+
break
|
129
|
+
end
|
130
|
+
end
|
131
|
+
ret
|
132
|
+
end
|
133
|
+
def set_type
|
134
|
+
end
|
135
|
+
|
136
|
+
class Unary < Operation
|
137
|
+
NUMBER_OF_OPERANDS = 1
|
138
|
+
Applicable = nil
|
139
|
+
end #of class Unary
|
140
|
+
|
141
|
+
class Integer2 < Operation
|
142
|
+
NUMBER_OF_OPERANDS = 2
|
143
|
+
Applicable = [
|
144
|
+
IDL::Type::LongLong, IDL::Type::ULongLong,
|
145
|
+
IDL::Type::Long, IDL::Type::ULong,
|
146
|
+
IDL::Type::Short, IDL::Type::UShort,
|
147
|
+
IDL::Type::Octet
|
148
|
+
]
|
149
|
+
|
150
|
+
def Integer2.suite_sign(_t, _v)
|
151
|
+
[ [IDL::Type::LongLong, IDL::Type::ULongLong],
|
152
|
+
[IDL::Type::Long, IDL::Type::ULong],
|
153
|
+
[IDL::Type::Short, IDL::Type::UShort]
|
154
|
+
].each do |t|
|
155
|
+
next unless t.include? _t
|
156
|
+
return (if _v < 0 then t[0] else t[1] end)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def set_type
|
161
|
+
if Integer2::Applicable.include? @idltype
|
162
|
+
@idltype = self.class.suite_sign(@idltype, @value)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class Boolean2 < Integer2
|
168
|
+
Applicable = [
|
169
|
+
IDL::Type::Boolean
|
170
|
+
] + Integer2::Applicable
|
171
|
+
|
172
|
+
def Boolean2.checktype(t1, t2)
|
173
|
+
superclass.checktype(*types)
|
174
|
+
|
175
|
+
t = IDL::Type::Boolean
|
176
|
+
if (t1 == t && t2 != t) or (t1 != t && t2 == t)
|
177
|
+
raise RuntimeError,
|
178
|
+
"#{self.name} about #{t1.typename} and #{t2.typename} is illegal."
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
class Float2 < Integer2
|
184
|
+
Applicable = [
|
185
|
+
IDL::Type::LongDouble, IDL::Type::Double, IDL::Type::Float,
|
186
|
+
IDL::Type::Fixed
|
187
|
+
] + Integer2::Applicable
|
188
|
+
|
189
|
+
def Float2.checktype(t1, t2)
|
190
|
+
superclass.checktype(*types)
|
191
|
+
|
192
|
+
# it's expected that Double, LongDouble is a Float.
|
193
|
+
s1,s2 = IDL::Type::Float, IDL::Type::Fixed
|
194
|
+
if (t1 === s1 && t2 === s2) or (t1 === s2 && t2 === s1)
|
195
|
+
raise RuntimeError,
|
196
|
+
"#{self.name} about #{t1.typename} and #{t2.typename} is illegal."
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
class UnaryPlus < Unary
|
202
|
+
Applicable = Float2::Applicable
|
203
|
+
def calculate(op)
|
204
|
+
op
|
205
|
+
end
|
206
|
+
end
|
207
|
+
class UnaryMinus < Unary
|
208
|
+
Applicable = Float2::Applicable
|
209
|
+
def calculate(op)
|
210
|
+
-op
|
211
|
+
end
|
212
|
+
def set_type
|
213
|
+
@idltype = Integer2.suite_sign(@idltype, @value)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
class UnaryNot < Unary
|
217
|
+
Applicable = Integer2::Applicable
|
218
|
+
def calculate(op)
|
219
|
+
if @idltype.is_unsigned?()
|
220
|
+
(2**@idltype.bits-1)-op
|
221
|
+
else
|
222
|
+
~op
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
class Or < Boolean2
|
228
|
+
def calculate(lop,rop); lop | rop; end
|
229
|
+
end
|
230
|
+
class And < Boolean2
|
231
|
+
def calculate(lop,rop); lop & rop; end
|
232
|
+
end
|
233
|
+
class Xor < Boolean2
|
234
|
+
def calculate(lop,rop); lop ^ rop; end
|
235
|
+
end
|
236
|
+
|
237
|
+
class Shift < Integer2
|
238
|
+
protected
|
239
|
+
def check_rop(rop)
|
240
|
+
if not (0...64) === rop
|
241
|
+
raise RuntimeError,
|
242
|
+
"right operand for shift must be in the range 0 <= right operand < 64: #{rop}."
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
class LShift < Shift
|
247
|
+
def calculate(lop,rop)
|
248
|
+
check_rop(rop)
|
249
|
+
lop << rop
|
250
|
+
end
|
251
|
+
end
|
252
|
+
class RShift < Shift
|
253
|
+
def calculate(lop,rop)
|
254
|
+
check_rop(rop)
|
255
|
+
lop >> rop
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
class Add < Float2
|
260
|
+
def calculate(lop,rop); lop + rop; end
|
261
|
+
end
|
262
|
+
class Minus < Float2
|
263
|
+
def calculate(lop,rop); lop - rop; end
|
264
|
+
end
|
265
|
+
class Mult < Float2
|
266
|
+
def calculate(lop,rop); lop * rop; end
|
267
|
+
end
|
268
|
+
class Div < Float2
|
269
|
+
def calculate(lop,rop); lop / rop; end
|
270
|
+
end
|
271
|
+
class Mod < Integer2
|
272
|
+
def calculate(lop,rop); lop % rop; end
|
273
|
+
end
|
274
|
+
end #of class Operation
|
275
|
+
end #of class Expression
|
276
|
+
end
|
data/lib/ridl/genfile.rb
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
#--------------------------------------------------------------------
|
2
|
+
# genfile.rb - Generator file class implementation.
|
3
|
+
#
|
4
|
+
# Author: Martin Corino
|
5
|
+
#
|
6
|
+
# This program is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the RIDL LICENSE which is
|
8
|
+
# included with this program.
|
9
|
+
#
|
10
|
+
# Copyright (c) Remedy IT Expertise BV
|
11
|
+
# Chamber of commerce Rotterdam nr.276339, The Netherlands
|
12
|
+
#--------------------------------------------------------------------
|
13
|
+
require 'tempfile'
|
14
|
+
require 'fileutils'
|
15
|
+
|
16
|
+
module IDL
|
17
|
+
|
18
|
+
class GenFile
|
19
|
+
|
20
|
+
@@stack = []
|
21
|
+
@@cur_trans = nil
|
22
|
+
|
23
|
+
def self.transaction(&block)
|
24
|
+
@@cur_trans = []
|
25
|
+
@@stack << @@cur_trans
|
26
|
+
begin
|
27
|
+
block.call if block_given?
|
28
|
+
@@cur_trans.each {|fgen| fgen.save }
|
29
|
+
@@cur_trans.clear
|
30
|
+
ensure
|
31
|
+
self.rollback # after successful transaction should be nothing left
|
32
|
+
@@stack.pop
|
33
|
+
@@cur_trans = @@stack.last
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.rollback
|
38
|
+
if @@cur_trans
|
39
|
+
@@cur_trans.each {|fgen| fgen.remove }
|
40
|
+
@@cur_trans.clear
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Content
|
45
|
+
def initialize(sections = {})
|
46
|
+
# copy content map transforming all keys to symbols
|
47
|
+
@sections = sections.inject({}) {|m,(k,v)| m[k.to_sym] = v; m }
|
48
|
+
end
|
49
|
+
|
50
|
+
def sections
|
51
|
+
@sections.keys
|
52
|
+
end
|
53
|
+
|
54
|
+
def has_section?(sectionid)
|
55
|
+
@sections.has_key?((sectionid || '').to_sym)
|
56
|
+
end
|
57
|
+
|
58
|
+
def [](sectionid)
|
59
|
+
@sections[(sectionid || '').to_sym]
|
60
|
+
end
|
61
|
+
|
62
|
+
def each(&block)
|
63
|
+
@sections.each(&block)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
REGEN_MARKER_DEFAULT = '@@{__RIDL_REGEN_MARKER__}'
|
68
|
+
|
69
|
+
attr_reader :path, :fullpath, :name, :ext, :content
|
70
|
+
|
71
|
+
def initialize(path, opts = {})
|
72
|
+
if path
|
73
|
+
@path = path
|
74
|
+
@fullpath = File.expand_path(path)
|
75
|
+
@name = File.basename(path)
|
76
|
+
@ext = File.extname(path).sub(/^\./,'')
|
77
|
+
else
|
78
|
+
@path = @fullpath = @name = @ext = ''
|
79
|
+
end
|
80
|
+
@options = {
|
81
|
+
:regenerate => false,
|
82
|
+
:regen_marker_prefix => '//',
|
83
|
+
:regen_marker_postfix => nil,
|
84
|
+
:regen_marker => REGEN_MARKER_DEFAULT,
|
85
|
+
:regen_keep_header => false,
|
86
|
+
:output_file => nil
|
87
|
+
}.merge(opts)
|
88
|
+
if @options[:regenerate] && File.exists?(@fullpath)
|
89
|
+
parse_regeneration_content
|
90
|
+
else
|
91
|
+
@content = Content.new
|
92
|
+
end
|
93
|
+
@fout = @options[:output_file] || Tempfile.new(@name)
|
94
|
+
@@cur_trans << self
|
95
|
+
end
|
96
|
+
|
97
|
+
def <<(txt)
|
98
|
+
@fout << txt if @fout
|
99
|
+
self
|
100
|
+
end
|
101
|
+
|
102
|
+
def regen_start_marker(sectionid)
|
103
|
+
"#{@options[:regen_marker_prefix]}#{@options[:regen_marker]} - BEGIN : #{sectionid}#{@options[:regen_marker_postfix]}"
|
104
|
+
end
|
105
|
+
|
106
|
+
def regen_end_marker(sectionid)
|
107
|
+
"#{@options[:regen_marker_prefix]}#{@options[:regen_marker]} - END : #{sectionid}#{@options[:regen_marker_postfix]}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def regen_header_end_marker(sectionid)
|
111
|
+
"#{@options[:regen_marker_prefix]}#{@options[:regen_marker]} - HEADER_END : #{sectionid}#{@options[:regen_marker_postfix]}"
|
112
|
+
end
|
113
|
+
|
114
|
+
def write_regen_section(sectionid, default_content, indent = '', options = {})
|
115
|
+
self << indent << regen_start_marker(sectionid) << "\n" unless options[:header]
|
116
|
+
if content.has_section?(sectionid)
|
117
|
+
self << content[sectionid].join unless content[sectionid].empty?
|
118
|
+
else
|
119
|
+
default_content = (Array === default_content) ? default_content : default_content.to_s.split("\n")
|
120
|
+
self << (default_content.collect {|l| (s = indent.dup) << l << "\n"; s }.join) unless default_content.empty?
|
121
|
+
end
|
122
|
+
if options[:header]
|
123
|
+
self << indent << regen_header_end_marker(sectionid) << "\n"
|
124
|
+
else
|
125
|
+
self << indent << regen_end_marker(sectionid) << "\n" unless options[:footer]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def save
|
130
|
+
return if @options[:output_file]
|
131
|
+
if @fout
|
132
|
+
fgen = @fout
|
133
|
+
@fout = nil
|
134
|
+
fgen.close(false) # close but do NOT unlink
|
135
|
+
if File.exists?(@fullpath)
|
136
|
+
# create temporary backup
|
137
|
+
ftmp = Tempfile.new(@name)
|
138
|
+
ftmp_name = ftmp.path.dup
|
139
|
+
ftmp.close(true) # close AND unlink
|
140
|
+
FileUtils::mv(@fullpath, ftmp_name) # backup existing file
|
141
|
+
# replace original
|
142
|
+
begin
|
143
|
+
# rename newly generated file
|
144
|
+
FileUtils::mv(fgen.path, @fullpath)
|
145
|
+
# preserve file mode
|
146
|
+
FileUtils::chmod(File.lstat(ftmp_name).mode, @fullpath)
|
147
|
+
rescue
|
148
|
+
IDL.log(0, %Q{ERROR: FAILED updating #{@path}: #{$!}})
|
149
|
+
# restore backup
|
150
|
+
FileUtils::mv(ftmp_name, @fullpath)
|
151
|
+
raise
|
152
|
+
end
|
153
|
+
# remove backup
|
154
|
+
File.unlink(ftmp_name)
|
155
|
+
else
|
156
|
+
# just rename newly generated file
|
157
|
+
FileUtils::mv(fgen.path, @fullpath)
|
158
|
+
# set default mode for new files
|
159
|
+
FileUtils::chmod(0666 - File.umask, @fullpath)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def remove
|
165
|
+
return if @options[:output_file]
|
166
|
+
if @fout
|
167
|
+
begin
|
168
|
+
@fout.close(true)
|
169
|
+
rescue
|
170
|
+
IDL.log(0, %Q{ERROR: FAILED to clean up temp file #{@fout.path}: #{$!}})
|
171
|
+
end
|
172
|
+
@fout = nil
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
def parse_regeneration_content
|
179
|
+
markers_sel = %w{BEGIN END}
|
180
|
+
_keep_header = (@options[:regen_keep_header] == true)
|
181
|
+
markers_sel << 'HEADER_END' if _keep_header
|
182
|
+
regen_marker_re = /#{@options[:regen_marker]}\s+[-]\s+(#{markers_sel.join('|')})\s+:\s+(.+)/
|
183
|
+
sections = {}
|
184
|
+
section = []
|
185
|
+
in_section = _keep_header ? ['HEADER', 0] : nil
|
186
|
+
linenr = 0
|
187
|
+
File.open(@fullpath) do |fio|
|
188
|
+
fio.each do |line|
|
189
|
+
linenr += 1
|
190
|
+
if regen_marker_re =~ line
|
191
|
+
case $1
|
192
|
+
when 'BEGIN'
|
193
|
+
raise RuntimeError, "ERROR: Found unterminated regeneration section starting at #{@path}:#{in_section.last}." if in_section
|
194
|
+
in_section = [$2, linenr]
|
195
|
+
section = []
|
196
|
+
when 'END'
|
197
|
+
raise RuntimeError, "ERROR: Found unmatched regeneration end at #{@path}:#{linenr}." unless in_section && ($2 == in_section.first)
|
198
|
+
sections[$2] = section
|
199
|
+
in_section = nil
|
200
|
+
section = []
|
201
|
+
when 'HEADER_END'
|
202
|
+
raise RuntimeError, "ERROR: Found illegal header end marker at #{@path}:#{linenr}." unless _keep_header && in_section &&
|
203
|
+
('HEADER' == in_section.first ) && (0 == in_section.last)
|
204
|
+
sections[$2] = section
|
205
|
+
in_section = nil
|
206
|
+
section = []
|
207
|
+
else
|
208
|
+
raise RuntimeError, "ERROR: Found invalid regeneration marker at #{@path}:#{linenr}."
|
209
|
+
end
|
210
|
+
elsif in_section
|
211
|
+
section << line
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
sections[in_section.first] = section if in_section
|
216
|
+
@content = Content.new(sections)
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|