cursor 0.8 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- # $Id: buffered.rb,v 1.11 2005/07/21 15:15:38 eric_mahurin Exp $
1
+ # $Id: buffered.rb,v 1.12 2005/08/31 14:41:16 eric_mahurin Exp $
2
2
 
3
3
  require 'cursor'
4
4
  require 'cursor/split'
@@ -68,8 +68,8 @@ class Buffered < Cursor
68
68
  @buffer.insert1after(v)
69
69
  end
70
70
  public
71
- def pos(reverse=false) # :yield:
72
- if reverse
71
+ def pos(reverse=false,&code) # :yield:
72
+ if code or reverse
73
73
  super
74
74
  else
75
75
  @buffer.pos+@output_pos
@@ -1,4 +1,4 @@
1
- # $Id: circular.rb,v 1.19 2005/07/21 15:15:38 eric_mahurin Exp $
1
+ # $Id: circular.rb,v 1.20 2005/08/08 02:06:28 eric_mahurin Exp $
2
2
 
3
3
  require 'cursor'
4
4
 
@@ -233,6 +233,8 @@ class Circular < Cursor
233
233
  end
234
234
  # :startdoc:
235
235
  undef_method(:scan_until)
236
+ undef_method(:scan_pattern_until)
237
+ undef_method(:scan_pattern_while)
236
238
  undef_method(:modify)
237
239
  undef_method(:each)
238
240
  undef_method(:collect!)
@@ -1,4 +1,4 @@
1
- # $Id: io.rb,v 1.15 2005/07/21 15:15:38 eric_mahurin Exp $
1
+ # $Id: io.rb,v 1.17 2005/10/14 00:22:58 eric_mahurin Exp $
2
2
 
3
3
  require 'cursor'
4
4
  require 'cursor/usenext'
@@ -76,8 +76,12 @@ class IO < Cursor
76
76
  def skip1before
77
77
  @io.pos.zero? ? nil : true
78
78
  end
79
+ def scan1next(v)
80
+ v0 = @io.getc
81
+ (v0.nil? || v==v0) ? v0 : (@io.ungetc(v0);nil)
82
+ end
79
83
  def read(len,hold=false,buffer=nil)
80
- len.nonzero? or return(buffer||"")
84
+ len.nonzero? or return(buffer ? 0 : "")
81
85
  reverse = len<0
82
86
  len = len.abs
83
87
  if reverse
@@ -118,12 +122,12 @@ class IO < Cursor
118
122
  else
119
123
  buffer1.each_byte { |c| buffer << c }
120
124
  end
125
+ buffer1.size
121
126
  else
122
127
  buffer = buffer1
123
128
  end
124
- buffer
125
129
  end
126
- def read!(reverse=false,hold=false,buffer=new_data)
130
+ def read!(reverse=false,hold=false,buffer=nil)
127
131
  if reverse
128
132
  len = @io.pos.nonzero? or return
129
133
  @io.seek(0,::IO::SEEK_SET)
@@ -158,10 +162,10 @@ class IO < Cursor
158
162
  else
159
163
  buffer1.each_byte { |c| buffer << c }
160
164
  end
165
+ buffer1.size
161
166
  else
162
167
  buffer = buffer1
163
168
  end
164
- buffer
165
169
  end
166
170
  def skip(len,hold=false)
167
171
  len.nonzero? or return(0)
@@ -243,6 +247,7 @@ class IO < Cursor
243
247
  end
244
248
  value1 = value1.reverse if reverse
245
249
  end
250
+ len_written = len
246
251
  if reverse
247
252
  if hold.nil?
248
253
  @positions && _adjust_insert(len)
@@ -261,7 +266,7 @@ class IO < Cursor
261
266
  else
262
267
  @io.seek(-len_overwrite,::IO::SEEK_CUR)
263
268
  if overwrite_only
264
- len = len_overwrite.nonzero? or return
269
+ len_written = len_overwrite.nonzero? or return
265
270
  else
266
271
  @positions && _adjust_insert(len_insert)
267
272
  buffer2 = @io.read(nil)
@@ -274,7 +279,7 @@ class IO < Cursor
274
279
  @io.write(value1[len_insert,len_overwrite])
275
280
 
276
281
  end
277
- @io.seek(-len,::IO::SEEK_CUR) if !hold
282
+ @io.seek(-len_written,::IO::SEEK_CUR) if !hold
278
283
  end
279
284
  else
280
285
  if hold.nil?
@@ -292,23 +297,23 @@ class IO < Cursor
292
297
  if @io.eof?
293
298
  p0 = @io.pos
294
299
  @io.seek(0,::IO::SEEK_END)
295
- len -= p0-@io.pos
296
- len.nonzero? or return
297
- value1 = value1[0,len]
300
+ len_written -= p0-@io.pos
301
+ len_written.nonzero? or return
302
+ value1 = value1[0,len_written]
298
303
  end
299
- @io.seek(-len,::IO::SEEK_CUR)
304
+ @io.seek(-len_written,::IO::SEEK_CUR)
300
305
  end
301
306
  @io.write(value1)
302
- @io.seek(-len,::IO::SEEK_CUR) if hold
307
+ @io.seek(-len_written,::IO::SEEK_CUR) if hold
303
308
  end
304
309
  end
305
- len
310
+ len_written==len ? len : -len_written
306
311
  end
307
312
  def scan_until(value,reverse=false,hold=false,buffer=nil)
308
313
  if String===value && !reverse && hold==false && !buffer && !value.empty?
309
314
  @io.gets(value)
310
315
  else
311
- super(value,reverse,hold,buffer||value.class.new)
316
+ super(value,reverse,hold,buffer)
312
317
  end
313
318
  end
314
319
  def pos=(p)
@@ -1,4 +1,4 @@
1
- # $Id: position.rb,v 1.18 2005/07/18 14:46:28 eric_mahurin Exp $
1
+ # $Id: position.rb,v 1.19 2005/08/31 14:41:16 eric_mahurin Exp $
2
2
 
3
3
  require 'cursor'
4
4
 
@@ -11,7 +11,7 @@ class Position < Cursor # :nodoc:
11
11
  def initialize(parent,reverse=false)
12
12
  @parent = parent
13
13
  @anchor_after = reverse
14
- @pos = @parent.__send__(:pos)
14
+ @pos = @parent.pos
15
15
  prop(nil,@parent.prop)
16
16
  end
17
17
  def new_data
@@ -19,7 +19,7 @@ class Position < Cursor # :nodoc:
19
19
  end
20
20
  public
21
21
  localMethods = %w(
22
- prop pos pos= to_s to_i position position= position? position!
22
+ prop pos pos? pos= to_s to_i position position= position? position!
23
23
  close closed? each collect! map!)
24
24
  stableMethods = %w(
25
25
  read1after read1before skip1after skip1before
@@ -61,8 +61,10 @@ class Position < Cursor # :nodoc:
61
61
  end")
62
62
  }
63
63
 
64
- def pos(reverse=false)
65
- if reverse.nil? ? @anchor_after : reverse
64
+ def pos(reverse=false,&code)
65
+ if code
66
+ super
67
+ elsif reverse.nil? ? @anchor_after : reverse
66
68
  (@pos.to_i-@parent.size).nonzero? || -0.0
67
69
  else
68
70
  @pos
@@ -100,22 +102,18 @@ class Position < Cursor # :nodoc:
100
102
  def position?(p=nil,&code) # :yield:
101
103
  if code
102
104
  super
103
- elsif p
104
- @parent.position?(p)
105
105
  else
106
- nil
106
+ @parent.position?(p)
107
107
  end
108
108
  end
109
- def position!(p=nil)
110
- if p
111
- @parent.position!(p)
112
- self
113
- else
114
- nil
115
- end
109
+ undef_method(:_delete_position)
110
+ # Returns the parent of this Position.
111
+ # Should only be used by parent Cursor.
112
+ def _parent # :nodoc:
113
+ @parent
116
114
  end
117
115
  def close
118
- @parent.position!(self)
116
+ @parent._delete_position(self)
119
117
  super
120
118
  end
121
119
  protected
@@ -1,4 +1,4 @@
1
- # $Id: reversed.rb,v 1.10 2005/07/21 15:15:38 eric_mahurin Exp $
1
+ # $Id: reversed.rb,v 1.11 2005/08/31 14:41:16 eric_mahurin Exp $
2
2
 
3
3
  require 'cursor'
4
4
 
@@ -101,7 +101,8 @@ class Reversed < Cursor
101
101
  def modify1prev(lookup)
102
102
  @cursor.modify1next(lookup)
103
103
  end
104
- def pos(reverse=false) # :yield:
104
+ def pos(reverse=false,&code) # :yield:
105
+ code ? super :
105
106
  -(@cursor.pos(!reverse).nonzero? or return(reverse ? -0.0 : 0))
106
107
  end
107
108
  def pos=(p)
@@ -1,4 +1,4 @@
1
- # $Id: split.rb,v 1.3 2005/07/21 15:15:38 eric_mahurin Exp $
1
+ # $Id: split.rb,v 1.4 2005/08/31 14:41:16 eric_mahurin Exp $
2
2
 
3
3
  require 'cursor'
4
4
  require 'cursor/usedeleteinsert'
@@ -35,8 +35,8 @@ class Split < Cursor
35
35
  true
36
36
  end
37
37
  public
38
- def pos(reverse=false)
39
- reverse ? -(@after.size.nonzero?||0.0) : @before.size
38
+ def pos(reverse=false,&code)
39
+ code ? super : reverse ? -(@after.size.nonzero?||0.0) : @before.size
40
40
  end
41
41
  # :startdoc:
42
42
  end
@@ -1,5 +1,5 @@
1
1
 
2
- # $Id: test.rb,v 1.22 2005/07/21 15:15:38 eric_mahurin Exp $
2
+ # $Id: test.rb,v 1.25 2005/08/31 14:41:16 eric_mahurin Exp $
3
3
 
4
4
  require 'test/unit'
5
5
  require 'cursor'
@@ -61,7 +61,7 @@ class Test < ::Test::Unit::TestCase
61
61
  !(methods=~matchdata[1])
62
62
  end
63
63
  }
64
- @flags = flags
64
+ @flags = flags.to_i
65
65
  @use_positions = @flags[0].zero?
66
66
  @use_branches = true
67
67
  @allow_pruning = false
@@ -89,7 +89,7 @@ class Test < ::Test::Unit::TestCase
89
89
  elements[rand((weight*(elements.size+offset)).to_i)]
90
90
  end
91
91
  def self.sequence(offset=0,weight=2,value=empty)
92
- while v = element(offset,weight)
92
+ until (v = element(offset,weight)).nil?
93
93
  value << v
94
94
  end
95
95
  value
@@ -143,7 +143,7 @@ class Test < ::Test::Unit::TestCase
143
143
  def teardown
144
144
  if not passed?
145
145
  if @@output_level>=::Test::Unit::UI::PROGRESS_ONLY
146
- puts("\n#{self.class}")
146
+ puts("\n#{self}")
147
147
  puts("random_seed: #{@@random_seed}")
148
148
  puts(@call)
149
149
  end
@@ -238,6 +238,32 @@ class Test < ::Test::Unit::TestCase
238
238
  i==0 ? ret0 = ret : assert_equal(ret0,ret,message)
239
239
  }
240
240
  end
241
+ def _test_matchdata(name,*args,&block)
242
+ ret0 = nil
243
+ _multi_test(name,*(args << block)) {
244
+ |i,ret,cursor,message|
245
+ if i==0
246
+ ret0 = ret
247
+ elsif ret0.nil?
248
+ assert_nil(ret)
249
+ else
250
+ assert_equal(ret0.to_a,ret.to_a)
251
+ end
252
+ }
253
+ end
254
+ def _test_match(name,*args,&block)
255
+ ret0 = nil
256
+ _multi_test(name,*(args << block)) {
257
+ |i,ret,cursor,message|
258
+ if i==0
259
+ ret0 = ret
260
+ elsif ret0.nil?
261
+ assert_nil(ret)
262
+ else
263
+ assert_equal(ret0[0,ret0.size-1],ret[0,ret.size-1])
264
+ end
265
+ }
266
+ end
241
267
  def _exec_position?(cursor,name,*args,&block)
242
268
  cursor.position? { cursor.__send__(name,*args,&block) }
243
269
  end
@@ -369,6 +395,57 @@ class Test < ::Test::Unit::TestCase
369
395
  end
370
396
  value
371
397
  end
398
+ # responds to [int]
399
+ def _read_pattern_sequence
400
+ self.class.sequence(0,3,"")
401
+ rescue TypeError
402
+ throw(:invalid_test)
403
+ end
404
+ def _pattern(variable)
405
+ n = 0
406
+ seq1 = self.class.sequence(0,2,"")
407
+ n = seq1.size
408
+ seq1 = Regexp.escape(seq1)
409
+ if n>=1 and rand(2).zero?
410
+ seq1 = "[#{seq1}]"
411
+ n = 1
412
+ end
413
+ alt1 = self.class.sequence(0,2,"")
414
+ alt2 = self.class.sequence(0,2,"")
415
+ n += alt1.size>alt2.size ? alt1.size : alt2.size
416
+ alt1 = Regexp.escape(alt1)
417
+ alt2 = Regexp.escape(alt2)
418
+ if alt1.empty?
419
+ if alt2.empty?
420
+ seq2 = ""
421
+ else
422
+ seq2 = "(#{alt2})?"
423
+ end
424
+ else
425
+ if alt2.empty?
426
+ seq2 = "(#{alt1})?"
427
+ else
428
+ if alt1[0]==alt2[0]
429
+ seq2 = alt1
430
+ else
431
+ seq2 = "(#{alt1}|#{alt2})"
432
+ end
433
+ end
434
+ end
435
+ if rand(2).zero?
436
+ pat = seq1+seq2
437
+ else
438
+ pat = seq2+seq1
439
+ end
440
+ pat = "(?:#{pat})*" if variable
441
+ pat = '\A'+pat if false==variable && rand(2).zero?
442
+ pat = Regexp.new(pat)
443
+ n += rand(2)
444
+ n = -n if rand(2).zero?
445
+ [pat,n]
446
+ rescue TypeError
447
+ throw(:invalid_test)
448
+ end
372
449
  def _pos
373
450
  pos = rand(
374
451
  self.class.instance_eval{@cursors_root}[:trunk][0].size.abs.to_i+1
@@ -430,6 +507,13 @@ class Test < ::Test::Unit::TestCase
430
507
  @cursor.position? { @cursor.read1next==elements[1] }
431
508
  }
432
509
  end
510
+ def _pos_code
511
+ elements = self.class.elements
512
+ proc {
513
+ @cursor.scan1next(elements[0]) ||
514
+ @cursor.position? { @cursor.read1next==elements[1] }
515
+ }
516
+ end
433
517
 
434
518
 
435
519
  public
@@ -469,23 +553,28 @@ class Test < ::Test::Unit::TestCase
469
553
  define_method("test_skip!" ){_test_equal(:skip!,*_opt(_boolean,_booleannil))}
470
554
  define_method("test_write" ){_test_equal(:write,_write_sequence,*_opt(_boolean,_booleannil,_boolean))}
471
555
  define_method("test_write?" ){_test_equal(:write?,_write_sequence,*_opt(_boolean,_boolean,_read_sequence))}
472
- define_method("test_scan" ){_test_position?(:scan,_scan_sequence,*_opt(_boolean,_booleannil,_read_sequence))}
473
- define_method("test_scan_until" ){_test_equal(:scan_until,_scan_sequence)} #,*_opt(_boolean,_booleannil,_read_sequence)
474
- define_method("test_scan_partial"){_test_equal(:scan_partial,_scan_sequence,*_opt(_boolean,_boolean,_read_sequence))}
475
- define_method("test_modify" ){_test_equal(:modify,_replacer,*_opt(_boolean,_boolean,_read_sequence))}
476
- define_method("test_pos" ){_test_equal(:pos,*_opt(_boolean))}
556
+ define_method("test_scan" ){_test_equal(:scan,_scan_sequence,*_opt(_boolean,_booleannil,_read_sequence))}
557
+ define_method("test_scan_until" ){_test_equal(:scan_until,_scan_sequence,*_opt(_boolean,_booleannil,_read_sequence))}
558
+ define_method("test_1scan_pattern"){_test_equal(:scan_pattern,*(_pattern(false)+_opt(_boolean)))}
559
+ define_method("test_2scan_pattern"){_test_matchdata(:scan_pattern,*(_pattern(false) << _boolean << _read_pattern_sequence))}
560
+ define_method("test_1scan_pattern_until"){_test_equal(:scan_pattern_until,*(_pattern(nil)+_opt(_boolean)))}
561
+ define_method("test_2scan_pattern_until"){_test_match(:scan_pattern_until,*(_pattern(nil)+[_boolean]+[_read_pattern_sequence]+_opt(rand(2))))}
562
+ define_method("test_scan_pattern_while"){_test_equal(:scan_pattern_while,*(_pattern(true)+_opt(_boolean,_read_pattern_sequence,rand(2))))}
563
+ define_method("test_1pos" ){_test_equal(:pos,*_opt(_boolean))}
564
+ define_method("test_2pos" ){_test_equal(:pos,*_opt(_boolean),&_pos_code)}
565
+ define_method("test_pos=" ){_test_equal(:pos=,_pos)}
566
+ define_method("test_1pos?" ){_test_equal(:pos?,_pos+rand(5)-2)}
567
+ define_method("test_2pos?" ){_test_equal(:pos?,*_opt(_boolean),&_pos_code)}
477
568
  define_method("test_to_i" ){_test_equal(:to_i)}
478
569
  define_method("test_to_s" ){_test_equal(:to_s)}
479
- define_method("test_pos=" ){_test_equal(:pos=,_pos)}
480
570
  define_method("test_prop" ){_test_equal(:prop,_prop_name,*_opt(_prop_value))}
481
571
  define_method("test_closed?" ){_test_equal(:closed?)}
482
572
  define_method("test_close" ){_test_close(:close)}
483
573
  define_method("test_1position" ){_test_position(:position,*_opt(_boolean))}
484
574
  define_method("test_2position" ){_test_equal(:position,*_opt{_boolean},&_position_code)}
485
575
  define_method("test_position=" ){_test_equal(:position=,_position)}
486
- define_method("test_1position?" ){_test_equal(:position?,*_opt{_anyposition})}
576
+ define_method("test_1position?" ){_test_equal(:position?,_anyposition)}
487
577
  define_method("test_2position?" ){_test_equal(:position?,*_opt{_boolean},&_position_code)}
488
- define_method("test_position!" ){_test_self(:position!,*_opt{_deleteposition})}
489
578
  define_method("test_<=>" ){_test_equal(:<=>,_position)}
490
579
  define_method("test_-" ){_test_equal(:-,_position)}
491
580
  define_method("test_+" ){_test_position(:+,_len)}
@@ -1,6 +1,6 @@
1
1
  #!/bin/env ruby
2
2
  #
3
- # $Id: test_circulars.rb,v 1.10 2005/07/21 15:15:38 eric_mahurin Exp $
3
+ # $Id: test_circulars.rb,v 1.12 2005/08/31 14:41:16 eric_mahurin Exp $
4
4
  #
5
5
  # Run this to test circular cursors.
6
6
  # Here is a list of the optional arguments:
@@ -40,7 +40,7 @@ class Cursor
40
40
  class Test
41
41
  class Circulars < Test
42
42
  def self.suite
43
- @reject = /^(scan_until|modify|each|collect!|map!)$/
43
+ @reject = /^(scan_until|modify|each|collect!|map!|scan_pattern_(while|until))$/
44
44
  $0==__FILE__ ? super(*ARGV) : super()
45
45
  end
46
46
  def self.seed(before,after)
@@ -63,14 +63,14 @@ class Circulars < Test
63
63
  cursors
64
64
  end
65
65
  def self.plant
66
- @characters = rand(2).zero?
66
+ @characters = @flags[1].nonzero?||rand(2).zero?
67
67
  super
68
68
  end
69
69
  def self.elements
70
- @characters ? [?\n,?\0,?0] : [false,"",[]]
70
+ @flags[1].nonzero? ? [?A,?B,?C] : @characters ? [?\n,?\0,?0] : [false,"",[]]
71
71
  end
72
72
  def self.empty
73
- @characters&&rand(2).zero? ? "" : []
73
+ @characters&&(@flags[1].nonzero?||rand(2).zero?) ? "" : []
74
74
  end
75
75
  def self.reject(name,*args,&block)
76
76
  case name
@@ -1,6 +1,6 @@
1
1
  #!/bin/env ruby
2
2
  #
3
- # $Id: test_cursors.rb,v 1.6 2005/07/21 15:15:38 eric_mahurin Exp $
3
+ # $Id: test_cursors.rb,v 1.9 2005/08/31 14:41:16 eric_mahurin Exp $
4
4
  #
5
5
  # Run this to test non-circular cursors.
6
6
  # Here is a list of the optional arguments:
@@ -69,7 +69,7 @@ class Cursors < Test
69
69
  Cursor::Lined.new(Cursor::Indexed.new(before+after,before.size)),
70
70
  Cursor::Reversed.new(Cursor::Indexed.new((before+after).reverse,after.size)),
71
71
  ]
72
- if String===before
72
+ if @string = String===before
73
73
  io=StringIO.new(before+after)
74
74
  io.pos=before.size
75
75
  cursors << io.to_cursor
@@ -92,15 +92,16 @@ class Cursors < Test
92
92
  super
93
93
  end
94
94
  def self.elements
95
- @characters ? [?\n,?\0,?0] : [false,"",[]]
95
+ @flags[1].nonzero? ? [?A,?B,?C] : @characters ? [?\n,?\0,?0] : [false,"",[]]
96
96
  end
97
97
  def self.empty
98
98
  @characters&&(@flags[1].nonzero?||rand(2).zero?) ? "" : []
99
99
  end
100
100
  def self.reject(name,*args,&block)
101
101
  case name
102
- when :position! then !@use_positions && args[0].nil?
103
- when :position? then !@use_positions && args[0].nil? && block.nil?
102
+ when :scan_pattern then !@string
103
+ when :scan_pattern_until then !@string
104
+ when :scan_pattern_while then !@string
104
105
  end
105
106
  end
106
107
  end