ridl 2.5.6 → 2.8.1

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.
data/lib/ridl/parser.ry CHANGED
@@ -8,7 +8,6 @@
8
8
  # included with this program.
9
9
  #
10
10
  # Copyright (c) Remedy IT Expertise BV
11
- # Chamber of commerce Rotterdam nr.276339, The Netherlands
12
11
  #--------------------------------------------------------------------
13
12
 
14
13
  class Parser
@@ -52,7 +51,7 @@ rule
52
51
  { @d.register_template_module_name(val[1]) }
53
52
 
54
53
  template_module_parameters : template_module_parameter
55
- | template_module_parameters "," template_module_parameter
54
+ | template_module_parameters "," template_module_parameter
56
55
 
57
56
  template_module_parameter : "typename" identifier
58
57
  { @d.define_template_parameter(val[1], IDL::Type::Any.new) }
@@ -78,7 +77,7 @@ rule
78
77
  { @d.define_template_parameter(val[1], val[0]) }
79
78
 
80
79
  template_module_body : template_module_definition
81
- | template_module_body template_module_definition
80
+ | template_module_body template_module_definition
82
81
 
83
82
  template_module_definition : type_dcl ";"
84
83
  | const_dcl ";"
@@ -117,22 +116,20 @@ rule
117
116
 
118
117
  template_module_inst : template_module_header "<" template_module_inst_parameters ">" identifier
119
118
  { @d.instantiate_template_module(val[4], val[2]) }
120
-
119
+
121
120
  template_module_inst_parameters : template_module_inst_parameter
122
121
  { [val[0]] }
123
122
  | template_module_inst_parameters "," template_module_inst_parameter
124
- { val[0] << val[2]; val[0] }
123
+ { val[0] << val[2]; val[0] }
125
124
 
126
- template_module_inst_parameter : base_type_spec
127
- { val[0] }
128
- | template_type_spec
125
+ template_module_inst_parameter : simple_type_spec
129
126
  { val[0] }
130
127
  | const_exp
131
128
  { val[0] }
132
129
 
133
130
  template_module_reference : "alias" scoped_name "<" _scoped_name_list ">" identifier
134
131
  { @d.declare_template_reference(val[5], val[1], val[3]) }
135
-
132
+
136
133
  interface : interface_dcl
137
134
  | forward_dcl
138
135
 
@@ -194,7 +191,7 @@ rule
194
191
 
195
192
  home : home_header "{" home_body "}"
196
193
  { @d.end_home(val[0]) }
197
-
194
+
198
195
  home_header : "home" identifier ":" home_inheritance_spec "supports" home_supports_spec "manages" scoped_name "primarykey" home_primarykey_spec
199
196
  { @d.define_home(val[1], val[3], val[7], val[9], val[5]) }
200
197
  | "home" identifier ":" home_inheritance_spec "supports" home_supports_spec "manages" scoped_name
@@ -211,11 +208,11 @@ rule
211
208
  { @d.define_home(val[1], nil, val[3], val[5], nil) }
212
209
  | "home" identifier "manages" scoped_name
213
210
  { @d.define_home(val[1], nil, val[3], nil, nil) }
214
-
215
- home_inheritance_spec : scoped_name
216
-
211
+
212
+ home_inheritance_spec : scoped_name
213
+
217
214
  home_supports_spec : _interface_name_list
218
-
215
+
219
216
  home_primarykey_spec : scoped_name
220
217
 
221
218
  home_body : home_export
@@ -227,26 +224,26 @@ rule
227
224
 
228
225
  porttype : porttype_header "{" porttype_body "}"
229
226
  { @d.end_porttype(val[0]) }
230
-
227
+
231
228
  porttype_header : "porttype" identifier
232
229
  { @d.define_porttype(val[1]) }
233
-
230
+
234
231
  porttype_body : porttype_export
235
232
  | porttype_body porttype_export
236
233
 
237
234
  porttype_export : provides_dcl ";"
238
235
  | uses_dcl ";"
239
236
  | attr_dcl ";"
240
-
237
+
241
238
  component : component_dcl
242
239
  | component_forward_dcl
243
-
240
+
244
241
  component_forward_dcl : "component" identifier
245
242
  { @d.declare_component(val[1]) }
246
-
243
+
247
244
  component_dcl : component_header "{" component_body "}"
248
245
  { @d.end_component(val[0]) }
249
-
246
+
250
247
  component_header : "component" identifier ":" component_inheritance_spec "supports" component_supports_spec
251
248
  { @d.define_component(val[1], val[3], val[5]) }
252
249
  | "component" identifier ":" component_inheritance_spec
@@ -255,11 +252,11 @@ rule
255
252
  { @d.define_component(val[1], nil, val[3]) }
256
253
  | "component" identifier
257
254
  { @d.define_component(val[1], nil, nil) }
258
-
255
+
259
256
  component_inheritance_spec : scoped_name
260
-
257
+
261
258
  component_supports_spec : _interface_name_list
262
-
259
+
263
260
  component_body : component_export
264
261
  | component_body component_export
265
262
 
@@ -274,7 +271,7 @@ rule
274
271
 
275
272
  connector : connector_header "{" connector_body "}"
276
273
  { @d.end_connector(val[0]) }
277
-
274
+
278
275
  connector_header : "connector" identifier ":" scoped_name
279
276
  { @d.define_connector(val[1], val[3]) }
280
277
  | "connector" identifier
@@ -291,33 +288,33 @@ rule
291
288
 
292
289
  provides_dcl : "provides" interface_type identifier
293
290
  { @d.declare_port(val[2], :facet, val[1]) }
294
-
291
+
295
292
  uses_dcl : "uses" "multiple" interface_type identifier
296
293
  { @d.declare_port(val[3], :receptacle, val[2], true) }
297
294
  | "uses" interface_type identifier
298
295
  { @d.declare_port(val[2], :receptacle, val[1], false) }
299
-
296
+
300
297
  publishes_dcl : "publishes" scoped_name identifier
301
298
  { @d.declare_port(val[2], :publisher, val[1]) }
302
-
299
+
303
300
  emits_dcl : "emits" scoped_name identifier
304
301
  { @d.declare_port(val[2], :emitter, val[1]) }
305
-
302
+
306
303
  consumes_dcl : "consumes" scoped_name identifier
307
304
  { @d.declare_port(val[2], :consumer, val[1]) }
308
-
305
+
309
306
  port_dcl : "port" scoped_name identifier
310
307
  { @d.declare_port(val[2], :port, val[1]) }
311
308
  | "mirrorport" scoped_name identifier
312
309
  { @d.declare_port(val[2], :mirrorport, val[1]) }
313
-
310
+
314
311
  interface_type : scoped_name
315
- | object_type
312
+ | object_type
316
313
 
317
314
  scoped_name : scoped_name_0 { @d.parse_scopedname(*val[0]) }
318
315
 
319
- scoped_name_0 : identifier { [FALSE, [val[0]]] }
320
- | "::" identifier { [TRUE, [val[1]]] }
316
+ scoped_name_0 : identifier { [false, [val[0]]] }
317
+ | "::" identifier { [true, [val[1]]] }
321
318
  | scoped_name_0 "::" identifier
322
319
  { val[0][1] << val[2]; val[0] }
323
320
 
@@ -396,8 +393,8 @@ rule
396
393
 
397
394
  value_name : scoped_name
398
395
 
399
- value_element : export
400
- | state_member ";"
396
+ value_element : export
397
+ | state_member ";"
401
398
  | init_dcl ";"
402
399
 
403
400
  state_member : "public" type_spec declarators
@@ -460,7 +457,7 @@ rule
460
457
  const_exp : or_expr
461
458
 
462
459
  or_expr : xor_expr
463
- | or_expr "|" xor_expr
460
+ | or_expr "|" xor_expr
464
461
  { Expression::Operation::Or.new(val[0], val[2]) }
465
462
 
466
463
  xor_expr : and_expr
@@ -512,8 +509,8 @@ rule
512
509
  | floating_pt_literal { @d.parse_literal(:float, val[0]) }
513
510
  | boolean_literal { @d.parse_literal(:boolean, val[0]) }
514
511
 
515
- boolean_literal : "TRUE" { TRUE }
516
- | "FALSE" { FALSE }
512
+ boolean_literal : "TRUE" { true }
513
+ | "FALSE" { false }
517
514
 
518
515
  positive_int_const : const_exp { @d.parse_positive_int(val[0]) }
519
516
 
@@ -525,7 +522,7 @@ rule
525
522
  | enum_type
526
523
  | "native" native_declarator
527
524
 
528
- type_declarator : type_spec declarators
525
+ type_declarator : type_spec declarators
529
526
  {
530
527
  dcls = parse_type_declarator(val[0], val[1])
531
528
  dcls.each do |d|
@@ -624,7 +621,7 @@ rule
624
621
  member_list : member
625
622
  | member_list member
626
623
 
627
- member : type_spec declarators ";"
624
+ member : type_spec declarators ";"
628
625
  {
629
626
  dcls = parse_type_declarator(val[0], val[1])
630
627
  dcls.each do |d|
@@ -659,10 +656,10 @@ rule
659
656
  | union_body union_case
660
657
 
661
658
  union_case : _case_label_1 element_spec ";"
662
- {
659
+ {
663
660
  dcls = parse_type_declarator(val[1][0], [val[1][1]])
664
661
  dcls.each do |d|
665
- @d.define_case(val[0], d[0], d[1])
662
+ @d.define_case(val[0], d[0], d[1])
666
663
  end
667
664
  }
668
665
 
@@ -684,7 +681,7 @@ rule
684
681
  _enumerator_list : enumerator
685
682
  | _enumerator_list "," enumerator
686
683
 
687
- enumerator : identifier
684
+ enumerator : identifier
688
685
  {
689
686
  @d.declare_enumerator(val[0])
690
687
  }
@@ -746,7 +743,7 @@ rule
746
743
  attr_no_raises_expr : { [[], []] }
747
744
 
748
745
  attr_declarator_list : simple_declarator "," _simple_declarator_list
749
- { [val[0]].concat(val[2]) }
746
+ { [val[0]].concat(val[2]) }
750
747
 
751
748
  readonly_attr_declarator : simple_declarator raises_expr
752
749
  { [[val[0]], val[1]] }
data/lib/ridl/require.rb CHANGED
@@ -8,7 +8,6 @@
8
8
  # included with this program.
9
9
  #
10
10
  # Copyright (c) Remedy IT Expertise BV
11
- # Chamber of commerce Rotterdam nr.276339, The Netherlands
12
11
  #--------------------------------------------------------------------
13
12
  require 'ridl/version'
14
13
  require 'ridl/scanner'
data/lib/ridl/ridl.rb CHANGED
@@ -13,7 +13,6 @@
13
13
  # included with this program.
14
14
  #
15
15
  # Copyright (c) Remedy IT Expertise BV
16
- # Chamber of commerce Rotterdam nr.276339, The Netherlands
17
16
  #--------------------------------------------------------------------
18
17
  require 'ridl/require'
19
18
 
data/lib/ridl/runner.rb CHANGED
@@ -8,23 +8,18 @@
8
8
  # included with this program.
9
9
  #
10
10
  # Copyright (c) Remedy IT Expertise BV
11
- # Chamber of commerce Rotterdam nr.276339, The Netherlands
12
11
  #--------------------------------------------------------------------
13
12
  require 'stringio'
14
13
  require 'ridl/optparse_ext'
15
14
  require 'ridl/genfile'
16
15
  require 'ridl/backend'
16
+ require 'ridl/options'
17
17
 
18
18
  # -----------------------------------------------------------------------
19
19
 
20
20
  module IDL
21
21
 
22
- # TODO : LEGACY solution for R2CORBA; to be removed when R2CORBA has been updated
23
- # See also IDL#init
24
- @@embedded = false unless class_variable_defined?(:@@embedded)
25
- @@be_name = nil unless class_variable_defined?(:@@be_name)
26
-
27
- OPTIONS = {
22
+ OPTIONS = Options.new({
28
23
  :outputdir => nil,
29
24
  :includepaths => [],
30
25
  :xincludepaths => [],
@@ -34,24 +29,73 @@ module IDL
34
29
  :search_incpath => false,
35
30
  :backend => nil,
36
31
  :macros => {
37
- :__RIDL__ => "#{RIDL_VERSION}",
38
- :__RIDLBE__ => nil,
39
- :__RIDLBE_VER__ => nil
40
32
  }
41
- }
33
+ })
34
+ CORE_OPTIONS = OPTIONS.keys
42
35
 
43
36
  class Engine
37
+
38
+ class ProductionStack
39
+ def initialize
40
+ @stack = []
41
+ @index = {}
42
+ end
43
+
44
+ def size
45
+ @stack.size
46
+ end
47
+
48
+ def empty?
49
+ @stack.empty?
50
+ end
51
+
52
+ def push(id, prod)
53
+ @index[id.to_sym] = @stack.size
54
+ @stack << [id.to_sym, prod]
55
+ end
56
+
57
+ def pop
58
+ return nil if empty?
59
+ id, prod = @stack.shift
60
+ @index.delete(id)
61
+ prod
62
+ end
63
+
64
+ def peek
65
+ return nil if empty?
66
+ id, _ = @stack.first
67
+ id
68
+ end
69
+
70
+ def remove(id)
71
+ return nil unless has?(id)
72
+ i = @index.delete(id.to_sym)
73
+ _, producer = @productionstack.delete(i)
74
+ producer
75
+ end
76
+
77
+ def has?(id)
78
+ @index.has_key?(id.to_sym)
79
+ end
80
+
81
+ def [](id)
82
+ @stack[@index[id.to_sym]].last
83
+ end
84
+ end
85
+
44
86
  def initialize(backend, options)
45
87
  @backend = backend ? Backend.load(backend) : Backend.null_be
46
88
  @initopts = options.merge({
47
89
  backend: @backend.name,
48
90
  macros: options[:macros].merge({
91
+ __RIDL__: "#{RIDL_VERSION}",
49
92
  __RIDLBE__: @backend.name.to_s,
50
93
  __RIDLBE_VER__: @backend.version
51
94
  })
52
95
  })
53
96
  @optparser = init_optparser
54
97
  @inputstack = []
98
+ @productionstack = ProductionStack.new
55
99
  @options = nil
56
100
  end
57
101
 
@@ -63,6 +107,8 @@ module IDL
63
107
  @options || @initopts
64
108
  end
65
109
 
110
+ # Input management
111
+
66
112
  def push_input(idlfile, opts)
67
113
  @inputstack << [idlfile, opts]
68
114
  end
@@ -79,6 +125,39 @@ module IDL
79
125
  !@inputstack.empty?
80
126
  end
81
127
 
128
+ # Production management
129
+
130
+ def push_production(id, producer)
131
+ raise "Producer #{id} already queued" if @productionstack.has?(id)
132
+ @productionstack.push(id, producer)
133
+ end
134
+
135
+ def pop_production
136
+ @productionstack.pop
137
+ end
138
+
139
+ def peek_production
140
+ @productionstack.peek
141
+ end
142
+
143
+ def remove_production(id)
144
+ @productionstack.remove(id)
145
+ end
146
+
147
+ def has_productions?
148
+ !@productionstack.empty?
149
+ end
150
+
151
+ def has_production?(id)
152
+ @productionstack.has?(id)
153
+ end
154
+
155
+ def production(id)
156
+ @productionstack[id]
157
+ end
158
+
159
+ # Verbosity control
160
+
82
161
  def verbose_level
83
162
  options[:verbose]
84
163
  end
@@ -92,6 +171,9 @@ module IDL
92
171
  # initialize options
93
172
  @options = @initopts.merge(runopts)
94
173
 
174
+ # mark current (clean) state
175
+ @options.mark
176
+
95
177
  # backup current engine (if any)
96
178
  cur_engine = Thread.current[:ridl_engine]
97
179
  # store currently running engine for current thread
@@ -103,7 +185,7 @@ module IDL
103
185
  @optparser.parse!(argv)
104
186
  rescue ArgumentError => ex
105
187
  IDL.error(ex.inspect)
106
- IDL.error(ex.backtrace.join("\n")) if IDL.verbose_level>0
188
+ IDL.error(ex.backtrace.join("\n")) if IDL.verbose_level > 0
107
189
  return false
108
190
  end
109
191
 
@@ -118,8 +200,8 @@ module IDL
118
200
  options[:output] = o
119
201
 
120
202
  input_base = File.basename(argv.first)
121
- if (input_base != argv.first)
122
- options[:xincludepaths] << (File.dirname(argv.first)+'/')
203
+ if input_base != argv.first
204
+ options[:xincludepaths] << (File.dirname(argv.first) + '/')
123
205
  end
124
206
 
125
207
  return !parse("#include \"#{input_base}\"", options).nil?
@@ -137,23 +219,41 @@ module IDL
137
219
  else
138
220
  File.open(_idlfile, 'r')
139
221
  end
140
- raise RuntimeError, 'cannot read from STDOUT' if $stdout == _fio
222
+ raise 'cannot read from STDOUT' if $stdout == _fio
141
223
 
142
224
  # parse IDL source
143
- IDL.log(1, "RIDL - parsing #{IO === _idlfile ? 'from STDIN': (StringIO === _idlfile ? 'from string' : _idlfile)}")
225
+ IDL.log(1, "RIDL - parsing #{IO === _idlfile ? 'from STDIN' : (StringIO === _idlfile ? 'from string' : _idlfile)}")
144
226
 
145
227
  unless _parser = parse(_fio, _opts)
146
228
  return false
147
229
  end
148
230
 
149
231
  # process parse result -> code generation
150
- IDL.log(2, 'RIDL - starting code generation')
232
+ IDL.log(2, 'RIDL - processing input')
151
233
 
152
234
  GenFile.transaction do
153
235
  begin
236
+
154
237
  backend.process_input(_parser, _opts)
238
+
239
+ # handle productions
240
+ while has_productions?
241
+ IDL.log(2, "RIDL - running production #{peek_production}")
242
+
243
+ # get next-in-line producer
244
+ producer = pop_production
245
+
246
+ # execute the producer
247
+ producer.run(_parser)
248
+ end
249
+
155
250
  rescue Backend::ProcessStop
156
- IDL.log(2, "RIDL - processing #{IO === _idlfile ? 'from STDIN': (StringIO === _idlfile ? 'from string' : _idlfile)} stopped with \"#{$!.message}\"")
251
+ IDL.log(2, "RIDL - processing #{IO === _idlfile ? 'from STDIN' : (StringIO === _idlfile ? 'from string' : _idlfile)} stopped with \"#{$!.message}\"")
252
+
253
+ rescue => ex
254
+ IDL.error(ex)
255
+ IDL.error(ex.backtrace.join("\n")) unless ex.is_a? IDL::ParseError
256
+ return false
157
257
  end
158
258
  end
159
259
  end
@@ -190,22 +290,28 @@ module IDL
190
290
  _opts = options.dup
191
291
 
192
292
  _opts[:idlfile] = _arg
193
- if _opts[:search_incpath]
194
- _fname = _arg
195
- _fpath = if File.file?(_fname) && File.readable?(_fname)
196
- _fname
197
- else
198
- _fp = _opts[:includepaths].find do |_p|
199
- _f = _p + _fname
200
- File.file?(_f) && File.readable?(_f)
293
+ if _opts[:no_input]
294
+ # do not parse specified file (only used as template for output names)
295
+ # instead push an empty StringIO object
296
+ _arg = StringIO.new('')
297
+ else
298
+ if _opts[:search_incpath]
299
+ _fname = _arg
300
+ _fpath = if File.file?(_fname) && File.readable?(_fname)
301
+ _fname
302
+ else
303
+ _fp = _opts[:includepaths].find do |_p|
304
+ _f = _p + _fname
305
+ File.file?(_f) && File.readable?(_f)
306
+ end
307
+ _opts[:outputdir] = _fp unless _fp.nil? || !_opts[:outputdir].nil?
308
+ _fp += '/' + _fname unless _fp.nil?
309
+ _fp
201
310
  end
202
- _opts[:outputdir] = _fp unless _fp.nil? || !_opts[:outputdir].nil?
203
- _fp += '/' + _fname unless _fp.nil?
204
- _fp
205
- end
206
- _arg = _fpath unless _fpath.nil?
311
+ _arg = _fpath unless _fpath.nil?
312
+ end
313
+ _opts[:xincludepaths] << (File.dirname(_arg) + '/')
207
314
  end
208
- _opts[:xincludepaths] << (File.dirname(_arg)+'/')
209
315
 
210
316
  _opts[:outputdir] ||= '.'
211
317
 
@@ -223,44 +329,56 @@ module IDL
223
329
  def init_optparser
224
330
  script_name = File.basename($0, '.*')
225
331
  if not script_name =~ /ridlc/
226
- script_name = 'ruby '+$0
332
+ script_name = 'ruby ' + $0
227
333
  end
228
334
 
229
335
  # set up option parser with common options
230
336
  opts = OptionParser.new
231
337
  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"+
338
+ " backend\t\tSpecifies the IDL language mapping backend to use.\n" +
339
+ " \t\tDefault = :null\n\n" +
234
340
  " Active language mapping = :#{backend.name}"
235
- opts.separator ""
236
- opts.on("-I PATH", "--include=PATH", String,
237
- "Adds include searchpath.",
238
- "Default: none") { |v| @options[:includepaths] << (v.end_with?('\\','/') ? v : v+'/') }
341
+ opts.separator ''
342
+ opts.on('-I PATH', '--include=PATH', String,
343
+ 'Adds include searchpath.',
344
+ 'Default: none') { |v|
345
+ self.options[:includepaths] << (v.end_with?('\\', '/') ? v : v + '/')
346
+ }
239
347
  opts.on('-Dmacro=[value]', String, 'defines preprocessor macro') { |v|
240
348
  name, value = v.split('=')
241
- @options[:macros][name] = (value ? value : true)
349
+ self.options[:macros][name] = (value ? value : true)
350
+ }
351
+ opts.on('-n NAMESPACE', '--namespace=NAMESPACE', String,
352
+ 'Defines rootlevel enclosing namespace.',
353
+ 'Default: nil') { |v|
354
+ self.options[:namespace] = v
355
+ }
356
+ opts.on('-v', '--verbose',
357
+ 'Set verbosity level. Repeat to increment.',
358
+ 'Default: 0') { |_|
359
+ self.options[:verbose] += 1
242
360
  }
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'))+'/')
361
+ opts.on('--debug',
362
+ 'Set parser debug mode. Do NOT do this at home!',
363
+ 'Default: off') { |_|
364
+ self.options[:debug] = true
365
+ }
366
+ opts.on('--search-includepath',
367
+ 'Use include paths to find main IDL source.',
368
+ 'Default: off') { |_|
369
+ self.options[:search_incpath] = true
370
+ }
371
+ opts.on('--no-input',
372
+ 'Do not parse specified file(s) as input IDL.',
373
+ 'Default: off') { |_|
374
+ self.options[:no_input] = true
256
375
  }
257
- opts.on("--search-includepath",
258
- "Use include paths to find main IDL source.",
259
- "Default: off") { |v| @options[:search_incpath]=v }
260
376
  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 }
377
+ opts.on('--output=FILE', String,
378
+ 'Specifies filename to generate output in.',
379
+ 'Default: basename(idlfile)-\'.idl\'+<postfix>+<ext>') { |v|
380
+ self.options[:output] = v
381
+ }
264
382
  end
265
383
 
266
384
  # setup language mapping specific options
@@ -270,7 +388,7 @@ module IDL
270
388
 
271
389
  opts.on('-V', '--version',
272
390
  'Show version information and exit.') {
273
- puts "RIDL compiler #{@options[:macros][:__RIDL__]}"
391
+ puts "RIDL compiler #{RIDL_VERSION}"
274
392
  puts RIDL_COPYRIGHT
275
393
  puts '---'
276
394
  @backend.print_version
@@ -287,24 +405,57 @@ module IDL
287
405
 
288
406
  end
289
407
 
408
+ def IDL.engine?
409
+ !Thread.current[:ridl_engine].nil?
410
+ end
411
+
290
412
  def IDL.backend
291
413
  Thread.current[:ridl_engine] ? Thread.current[:ridl_engine].backend : nil
292
414
  end
293
415
 
294
416
  def IDL.push_input(idlfile, opts)
295
- Thread.current[:ridl_engine].push_input(idlfile, opts) if Thread.current[:ridl_engine]
417
+ Thread.current[:ridl_engine].push_input(idlfile, opts) if engine?
296
418
  end
297
419
 
298
420
  def IDL.pop_input
299
- Thread.current[:ridl_engine].pop_input if Thread.current[:ridl_engine]
421
+ return nil unless engine?
422
+ Thread.current[:ridl_engine].pop_input
300
423
  end
301
424
 
302
425
  def IDL.peek_input
303
- Thread.current[:ridl_engine].peek_input if Thread.current[:ridl_engine]
426
+ return nil unless engine?
427
+ Thread.current[:ridl_engine].peek_input
304
428
  end
305
429
 
306
430
  def IDL.has_input?
307
- Thread.current[:ridl_engine].has_input? if Thread.current[:ridl_engine]
431
+ engine? && Thread.current[:ridl_engine].has_input?
432
+ end
433
+
434
+ def IDL.push_production(id, producer)
435
+ Thread.current[:ridl_engine].push_production(id, producer) if engine?
436
+ end
437
+
438
+ def IDL.pop_production
439
+ return nil unless engine?
440
+ Thread.current[:ridl_engine].pop_production
441
+ end
442
+
443
+ def IDL.remove_production(id)
444
+ return nil unless engine?
445
+ Thread.current[:ridl_engine].remove_production(id)
446
+ end
447
+
448
+ def IDL.has_productions?
449
+ engine? && Thread.current[:ridl_engine].has_productions?
450
+ end
451
+
452
+ def IDL.has_production?(id)
453
+ engine? && Thread.current[:ridl_engine].has_production?(id)
454
+ end
455
+
456
+ def IDL.production(id)
457
+ return nil unless engine?
458
+ Thread.current[:ridl_engine].production(id)
308
459
  end
309
460
 
310
461
  def IDL.verbose_level
@@ -327,32 +478,45 @@ module IDL
327
478
  STDERR.puts(message)
328
479
  end
329
480
 
481
+ def IDL.fatal(message)
482
+ STDERR.puts(message, 'Exiting.')
483
+ exit 1
484
+ end
485
+
330
486
  def IDL.init(argv = ARGV)
331
487
  options = OPTIONS.dup
332
488
 
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
489
+ # load config file(s) if any
490
+ Options.load_config(options)
340
491
 
341
- # add optional search paths for RIDL backends
342
- $:.concat(ENV['RIDL_BE_PATH'].split(/:|;/)) if ENV['RIDL_BE_PATH']
492
+ IDL.log(2, "Configuration [#{options}]")
343
493
 
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
494
+ # check commandline args for explicit language mapping backend
495
+ if argv.first =~ /^:\S+/
496
+ be_name = argv.shift.reverse.chop.reverse.to_sym
497
+ elsif ENV['RIDL_BE_SELECT'] # or from environment
498
+ be_name = ENV['RIDL_BE_SELECT'].to_sym
499
+ elsif options[:backend] # or from configuration
500
+ be_name = options[:backend].to_sym
501
+ end
502
+
503
+ # add optional search paths for RIDL backends
504
+ options[:be_path] ||= []
505
+ options[:be_path].unshift(*ENV['RIDL_BE_PATH'].split(/#{File::PATH_SEPARATOR}/)) if ENV['RIDL_BE_PATH']
506
+ options[:be_path].collect! {|p| p.gsub('\\', '/') } # cleanup to prevent mixed path separators
507
+ $:.concat(options[:be_path]) unless options[:be_path].empty?
508
+
509
+ # check for special bootstrapping switches
510
+ if argv.first == '--preprocess'
511
+ options[:preprocess] = true
512
+ argv.shift
513
+ elsif argv.first == '--ignore-pidl'
514
+ options[:ignore_pidl] = true
515
+ argv.shift
352
516
  end
353
517
 
354
518
  # create RIDL engine
355
- Thread.current[:ridl_engine] = Engine.new(@@be_name, options)
519
+ Thread.current[:ridl_engine] = Engine.new(be_name, options)
356
520
  end
357
521
 
358
522
  # main run method