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/scanner.rb
CHANGED
@@ -21,9 +21,9 @@ module IDL
|
|
21
21
|
@positions = positions
|
22
22
|
end
|
23
23
|
def inspect
|
24
|
-
puts self.class.name
|
24
|
+
puts "#{self.class.name}: #{message}"
|
25
25
|
@positions.each { |pos|
|
26
|
-
print
|
26
|
+
print ' '
|
27
27
|
puts pos
|
28
28
|
}
|
29
29
|
nil
|
@@ -35,7 +35,7 @@ module IDL
|
|
35
35
|
|
36
36
|
class Position
|
37
37
|
def to_s
|
38
|
-
format(
|
38
|
+
format('%s: line %d, column %d', name.to_s, line, column)
|
39
39
|
end
|
40
40
|
def inspect
|
41
41
|
to_s
|
@@ -88,7 +88,7 @@ module IDL
|
|
88
88
|
def gets
|
89
89
|
return nil if @fwd.nil?
|
90
90
|
|
91
|
-
s =
|
91
|
+
s = ''
|
92
92
|
s << getc until [nil, ?\n, ?\r].include? lookc
|
93
93
|
s << getc while [?\n, ?\r].include? lookc
|
94
94
|
|
@@ -112,7 +112,7 @@ module IDL
|
|
112
112
|
false
|
113
113
|
end
|
114
114
|
}
|
115
|
-
|
115
|
+
false
|
116
116
|
end
|
117
117
|
|
118
118
|
def skipwhile(*chars, &block)
|
@@ -140,7 +140,7 @@ module IDL
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def mark(*ini)
|
143
|
-
@mark =
|
143
|
+
@mark = ''
|
144
144
|
ini.each { |i|
|
145
145
|
case i
|
146
146
|
when nil
|
@@ -157,25 +157,25 @@ module IDL
|
|
157
157
|
def getregion
|
158
158
|
ret = @mark
|
159
159
|
@mark = nil
|
160
|
-
|
160
|
+
ret
|
161
161
|
end
|
162
162
|
end ## of class In
|
163
163
|
|
164
164
|
class StrIStream
|
165
165
|
def initialize(src)
|
166
166
|
@src = src
|
167
|
-
@
|
167
|
+
@ix = 0
|
168
168
|
end
|
169
169
|
def to_s
|
170
170
|
@src
|
171
171
|
end
|
172
172
|
def getc
|
173
|
-
ch = @src[@
|
174
|
-
@
|
173
|
+
ch = @src[@ix]
|
174
|
+
@ix += 1
|
175
175
|
ch
|
176
176
|
end
|
177
177
|
def close
|
178
|
-
@
|
178
|
+
@ix = 0
|
179
179
|
end
|
180
180
|
end ## of class StrIStream
|
181
181
|
|
@@ -213,19 +213,23 @@ module IDL
|
|
213
213
|
# name
|
214
214
|
class Identifier < DelegateClass(::String)
|
215
215
|
attr_reader :checked_name
|
216
|
-
|
216
|
+
attr_reader :unescaped_name
|
217
|
+
def initialize(idl_id, checked_id, unescaped_idl_id = nil)
|
217
218
|
super(idl_id)
|
218
219
|
@checked_name = checked_id
|
220
|
+
@unescaped_name = unescaped_idl_id || idl_id
|
219
221
|
end
|
220
222
|
end
|
221
223
|
|
222
224
|
# Scanner
|
223
225
|
def initialize(src, directiver, params = {})
|
224
226
|
@includepaths = params[:includepaths] || []
|
227
|
+
@xincludepaths = params[:xincludepaths] || []
|
225
228
|
@stack = []
|
226
229
|
@expansions = []
|
227
230
|
@prefix = nil
|
228
231
|
@directiver = directiver
|
232
|
+
@directiver.instance_variable_get('@d').instance_variable_set('@scanner', self)
|
229
233
|
@defined = TokenRegistry.new
|
230
234
|
# initialize with predefined macros
|
231
235
|
if params[:macros]
|
@@ -255,35 +259,53 @@ module IDL
|
|
255
259
|
@scan_comment = false # true if parsing commented annotation
|
256
260
|
@in_annotation = false # true if parsing annotation
|
257
261
|
end
|
258
|
-
def find_include(fname)
|
259
|
-
|
262
|
+
def find_include(fname, all = true)
|
263
|
+
if File.file?(fname) && File.readable?(fname)
|
260
264
|
fname
|
261
265
|
else
|
266
|
+
# search transient include paths if allowed (quoted includes)
|
267
|
+
fp = if all then
|
268
|
+
@xincludepaths.find do |p|
|
269
|
+
f = p + '/' + fname
|
270
|
+
File.file?(f) && File.readable?(f)
|
271
|
+
end
|
272
|
+
else
|
273
|
+
nil
|
274
|
+
end
|
275
|
+
# search system include paths if still needed
|
262
276
|
fp = @includepaths.find do |p|
|
263
|
-
f = p +
|
277
|
+
f = p + '/' + fname
|
264
278
|
File.file?(f) && File.readable?(f)
|
265
|
-
end
|
266
|
-
fp += '/' + fname if
|
279
|
+
end unless fp
|
280
|
+
fp += '/' + fname if fp
|
267
281
|
fp
|
268
282
|
end
|
269
283
|
end
|
270
|
-
|
284
|
+
|
285
|
+
def position
|
286
|
+
@in.position
|
287
|
+
end
|
288
|
+
|
289
|
+
def enter_include(src, all = true)
|
271
290
|
if @directiver.is_included?(src)
|
272
291
|
@directiver.declare_include(src)
|
273
292
|
else
|
274
|
-
fpath = find_include(src)
|
293
|
+
fpath = find_include(src, all)
|
275
294
|
if fpath.nil?
|
276
295
|
parse_error "Cannot open include file '#{src}'"
|
277
296
|
end
|
278
297
|
@stack << [:include, @prefix, @ifdef, @in, @ifskip]
|
298
|
+
# record file dir as new searchpath
|
299
|
+
@xincludepaths << File.dirname(fpath)
|
279
300
|
@prefix = nil
|
280
301
|
@ifdef = Array.new
|
281
302
|
@in = In.new(File.open(fpath, 'r'), fpath)
|
282
|
-
@directiver.enter_include(src)
|
303
|
+
@directiver.enter_include(src, fpath)
|
283
304
|
@directiver.pragma_prefix(nil)
|
284
305
|
end
|
285
306
|
end
|
286
307
|
def enter_expansion(src, define)
|
308
|
+
IDL.log(2, "** RIDL - enter_expansion > #{define} = #{src}")
|
287
309
|
@stack << [:define, nil, nil, @in, nil]
|
288
310
|
@expansions << define
|
289
311
|
@in = In.new(StrIStream.new(src), @in.position.name, @in.position.line, @in.position.column)
|
@@ -297,14 +319,15 @@ module IDL
|
|
297
319
|
def in_expansion?
|
298
320
|
more_source? and @stack.last[0] == :define
|
299
321
|
end
|
300
|
-
def leave_source
|
322
|
+
def leave_source
|
301
323
|
if @stack.size>0
|
302
324
|
if @stack.last[0] == :include
|
325
|
+
@xincludepaths.pop # remove directory of finished include
|
303
326
|
@directiver.leave_include
|
304
|
-
|
327
|
+
_, @prefix, @ifdef, @in, @ifskip = @stack.pop
|
305
328
|
@directiver.pragma_prefix(@prefix)
|
306
329
|
else
|
307
|
-
|
330
|
+
_, _, _, @in, _ = @stack.pop
|
308
331
|
@expansions.pop
|
309
332
|
end
|
310
333
|
end
|
@@ -313,7 +336,7 @@ module IDL
|
|
313
336
|
@ifdef.empty? || @ifdef.last
|
314
337
|
end
|
315
338
|
def positions
|
316
|
-
@stack.reverse.inject(@in.nil? ? [] : [@in.position]) {|pos_arr,(
|
339
|
+
@stack.reverse.inject(@in.nil? ? [] : [@in.position]) {|pos_arr,(_, _, _,in_, _)| pos_arr << in_.position }
|
317
340
|
end
|
318
341
|
def parse_error(msg, ex = nil)
|
319
342
|
e = IDL::ParseError.new(msg, positions)
|
@@ -364,45 +387,46 @@ module IDL
|
|
364
387
|
:boolean_literal ]
|
365
388
|
|
366
389
|
BOOL_LITERALS = {
|
367
|
-
|
368
|
-
|
390
|
+
:false => false,
|
391
|
+
:true => true
|
369
392
|
}
|
370
393
|
|
371
394
|
def is_literal?(o)
|
372
|
-
|
395
|
+
LITERALS.include?(o)
|
373
396
|
end
|
374
397
|
|
375
|
-
def extract_annotation_value
|
376
|
-
annotation_value = nil
|
398
|
+
def extract_annotation_value
|
377
399
|
token = next_token # needs '{' (array) or literal or identifier (which means nested annotation object or enum value)
|
378
400
|
if token.first == '{'
|
379
401
|
# extract array of values (literals or identifiers) separated by ','
|
380
402
|
annotation_value = []
|
381
403
|
begin
|
382
|
-
token, ann_value = extract_annotation_value
|
404
|
+
token, ann_value = extract_annotation_value
|
383
405
|
parse_error 'invalid annotation value array' unless token.first == ',' || token.first == '}'
|
384
406
|
annotation_value << ann_value
|
385
407
|
end until token.first == '}'
|
386
408
|
token = next_token
|
387
409
|
elsif token.first == :identifier
|
388
|
-
member_annotation_id = token.last
|
410
|
+
member_annotation_id = token.last.to_s
|
389
411
|
# get nested body
|
390
|
-
token, member_annotation_body = extract_annotation
|
412
|
+
token, member_annotation_body = extract_annotation
|
391
413
|
# determin vaue type; if it has a body it is an annotation instance
|
392
|
-
if member_annotation_body
|
393
|
-
|
414
|
+
annotation_value = if member_annotation_body
|
415
|
+
{ member_annotation_id => member_annotation_body }
|
394
416
|
else # otherwise it is a symbolic value
|
395
|
-
|
417
|
+
member_annotation_id.to_sym
|
396
418
|
end
|
419
|
+
# get next token if needed
|
420
|
+
token = next_token unless token
|
397
421
|
else
|
398
422
|
parse_error 'invalid annotation member' unless is_literal?(token.first)
|
399
423
|
annotation_value = token.last
|
400
424
|
token = next_token
|
401
425
|
end
|
402
|
-
|
426
|
+
[token, annotation_value]
|
403
427
|
end
|
404
428
|
|
405
|
-
def extract_annotation
|
429
|
+
def extract_annotation
|
406
430
|
annotation_body = nil
|
407
431
|
# next token should be '(' in case of normal/single value annotation
|
408
432
|
# or anything else in case of marker annotation
|
@@ -422,17 +446,18 @@ module IDL
|
|
422
446
|
annotation_body = { :value => s1 }
|
423
447
|
else
|
424
448
|
parse_error 'invalid annotation member' unless token.first == '='
|
425
|
-
token, annotation_value = extract_annotation_value
|
449
|
+
token, annotation_value = extract_annotation_value
|
426
450
|
parse_error 'invalid annotation body' unless token.first == ',' || token.first == ')'
|
427
|
-
(annotation_body ||= {})[s1] = annotation_value
|
451
|
+
(annotation_body ||= {})[s1.to_s] = annotation_value
|
428
452
|
end
|
429
453
|
end
|
430
454
|
end until token.first == ')'
|
431
|
-
token = next_token # need to get next token
|
455
|
+
# token = next_token # need to get next token
|
456
|
+
token = nil
|
432
457
|
else
|
433
458
|
# marker annotation or symbolic value; leave body nil
|
434
459
|
end
|
435
|
-
|
460
|
+
[token, annotation_body]
|
436
461
|
end
|
437
462
|
|
438
463
|
def parse_annotation(in_comment = false)
|
@@ -441,30 +466,31 @@ module IDL
|
|
441
466
|
begin
|
442
467
|
# parse (possibly multiple) annotation(s)
|
443
468
|
begin
|
469
|
+
annotation_position = self.position.dup
|
444
470
|
# next token should be identifier (must be on same line following '@')
|
445
471
|
token = next_token
|
446
472
|
parse_error 'annotation identifier expected!' unless token.first == :identifier
|
447
|
-
annotation_id = token.last
|
448
|
-
token, annotation_body = extract_annotation
|
473
|
+
annotation_id = token.last.to_s
|
474
|
+
token, annotation_body = extract_annotation
|
449
475
|
# pass annotation to directiver for processing
|
450
|
-
@directiver.define_annotation(annotation_id, annotation_body || {})
|
451
|
-
end until token.first != ANNOTATION_STR
|
476
|
+
@directiver.define_annotation(annotation_id, annotation_position, in_comment, annotation_body || {})
|
477
|
+
end until token.nil? || token.first != ANNOTATION_STR
|
452
478
|
ensure
|
453
479
|
@in_annotation = false
|
454
480
|
@scan_comment = false
|
455
481
|
end
|
456
482
|
# check identifier for keywords
|
457
|
-
if token.first == :identifier
|
483
|
+
if token && token.first == :identifier
|
458
484
|
# keyword check
|
459
|
-
if (a = KEYWORDS.assoc(token.last)).nil?
|
460
|
-
token = [ :identifier, Identifier.new(token.last, chk_identifier(token.last)) ]
|
485
|
+
if (a = KEYWORDS.assoc(token.last.to_s)).nil?
|
486
|
+
token = [ :identifier, Identifier.new(token.last.to_s, chk_identifier(token.last.to_s), token.last.unescaped_name) ]
|
461
487
|
elsif token.last == a[1]
|
462
488
|
token = [ a[1], nil ]
|
463
489
|
else
|
464
|
-
parse_error "
|
490
|
+
parse_error "'#{token.last}' collides with a keyword '#{a[1]}'"
|
465
491
|
end
|
466
492
|
end
|
467
|
-
|
493
|
+
token
|
468
494
|
end
|
469
495
|
|
470
496
|
def next_identifier(first = nil)
|
@@ -479,26 +505,29 @@ module IDL
|
|
479
505
|
break
|
480
506
|
end
|
481
507
|
end
|
482
|
-
s0 = @in.getregion
|
483
|
-
s1 = s0.downcase
|
508
|
+
s0 = @in.getregion # raw IDL id
|
509
|
+
s1 = s0.downcase.to_sym # downcased symbolized
|
510
|
+
s2 = s0.dup # (to be) unescaped id
|
484
511
|
|
485
512
|
# simple check
|
486
|
-
|
487
|
-
|
513
|
+
escape = false
|
514
|
+
if s2.length == 0
|
515
|
+
parse_error 'identifier expected!'
|
488
516
|
else
|
489
|
-
case
|
517
|
+
case s2[0]
|
490
518
|
when ?a..?z, ?A..?Z
|
491
519
|
when ?_ ## if starts with CORBA IDL escape => remove
|
492
|
-
|
520
|
+
escape = true
|
521
|
+
s2.slice!(0)
|
493
522
|
else
|
494
|
-
parse_error "identifier must begin with alphabet character: #{
|
523
|
+
parse_error "identifier must begin with alphabet character: #{s2}"
|
495
524
|
end
|
496
525
|
end
|
497
526
|
|
498
527
|
# preprocessor check
|
499
|
-
if @defined.has_key?(
|
528
|
+
if @defined.has_key?(s2) and !is_expanded?(s2)
|
500
529
|
# enter expansion as new source
|
501
|
-
enter_expansion(@defined[
|
530
|
+
enter_expansion(@defined[s2], s2)
|
502
531
|
# call next_token to parse expanded source
|
503
532
|
next_token
|
504
533
|
# keyword check
|
@@ -506,16 +535,16 @@ module IDL
|
|
506
535
|
if BOOL_LITERALS.has_key?(s1)
|
507
536
|
[ :boolean_literal, BOOL_LITERALS[s1] ]
|
508
537
|
else
|
509
|
-
[ :identifier, s0 ]
|
538
|
+
[ :identifier, Identifier.new(s2, s2, s0) ]
|
510
539
|
end
|
511
540
|
elsif (a = KEYWORDS.assoc(s1)).nil?
|
512
541
|
# check for language mapping keyword except when
|
513
542
|
# - this is an IDL escaped ('_' prefix) identifier
|
514
|
-
[ :identifier, Identifier.new(
|
543
|
+
[ :identifier, Identifier.new(s2, escape ? s2 : chk_identifier(s2), s0) ]
|
515
544
|
elsif s0 == a[1]
|
516
545
|
[ a[1], nil ]
|
517
546
|
else
|
518
|
-
parse_error "
|
547
|
+
parse_error "'#{s0}' collides with IDL keyword '#{a[1]}'"
|
519
548
|
end
|
520
549
|
end
|
521
550
|
|
@@ -525,7 +554,7 @@ module IDL
|
|
525
554
|
when nil
|
526
555
|
parse_error 'illegal escape sequence'
|
527
556
|
when ?0..?7
|
528
|
-
ret =
|
557
|
+
ret = ''
|
529
558
|
ret << ch
|
530
559
|
1.upto(2) {
|
531
560
|
ch = @in.lookc
|
@@ -538,7 +567,7 @@ module IDL
|
|
538
567
|
}
|
539
568
|
ret = ret.oct
|
540
569
|
when ?x # i'm not sure '\x' should be 0 or 'x'. currently returns 0.
|
541
|
-
ret =
|
570
|
+
ret = ''
|
542
571
|
1.upto(2) {
|
543
572
|
ch = @in.lookc
|
544
573
|
if HEXCHARS.include? ch
|
@@ -550,7 +579,7 @@ module IDL
|
|
550
579
|
}
|
551
580
|
ret = ret.hex
|
552
581
|
when ?u
|
553
|
-
ret =
|
582
|
+
ret = ''
|
554
583
|
1.upto(4) {
|
555
584
|
ch = @in.lookc
|
556
585
|
if HEXCHARS.include? ch
|
@@ -566,7 +595,7 @@ module IDL
|
|
566
595
|
else
|
567
596
|
ret = ('' << ch).unpack('C').first
|
568
597
|
end
|
569
|
-
|
598
|
+
ret
|
570
599
|
end
|
571
600
|
|
572
601
|
def next_escape_str(keep_type_ch = false)
|
@@ -575,7 +604,7 @@ module IDL
|
|
575
604
|
when nil
|
576
605
|
parse_error 'illegal escape sequence'
|
577
606
|
when ?0..?7
|
578
|
-
ret =
|
607
|
+
ret = ''
|
579
608
|
ret << ch
|
580
609
|
1.upto(2) {
|
581
610
|
ch = @in.lookc
|
@@ -588,7 +617,7 @@ module IDL
|
|
588
617
|
}
|
589
618
|
ret = [ :oct, ret ]
|
590
619
|
when ?x # i'm not sure '\x' should be 0 or 'x'. currently returns 0.
|
591
|
-
ret =
|
620
|
+
ret = ''
|
592
621
|
ret << ch if keep_type_ch
|
593
622
|
1.upto(2) {
|
594
623
|
ch = @in.lookc
|
@@ -601,7 +630,7 @@ module IDL
|
|
601
630
|
}
|
602
631
|
ret = [ :hex2, ret ]
|
603
632
|
when ?u
|
604
|
-
ret =
|
633
|
+
ret = ''
|
605
634
|
ret << ch if keep_type_ch
|
606
635
|
1.upto(4) {
|
607
636
|
ch = @in.lookc
|
@@ -622,11 +651,11 @@ module IDL
|
|
622
651
|
ret << ch
|
623
652
|
ret = [ :esc_ch, ch ]
|
624
653
|
end
|
625
|
-
|
654
|
+
ret
|
626
655
|
end
|
627
656
|
|
628
657
|
def skipfloat_or_fixed
|
629
|
-
if
|
658
|
+
if @in.lookc == ?.
|
630
659
|
@in.skipc
|
631
660
|
@in.skipwhile(?0..?9)
|
632
661
|
end
|
@@ -641,7 +670,7 @@ module IDL
|
|
641
670
|
@in.skipwhile(?0..?9)
|
642
671
|
return :fixed_pt_literal
|
643
672
|
end
|
644
|
-
|
673
|
+
:floating_pt_literal
|
645
674
|
end
|
646
675
|
|
647
676
|
def skipline
|
@@ -653,7 +682,7 @@ module IDL
|
|
653
682
|
end
|
654
683
|
|
655
684
|
def getline
|
656
|
-
s =
|
685
|
+
s = ''
|
657
686
|
while TRUE
|
658
687
|
ch = @in.lookc
|
659
688
|
break if ch.nil?
|
@@ -664,7 +693,7 @@ module IDL
|
|
664
693
|
if @in.lookc == ?\\
|
665
694
|
# escape sequence
|
666
695
|
s << @in.getc
|
667
|
-
|
696
|
+
_, escstr = next_escape_str(true)
|
668
697
|
s << escstr
|
669
698
|
elsif @in.lookc == ?\" #"
|
670
699
|
break
|
@@ -672,7 +701,7 @@ module IDL
|
|
672
701
|
# normal character
|
673
702
|
s << @in.getc
|
674
703
|
else
|
675
|
-
parse_error
|
704
|
+
parse_error 'unterminated string literal'
|
676
705
|
end
|
677
706
|
end
|
678
707
|
s << @in.getc # closing quote
|
@@ -681,7 +710,7 @@ module IDL
|
|
681
710
|
if @in.lookc == ?\\
|
682
711
|
# escape sequence
|
683
712
|
s << @in.getc
|
684
|
-
|
713
|
+
_, escstr = next_escape_str(true)
|
685
714
|
s << escstr
|
686
715
|
elsif @in.lookc && @in.lookc != ?\' #'
|
687
716
|
# normal character
|
@@ -692,7 +721,7 @@ module IDL
|
|
692
721
|
end
|
693
722
|
s << @in.getc # closing quote
|
694
723
|
when LFCR.include?(ch)
|
695
|
-
@in.skipwhile
|
724
|
+
@in.skipwhile { |ch_| LFCR.include? ch_ }
|
696
725
|
break
|
697
726
|
when ch == ?/
|
698
727
|
@in.skipc
|
@@ -718,7 +747,7 @@ module IDL
|
|
718
747
|
@in.skipc
|
719
748
|
if LFCR.include?(@in.lookc)
|
720
749
|
# line continuation
|
721
|
-
@in.skipwhile
|
750
|
+
@in.skipwhile { |ch_| LFCR.include? ch_ }
|
722
751
|
if @in.lookc.nil?
|
723
752
|
parse_error "line continuation character ('\\') not allowed as last character in file."
|
724
753
|
end
|
@@ -734,14 +763,14 @@ module IDL
|
|
734
763
|
end
|
735
764
|
|
736
765
|
def resolve_define(id, stack = [])
|
737
|
-
return id if
|
766
|
+
return id if %w(true false).include?(id)
|
738
767
|
IDL.log(3,"*** RIDL - resolve_define(#{id})")
|
739
768
|
if @defined.has_key?(id)
|
740
769
|
define_ = @defined[id]
|
741
770
|
stack << id
|
742
771
|
parse_error("circular macro reference detected for [#{define_}]") if stack.include?(define_)
|
743
772
|
# resolve any nested macro definitions
|
744
|
-
define_.gsub(/(^|[\W])([A-Za-z_][\w]*)/) do |
|
773
|
+
define_.gsub(/(^|[\W])([A-Za-z_][\w]*)/) do |_| "#{$1}#{resolve_define($2, stack)}" end
|
745
774
|
else
|
746
775
|
'0' # unknown id
|
747
776
|
end
|
@@ -756,7 +785,7 @@ module IDL
|
|
756
785
|
when Numeric
|
757
786
|
rc != 0
|
758
787
|
else
|
759
|
-
parse_error
|
788
|
+
parse_error 'invalid preprocessor expression.'
|
760
789
|
end
|
761
790
|
end
|
762
791
|
|
@@ -769,7 +798,7 @@ module IDL
|
|
769
798
|
if /(else|endif|elif)/ === s1
|
770
799
|
|
771
800
|
if @ifdef.empty?
|
772
|
-
parse_error
|
801
|
+
parse_error '#else/#elif/#endif must not appear without preceding #if'
|
773
802
|
end
|
774
803
|
case s1
|
775
804
|
when 'else'
|
@@ -777,7 +806,7 @@ module IDL
|
|
777
806
|
if @ifskip # true branch has already been parsed
|
778
807
|
@ifdef[@ifdef.size - 1] = false
|
779
808
|
else
|
780
|
-
@ifdef[@ifdef.size - 1] ^= true
|
809
|
+
@ifdef[@ifdef.size - 1] ^= true
|
781
810
|
@ifskip = @ifdef.last
|
782
811
|
end
|
783
812
|
end
|
@@ -799,7 +828,7 @@ module IDL
|
|
799
828
|
def_id = $2
|
800
829
|
s2.gsub!(/(^|[\W])(defined\s*\(\s*\w+\s*\))/, '\1'+"#{@defined.has_key?(def_id).to_s}")
|
801
830
|
end
|
802
|
-
s2.gsub!(/(^|[\W])([A-Za-z_][\w]*)/) do |
|
831
|
+
s2.gsub!(/(^|[\W])([A-Za-z_][\w]*)/) do |_| "#{$1}#{resolve_define($2)}" end
|
803
832
|
begin
|
804
833
|
@ifdef[@ifdef.size - 1] = eval_directive(s2)
|
805
834
|
@ifskip = @ifdef[@ifdef.size - 1]
|
@@ -808,7 +837,7 @@ module IDL
|
|
808
837
|
rescue => ex
|
809
838
|
p ex
|
810
839
|
puts ex.backtrace.join("\n")
|
811
|
-
parse_error
|
840
|
+
parse_error 'error evaluating #elif'
|
812
841
|
end
|
813
842
|
end
|
814
843
|
end
|
@@ -816,25 +845,26 @@ module IDL
|
|
816
845
|
|
817
846
|
elsif /(if|ifn?def)/ === s1
|
818
847
|
|
819
|
-
|
820
|
-
when /ifn?def/
|
848
|
+
if /ifn?def/ === s1
|
821
849
|
if do_parse?
|
822
|
-
if
|
823
|
-
|
824
|
-
end
|
825
|
-
@ifdef.push(@defined[$1].nil? ^ (s1 == "ifdef"))
|
850
|
+
parse_error 'no #if(n)def target.' unless /^(\w+)/ === s2
|
851
|
+
@ifdef.push(@defined[$1].nil? ^ (s1 == 'ifdef'))
|
826
852
|
@ifskip = @ifdef.last
|
827
853
|
else
|
828
854
|
@ifnest += 1
|
829
855
|
end
|
830
856
|
|
831
|
-
when 'if'
|
857
|
+
else # when 'if'
|
832
858
|
if do_parse?
|
833
|
-
|
834
|
-
|
835
|
-
|
859
|
+
# match 'defined(Foo)' or 'defined Foo'
|
860
|
+
while s2 =~ /(^|[\W])defined(\s*\(\s*(\w+)\s*\)|\s+(\w+))/
|
861
|
+
IDL.log(2,"** RIDL - parse_directive : resolving 'defined(#{$3 || $4})'")
|
862
|
+
def_id = $3 || $4
|
863
|
+
# resolve 'defined' expression to 'true' or 'false' according to actual macro definition
|
864
|
+
s2.gsub!(/(^|[\W])(defined\s*[\s\(]\s*#{def_id}(\s*\))?)/, '\1'+"#{@defined.has_key?(def_id).to_s}")
|
836
865
|
end
|
837
|
-
|
866
|
+
# match and resolve any macro variables listed in conditional expression
|
867
|
+
s2.gsub!(/(^|[\W])([A-Za-z_][\w]*)/) do |_| "#{$1}#{resolve_define($2)}" end
|
838
868
|
begin
|
839
869
|
@ifdef.push(eval_directive(s2))
|
840
870
|
@ifskip = @ifdef.last
|
@@ -843,7 +873,7 @@ module IDL
|
|
843
873
|
rescue => ex
|
844
874
|
p ex
|
845
875
|
puts ex.backtrace.join("\n")
|
846
|
-
parse_error
|
876
|
+
parse_error 'error evaluating #if'
|
847
877
|
end
|
848
878
|
else
|
849
879
|
@ifnest += 1
|
@@ -860,28 +890,27 @@ module IDL
|
|
860
890
|
parse_error(s2)
|
861
891
|
|
862
892
|
when 'define'
|
863
|
-
|
864
|
-
|
865
|
-
if
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
end
|
870
|
-
@defined[a[0]] = a[1]
|
893
|
+
defid = s2.split.first
|
894
|
+
parse_error 'no #define target.' unless defid
|
895
|
+
parse_error "#{defid} is already #define-d." if @defined[defid]
|
896
|
+
defval = s2.sub(/^\s*#{defid}/, '').strip
|
897
|
+
defval = true if defval.empty?
|
898
|
+
@defined[defid] = defval
|
871
899
|
|
872
900
|
when 'undef'
|
873
901
|
@defined.delete(s2)
|
874
902
|
|
875
903
|
when 'include'
|
876
904
|
if s2[0,1] == '"' || s2[0,1] == '<'
|
905
|
+
quoted_inc = (s2[0,1] == '"')
|
877
906
|
if s2.size>2
|
878
907
|
s2.strip!
|
879
908
|
s2 = s2.slice(1..(s2.size-2))
|
880
909
|
else
|
881
|
-
s2 =
|
910
|
+
s2 = ''
|
882
911
|
end
|
883
912
|
end
|
884
|
-
enter_include(s2)
|
913
|
+
enter_include(s2, quoted_inc)
|
885
914
|
|
886
915
|
when /[0-9]+/
|
887
916
|
# ignore line directive
|
@@ -907,12 +936,12 @@ module IDL
|
|
907
936
|
|
908
937
|
def next_token
|
909
938
|
sign = nil
|
910
|
-
str =
|
939
|
+
str = '' #initialize empty string
|
911
940
|
while TRUE
|
912
941
|
ch = @in.getc
|
913
942
|
if ch.nil?
|
914
943
|
if @ifdef.size>0 and !in_expansion?
|
915
|
-
parse_error
|
944
|
+
parse_error 'mismatched #if/#endif'
|
916
945
|
end
|
917
946
|
if more_source?
|
918
947
|
leave_source
|
@@ -949,32 +978,30 @@ module IDL
|
|
949
978
|
if @in_annotation
|
950
979
|
return [str, str]
|
951
980
|
else
|
952
|
-
return parse_annotation
|
981
|
+
# return token returned by parse_annotation or parse next token recursively
|
982
|
+
return parse_annotation || next_token
|
953
983
|
end
|
954
984
|
|
955
985
|
when ch == ?: #
|
956
986
|
if @in.lookc == ?: #
|
957
987
|
@in.skipc
|
958
|
-
return
|
988
|
+
return %w(:: ::)
|
959
989
|
else
|
960
|
-
return
|
990
|
+
return %w(: :)
|
961
991
|
end
|
962
992
|
|
963
993
|
when ch == ?L
|
964
994
|
_nxtc = @in.lookc
|
965
995
|
if _nxtc == ?\' #' #single quote, for a character literal.
|
966
|
-
ret = 0
|
967
996
|
@in.skipc # skip 'L'
|
968
997
|
_nxtc = @in.lookc
|
969
|
-
if _nxtc == ?\\
|
998
|
+
ret = if _nxtc == ?\\
|
970
999
|
@in.skipc
|
971
|
-
|
1000
|
+
next_escape_str
|
972
1001
|
elsif _nxtc == ?\' #'
|
973
|
-
|
1002
|
+
[ nil, nil ]
|
974
1003
|
else
|
975
|
-
|
976
|
-
ret << @in.getc
|
977
|
-
ret = [ :char, ret ]
|
1004
|
+
[ :char, '' << @in.getc ]
|
978
1005
|
end
|
979
1006
|
|
980
1007
|
if @in.lookc != ?\' #'
|
@@ -1025,7 +1052,7 @@ module IDL
|
|
1025
1052
|
parse_error "cannot find comment closing brace (\'*/\'). "
|
1026
1053
|
end
|
1027
1054
|
@in.skipc
|
1028
|
-
str =
|
1055
|
+
str = '' # reset
|
1029
1056
|
next
|
1030
1057
|
|
1031
1058
|
elsif _nxtc == ?/
|
@@ -1035,23 +1062,24 @@ module IDL
|
|
1035
1062
|
_nxtc = @in.lookc
|
1036
1063
|
if _nxtc == ANNOTATION
|
1037
1064
|
@in.skipc
|
1038
|
-
return parse_annotation
|
1065
|
+
# return token returned by parse_annotation or parse next token recursively
|
1066
|
+
return parse_annotation(true) || next_token
|
1039
1067
|
else
|
1040
1068
|
@in.skipuntil(?\n, ?\r)
|
1041
1069
|
end
|
1042
1070
|
end
|
1043
|
-
str =
|
1071
|
+
str = '' # reset
|
1044
1072
|
next
|
1045
1073
|
|
1046
1074
|
else
|
1047
|
-
return
|
1075
|
+
return %w(/ /)
|
1048
1076
|
end
|
1049
1077
|
|
1050
1078
|
when ch == ?+ || ch == ?-
|
1051
1079
|
_nxtc = @in.lookc
|
1052
1080
|
if (?0..?9).include? _nxtc
|
1053
1081
|
sign = ch
|
1054
|
-
str =
|
1082
|
+
str = '' # reset
|
1055
1083
|
next
|
1056
1084
|
else
|
1057
1085
|
return [str, str]
|
@@ -1059,7 +1087,6 @@ module IDL
|
|
1059
1087
|
|
1060
1088
|
when (?1..?9).include?(ch)
|
1061
1089
|
@in.mark(sign, ch)
|
1062
|
-
sign = nil
|
1063
1090
|
@in.skipwhile(?0..?9)
|
1064
1091
|
num_type = ([?., ?e, ?E, ?d, ?D].include?(@in.lookc)) ? skipfloat_or_fixed : :integer_literal
|
1065
1092
|
|
@@ -1078,28 +1105,26 @@ module IDL
|
|
1078
1105
|
@in.skipwhile(?0..?9)
|
1079
1106
|
num_type = (?. != @in.lookc) ? skipfloat_or_fixed : nil
|
1080
1107
|
s = @in.getregion
|
1081
|
-
if s ==
|
1082
|
-
parse_error
|
1108
|
+
if s == '.'
|
1109
|
+
parse_error 'token consisting of single dot (.) is invalid.'
|
1083
1110
|
end
|
1084
1111
|
if num_type == :floating_pt_literal
|
1085
1112
|
return [:floating_pt_literal, s.to_f]
|
1086
1113
|
elsif num_type == :fixed_pt_literal
|
1087
1114
|
return [:fixed_pt_literal, s]
|
1088
1115
|
else
|
1089
|
-
parse_error
|
1116
|
+
parse_error 'invalid floating point constant.'
|
1090
1117
|
end
|
1091
1118
|
|
1092
1119
|
when ch == ?0
|
1093
1120
|
@in.mark(sign, ch)
|
1094
|
-
sign = nil
|
1095
1121
|
|
1096
1122
|
_nxtc = @in.lookc
|
1097
1123
|
if _nxtc == ?x || _nxtc == ?X
|
1098
1124
|
@in.skipc
|
1099
|
-
@in.skipwhile
|
1125
|
+
@in.skipwhile { |ch_| HEXCHARS.include? ch_ }
|
1100
1126
|
s = @in.getregion
|
1101
1127
|
return [:integer_literal, s.hex]
|
1102
|
-
|
1103
1128
|
else
|
1104
1129
|
dec = FALSE
|
1105
1130
|
@in.skipwhile(?0..?7)
|
@@ -1110,30 +1135,28 @@ module IDL
|
|
1110
1135
|
|
1111
1136
|
num_type = ([?., ?e, ?E, ?d, ?D].include?(@in.lookc)) ? skipfloat_or_fixed : :integer_literal
|
1112
1137
|
|
1113
|
-
ret = nil
|
1114
1138
|
s = @in.getregion
|
1115
|
-
if num_type == :floating_pt_literal
|
1116
|
-
|
1139
|
+
ret = if num_type == :floating_pt_literal
|
1140
|
+
[:floating_pt_literal, s.to_f]
|
1117
1141
|
elsif num_type == :fixed_pt_literal
|
1118
|
-
|
1142
|
+
[:fixed_pt_literal, s]
|
1119
1143
|
elsif dec
|
1120
1144
|
parse_error "decimal literal starting with '0' should be octal ('0'..'7' only): #{s}"
|
1121
1145
|
else
|
1122
|
-
|
1146
|
+
[:integer_literal, s.oct]
|
1123
1147
|
end
|
1124
1148
|
return ret
|
1125
1149
|
end
|
1126
1150
|
|
1127
1151
|
when ch == ?\' #' #single quote, for a character literal.
|
1128
|
-
ret = 0
|
1129
1152
|
_nxtc = @in.lookc
|
1130
|
-
if _nxtc == ?\\
|
1153
|
+
ret = if _nxtc == ?\\
|
1131
1154
|
@in.skipc
|
1132
|
-
|
1155
|
+
next_escape
|
1133
1156
|
elsif _nxtc == ?\' #'
|
1134
|
-
|
1157
|
+
0
|
1135
1158
|
elsif _nxtc
|
1136
|
-
|
1159
|
+
('' << @in.getc).unpack('C').first
|
1137
1160
|
end
|
1138
1161
|
|
1139
1162
|
if @in.lookc != ?\' #'
|
@@ -1144,7 +1167,7 @@ module IDL
|
|
1144
1167
|
return [ :character_literal, ret ]
|
1145
1168
|
|
1146
1169
|
when ch == ?\" #" #double quote, for a string literal.
|
1147
|
-
ret =
|
1170
|
+
ret = ''
|
1148
1171
|
while TRUE
|
1149
1172
|
_nxtc = @in.lookc
|
1150
1173
|
if _nxtc == ?\\
|
@@ -1156,7 +1179,7 @@ module IDL
|
|
1156
1179
|
elsif _nxtc
|
1157
1180
|
ret << @in.getc
|
1158
1181
|
else
|
1159
|
-
parse_error
|
1182
|
+
parse_error 'unterminated string literal'
|
1160
1183
|
end
|
1161
1184
|
end
|
1162
1185
|
|
@@ -1166,7 +1189,7 @@ module IDL
|
|
1166
1189
|
end #of case
|
1167
1190
|
|
1168
1191
|
end #of while
|
1169
|
-
parse_error
|
1192
|
+
parse_error 'unexcepted error'
|
1170
1193
|
end #of method next_token
|
1171
1194
|
end
|
1172
1195
|
|