ridl 2.5.6 → 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ridl/scanner.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 'racc/parser'
14
13
  require 'delegate'
@@ -44,7 +43,9 @@ module IDL
44
43
 
45
44
  class In
46
45
  def initialize(src, name = '', line = 0, column = 1)
47
- @src, @fwd, @bwd = src, src.getc, nil
46
+ @src = src
47
+ @fwd = src.getc # look ahead character
48
+ @bwd = nil # look back character
48
49
  @pos = Position.new(name, line, column)
49
50
  @mark = nil
50
51
  end
@@ -72,14 +73,14 @@ module IDL
72
73
  @pos.line += 1
73
74
  @pos.column = 1
74
75
  end
75
- else
76
+ else
76
77
  @pos.column += 1
77
78
  end
78
79
 
79
80
  if false
80
81
  if not @bwd.nil? or cur.nil? or @fwd.nil?
81
82
  printf("%c(%02x), %c(%02x), %c(%02x) @(l:%d,c:%d)\n",
82
- @bwd,@bwd,cur,cur,@fwd,@fwd, @pos.line, @pos.column)
83
+ @bwd, @bwd, cur, cur, @fwd, @fwd, @pos.line, @pos.column)
83
84
  end
84
85
  end
85
86
  @bwd = cur
@@ -97,46 +98,24 @@ module IDL
97
98
  end
98
99
  alias skipc getc
99
100
 
100
- def _include?(ch, *chars)
101
- chars.each { |v|
102
- return true if case v
103
- when Array
104
- _include?(ch, *v)
105
- when Enumerable
106
- v.include? ch
107
- when Fixnum
108
- v == ch
109
- when String
110
- v == ch
111
- else
112
- false
113
- end
114
- }
115
- false
116
- end
117
-
118
101
  def skipwhile(*chars, &block)
119
- if block.nil?
120
- block = Proc.new { |ch| _include?(ch, *chars) }
121
- end
122
-
123
- until (ch = lookc).nil?
124
- break unless block.call(ch)
125
- skipc
102
+ if block
103
+ until (ch = lookc).nil?
104
+ return ch unless block.call(ch)
105
+ skipc
106
+ end
126
107
  end
127
- ch
108
+ nil
128
109
  end
129
110
 
130
111
  def skipuntil(*chars, &block)
131
- if block.nil?
132
- block = Proc.new { |ch| _include?(ch, *chars) }
133
- end
134
-
135
- until (ch = lookc).nil?
136
- break if block.call(ch)
137
- skipc
112
+ if block
113
+ until (ch = lookc).nil?
114
+ return ch if block.call(ch)
115
+ skipc
116
+ end
138
117
  end
139
- ch
118
+ nil
140
119
  end
141
120
 
142
121
  def mark(*ini)
@@ -159,6 +138,10 @@ module IDL
159
138
  @mark = nil
160
139
  ret
161
140
  end
141
+
142
+ def close
143
+ @src.close # close input source
144
+ end
162
145
  end ## of class In
163
146
 
164
147
  class StrIStream
@@ -249,7 +232,7 @@ module IDL
249
232
  when File
250
233
  i = src
251
234
  nm = src.path
252
- when IO
235
+ when IO, StringIO
253
236
  i = src
254
237
  nm = '<io>'
255
238
  else
@@ -261,7 +244,7 @@ module IDL
261
244
  end
262
245
  def find_include(fname, all = true)
263
246
  if File.file?(fname) && File.readable?(fname)
264
- fname
247
+ File.expand_path(fname)
265
248
  else
266
249
  # search transient include paths if allowed (quoted includes)
267
250
  fp = if all then
@@ -298,7 +281,7 @@ module IDL
298
281
  end
299
282
  @stack << [:include, @prefix, @ifdef, @in, @ifskip]
300
283
  # record file dir as new searchpath
301
- @xincludepaths << (File.dirname(fpath)+'/')
284
+ @xincludepaths << (File.dirname(fpath) + '/')
302
285
  @prefix = nil
303
286
  @ifdef = Array.new
304
287
  @in = In.new(File.open(fpath, 'r'), fpath)
@@ -316,13 +299,16 @@ module IDL
316
299
  @expansions.include?(define)
317
300
  end
318
301
  def more_source?
319
- @stack.size>0
302
+ @stack.size > 0
320
303
  end
321
304
  def in_expansion?
322
305
  more_source? and @stack.last[0] == :define
323
306
  end
324
307
  def leave_source
325
- if @stack.size>0
308
+ # make sure to close the input source
309
+ @in.close
310
+ # check if we have any previous source still stacked up
311
+ if @stack.size > 0
326
312
  if @stack.last[0] == :include
327
313
  @xincludepaths.pop # remove directory of finished include
328
314
  @directiver.leave_include
@@ -338,7 +324,7 @@ module IDL
338
324
  @ifdef.empty? || @ifdef.last
339
325
  end
340
326
  def positions
341
- @stack.reverse.inject(@in.nil? ? [] : [@in.position]) {|pos_arr,(_, _, _,in_, _)| pos_arr << in_.position }
327
+ @stack.reverse.inject(@in.nil? ? [] : [@in.position]) {|pos_arr, (_, _, _, in_, _)| pos_arr << in_.position }
342
328
  end
343
329
  def parse_error(msg, ex = nil)
344
330
  e = IDL::ParseError.new(msg, positions)
@@ -347,7 +333,8 @@ module IDL
347
333
  end
348
334
 
349
335
  LFCR = [ (?\n), (?\r) ]
350
- WHITESPACE = [ (?\ ), (?\t) ].concat(LFCR)
336
+ SPACES = [ (?\ ), (?\t) ]
337
+ WHITESPACE = SPACES + LFCR
351
338
 
352
339
  ANNOTATION = ?@
353
340
  ANNOTATION_STR = '@'
@@ -361,9 +348,16 @@ module IDL
361
348
 
362
349
  SHIFTCHARS = [ ?<, ?> ]
363
350
 
364
- HEXCHARS = [(?0..?9).to_a, (?a..?f).to_a, (?A..?F).to_a].flatten
351
+ DIGITS = (?0..?9).to_a
352
+ ALPHA_LC = (?a..?z).to_a
353
+ ALPHA_UC = (?A..?Z).to_a
354
+ OCTALS = (?0..?7).to_a
355
+ HEXCHARS = DIGITS + (?a..?f).to_a + (?A..?F).to_a
356
+ SIGNS = [?-, ?+]
357
+ DOT = ?.
365
358
 
366
- IDCHARS = [?_ , (?a..?z).to_a, (?A..?Z).to_a].flatten
359
+ IDCHARS = [?_ ] + ALPHA_LC + ALPHA_UC
360
+ FULL_IDCHARS = IDCHARS + DIGITS
367
361
 
368
362
  ESCTBL = CharRegistry.new({
369
363
  :n => ?\n, :t => ?\t, :v => ?\v, :b => ?\b,
@@ -376,7 +370,7 @@ module IDL
376
370
  long manages mirrorport module multiple native Object octet oneway out port porttype primarykey private provides
377
371
  public publishes raises readonly setraises sequence short string struct supports switch TRUE truncatable typedef
378
372
  typeid typename typeprefix unsigned union uses ValueBase valuetype void wchar wstring
379
- ).inject(TokenRegistry.new) { |h,a| h[a.downcase.to_sym] = a; h }
373
+ ).inject(TokenRegistry.new) { |h, a| h[a.downcase.to_sym] = a; h }
380
374
 
381
375
  LITERALS = [
382
376
  :integer_literal,
@@ -432,8 +426,9 @@ module IDL
432
426
  annotation_body = nil
433
427
  # next token should be '(' in case of normal/single value annotation
434
428
  # or anything else in case of marker annotation
435
- token = next_token
436
- if token.first == '('
429
+ skip_spaces # skip till next non-space or eol
430
+ if peek_next == '('
431
+ token = next_token # parse '('
437
432
  begin
438
433
  # identifier or value (in case of single value annotation) expected
439
434
  token = next_token
@@ -454,9 +449,9 @@ module IDL
454
449
  end
455
450
  end
456
451
  end until token.first == ')'
457
- # token = next_token # need to get next token
458
- token = nil
452
+ token = next_token_before_eol
459
453
  else
454
+ token = next_token_before_eol
460
455
  # marker annotation or symbolic value; leave body nil
461
456
  end
462
457
  [token, annotation_body]
@@ -495,13 +490,18 @@ module IDL
495
490
  token
496
491
  end
497
492
 
493
+ def peek_next
494
+ @in.lookc
495
+ end
496
+
497
+ def skip_spaces
498
+ @in.skipwhile {|c| SPACES.include?(c) }
499
+ end
500
+
498
501
  def next_identifier(first = nil)
499
502
  @in.mark(first)
500
- while TRUE
501
- case @in.lookc
502
- when nil
503
- break
504
- when ?0..?9, ?a..?z, ?A..?Z, ?_
503
+ while true
504
+ if FULL_IDCHARS.include?(@in.lookc)
505
505
  @in.skipc
506
506
  else
507
507
  break
@@ -512,18 +512,13 @@ module IDL
512
512
  s2 = s0.dup # (to be) unescaped id
513
513
 
514
514
  # simple check
515
- escape = false
516
515
  if s2.length == 0
517
516
  parse_error 'identifier expected!'
518
517
  else
519
- case s2[0]
520
- when ?a..?z, ?A..?Z
521
- when ?_ ## if starts with CORBA IDL escape => remove
522
- escape = true
523
- s2.slice!(0)
524
- else
525
- parse_error "identifier must begin with alphabet character: #{s2}"
518
+ if s2[0] == ?_
519
+ s2.slice!(0) ## if starts with CORBA IDL escape => remove
526
520
  end
521
+ parse_error "identifier must begin with alphabet character: #{s2}" unless ALPHA_LC.include?(s2[0]) || ALPHA_UC.include?(s2[0])
527
522
  end
528
523
 
529
524
  # preprocessor check
@@ -540,9 +535,8 @@ module IDL
540
535
  [ :identifier, Identifier.new(s2, s2, s0) ]
541
536
  end
542
537
  elsif (a = KEYWORDS.assoc(s1)).nil?
543
- # check for language mapping keyword except when
544
- # - this is an IDL escaped ('_' prefix) identifier
545
- [ :identifier, Identifier.new(s2, escape ? s2 : chk_identifier(s2), s0) ]
538
+ # check for language mapping keyword
539
+ [ :identifier, Identifier.new(s2, chk_identifier(s2), s0) ]
546
540
  elsif s0 == a[1]
547
541
  [ a[1], nil ]
548
542
  else
@@ -657,26 +651,26 @@ module IDL
657
651
  end
658
652
 
659
653
  def skipfloat_or_fixed
660
- if @in.lookc == ?.
654
+ if @in.lookc == DOT
661
655
  @in.skipc
662
- @in.skipwhile(?0..?9)
656
+ @in.skipwhile {|c| DIGITS.include?(c) }
663
657
  end
664
658
  if [?e, ?E].include? @in.lookc
665
659
  @in.skipc
666
- @in.skipc if [?+, ?-].include? @in.lookc
667
- @in.skipwhile(?0..?9)
660
+ @in.skipc if SIGNS.include? @in.lookc
661
+ @in.skipwhile {|c| DIGITS.include?(c) }
668
662
  return :floating_pt_literal
669
663
  elsif [?d, ?D].include? @in.lookc
670
664
  @in.skipc
671
- @in.skipc if [?+, ?-].include? @in.lookc
672
- @in.skipwhile(?0..?9)
665
+ @in.skipc if SIGNS.include? @in.lookc
666
+ @in.skipwhile {|c| DIGITS.include?(c) }
673
667
  return :fixed_pt_literal
674
668
  end
675
669
  :floating_pt_literal
676
670
  end
677
671
 
678
672
  def skipline
679
- while TRUE
673
+ while true
680
674
  s = @in.gets
681
675
  until s.chomp!.nil?; end
682
676
  break unless s[s.length - 1] == ?\\
@@ -685,13 +679,13 @@ module IDL
685
679
 
686
680
  def getline
687
681
  s = ''
688
- while TRUE
682
+ while true
689
683
  ch = @in.lookc
690
684
  break if ch.nil?
691
685
  case
692
686
  when (ch == ?\") #"
693
687
  s << @in.getc # opening quote
694
- while TRUE
688
+ while true
695
689
  if @in.lookc == ?\\
696
690
  # escape sequence
697
691
  s << @in.getc
@@ -766,7 +760,7 @@ module IDL
766
760
 
767
761
  def resolve_define(id, stack = [])
768
762
  return id if %w(true false).include?(id)
769
- IDL.log(3,"*** RIDL - resolve_define(#{id})")
763
+ IDL.log(3, "*** RIDL - resolve_define(#{id})")
770
764
  if @defined.has_key?(id)
771
765
  define_ = @defined[id]
772
766
  stack << id
@@ -779,7 +773,7 @@ module IDL
779
773
  end
780
774
 
781
775
  def eval_directive(s)
782
- IDL.log(2,"** RIDL - eval_directive(#{s})")
776
+ IDL.log(3, "** RIDL - eval_directive(#{s})")
783
777
  rc = eval(s)
784
778
  case rc
785
779
  when FalseClass, TrueClass
@@ -792,10 +786,10 @@ module IDL
792
786
  end
793
787
 
794
788
  def parse_directive
795
- @in.skipwhile(?\ , ?\t)
789
+ @in.skipwhile {|c| SPACES.include?(c) }
796
790
  s = getline
797
791
  /^(\w*)\s*/ === s
798
- s1,s2 = $1, $' #'
792
+ s1, s2 = $1, $' #'
799
793
 
800
794
  if /(else|endif|elif)/ === s1
801
795
 
@@ -828,7 +822,7 @@ module IDL
828
822
  else
829
823
  while s2 =~ /(^|[\W])defined\s*\(\s*(\w+)\s*\)/
830
824
  def_id = $2
831
- s2.gsub!(/(^|[\W])(defined\s*\(\s*\w+\s*\))/, '\1'+"#{@defined.has_key?(def_id).to_s}")
825
+ s2.gsub!(/(^|[\W])(defined\s*\(\s*\w+\s*\))/, '\1' + "#{@defined.has_key?(def_id).to_s}")
832
826
  end
833
827
  s2.gsub!(/(^|[\W])([A-Za-z_][\w]*)/) do |_| "#{$1}#{resolve_define($2)}" end
834
828
  begin
@@ -860,10 +854,10 @@ module IDL
860
854
  if do_parse?
861
855
  # match 'defined(Foo)' or 'defined Foo'
862
856
  while s2 =~ /(^|[\W])defined(\s*\(\s*(\w+)\s*\)|\s+(\w+))/
863
- IDL.log(2,"** RIDL - parse_directive : resolving 'defined(#{$3 || $4})'")
857
+ IDL.log(3, "** RIDL - parse_directive : resolving 'defined(#{$3 || $4})'")
864
858
  def_id = $3 || $4
865
859
  # resolve 'defined' expression to 'true' or 'false' according to actual macro definition
866
- s2.gsub!(/(^|[\W])(defined\s*[\s\(]\s*#{def_id}(\s*\))?)/, '\1'+"#{@defined.has_key?(def_id).to_s}")
860
+ s2.gsub!(/(^|[\W])(defined\s*[\s\(]\s*#{def_id}(\s*\))?)/, '\1' + "#{@defined.has_key?(def_id).to_s}")
867
861
  end
868
862
  # match and resolve any macro variables listed in conditional expression
869
863
  s2.gsub!(/(^|[\W])([A-Za-z_][\w]*)/) do |_| "#{$1}#{resolve_define($2)}" end
@@ -903,11 +897,11 @@ module IDL
903
897
  @defined.delete(s2)
904
898
 
905
899
  when 'include'
906
- if s2[0,1] == '"' || s2[0,1] == '<'
907
- quoted_inc = (s2[0,1] == '"')
908
- if s2.size>2
900
+ if s2[0, 1] == '"' || s2[0, 1] == '<'
901
+ quoted_inc = (s2[0, 1] == '"')
902
+ if s2.size > 2
909
903
  s2.strip!
910
- s2 = s2.slice(1..(s2.size-2))
904
+ s2 = s2.slice(1..(s2.size - 2))
911
905
  else
912
906
  s2 = ''
913
907
  end
@@ -936,25 +930,30 @@ module IDL
936
930
  end
937
931
  end
938
932
 
933
+ def next_token_before_eol
934
+ @in.skipwhile {|c| SPACES.include?(c)}
935
+ LFCR.include?(@in.lookc) ? nil : next_token
936
+ end
937
+
939
938
  def next_token
940
939
  sign = nil
941
940
  str = '' #initialize empty string
942
- while TRUE
941
+ while true
943
942
  ch = @in.getc
944
943
  if ch.nil?
945
- if @ifdef.size>0 and !in_expansion?
944
+ if @ifdef.size > 0 and !in_expansion?
946
945
  parse_error 'mismatched #if/#endif'
947
946
  end
948
947
  if more_source?
949
948
  leave_source
950
949
  next
951
950
  else
952
- return [FALSE, nil]
951
+ return [false, nil]
953
952
  end
954
953
  end
955
954
 
956
955
  if WHITESPACE.include? ch
957
- @in.skipwhile( WHITESPACE )
956
+ @in.skipwhile {|c| WHITESPACE.include?(c) }
958
957
  next
959
958
  end
960
959
 
@@ -1017,7 +1016,7 @@ module IDL
1017
1016
  ret = []
1018
1017
  chs = ''
1019
1018
  @in.skipc # skip 'L'
1020
- while TRUE
1019
+ while true
1021
1020
  _nxtc = @in.lookc
1022
1021
  if _nxtc == ?\\
1023
1022
  @in.skipc
@@ -1067,7 +1066,7 @@ module IDL
1067
1066
  # return token returned by parse_annotation or parse next token recursively
1068
1067
  return parse_annotation(true) || next_token
1069
1068
  else
1070
- @in.skipuntil(?\n, ?\r)
1069
+ @in.skipuntil {|c| LFCR.include?(c) }
1071
1070
  end
1072
1071
  end
1073
1072
  str = '' # reset
@@ -1077,9 +1076,9 @@ module IDL
1077
1076
  return %w(/ /)
1078
1077
  end
1079
1078
 
1080
- when ch == ?+ || ch == ?-
1079
+ when SIGNS.include?(ch)
1081
1080
  _nxtc = @in.lookc
1082
- if (?0..?9).include? _nxtc
1081
+ if DIGITS.include? _nxtc
1083
1082
  sign = ch
1084
1083
  str = '' # reset
1085
1084
  next
@@ -1089,7 +1088,7 @@ module IDL
1089
1088
 
1090
1089
  when (?1..?9).include?(ch)
1091
1090
  @in.mark(sign, ch)
1092
- @in.skipwhile(?0..?9)
1091
+ @in.skipwhile {|c| DIGITS.include?(c) }
1093
1092
  num_type = ([?., ?e, ?E, ?d, ?D].include?(@in.lookc)) ? skipfloat_or_fixed : :integer_literal
1094
1093
 
1095
1094
  r = @in.getregion
@@ -1102,10 +1101,10 @@ module IDL
1102
1101
  return [:integer_literal, r.to_i]
1103
1102
  end
1104
1103
 
1105
- when ch == ?. #
1104
+ when ch == DOT #
1106
1105
  @in.mark(ch)
1107
- @in.skipwhile(?0..?9)
1108
- num_type = (?. != @in.lookc) ? skipfloat_or_fixed : nil
1106
+ @in.skipwhile {|c| DIGITS.include?(c) }
1107
+ num_type = (DOT != @in.lookc) ? skipfloat_or_fixed : nil
1109
1108
  s = @in.getregion
1110
1109
  if s == '.'
1111
1110
  parse_error 'token consisting of single dot (.) is invalid.'
@@ -1128,11 +1127,11 @@ module IDL
1128
1127
  s = @in.getregion
1129
1128
  return [:integer_literal, s.hex]
1130
1129
  else
1131
- dec = FALSE
1132
- @in.skipwhile(?0..?7)
1130
+ dec = false
1131
+ @in.skipwhile {|c| OCTALS.include?(c) }
1133
1132
  if (?8..?9).include? @in.lookc
1134
1133
  dec = TRUE
1135
- @in.skipwhile(?0..?9)
1134
+ @in.skipwhile {|c| DIGITS.include?(c) }
1136
1135
  end
1137
1136
 
1138
1137
  num_type = ([?., ?e, ?E, ?d, ?D].include?(@in.lookc)) ? skipfloat_or_fixed : :integer_literal
@@ -1170,7 +1169,7 @@ module IDL
1170
1169
 
1171
1170
  when ch == ?\" #" #double quote, for a string literal.
1172
1171
  ret = ''
1173
- while TRUE
1172
+ while true
1174
1173
  _nxtc = @in.lookc
1175
1174
  if _nxtc == ?\\
1176
1175
  @in.skipc