ridl 2.2.5 → 2.5.5
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 +4 -4
- data/lib/ridl/backend.rb +7 -8
- data/lib/ridl/delegate.rb +91 -24
- data/lib/ridl/genfile.rb +58 -23
- data/lib/ridl/node.rb +44 -12
- data/lib/ridl/optparse_ext.rb +3 -3
- data/lib/ridl/parser.rb +5 -5
- data/lib/ridl/parser.ry +5 -5
- data/lib/ridl/runner.rb +260 -197
- data/lib/ridl/scanner.rb +167 -144
- data/lib/ridl/version.rb +2 -2
- metadata +16 -16
data/lib/ridl/genfile.rb
CHANGED
@@ -17,28 +17,52 @@ module IDL
|
|
17
17
|
|
18
18
|
class GenFile
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
self.singleton_class.class_eval do
|
21
|
+
private
|
22
22
|
|
23
|
+
def _stack
|
24
|
+
@stack ||= []
|
25
|
+
end
|
26
|
+
|
27
|
+
def _start_transaction
|
28
|
+
_stack << (@transaction = [])
|
29
|
+
end
|
30
|
+
|
31
|
+
def _close_transaction
|
32
|
+
_stack.pop
|
33
|
+
@transaction = _stack.last
|
34
|
+
end
|
35
|
+
|
36
|
+
def _transaction
|
37
|
+
@transaction
|
38
|
+
end
|
39
|
+
|
40
|
+
def _commit
|
41
|
+
_transaction.reject! { |fgen| fgen.save; true }
|
42
|
+
end
|
43
|
+
|
44
|
+
def _rollback
|
45
|
+
_transaction.reject! { |fgen| fgen.remove; true } if _transaction
|
46
|
+
end
|
47
|
+
|
48
|
+
def _push(fgen)
|
49
|
+
_transaction << fgen if _transaction
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
23
53
|
def self.transaction(&block)
|
24
|
-
|
25
|
-
@@stack << @@cur_trans
|
54
|
+
_start_transaction
|
26
55
|
begin
|
27
56
|
block.call if block_given?
|
28
|
-
|
29
|
-
@@cur_trans.clear
|
57
|
+
_commit
|
30
58
|
ensure
|
31
|
-
|
32
|
-
|
33
|
-
@@cur_trans = @@stack.last
|
59
|
+
_rollback # after successful transaction should be nothing left
|
60
|
+
_close_transaction
|
34
61
|
end
|
35
62
|
end
|
36
63
|
|
37
64
|
def self.rollback
|
38
|
-
|
39
|
-
@@cur_trans.each {|fgen| fgen.remove }
|
40
|
-
@@cur_trans.clear
|
41
|
-
end
|
65
|
+
_rollback
|
42
66
|
end
|
43
67
|
|
44
68
|
class Content
|
@@ -82,8 +106,9 @@ module IDL
|
|
82
106
|
:regen_marker_prefix => '//',
|
83
107
|
:regen_marker_postfix => nil,
|
84
108
|
:regen_marker => REGEN_MARKER_DEFAULT,
|
85
|
-
:regen_keep_header =>
|
86
|
-
:output_file => nil
|
109
|
+
:regen_keep_header => true,
|
110
|
+
:output_file => nil,
|
111
|
+
:create_missing_dir => false
|
87
112
|
}.merge(opts)
|
88
113
|
if @options[:regenerate] && File.exists?(@fullpath)
|
89
114
|
parse_regeneration_content
|
@@ -91,7 +116,7 @@ module IDL
|
|
91
116
|
@content = Content.new
|
92
117
|
end
|
93
118
|
@fout = @options[:output_file] || Tempfile.new(@name)
|
94
|
-
|
119
|
+
self.class.__send__(:_push, self)
|
95
120
|
end
|
96
121
|
|
97
122
|
def <<(txt)
|
@@ -111,11 +136,14 @@ module IDL
|
|
111
136
|
"#{@options[:regen_marker_prefix]}#{@options[:regen_marker]} - HEADER_END : #{sectionid}#{@options[:regen_marker_postfix]}"
|
112
137
|
end
|
113
138
|
|
114
|
-
def write_regen_section(sectionid,
|
139
|
+
def write_regen_section(sectionid, options = {})
|
140
|
+
indent = options[:indent] || ''
|
115
141
|
self << indent << regen_start_marker(sectionid) << "\n" unless options[:header]
|
116
142
|
if content.has_section?(sectionid)
|
117
143
|
self << content[sectionid].join unless content[sectionid].empty?
|
118
|
-
|
144
|
+
elsif block_given?
|
145
|
+
yield # block should yield default content
|
146
|
+
elsif default_content = options[:default_content]
|
119
147
|
default_content = (Array === default_content) ? default_content : default_content.to_s.split("\n")
|
120
148
|
self << (default_content.collect {|l| (s = indent.dup) << l << "\n"; s }.join) unless default_content.empty?
|
121
149
|
end
|
@@ -141,22 +169,29 @@ module IDL
|
|
141
169
|
# replace original
|
142
170
|
begin
|
143
171
|
# rename newly generated file
|
144
|
-
FileUtils
|
172
|
+
FileUtils.mv(fgen.path, @fullpath)
|
145
173
|
# preserve file mode
|
146
|
-
FileUtils
|
174
|
+
FileUtils.chmod(File.lstat(ftmp_name).mode, @fullpath)
|
147
175
|
rescue
|
148
176
|
IDL.log(0, %Q{ERROR: FAILED updating #{@path}: #{$!}})
|
149
177
|
# restore backup
|
150
|
-
FileUtils
|
178
|
+
FileUtils.mv(ftmp_name, @fullpath)
|
151
179
|
raise
|
152
180
|
end
|
153
181
|
# remove backup
|
154
182
|
File.unlink(ftmp_name)
|
155
183
|
else
|
184
|
+
unless File.directory?(File.dirname(@fullpath))
|
185
|
+
unless @options[:create_missing_dir]
|
186
|
+
IDL.log(0, %Q{ERROR: Cannot access output folder #{File.dirname(@fullpath)}})
|
187
|
+
exit(1)
|
188
|
+
end
|
189
|
+
FileUtils.mkdir_p(File.dirname(@fullpath))
|
190
|
+
end
|
156
191
|
# just rename newly generated file
|
157
|
-
FileUtils
|
192
|
+
FileUtils.mv(fgen.path, @fullpath)
|
158
193
|
# set default mode for new files
|
159
|
-
FileUtils
|
194
|
+
FileUtils.chmod(0666 - File.umask, @fullpath)
|
160
195
|
end
|
161
196
|
end
|
162
197
|
end
|
data/lib/ridl/node.rb
CHANGED
@@ -115,6 +115,10 @@ module IDL::AST
|
|
115
115
|
@annotations = Annotations.new
|
116
116
|
end
|
117
117
|
|
118
|
+
def unescaped_name
|
119
|
+
@name.unescaped_name
|
120
|
+
end
|
121
|
+
|
118
122
|
def parsed_name_scope
|
119
123
|
(@enclosure ? @enclosure.parsed_name_scope : '') + '::' + @name
|
120
124
|
end
|
@@ -128,7 +132,7 @@ module IDL::AST
|
|
128
132
|
end
|
129
133
|
|
130
134
|
def scoped_lm_name
|
131
|
-
@scoped_lm_name ||= @scopes.collect{|s| s.lm_name_for_scope }.join(
|
135
|
+
@scoped_lm_name ||= @scopes.collect{|s| s.lm_name_for_scope }.join('::').freeze
|
132
136
|
end
|
133
137
|
|
134
138
|
def marshal_dump
|
@@ -314,11 +318,15 @@ module IDL::AST
|
|
314
318
|
end
|
315
319
|
|
316
320
|
def walk_members(&block)
|
317
|
-
@children.each
|
321
|
+
@children.each(&block)
|
318
322
|
end
|
319
323
|
|
320
324
|
def match_members(&block)
|
321
|
-
!(@children.find
|
325
|
+
!(@children.find(&block)).nil?
|
326
|
+
end
|
327
|
+
|
328
|
+
def select_members(&block)
|
329
|
+
@children.select(&block)
|
322
330
|
end
|
323
331
|
|
324
332
|
def replace_prefix(pfx)
|
@@ -403,12 +411,14 @@ module IDL::AST
|
|
403
411
|
IDL::AST::Union, IDL::AST::Enum, IDL::AST::Enumerator, IDL::AST::Typedef, IDL::AST::Include,
|
404
412
|
IDL::AST::Home, IDL::AST::Porttype, IDL::AST::Component, IDL::AST::Connector
|
405
413
|
]
|
406
|
-
attr_reader :anchor, :next
|
414
|
+
attr_reader :anchor, :next, :template, :template_params
|
407
415
|
def initialize(_name, _enclosure, params)
|
408
416
|
super(_name, _enclosure)
|
409
417
|
@anchor = params[:anchor]
|
410
418
|
@prefix = params[:prefix] || @prefix
|
411
419
|
@not_in_repo_id = params[:not_in_repo_id]
|
420
|
+
@template = params[:template]
|
421
|
+
@template_params = (params[:template_params] || []).dup
|
412
422
|
@next = nil
|
413
423
|
end
|
414
424
|
|
@@ -416,6 +426,23 @@ module IDL::AST
|
|
416
426
|
!@anchor.nil?
|
417
427
|
end
|
418
428
|
|
429
|
+
def is_templated?
|
430
|
+
@template ? true : false
|
431
|
+
end
|
432
|
+
|
433
|
+
def template_param(param)
|
434
|
+
return nil unless @template
|
435
|
+
param = param.to_s if ::Symbol === param
|
436
|
+
if ::String === param
|
437
|
+
@template.params.each_with_index do |tp, ix|
|
438
|
+
return @template_params[ix] if tp.name == param
|
439
|
+
end
|
440
|
+
nil
|
441
|
+
else
|
442
|
+
@template_params[param] rescue nil
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
419
446
|
def annotations
|
420
447
|
(has_anchor? ? self.anchor : self).get_annotations
|
421
448
|
end
|
@@ -452,9 +479,9 @@ module IDL::AST
|
|
452
479
|
when IDL::AST::Module
|
453
480
|
# Module reopening
|
454
481
|
_anchor = node.has_anchor? ? node.anchor : node
|
455
|
-
_anchor.annotations.concat(params
|
482
|
+
_anchor.annotations.concat(params.delete(:annotations))
|
456
483
|
_last = _anchor.find_last
|
457
|
-
_params = { :anchor => _anchor, :prefix => node.prefix }
|
484
|
+
_params = params.merge({ :anchor => _anchor, :prefix => node.prefix })
|
458
485
|
_next = IDL::AST::Module.new(node.name, self, _params)
|
459
486
|
_last.set_next(_next)
|
460
487
|
@children << _next
|
@@ -685,12 +712,16 @@ module IDL::AST
|
|
685
712
|
true
|
686
713
|
end
|
687
714
|
|
688
|
-
def
|
715
|
+
def params
|
716
|
+
@template_params
|
717
|
+
end
|
718
|
+
|
719
|
+
def instantiate(_module_instance, _context = {})
|
689
720
|
# process concrete parameters
|
690
721
|
@template_params.each_with_index do |_tp, _ix|
|
691
722
|
raise RuntimeError,
|
692
|
-
"missing template parameter for #{typename} #{scoped_lm_name}: #{_tp.name}" unless _ix <
|
693
|
-
_cp =
|
723
|
+
"missing template parameter for #{typename} #{scoped_lm_name}: #{_tp.name}" unless _ix < _module_instance.template_params.size
|
724
|
+
_cp = _module_instance.template_params[_ix]
|
694
725
|
if _cp.is_a?(IDL::Type)
|
695
726
|
raise RuntimeError, "anonymous type definitions are not allowed!" if _cp.is_anonymous?
|
696
727
|
# parameter should be a matching IDL::Type
|
@@ -772,13 +803,13 @@ module IDL::AST
|
|
772
803
|
end
|
773
804
|
|
774
805
|
def instantiate(_context, _enclosure)
|
775
|
-
mod_inst = IDL::AST::Module.new(self.name, _enclosure, {})
|
776
806
|
inst_params = @params.collect do |tp|
|
777
807
|
# concrete objects are either Expression or Node; latter needs to be repacked as IDL::Type::ScopedName
|
778
808
|
# as that is what the TemplateModule#instantiate expects
|
779
809
|
tp.concrete.is_a?(IDL::Expression) ? tp.concrete : IDL::Type::ScopedName.new(tp.concrete)
|
780
810
|
end
|
781
|
-
|
811
|
+
mod_inst = IDL::AST::Module.new(self.name, _enclosure, { :template => @template, :template_params => inst_params })
|
812
|
+
@template.instantiate(mod_inst, _context)
|
782
813
|
mod_inst
|
783
814
|
end
|
784
815
|
|
@@ -788,10 +819,11 @@ module IDL::AST
|
|
788
819
|
end # TemplateModuleReference
|
789
820
|
|
790
821
|
class Include < Module
|
791
|
-
attr_reader :filename
|
822
|
+
attr_reader :filename, :fullpath
|
792
823
|
def initialize(_name, _enclosure, params)
|
793
824
|
super(_name, _enclosure, params)
|
794
825
|
@filename = params[:filename]
|
826
|
+
@fullpath = params[:fullpath]
|
795
827
|
@defined = params[:defined] || false
|
796
828
|
@preprocessed = params[:preprocessed] || false
|
797
829
|
#overrule
|
data/lib/ridl/optparse_ext.rb
CHANGED
@@ -341,14 +341,14 @@ module IDL
|
|
341
341
|
@options.delete(switch)
|
342
342
|
end
|
343
343
|
|
344
|
-
def to_option_parser(optp,
|
344
|
+
def to_option_parser(optp, option_holder)
|
345
345
|
@options.each do |sw, op|
|
346
346
|
(arg_list = [sw]) << op.type
|
347
347
|
arg_list.concat(op.description(optp.summary_indent))
|
348
348
|
optp.on(*arg_list) do |v|
|
349
|
-
op.run(v,
|
349
|
+
op.run(v, option_holder.options)
|
350
350
|
end
|
351
|
-
optp.separator
|
351
|
+
optp.separator '' if op.separator
|
352
352
|
end
|
353
353
|
end
|
354
354
|
|
data/lib/ridl/parser.rb
CHANGED
@@ -499,7 +499,7 @@ def parse(src)
|
|
499
499
|
rescue IDL::ParseError
|
500
500
|
raise
|
501
501
|
rescue
|
502
|
-
STDERR.puts "#{$!}\n#{$!.backtrace.join("\n")}" if
|
502
|
+
STDERR.puts "#{$!}\n#{$!.backtrace.join("\n")}" if IDL.verbose_level>0
|
503
503
|
raise IDL::ParseError.new($!.message, @scanner.positions)
|
504
504
|
end
|
505
505
|
@d.post_parse
|
@@ -529,8 +529,8 @@ def is_included?(s)
|
|
529
529
|
@d.is_included?(s)
|
530
530
|
end
|
531
531
|
|
532
|
-
def enter_include(s)
|
533
|
-
@d.enter_include(s)
|
532
|
+
def enter_include(s, fp)
|
533
|
+
@d.enter_include(s, fp)
|
534
534
|
end
|
535
535
|
|
536
536
|
def leave_include()
|
@@ -541,8 +541,8 @@ def declare_include(s)
|
|
541
541
|
@d.declare_include(s)
|
542
542
|
end
|
543
543
|
|
544
|
-
def define_annotation(
|
545
|
-
@d.define_annotation(
|
544
|
+
def define_annotation(*args)
|
545
|
+
@d.define_annotation(*args)
|
546
546
|
end
|
547
547
|
|
548
548
|
def next_token
|
data/lib/ridl/parser.ry
CHANGED
@@ -873,7 +873,7 @@ def parse(src)
|
|
873
873
|
rescue IDL::ParseError
|
874
874
|
raise
|
875
875
|
rescue
|
876
|
-
STDERR.puts "#{$!}\n#{$!.backtrace.join("\n")}" if
|
876
|
+
STDERR.puts "#{$!}\n#{$!.backtrace.join("\n")}" if IDL.verbose_level>0
|
877
877
|
raise IDL::ParseError.new($!.message, @scanner.positions)
|
878
878
|
end
|
879
879
|
@d.post_parse
|
@@ -903,8 +903,8 @@ def is_included?(s)
|
|
903
903
|
@d.is_included?(s)
|
904
904
|
end
|
905
905
|
|
906
|
-
def enter_include(s)
|
907
|
-
@d.enter_include(s)
|
906
|
+
def enter_include(s, fp)
|
907
|
+
@d.enter_include(s, fp)
|
908
908
|
end
|
909
909
|
|
910
910
|
def leave_include()
|
@@ -915,8 +915,8 @@ def declare_include(s)
|
|
915
915
|
@d.declare_include(s)
|
916
916
|
end
|
917
917
|
|
918
|
-
def define_annotation(
|
919
|
-
@d.define_annotation(
|
918
|
+
def define_annotation(*args)
|
919
|
+
@d.define_annotation(*args)
|
920
920
|
end
|
921
921
|
|
922
922
|
def next_token
|
data/lib/ridl/runner.rb
CHANGED
@@ -17,219 +17,195 @@ require 'ridl/backend'
|
|
17
17
|
|
18
18
|
# -----------------------------------------------------------------------
|
19
19
|
|
20
|
-
$VERBOSE = $VERBOSE || ENV['RIDL_VERBOSE']
|
21
|
-
|
22
20
|
module IDL
|
23
21
|
|
22
|
+
# TODO : LEGACY solution for R2CORBA; to be removed when R2CORBA has been updated
|
23
|
+
# See also IDL#init
|
24
24
|
@@embedded = false unless class_variable_defined?(:@@embedded)
|
25
25
|
@@be_name = nil unless class_variable_defined?(:@@be_name)
|
26
|
-
@@preprocessing = false
|
27
|
-
@@no_pidl = false
|
28
|
-
@@idlstack = []
|
29
|
-
@@backend = nil
|
30
|
-
@@verbose_level = 0
|
31
26
|
|
32
27
|
OPTIONS = {
|
33
28
|
:outputdir => nil,
|
34
29
|
:includepaths => [],
|
35
|
-
:
|
30
|
+
:xincludepaths => [],
|
31
|
+
:verbose => (ENV['RIDL_VERBOSE'] || 0).to_i,
|
36
32
|
:debug => false,
|
37
33
|
:namespace => nil,
|
38
34
|
:search_incpath => false,
|
39
35
|
:backend => nil,
|
40
36
|
:macros => {
|
41
|
-
|
42
|
-
|
43
|
-
|
37
|
+
:__RIDL__ => "#{RIDL_VERSION}",
|
38
|
+
:__RIDLBE__ => nil,
|
39
|
+
:__RIDLBE_VER__ => nil
|
44
40
|
}
|
45
41
|
}
|
46
42
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
43
|
+
class Engine
|
44
|
+
def initialize(backend, options)
|
45
|
+
@backend = backend ? Backend.load(backend) : Backend.null_be
|
46
|
+
@initopts = options.merge({
|
47
|
+
backend: @backend.name,
|
48
|
+
macros: options[:macros].merge({
|
49
|
+
__RIDLBE__: @backend.name.to_s,
|
50
|
+
__RIDLBE_VER__: @backend.version
|
51
|
+
})
|
52
|
+
})
|
53
|
+
@optparser = init_optparser
|
54
|
+
@inputstack = []
|
55
|
+
@options = nil
|
56
|
+
end
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
def backend
|
59
|
+
@backend
|
60
|
+
end
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
if ARGV.first =~ /^:\S+/
|
63
|
-
@@be_name = ARGV.shift.reverse.chop.reverse.to_sym
|
64
|
-
elsif ENV['RIDL_BE_SELECT'] # or from environment
|
65
|
-
@@be_name = ENV['RIDL_BE_SELECT'].to_sym
|
66
|
-
end
|
62
|
+
def options
|
63
|
+
@options || @initopts
|
64
|
+
end
|
67
65
|
|
68
|
-
|
69
|
-
|
66
|
+
def push_input(idlfile, opts)
|
67
|
+
@inputstack << [idlfile, opts]
|
68
|
+
end
|
70
69
|
|
71
|
-
|
72
|
-
|
73
|
-
@@preprocessing = true
|
74
|
-
ARGV.shift
|
75
|
-
elsif ARGV.first == '--ignore-pidl'
|
76
|
-
@@no_pidl = true
|
77
|
-
ARGV.shift
|
78
|
-
end
|
70
|
+
def pop_input
|
71
|
+
@inputstack.shift
|
79
72
|
end
|
80
|
-
# try to load the active laguage mapping backend
|
81
|
-
@@backend = @@be_name ? Backend.load(@@be_name) : Backend.null_be
|
82
|
-
# finalize base options
|
83
|
-
OPTIONS[:preprocess] = preprocessing?
|
84
|
-
OPTIONS[:ignore_pidl] = no_pidl?
|
85
|
-
OPTIONS[:backend] = @@backend
|
86
|
-
OPTIONS[:__RIDLBE__] = @@backend.name.to_s
|
87
|
-
OPTIONS[:__RIDLBE_VER__] = @@backend.version
|
88
|
-
end
|
89
73
|
|
90
|
-
|
91
|
-
|
92
|
-
def IDL.parse_args
|
93
|
-
script_name = File.basename($0, '.*')
|
94
|
-
if not script_name =~ /ridlc/
|
95
|
-
script_name = "ruby "+$0
|
74
|
+
def peek_input
|
75
|
+
@inputstack.first
|
96
76
|
end
|
97
77
|
|
98
|
-
|
99
|
-
|
100
|
-
opts.banner = "Usage: #{script_name} [:backend] [options] [<idlfile> [<idlfile> ...]]\n\n" +
|
101
|
-
" backend\t\tSpecifies the IDL language mapping backend to use.\n"+
|
102
|
-
" \t\tDefault = :null\n\n"+
|
103
|
-
" Active language mapping = :#{IDL.backend.name}"
|
104
|
-
opts.separator ""
|
105
|
-
opts.on("-I PATH", "--include=PATH", String,
|
106
|
-
"Adds include searchpath.",
|
107
|
-
"Default: nil") { |v| OPTIONS[:includepaths] << v }
|
108
|
-
opts.on('-Dmacro=[value]', String, 'defines preprocessor macro') { |v|
|
109
|
-
name, value = v.split('=')
|
110
|
-
OPTIONS[:macros][name] = (value ? value : true)
|
111
|
-
}
|
112
|
-
opts.on("-n NAMESPACE", "--namespace=NAMESPACE", String,
|
113
|
-
"Defines rootlevel enclosing namespace.",
|
114
|
-
"Default: nil") { |v| OPTIONS[:namespace]=v }
|
115
|
-
opts.on("-v", "--verbose",
|
116
|
-
"Set verbosity level. Repeat to increment.",
|
117
|
-
"Default: 0") { |v| OPTIONS[:verbose] += 1 }
|
118
|
-
opts.on("--debug",
|
119
|
-
"Set parser debug mode. Don't do this at home!",
|
120
|
-
"Default: off") { |v| OPTIONS[:debug] = true }
|
121
|
-
opts.on('--stdidl',
|
122
|
-
'Adds include path to standard IDL files provided with RIDL.',
|
123
|
-
'Default: not set') { |v|
|
124
|
-
OPTIONS[:includepaths] << File.expand_path(File.join(File.dirname(__FILE__), '..', 'idl'))
|
125
|
-
}
|
126
|
-
opts.on("--search-includepath",
|
127
|
-
"Use include paths to find main IDL source.",
|
128
|
-
"Default: off") { |v| OPTIONS[:search_incpath]=v }
|
129
|
-
if preprocessing?
|
130
|
-
opts.on("--output=FILE", String,
|
131
|
-
"Specifies filename to generate output in.",
|
132
|
-
"Default: File.basename(idlfile, '.idl')+<postfix>+<ext>") { |v| OPTIONS[:output]=v }
|
78
|
+
def has_input?
|
79
|
+
!@inputstack.empty?
|
133
80
|
end
|
134
81
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
be_options.to_option_parser(opts, OPTIONS)
|
82
|
+
def verbose_level
|
83
|
+
options[:verbose]
|
84
|
+
end
|
139
85
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
puts RIDL_COPYRIGHT
|
144
|
-
puts '---'
|
145
|
-
@@backend.print_version
|
146
|
-
exit
|
147
|
-
}
|
86
|
+
def verbose_level=(l)
|
87
|
+
options[:verbose] = l
|
88
|
+
end
|
148
89
|
|
149
|
-
|
90
|
+
def run(argv, runopts = {})
|
150
91
|
|
151
|
-
|
152
|
-
|
92
|
+
# initialize options
|
93
|
+
@options = @initopts.merge(runopts)
|
153
94
|
|
154
|
-
|
155
|
-
|
95
|
+
# backup current engine (if any)
|
96
|
+
cur_engine = Thread.current[:ridl_engine]
|
97
|
+
# store currently running engine for current thread
|
98
|
+
Thread.current[:ridl_engine] = self
|
156
99
|
|
157
|
-
|
158
|
-
|
159
|
-
|
100
|
+
begin
|
101
|
+
# parse arguments
|
102
|
+
begin
|
103
|
+
@optparser.parse!(argv)
|
104
|
+
rescue ArgumentError => ex
|
105
|
+
IDL.error(ex.inspect)
|
106
|
+
IDL.error(ex.backtrace.join("\n")) if IDL.verbose_level>0
|
107
|
+
return false
|
108
|
+
end
|
160
109
|
|
161
|
-
|
162
|
-
@@idlstack.shift
|
163
|
-
end
|
110
|
+
if options[:preprocess]
|
164
111
|
|
165
|
-
|
166
|
-
|
167
|
-
|
112
|
+
## PREPROCESSING
|
113
|
+
o = if options[:output].nil?
|
114
|
+
$stdout
|
115
|
+
else
|
116
|
+
File.open(options[:output], 'w+')
|
117
|
+
end
|
118
|
+
options[:output] = o
|
168
119
|
|
169
|
-
|
170
|
-
|
171
|
-
|
120
|
+
input_base = File.basename(argv.first)
|
121
|
+
if (input_base != argv.first)
|
122
|
+
options[:xincludepaths] << File.dirname(argv.first)
|
123
|
+
end
|
172
124
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
125
|
+
return !parse("#include \"#{input_base}\"", options).nil?
|
126
|
+
else
|
127
|
+
## collect input files from commandline
|
128
|
+
collect_input(argv)
|
129
|
+
|
130
|
+
## CODE GENERATION
|
131
|
+
while has_input?
|
132
|
+
# get input from stack
|
133
|
+
_idlfile, _opts = pop_input
|
134
|
+
|
135
|
+
_fio = if IO === _idlfile || StringIO === _idlfile
|
136
|
+
_idlfile
|
137
|
+
else
|
138
|
+
File.open(_idlfile, 'r')
|
139
|
+
end
|
140
|
+
raise RuntimeError, 'cannot read from STDOUT' if $stdout == _fio
|
141
|
+
|
142
|
+
# parse IDL source
|
143
|
+
IDL.log(1, "RIDL - parsing #{IO === _idlfile ? 'from STDIN': (StringIO === _idlfile ? 'from string' : _idlfile)}")
|
144
|
+
|
145
|
+
unless _parser = parse(_fio, _opts)
|
146
|
+
return false
|
147
|
+
end
|
184
148
|
|
185
|
-
|
149
|
+
# process parse result -> code generation
|
150
|
+
IDL.log(2, 'RIDL - starting code generation')
|
186
151
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
152
|
+
GenFile.transaction do
|
153
|
+
begin
|
154
|
+
backend.process_input(_parser, _opts)
|
155
|
+
rescue Backend::ProcessStop
|
156
|
+
IDL.log(2, "RIDL - processing #{IO === _idlfile ? 'from STDIN': (StringIO === _idlfile ? 'from string' : _idlfile)} stopped with \"#{$!.message}\"")
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
193
160
|
end
|
194
|
-
|
161
|
+
ensure
|
162
|
+
# restore previous state
|
163
|
+
Thread.current[:ridl_engine] = cur_engine
|
164
|
+
end
|
165
|
+
true
|
166
|
+
end
|
195
167
|
|
196
|
-
|
197
|
-
|
168
|
+
def parse(io, opts)
|
169
|
+
# parse IDL source
|
170
|
+
_parser = ::IDL::Parser.new(opts)
|
171
|
+
_parser.yydebug = opts[:debug]
|
198
172
|
|
199
173
|
begin
|
200
|
-
|
201
|
-
if (input_base != ARGV.first)
|
202
|
-
OPTIONS[:includepaths] << File.dirname(ARGV.first)
|
203
|
-
end
|
204
|
-
parser.parse("#include \"#{input_base}\"")
|
174
|
+
_parser.parse(io)
|
205
175
|
rescue => ex
|
206
176
|
IDL.error(ex.inspect)
|
207
177
|
IDL.error(ex.backtrace.join("\n")) unless ex.is_a? IDL::ParseError
|
178
|
+
return nil
|
208
179
|
ensure
|
209
|
-
|
180
|
+
io.close unless String === io || io == $stdin
|
210
181
|
end
|
211
|
-
|
182
|
+
_parser
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def collect_input(argv)
|
212
188
|
## collect input files from commandline
|
213
|
-
|
214
|
-
_opts =
|
189
|
+
argv.each do |_arg|
|
190
|
+
_opts = options.dup
|
215
191
|
|
216
192
|
_opts[:idlfile] = _arg
|
217
193
|
if _opts[:search_incpath]
|
218
194
|
_fname = _arg
|
219
195
|
_fpath = if File.file?(_fname) && File.readable?(_fname)
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
196
|
+
_fname
|
197
|
+
else
|
198
|
+
_fp = _opts[:includepaths].find do |_p|
|
199
|
+
_f = _p + "/" + _fname
|
200
|
+
File.file?(_f) && File.readable?(_f)
|
201
|
+
end
|
202
|
+
_opts[:outputdir] = _fp unless _fp.nil? || !_opts[:outputdir].nil?
|
203
|
+
_fp += '/' + _fname unless _fp.nil?
|
204
|
+
_fp
|
205
|
+
end
|
230
206
|
_arg = _fpath unless _fpath.nil?
|
231
207
|
end
|
232
|
-
_opts[:
|
208
|
+
_opts[:xincludepaths] << File.dirname(_arg)
|
233
209
|
|
234
210
|
_opts[:outputdir] ||= '.'
|
235
211
|
|
@@ -238,59 +214,109 @@ module IDL
|
|
238
214
|
|
239
215
|
## if no IDL input file specified read from STDIN
|
240
216
|
unless has_input?
|
241
|
-
_opts =
|
217
|
+
_opts = options.dup
|
242
218
|
_opts[:outputdir] ||= '.'
|
243
219
|
push_input($stdin, _opts)
|
244
220
|
end
|
221
|
+
end
|
245
222
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
_fio = if IO === _idlfile || StringIO === _idlfile
|
252
|
-
_idlfile
|
253
|
-
else
|
254
|
-
File.open(_idlfile, "r")
|
255
|
-
end
|
256
|
-
raise RuntimeError, 'cannot read from STDOUT' if $stdout == _fio
|
223
|
+
def init_optparser
|
224
|
+
script_name = File.basename($0, '.*')
|
225
|
+
if not script_name =~ /ridlc/
|
226
|
+
script_name = 'ruby '+$0
|
227
|
+
end
|
257
228
|
|
258
|
-
|
259
|
-
|
229
|
+
# set up option parser with common options
|
230
|
+
opts = OptionParser.new
|
231
|
+
opts.banner = "Usage: #{script_name} [:backend] [options] [<idlfile> [<idlfile> ...]]\n\n" +
|
232
|
+
" backend\t\tSpecifies the IDL language mapping backend to use.\n"+
|
233
|
+
" \t\tDefault = :null\n\n"+
|
234
|
+
" Active language mapping = :#{backend.name}"
|
235
|
+
opts.separator ""
|
236
|
+
opts.on("-I PATH", "--include=PATH", String,
|
237
|
+
"Adds include searchpath.",
|
238
|
+
"Default: nil") { |v| @options[:includepaths] << v }
|
239
|
+
opts.on('-Dmacro=[value]', String, 'defines preprocessor macro') { |v|
|
240
|
+
name, value = v.split('=')
|
241
|
+
@options[:macros][name] = (value ? value : true)
|
242
|
+
}
|
243
|
+
opts.on("-n NAMESPACE", "--namespace=NAMESPACE", String,
|
244
|
+
"Defines rootlevel enclosing namespace.",
|
245
|
+
"Default: nil") { |v| @options[:namespace]=v }
|
246
|
+
opts.on("-v", "--verbose",
|
247
|
+
"Set verbosity level. Repeat to increment.",
|
248
|
+
"Default: 0") { |v| @options[:verbose] += 1 }
|
249
|
+
opts.on("--debug",
|
250
|
+
"Set parser debug mode. Don't do this at home!",
|
251
|
+
"Default: off") { |v| @options[:debug] = true }
|
252
|
+
opts.on('--stdidl',
|
253
|
+
'Adds include path to standard IDL files provided with RIDL.',
|
254
|
+
'Default: not set') { |v|
|
255
|
+
@options[:includepaths] << File.expand_path(File.join(File.dirname(__FILE__), '..', 'idl'))
|
256
|
+
}
|
257
|
+
opts.on("--search-includepath",
|
258
|
+
"Use include paths to find main IDL source.",
|
259
|
+
"Default: off") { |v| @options[:search_incpath]=v }
|
260
|
+
if @initopts[:preprocess]
|
261
|
+
opts.on("--output=FILE", String,
|
262
|
+
"Specifies filename to generate output in.",
|
263
|
+
"Default: basename(idlfile)-'.idl'+<postfix>+<ext>") { |v| @options[:output]=v }
|
264
|
+
end
|
260
265
|
|
261
|
-
|
262
|
-
|
266
|
+
# setup language mapping specific options
|
267
|
+
be_options = OptionList.new
|
268
|
+
@backend.setup_be(be_options, @initopts)
|
269
|
+
be_options.to_option_parser(opts, self)
|
270
|
+
|
271
|
+
opts.on('-V', '--version',
|
272
|
+
'Show version information and exit.') {
|
273
|
+
puts "RIDL compiler #{@options[:macros][:__RIDL__]}"
|
274
|
+
puts RIDL_COPYRIGHT
|
275
|
+
puts '---'
|
276
|
+
@backend.print_version
|
277
|
+
exit
|
278
|
+
}
|
263
279
|
|
264
|
-
|
265
|
-
_parser.parse(_fio)
|
266
|
-
rescue => ex
|
267
|
-
IDL.error(ex.inspect)
|
268
|
-
IDL.error(ex.backtrace.join("\n")) unless ex.is_a? IDL::ParseError
|
269
|
-
exit 1
|
270
|
-
ensure
|
271
|
-
_fio.close unless _fio == $stdin
|
272
|
-
end
|
280
|
+
opts.separator ""
|
273
281
|
|
274
|
-
|
275
|
-
|
282
|
+
opts.on('-h', '--help',
|
283
|
+
'Show this help message.') { puts opts; puts; exit }
|
276
284
|
|
277
|
-
|
278
|
-
begin
|
279
|
-
@@backend.process_input(_parser, _opts)
|
280
|
-
rescue Backend::ProcessStop
|
281
|
-
IDL.log(2, "RIDL - processing #{IO === _idlfile ? 'from STDIN': _idlfile} stopped from #{$!.message}")
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
+
opts
|
285
286
|
end
|
286
|
-
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
def IDL.backend
|
291
|
+
Thread.current[:ridl_engine] ? Thread.current[:ridl_engine].backend : nil
|
292
|
+
end
|
293
|
+
|
294
|
+
def IDL.push_input(idlfile, opts)
|
295
|
+
Thread.current[:ridl_engine].push_input(idlfile, opts) if Thread.current[:ridl_engine]
|
296
|
+
end
|
297
|
+
|
298
|
+
def IDL.pop_input
|
299
|
+
Thread.current[:ridl_engine].pop_input if Thread.current[:ridl_engine]
|
300
|
+
end
|
301
|
+
|
302
|
+
def IDL.peek_input
|
303
|
+
Thread.current[:ridl_engine].peek_input if Thread.current[:ridl_engine]
|
304
|
+
end
|
305
|
+
|
306
|
+
def IDL.has_input?
|
307
|
+
Thread.current[:ridl_engine].has_input? if Thread.current[:ridl_engine]
|
308
|
+
end
|
287
309
|
|
288
310
|
def IDL.verbose_level
|
289
|
-
|
311
|
+
Thread.current[:ridl_engine] ? Thread.current[:ridl_engine].verbose_level : OPTIONS[:verbose]
|
290
312
|
end
|
291
313
|
|
292
314
|
def IDL.verbose_level=(l)
|
293
|
-
|
315
|
+
if Thread.current[:ridl_engine]
|
316
|
+
Thread.current[:ridl_engine].verbose_level = l.to_i
|
317
|
+
else
|
318
|
+
OPTIONS[:verbose] = l.to_i
|
319
|
+
end
|
294
320
|
end
|
295
321
|
|
296
322
|
def IDL.log(level, message)
|
@@ -301,4 +327,41 @@ module IDL
|
|
301
327
|
STDERR.puts(message)
|
302
328
|
end
|
303
329
|
|
330
|
+
def IDL.init(argv = ARGV)
|
331
|
+
options = OPTIONS.dup
|
332
|
+
|
333
|
+
unless @@embedded
|
334
|
+
# check commandline args for explicit language mapping backend
|
335
|
+
if argv.first =~ /^:\S+/
|
336
|
+
@@be_name = argv.shift.reverse.chop.reverse.to_sym
|
337
|
+
elsif ENV['RIDL_BE_SELECT'] # or from environment
|
338
|
+
@@be_name = ENV['RIDL_BE_SELECT'].to_sym
|
339
|
+
end
|
340
|
+
|
341
|
+
# add optional search paths for RIDL backends
|
342
|
+
$:.concat(ENV['RIDL_BE_PATH'].split(/:|;/)) if ENV['RIDL_BE_PATH']
|
343
|
+
|
344
|
+
# check for special bootstrapping switches
|
345
|
+
if argv.first == '--preprocess'
|
346
|
+
options[:preprocess] = true
|
347
|
+
argv.shift
|
348
|
+
elsif argv.first == '--ignore-pidl'
|
349
|
+
options[:ignore_pidl] = true
|
350
|
+
argv.shift
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
# create RIDL engine
|
355
|
+
Thread.current[:ridl_engine] = Engine.new(@@be_name, options)
|
356
|
+
end
|
357
|
+
|
358
|
+
# main run method
|
359
|
+
#
|
360
|
+
def IDL.run(argv = ARGV)
|
361
|
+
# run default engine if available
|
362
|
+
if Thread.current[:ridl_engine]
|
363
|
+
exit(1) unless Thread.current[:ridl_engine].run(argv)
|
364
|
+
end
|
365
|
+
end # IDL.run
|
366
|
+
|
304
367
|
end
|