ridl 2.2.5 → 2.5.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|