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/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
|
|