rubylexer 0.7.6 → 0.7.7

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.
@@ -0,0 +1,9 @@
1
+ charhandler.rb
2
+ charset.rb
3
+ context.rb
4
+ lextable.rb
5
+ rubycode.rb
6
+ rulexer.rb
7
+ symboltable.rb
8
+ tokenprinter.rb
9
+ token.rb
@@ -1,4 +1,4 @@
1
- =begin legal crap
1
+ =begin
2
2
  rubylexer - a ruby lexer written in ruby
3
3
  Copyright (C) 2004,2005,2008 Caleb Clausen
4
4
 
@@ -22,23 +22,29 @@ class RubyLexer
22
22
  #------------------------------------
23
23
  class CharHandler
24
24
  #-----------------------------------
25
- CHARSETSPECIALS=CharSet[?[ ,?] ,?\\ ,?-]
25
+ if ?A.is_a? String #ruby >= 1.9
26
+ CHARSETSPECIALS=/[\[\]\\\-]/
27
+ else
28
+ CHARSETSPECIALS=CharSet[?[ ,?] ,?\\ ,?-]
29
+ end
26
30
  def initialize(receiver,default,hash)
27
31
  @default=default
28
32
  @receiver=receiver
29
- #breakpoint
30
- @table=Array.new(0)
33
+ if ?A.is_a? String #ruby >= 1.9
34
+ @table={}
35
+ else
36
+ @table=Array.new(0)
37
+ end
31
38
  @matcher='^[^'
32
39
 
33
40
  hash.each_pair {|pattern,action|
34
41
  case pattern
35
42
  when Range
36
43
  pattern.each { |c|
37
- c.kind_of? String and c=c[0] #cvt to integer #still needed?
38
44
  self[c]=action
39
45
  }
40
46
  when String
41
- pattern.each_byte {|b| self[b]=action }
47
+ CharHandler.each_char(pattern) {|b| self[b]=action }
42
48
  when Fixnum
43
49
  self[pattern]=action
44
50
  else
@@ -47,15 +53,26 @@ class CharHandler
47
53
  }
48
54
 
49
55
  @matcher += ']$'
50
- @matcher=Regexp.new(@matcher)
56
+ @matcher=Regexp.new(@matcher,0,'n')
51
57
 
52
58
  freeze
53
59
  end
54
60
 
61
+ #-----------------------------------
62
+ if String===?a
63
+ def self.each_char(str,&block)
64
+ str.each_char(&block)
65
+ end
66
+ else
67
+ def self.each_char(str,&block)
68
+ str.each_byte(&block)
69
+ end
70
+ end
71
+
55
72
  #-----------------------------------
56
73
  def []=(b,action) #for use in initialize only
57
74
  assert b >= ?\x00
58
- assert b <= ?\xFF
75
+ assert b <= ?\x7F
59
76
  assert !frozen?
60
77
 
61
78
  @table[b]=action
@@ -69,17 +86,6 @@ class CharHandler
69
86
  @receiver.send((@table[b] or @default), b.chr, *args)
70
87
  end
71
88
 
72
- #-----------------------------------
73
- def eat_file(file,blocksize,*args)
74
- begin
75
- chars=file.read(blocksize)
76
- md=@matcher.match(chars)
77
- mychar=md[0][0]
78
- #get file back in the right pos
79
- file.pos+=md.offset(0)[0] - chars.length
80
- @receiver.send(@default,md[0])
81
- end until go(mychar,*args)
82
- end
83
89
  end
84
90
  end
85
91
 
@@ -1,4 +1,4 @@
1
- =begin legal crap
1
+ =begin
2
2
  rubylexer - a ruby lexer written in ruby
3
3
  Copyright (C) 2008 Caleb Clausen
4
4
 
@@ -74,6 +74,7 @@ module NestedContexts
74
74
  super('{','}',linenum)
75
75
  end
76
76
  attr_accessor :wanting_stabby_block_body
77
+ #attr_writer :starter,:ender
77
78
  end
78
79
 
79
80
  class BeginEndContext < NestedContext
@@ -118,6 +119,9 @@ module NestedContexts
118
119
  class UnparenedParamListLhsContext < ImplicitLhsContext
119
120
  def starter; huh end #" " ???
120
121
  def ender; huh end #; or \n when from method def, { or do when from stabby block
122
+ def endtoken offset
123
+ KwParamListEndToken.new offset
124
+ end
121
125
  end
122
126
 
123
127
  class ImplicitContext < ListContext
@@ -129,6 +133,9 @@ module NestedContexts
129
133
  end
130
134
  def lhs; false end
131
135
  def wantarrow; true end
136
+ def endtoken offset
137
+ ImplicitParamListEndToken.new offset
138
+ end
132
139
  end
133
140
 
134
141
  class KWParamListContextNoParen < ParamListContextNoParen
@@ -159,6 +166,9 @@ module NestedContexts
159
166
  def multi_assign?
160
167
  @multi if defined? @multi
161
168
  end
169
+ def endtoken offset
170
+ AssignmentRhsEndToken.new offset
171
+ end
162
172
  end
163
173
 
164
174
  class WantsEndContext < NestedContext
@@ -201,6 +211,9 @@ module NestedContexts
201
211
  end
202
212
 
203
213
  attr :in_body
214
+
215
+ attr_writer :has_parens
216
+ def has_parens?; @has_parens end
204
217
  end
205
218
 
206
219
  class StringContext < NestedContext #not used yet
@@ -283,13 +296,13 @@ module NestedContexts
283
296
  stack=lxr.parsestack
284
297
  assert msg!=:for
285
298
  case msg
286
- when :for: WantsEndContext===stack.last or raise 'syntax error: for not expected at this time'
299
+ when :for; WantsEndContext===stack.last or raise 'syntax error: for not expected at this time'
287
300
  #local var defined in this state
288
301
  #never actually used?
289
- when :in: self.equal? stack.pop or raise 'syntax error: in not expected at this time'
302
+ when :in; self.equal? stack.pop or raise 'syntax error: in not expected at this time'
290
303
  stack.push ExpectDoOrNlContext.new("for",/(do|;|:|\n)/,@linenum)
291
304
  #pop self off owning context stack and push ExpectDoOrNlContext
292
- when :comma, :splat: return
305
+ when :comma, :splat; return
293
306
  else super
294
307
  end
295
308
  LEGAL_SUCCESSORS[@state].include? msg or raise "for syntax error: #{msg} unexpected in #@state"
@@ -41,7 +41,7 @@ class RubyCode < Token
41
41
  result=[]
42
42
  keepwsprinter=KeepWsTokenPrinter.new('',@linenum)
43
43
  ident.each{|tok| result << keepwsprinter.sprint(tok) }
44
- return result.to_s
44
+ return result.join
45
45
  end
46
46
  end
47
47
  end
@@ -38,17 +38,10 @@ require 'sequence/file'
38
38
  require 'sequence/list'
39
39
  #-----------------------------------
40
40
  assert !defined? ::RubyLexer
41
- $RuLexer=Class.new{}
42
- class RubyLexer < $RuLexer
43
- RuLexer=$RuLexer
44
- end
45
- $RuLexer=nil
46
- #------------------------------------
47
41
  class RubyLexer
48
42
  FASTER_STRING_ESCAPES=true
49
43
  warn "FASTER_STRING_ESCAPES is off" unless FASTER_STRING_ESCAPES
50
44
  AUTO_UNESCAPE_STRINGS=false
51
- class RuLexer
52
45
  WHSP=" \t\r\v\f"
53
46
  WHSPLF=WHSP+"\n"
54
47
  #maybe \r should be in WHSPLF instead
@@ -75,11 +68,13 @@ class RubyLexer
75
68
  @moretokens=[ RubyLexer::FileAndLineToken.new(@filename, @linenum, input_position) ]
76
69
  @endsets={}
77
70
  end
71
+ alias rulexer_initialize initialize
78
72
 
79
73
  #-----------------------------------
80
74
  def endoffile_detected s=''
81
75
  EoiToken.new(s,@original_file, input_position-s.size)
82
76
  end
77
+ alias rulexer_endoffile_detected endoffile_detected
83
78
 
84
79
  #-----------------------------------
85
80
  def get1token
@@ -92,6 +87,7 @@ class RubyLexer
92
87
 
93
88
  @toptable.go( nextchar )
94
89
  end
90
+ alias rulexer_get1token get1token
95
91
 
96
92
  #-----------------------------------
97
93
  def no_more?
@@ -143,40 +139,41 @@ private
143
139
  if @rubyversion>=1.9
144
140
  named_brs=[]
145
141
  if result.elems.size==1 and String===result.elems.first
142
+ elem=result.elems.first
146
143
  index=0
147
- huh
148
- while index=elem.index(/#{EVEN_BS_S}( \(\?[<'] | \(\?\# | \[ )/xo,index)
149
- huh
150
- case alt
151
- when "(?<"; huh
144
+ while index=elem.index(/(#{EVEN_BS_S})( \(\?[<'] | \(\?\# | \[ )/xo,index)
145
+ index+=$1.size
146
+ case $2
147
+ when "(?<"
152
148
  index=elem.index(/\G...(#{LCLETTER}#{LETTER_DIGIT}+)>/o,index)
153
- index or huh
154
- index+=$1.size+4
149
+ break lexerror(result, "malformed named backreference") unless index
150
+ index+=$&.size
155
151
  named_brs<<$1
156
- when "(?'"; huh
152
+ when "(?'"
157
153
  index=elem.index(/\G...(#{LCLETTER}#{LETTER_DIGIT}+)'/o,index)
158
- index or huh
159
- index+=$1.size+4
154
+ break lexerror(result, "malformed named backreference") unless index
155
+ index+=$&.size
160
156
  named_brs<<$1
161
- when "(?#"; huh
157
+ when "(?#"
162
158
  index+=3
163
- index=elem.index(/#{EVEN_BS_S}\)/,index)
164
- index or huh
165
- index+=1
166
- when "["; huh
159
+ index=elem.index(/#{EVEN_BS_S}\)/o,index)
160
+ break lexerror(result, "unterminated regexp comment") unless index
161
+ index+=$&.size
162
+ when "["
167
163
  index+=1
168
164
  paren_ctr=1
169
165
  loop do
170
166
  index=elem.index(/#{EVEN_BS_S}(&&\[\^|\])/o,index)
171
- index or huh
167
+ break lexerror(result, "unterminated character class") unless index
172
168
  index+=$&.size
173
- unless $1[-1]==?]
174
- paren_ctr+=1
175
- else
169
+ if $1==']'
176
170
  paren_ctr-=1
177
171
  break if paren_ctr==0
172
+ else
173
+ paren_ctr+=1
178
174
  end
179
175
  end
176
+ break unless index
180
177
 
181
178
  end
182
179
  end
@@ -190,6 +187,7 @@ private
190
187
 
191
188
  #-----------------------------------
192
189
  def single_char_token(str) getchar end
190
+ alias rulexer_single_char_token single_char_token
193
191
 
194
192
  #-----------------------------------
195
193
  def illegal_char(ch)
@@ -239,12 +237,12 @@ else
239
237
  end
240
238
  result=send(strlex, beg, type, close=(PAIRS[beg] or beg))
241
239
  case ch
242
- when /^[Wwr]$/:
240
+ when /^[Wwr]$/
243
241
  str=result
244
242
  result=RenderExactlyStringToken.new(type).append_token(result)
245
243
  result.open=str.open; result.close=str.close
246
244
  result.line=@linenum
247
- when 's':
245
+ when 's'
248
246
  result.open=open+beg
249
247
  result.close=close
250
248
  result=SymbolToken.new result,nil,"%s"
@@ -274,12 +272,12 @@ end
274
272
  #-----------------------------------
275
273
  INTERIOR_REX_CACHE={}
276
274
  EVEN_BS_S=/
277
- ($|
275
+ (?:\G|
278
276
  [^\\c-]|
279
- ($|[^\\])(c|[CM]-)|
280
- ($|[^CM])-
277
+ (?:\G|[^\\])(?:c|[CM]-)|
278
+ (?:\G|[^CM])-
281
279
  )
282
- (\\(?:c|[CM]-)?){2}*
280
+ (?:\\(?:c|[CM]-)?){2}*
283
281
  /x
284
282
  ILLEGAL_ESCAPED=/#{EVEN_BS_S}(\\([CM][^-]|x[^a-fA-F0-9]))/o #whaddaya do with this?
285
283
  def all_quote(nester, type, delimiter, bs_handler=nil)
@@ -298,12 +296,12 @@ if FASTER_STRING_ESCAPES
298
296
  single_quotish=true
299
297
  special=/\\./m
300
298
  else
301
- crunch=/#(?=[^{$@])/
299
+ crunch=/\#(?=[^{$@])/
302
300
  escaped=/\\(?>[^xcCM0-7]|(?>c|[CM].)(?>[^\\]|(?=\\))|(?>x.[0-9a-fA-F]?)|(?>[0-7]{1,3}))/m
303
301
  special=
304
302
  case delimiter
305
- when '\\': crunch
306
- when '#': escaped
303
+ when '\\'; crunch
304
+ when '#'; escaped
307
305
  else /#{escaped}|#{crunch}/o
308
306
  end
309
307
  special_char<< maybe_crunch="#"
@@ -318,8 +316,8 @@ if FASTER_STRING_ESCAPES
318
316
  str=StringToken.new type
319
317
  str.bs_handler ||= case type
320
318
  when '/' then :regex_esc_seq
321
- when '{' then :Wquote_esc_seq
322
- when '"','`',':' then :dquote_esc_seq
319
+ when '{' then @rubyversion>=1.9 ? :Wquote19_esc_seq : :Wquote_esc_seq
320
+ when '"','`',':' then @rubyversion>=1.9 ? :dquote19_esc_seq : :dquote_esc_seq
323
321
  when "'" then :squote_esc_seq
324
322
  when "[" then :wquote_esc_seq
325
323
  else raise "unknown quote type: #{type}"
@@ -431,8 +429,8 @@ else
431
429
 
432
430
  bs_handler ||= case type
433
431
  when '/' then :regex_esc_seq
434
- when '{' then :Wquote_esc_seq
435
- when '"','`',':' then :dquote_esc_seq
432
+ when '{' then @rubyversion>=1.9 ? :Wquote19_esc_seq : :Wquote_esc_seq
433
+ when '"','`',':' then @rubyversion>=1.9 ? :dquote19_esc_seq : :dquote_esc_seq
436
434
  when "'" then :squote_esc_seq
437
435
  when "[" then :wquote_esc_seq
438
436
  else raise "unknown quote type: #{type}"
@@ -525,16 +523,25 @@ end
525
523
  k.tr(ESCAPECHRS,ESCAPESEQS)
526
524
  when "M"
527
525
  eat_next_if(?-) or raise 'bad \\M sequence'
528
- (getchar_maybe_escape | 0x80).chr
526
+ ch=getchar_maybe_escape[0]
527
+ ch=ch.ord if ch.respond_to? :ord
528
+ ch>=0xFF and raise 'bad \\M sequence'
529
+ (ch | 0x80).chr
529
530
 
530
531
  when "C"
531
532
  eat_next_if(?-) or raise 'bad \\C sequence'
532
533
  nextchar==?? and getchar and return "\177" #wtf?
533
- (getchar_maybe_escape & 0x9F).chr
534
+ ch=getchar_maybe_escape[0]
535
+ ch=ch.ord if ch.respond_to? :ord
536
+ ch>=0xFF and raise 'bad \\M sequence'
537
+ (ch & 0x9F).chr
534
538
 
535
539
  when "c"
536
540
  nextchar==?? and getchar and return "\177" #wtf?
537
- (getchar_maybe_escape & 0x9F).chr
541
+ ch=getchar_maybe_escape[0]
542
+ ch=ch.ord if ch.respond_to? :ord
543
+ ch>=0xFF and raise 'bad \\M sequence'
544
+ (ch & 0x9F).chr
538
545
 
539
546
  when /^[0-7]$/
540
547
  str=k
@@ -556,6 +563,33 @@ end
556
563
  end
557
564
  end
558
565
 
566
+ #-----------------------------------
567
+ def dquote19_esc_seq(ch,nester,delimiter)
568
+ assert ch == '\\'
569
+ case ch=getchar
570
+ when 'u'
571
+ case ch=getchar
572
+ when /[a-f0-9]/i
573
+ u=read(4)
574
+ raise "bad unicode escape" unless /[0-9a-f]{4}/i===u
575
+ [u.hex].pack "U"
576
+ when '{'
577
+ result=[]
578
+ until eat_next_if '}'
579
+ u=@file.scan(/\A[0-9a-f]{1,6}[ \t]?/i,7)
580
+ result<<u.hex
581
+ end
582
+ result=result.pack "U*"
583
+ else raise "bad unicode escape"
584
+ end
585
+ else
586
+ back1char
587
+ result=dquote_esc_seq('\\',nester,delimiter)
588
+ #/\s|\v/===result and result="\\"+result
589
+ result
590
+ end
591
+ end
592
+
559
593
  #-----------------------------------
560
594
  def regex_esc_seq(ch,nester,delimiter)
561
595
  assert ch == '\\'
@@ -571,9 +605,9 @@ end
571
605
  def Wquote_esc_seq(ch,nester,delimiter)
572
606
  assert ch == '\\'
573
607
  case ch=getchar
574
- when "\n": @linenum+=1; ch
575
- when nester,delimiter: ch
576
- when /[\s\v\\]/: ch
608
+ when "\n"; @linenum+=1; ch
609
+ when nester,delimiter; ch
610
+ when /[\s\v\\]/; ch
577
611
  else
578
612
  back1char
579
613
  result=dquote_esc_seq('\\',nester,delimiter)
@@ -582,6 +616,21 @@ end
582
616
  end
583
617
  end
584
618
 
619
+ #-----------------------------------
620
+ def Wquote19_esc_seq(ch,nester,delimiter)
621
+ assert ch == '\\'
622
+ case ch=getchar
623
+ when "\n"; @linenum+=1; ch
624
+ when nester,delimiter; ch
625
+ when /[\s\v\\]/; ch
626
+ else
627
+ back1char
628
+ result=dquote19_esc_seq('\\',nester,delimiter)
629
+ #/\s|\v/===result and result="\\"+result
630
+ result
631
+ end
632
+ end
633
+
585
634
  #-----------------------------------
586
635
  def wquote_esc_seq(ch,nester,delimiter)
587
636
  assert(ch=='\\')
@@ -592,10 +641,10 @@ end
592
641
  #all \ sequences
593
642
  #are unescaped; actual
594
643
  #newlines are counted but not changed
595
- when delimiter,nester,'\\': escchar
596
- # when delimiter,nester: escchar
597
- when "\n": @linenum+=1; escchar
598
- when /[\s\v]/: escchar
644
+ when delimiter,nester,'\\'; escchar
645
+ # when delimiter,nester; escchar
646
+ when "\n"; @linenum+=1; escchar
647
+ when /[\s\v]/; escchar
599
648
  else "\\"+escchar
600
649
  end
601
650
  end
@@ -610,9 +659,9 @@ end
610
659
  #all \ sequences
611
660
  #are unescaped; actual
612
661
  #newlines are counted but not changed
613
- when delimiter,nester,'\\': escchar
614
- # when delimiter,nester: escchar
615
- when "\n": @linenum+=1; "\\"+escchar
662
+ when delimiter,nester,'\\'; escchar
663
+ # when delimiter,nester; escchar
664
+ when "\n"; @linenum+=1; "\\"+escchar
616
665
  else "\\"+escchar
617
666
  end
618
667
  end
@@ -627,9 +676,9 @@ end
627
676
  #all \ sequences
628
677
  #are unescaped; actual
629
678
  #newlines are counted but not changed
630
- when delimiter,nester: escchar
631
- # when delimiter,nester: escchar
632
- when "\n": @linenum+=1; "\\"+escchar
679
+ when delimiter,nester; escchar
680
+ # when delimiter,nester; escchar
681
+ when "\n"; @linenum+=1; "\\"+escchar
633
682
  else "\\"+escchar
634
683
  end
635
684
  end
@@ -649,9 +698,11 @@ end
649
698
  # alias squote_esc_seq wquote_esc_seq
650
699
 
651
700
  module RecursiveRubyLexer
701
+ =begin
652
702
  def initial_nonblock_levels
653
703
  @localvars_stack.size==1 ? 2 : 1
654
704
  end
705
+ =end
655
706
  end
656
707
 
657
708
  def initial_nonblock_levels; 1 end
@@ -663,8 +714,8 @@ end
663
714
 
664
715
  def merge_levels levels, nil_empty_class
665
716
  case (levels.size rescue 0)
666
- when 0: {} unless nil_empty_class
667
- when 1: levels.first.dup
717
+ when 0; {} unless nil_empty_class
718
+ when 1; levels.first.dup
668
719
  else levels.inject{|a,b| a.merge b}
669
720
  end
670
721
  end
@@ -713,30 +764,7 @@ end
713
764
  #pass current local vars into new parser
714
765
  #must pass the lists of nonblock, parentblock and currentblock vars separately
715
766
  #then a table increment after each
716
- nonblocky,blocky,current=decompose_lvars(true)
717
- nonblocky.keys.each{|varname|
718
- rl.localvars[varname]=true
719
- }
720
- rl.localvars.start_block
721
- #incremental table, tells us what :local vars are defined in the str inclusion
722
-
723
- if blocky
724
- rl.localvars.start_block
725
- blocky.keys.each{|varname|
726
- rl.localvars[varname]=true
727
- }
728
- rl.localvars.start_block
729
- #incremental table, tells us what :block vars are defined in the str inclusion
730
- end
731
-
732
- if current
733
- rl.localvars.start_block
734
- current.keys.each{|varname|
735
- rl.localvars[varname]=true
736
- }
737
- rl.localvars.start_block
738
- #incremental table, tells us what :current vars are defined in the str inclusion
739
- end
767
+ rl.localvars_stack=@localvars_stack.map{|lvs| lvs.deep_copy}
740
768
 
741
769
  rl.pending_here_bodies=@pending_here_bodies
742
770
 
@@ -790,19 +818,13 @@ end
790
818
  # @pending_here_bodies=rl.pending_here_bodies
791
819
 
792
820
  #local vars defined in inclusion get propagated to outer parser
793
- newvars=rl.localvars.__locals_lists[1..-1].map{|bag| bag.keys }.flatten
794
- newvars.each{|newvar| localvars[newvar]=true }
821
+ @localvars_stack=rl.localvars_stack
795
822
 
796
823
  result=RubyCode.new(tokens,@filename,@linenum)
797
824
  @linenum=rl.linenum
798
825
  return result
799
826
  end
800
827
 
801
- #-----------------------------------
802
- def here_spread_over_ruby_code(rl,tok)
803
- lexerror tok, 'here body outside string inclusion'
804
- end
805
-
806
828
 
807
829
  #-----------------------------------
808
830
  # BINCHARS=?0..?1
@@ -913,6 +935,7 @@ else
913
935
  IgnoreToken.new(til_charset(/[\r\n]/))
914
936
  end
915
937
  end
938
+ alias rulexer_comment comment
916
939
 
917
940
  #-----------------------------------
918
941
  def whitespace(ch)
@@ -944,16 +967,17 @@ end
944
967
  @moretokens << FileAndLineToken.new( @filename, @linenum, offset+1 )
945
968
  return NewlineToken.new("\n",offset)
946
969
  end
947
-
970
+ alias rulexer_newline newline
948
971
 
949
972
  #-----------------------------------
950
973
  def getchar_maybe_escape
951
974
  eof? and raise "unterminated dq string"
952
- c=getc
953
-
954
- c == ?\\ and
955
- (c = (dquote_esc_seq('\\')[-1] or ?\n))
975
+ c=getc.chr
956
976
 
977
+ if c == "\\"
978
+ c = @rubyversion >= 1.9 ? dquote19_esc_seq('\\') : dquote_esc_seq('\\')
979
+ c = "\n" if c.empty?
980
+ end
957
981
  return c
958
982
  end
959
983
 
@@ -962,6 +986,7 @@ protected
962
986
  require 'forwardable'
963
987
  extend Forwardable
964
988
  def_delegators :@file, :readahead, :readback, :read, :eof?
989
+ alias rulexer_eof? eof?
965
990
 
966
991
  def til_charset cs,len=16; @file.read_til_charset cs,len end
967
992
  def getc; @file.read1 end
@@ -995,13 +1020,14 @@ protected
995
1020
 
996
1021
  #-----------------------------------
997
1022
  def input_position; @file.pos end
1023
+ alias rulexer_input_position input_position
998
1024
 
999
1025
  #-----------------------------------
1000
1026
  def input_position_set x; @file.pos=x end
1001
1027
 
1002
1028
  #-----------------------------------
1003
1029
  def self.save_offsets_in(*funcnames)
1004
- eval funcnames.collect{|fn| <<-endeval }.to_s
1030
+ eval funcnames.collect{|fn| <<-endeval }.join
1005
1031
  class ::#{self}
1006
1032
  alias #{fn}__no_offset #{fn} #rename old ver of fn
1007
1033
  def #{fn}(*args) #create new version
@@ -1015,7 +1041,6 @@ protected
1015
1041
  endeval
1016
1042
  end
1017
1043
 
1018
- end
1019
1044
 
1020
1045
  end
1021
1046