cursor 0.6 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/cursor.rb +626 -1143
- data/cursor/buffered.rb +89 -0
- data/cursor/circular.rb +245 -0
- data/cursor/circular/indexed.rb +51 -0
- data/cursor/circular/linked.rb +98 -0
- data/cursor/circular/position.rb +105 -0
- data/cursor/circular/shifting.rb +48 -0
- data/cursor/circular/split.rb +106 -0
- data/cursor/indexed.rb +52 -0
- data/cursor/io.rb +342 -0
- data/cursor/lined.rb +49 -0
- data/cursor/linked.rb +62 -0
- data/cursor/position.rb +145 -0
- data/cursor/reversed.rb +122 -0
- data/cursor/shifting.rb +40 -0
- data/cursor/split.rb +45 -0
- data/cursor/test.rb +519 -0
- data/cursor/test_circulars.rb +87 -0
- data/cursor/test_cursors.rb +112 -0
- data/cursor/usedeleteinsert.rb +150 -0
- data/cursor/usenext.rb +145 -0
- data/cursor/usenext/position.rb +71 -0
- data/cursor/useposition.rb +42 -0
- data/cursor/usereadwrite.rb +126 -0
- data/duck.rb +31 -0
- data/regexp_cursor.rb +50 -0
- data/weakrefset.rb +130 -0
- metadata +35 -7
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
#
|
3
|
+
# $Id: test_circulars.rb,v 1.10 2005/07/21 15:15:38 eric_mahurin Exp $
|
4
|
+
#
|
5
|
+
# Run this to test circular cursors.
|
6
|
+
# Here is a list of the optional arguments:
|
7
|
+
#
|
8
|
+
# <iterations> : approximate number of times to test each method
|
9
|
+
# <seed> : seed for random number generation (0: none)
|
10
|
+
# <classRE> : regular expression for the classes to test ('': all)
|
11
|
+
# <methodRE> : regular expression for the methods to test ('': all)
|
12
|
+
# <flags> : Combination of bits for various flags
|
13
|
+
# 1 : disable testing of positions
|
14
|
+
# 2 : only test with strings/characters
|
15
|
+
#
|
16
|
+
# All of the standar Test::Unit auto runner options apply. The --verbose=<level>
|
17
|
+
# option is especially useful. Here are the various levels:
|
18
|
+
#
|
19
|
+
# s[ilent] : don't display anything
|
20
|
+
# p[rogress] : show a progress bar. Upon fail, show the test and seed.
|
21
|
+
# n[ormal] : show each method (and args) tested
|
22
|
+
# v[erbose] : show each method and the object state (inspect)
|
23
|
+
#
|
24
|
+
# If you want to see a demo for a particular method, usually a good command
|
25
|
+
# line would be something like this:
|
26
|
+
#
|
27
|
+
# ruby cursor/test_circulars.rb --verbose=v 10 0 Indexed '^(<method>|close)$'
|
28
|
+
|
29
|
+
require 'cursor/test'
|
30
|
+
require 'cursor/circular'
|
31
|
+
require 'cursor/indexed'
|
32
|
+
require 'cursor/circular/indexed'
|
33
|
+
require 'cursor/circular/shifting'
|
34
|
+
require 'cursor/circular/split'
|
35
|
+
require 'cursor/circular/linked'
|
36
|
+
|
37
|
+
# :stopdoc:
|
38
|
+
|
39
|
+
class Cursor
|
40
|
+
class Test
|
41
|
+
class Circulars < Test
|
42
|
+
def self.suite
|
43
|
+
@reject = /^(scan_until|modify|each|collect!|map!)$/
|
44
|
+
$0==__FILE__ ? super(*ARGV) : super()
|
45
|
+
end
|
46
|
+
def self.seed(before,after)
|
47
|
+
cursors = [
|
48
|
+
Cursor::Circular::Indexed.new(before+after,before.size),
|
49
|
+
Cursor::Circular::Indexed.new(after+before,0),
|
50
|
+
Cursor::Circular::Shifting.new(after+before,after.size),
|
51
|
+
Cursor::Circular::Split.new(before.clone,after.reverse),
|
52
|
+
Cursor::Circular::Linked.new(before.clone,after.reverse),
|
53
|
+
Cursor::Circular.new(Cursor::Indexed.new(before+after,before.size)),
|
54
|
+
]
|
55
|
+
if rand(2).zero?
|
56
|
+
@use_positions = false
|
57
|
+
cursors << Cursor::Circular.new(
|
58
|
+
Cursor::Indexed.new(before+after,before.size)
|
59
|
+
).position
|
60
|
+
else
|
61
|
+
@use_positions = @flags[0].zero?
|
62
|
+
end
|
63
|
+
cursors
|
64
|
+
end
|
65
|
+
def self.plant
|
66
|
+
@characters = rand(2).zero?
|
67
|
+
super
|
68
|
+
end
|
69
|
+
def self.elements
|
70
|
+
@characters ? [?\n,?\0,?0] : [false,"",[]]
|
71
|
+
end
|
72
|
+
def self.empty
|
73
|
+
@characters&&rand(2).zero? ? "" : []
|
74
|
+
end
|
75
|
+
def self.reject(name,*args,&block)
|
76
|
+
case name
|
77
|
+
when :position! then !@use_positions && args[0].nil?
|
78
|
+
when :position? then !@use_positions && args[0].nil? && block.nil?
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# :startdoc:
|
86
|
+
|
87
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
#
|
3
|
+
# $Id: test_cursors.rb,v 1.6 2005/07/21 15:15:38 eric_mahurin Exp $
|
4
|
+
#
|
5
|
+
# Run this to test non-circular cursors.
|
6
|
+
# Here is a list of the optional arguments:
|
7
|
+
#
|
8
|
+
# <iterations> : approximate number of times to test each method
|
9
|
+
# <seed> : seed for random number generation (0: none)
|
10
|
+
# <classRE> : regular expression for the classes to test ('': all)
|
11
|
+
# <methodRE> : regular expression for the methods to test ('': all)
|
12
|
+
# <flags> : Combination of bits for various flags
|
13
|
+
# 1 : disable testing of positions
|
14
|
+
# 2 : only test with strings/characters
|
15
|
+
#
|
16
|
+
# All of the standar Test::Unit auto runner options apply. The --verbose=<level>
|
17
|
+
# option is especially useful. Here are the various levels:
|
18
|
+
#
|
19
|
+
# s[ilent] : don't display anything
|
20
|
+
# p[rogress] : show a progress bar. Upon fail, show the test and seed.
|
21
|
+
# n[ormal] : show each method (and args) tested
|
22
|
+
# v[erbose] : show each method and the object state (inspect)
|
23
|
+
#
|
24
|
+
# If you want to see a demo for a particular method, usually a good command
|
25
|
+
# line would be something like this:
|
26
|
+
#
|
27
|
+
# ruby cursor/test_cursors.rb --verbose=v 10 0 Indexed '^(<method>|close)$'
|
28
|
+
|
29
|
+
require 'cursor/test'
|
30
|
+
require 'cursor/indexed'
|
31
|
+
require 'cursor/shifting'
|
32
|
+
require 'cursor/split'
|
33
|
+
require 'cursor/linked'
|
34
|
+
require 'cursor/buffered'
|
35
|
+
require 'cursor/lined'
|
36
|
+
require 'cursor/reversed'
|
37
|
+
require 'cursor/usedeleteinsert'
|
38
|
+
require 'cursor/usereadwrite'
|
39
|
+
require 'cursor/usenext'
|
40
|
+
require 'cursor/useposition'
|
41
|
+
require 'stringio'
|
42
|
+
require 'cursor/io'
|
43
|
+
|
44
|
+
# :stopdoc:
|
45
|
+
|
46
|
+
class Cursor
|
47
|
+
class Test
|
48
|
+
class Cursors < Test
|
49
|
+
def self.suite
|
50
|
+
@reject = /to_s/ # because of Cursor::Lined
|
51
|
+
$0==__FILE__ ? super(*ARGV) : super()
|
52
|
+
end
|
53
|
+
def self.seed(before,after)
|
54
|
+
cursors = [
|
55
|
+
(before+after).to_cursor(before.size),
|
56
|
+
Cursor::Shifting.new(after+before,after.size),
|
57
|
+
Cursor::Split.new(before.clone,after.reverse),
|
58
|
+
Cursor::Linked.new(before.clone,after.reverse),
|
59
|
+
Cursor.new(Cursor::Indexed.new(before+after,before.size)),
|
60
|
+
Cursor.new(Cursor::Indexed.new(before+after,before.size)).extend(UseDeleteInsert),
|
61
|
+
Cursor.new(Cursor::Indexed.new(before+after,before.size)).extend(UseReadWrite),
|
62
|
+
Cursor.new(Cursor::Indexed.new(before+after,before.size)).extend(UseNext),
|
63
|
+
Cursor.new(Cursor::Indexed.new(before+after,before.size)).extend(UsePosition),
|
64
|
+
Cursor::Buffered.new(
|
65
|
+
Cursor::Indexed.new(after.clone),
|
66
|
+
Cursor::Indexed.new(before.clone,before.size),
|
67
|
+
before.size
|
68
|
+
),
|
69
|
+
Cursor::Lined.new(Cursor::Indexed.new(before+after,before.size)),
|
70
|
+
Cursor::Reversed.new(Cursor::Indexed.new((before+after).reverse,after.size)),
|
71
|
+
]
|
72
|
+
if String===before
|
73
|
+
io=StringIO.new(before+after)
|
74
|
+
io.pos=before.size
|
75
|
+
cursors << io.to_cursor
|
76
|
+
cursors << Cursor::Buffered.new(
|
77
|
+
StringIO.new(after),
|
78
|
+
Cursor::Indexed.new(before.clone,before.size),
|
79
|
+
before.size
|
80
|
+
)
|
81
|
+
end
|
82
|
+
if rand(2).zero?
|
83
|
+
@use_positions = false
|
84
|
+
cursors << Cursor.new(Cursor::Indexed.new(before+after,before.size)).position
|
85
|
+
else
|
86
|
+
@use_positions = @flags[0].zero?
|
87
|
+
end
|
88
|
+
cursors
|
89
|
+
end
|
90
|
+
def self.plant
|
91
|
+
@characters = @flags[1].nonzero?||rand(2).zero?
|
92
|
+
super
|
93
|
+
end
|
94
|
+
def self.elements
|
95
|
+
@characters ? [?\n,?\0,?0] : [false,"",[]]
|
96
|
+
end
|
97
|
+
def self.empty
|
98
|
+
@characters&&(@flags[1].nonzero?||rand(2).zero?) ? "" : []
|
99
|
+
end
|
100
|
+
def self.reject(name,*args,&block)
|
101
|
+
case name
|
102
|
+
when :position! then !@use_positions && args[0].nil?
|
103
|
+
when :position? then !@use_positions && args[0].nil? && block.nil?
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# :startdoc:
|
111
|
+
|
112
|
+
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# $Id: usedeleteinsert.rb,v 1.11 2005/07/15 22:34:42 eric_mahurin Exp $
|
2
|
+
|
3
|
+
;
|
4
|
+
|
5
|
+
class Cursor
|
6
|
+
# Mixin for derived classes to use these methods as the basis for others:
|
7
|
+
# #_delete1after?, #delete1before?, #_insert1before, #_insert1after.
|
8
|
+
# See Cursor for a description of these methods.
|
9
|
+
module UseDeleteInsert # :nodoc:
|
10
|
+
protected
|
11
|
+
def _delete1after
|
12
|
+
_delete1after?.nil? ? nil : true
|
13
|
+
end
|
14
|
+
def _delete1before
|
15
|
+
_delete1before?.nil? ? nil : true
|
16
|
+
end
|
17
|
+
public
|
18
|
+
def delete1after
|
19
|
+
_delete1after && (@positions && _adjust_delete;true)
|
20
|
+
end
|
21
|
+
def delete1before
|
22
|
+
_delete1before && (@positions && _adjust_delete;true)
|
23
|
+
end
|
24
|
+
def delete1after?
|
25
|
+
v0 = _delete1after?
|
26
|
+
v0.nil? || @positions && _adjust_delete
|
27
|
+
v0
|
28
|
+
end
|
29
|
+
def delete1before?
|
30
|
+
v0 = _delete1before?
|
31
|
+
v0.nil? || @positions && _adjust_delete
|
32
|
+
v0
|
33
|
+
end
|
34
|
+
def insert1before(v)
|
35
|
+
@positions && _adjust_insert
|
36
|
+
_insert1before(v)
|
37
|
+
end
|
38
|
+
def insert1after(v)
|
39
|
+
@positions && _adjust_insert
|
40
|
+
_insert1after(v)
|
41
|
+
end
|
42
|
+
|
43
|
+
def read1next
|
44
|
+
v0 = _delete1after?
|
45
|
+
v0.nil? || _insert1before(v0)
|
46
|
+
v0
|
47
|
+
end
|
48
|
+
def read1prev
|
49
|
+
v0 = _delete1before?
|
50
|
+
v0.nil? || _insert1after(v0)
|
51
|
+
v0
|
52
|
+
end
|
53
|
+
def read1after
|
54
|
+
v0 = _delete1after?
|
55
|
+
v0.nil? || _insert1after(v0)
|
56
|
+
v0
|
57
|
+
end
|
58
|
+
def read1before
|
59
|
+
v0 = _delete1before?
|
60
|
+
v0.nil? || _insert1before(v0)
|
61
|
+
v0
|
62
|
+
end
|
63
|
+
def skip1next
|
64
|
+
v0 = _delete1after?
|
65
|
+
v0.nil? ? nil : _insert1before(v0)
|
66
|
+
end
|
67
|
+
def skip1prev
|
68
|
+
v0 = _delete1before?
|
69
|
+
v0.nil? ? nil : _insert1after(v0)
|
70
|
+
end
|
71
|
+
def skip1after
|
72
|
+
v0 = _delete1after?
|
73
|
+
v0.nil? ? nil : _insert1after(v0)
|
74
|
+
end
|
75
|
+
def skip1before
|
76
|
+
v0 = _delete1before?
|
77
|
+
v0.nil? ? nil : _insert1before(v0)
|
78
|
+
end
|
79
|
+
def write1next(v)
|
80
|
+
_delete1after && _insert1before(v)
|
81
|
+
end
|
82
|
+
def write1prev(v)
|
83
|
+
_delete1before && _insert1after(v)
|
84
|
+
end
|
85
|
+
def write1after(v)
|
86
|
+
_delete1after && _insert1after(v)
|
87
|
+
end
|
88
|
+
def write1before(v)
|
89
|
+
_delete1before && _insert1before(v)
|
90
|
+
end
|
91
|
+
def write1next!(v)
|
92
|
+
_delete1after ? _insert1before(v) : insert1before(v)
|
93
|
+
end
|
94
|
+
def write1prev!(v)
|
95
|
+
_delete1before ? _insert1after(v) : insert1after(v)
|
96
|
+
end
|
97
|
+
def write1after!(v)
|
98
|
+
_delete1after ? _insert1after(v) : insert1after(v)
|
99
|
+
end
|
100
|
+
def write1before!(v)
|
101
|
+
_delete1before ? _insert1before(v) : insert1before(v)
|
102
|
+
end
|
103
|
+
def write1next?(v)
|
104
|
+
v0 = _delete1after?
|
105
|
+
v0.nil? || _insert1before(v)
|
106
|
+
v0
|
107
|
+
end
|
108
|
+
def write1prev?(v)
|
109
|
+
v0 = _delete1before?
|
110
|
+
v0.nil? || _insert1after(v)
|
111
|
+
v0
|
112
|
+
end
|
113
|
+
def write1after?(v)
|
114
|
+
v0 = _delete1after?
|
115
|
+
v0.nil? || _insert1after(v)
|
116
|
+
v0
|
117
|
+
end
|
118
|
+
def write1before?(v)
|
119
|
+
v0 = _delete1before?
|
120
|
+
v0.nil? || _insert1before(v)
|
121
|
+
v0
|
122
|
+
end
|
123
|
+
def scan1next(v)
|
124
|
+
v0 = _delete1after?
|
125
|
+
v0.nil? ? nil :
|
126
|
+
(v!=v0) ? (_insert1after(v0);nil) :
|
127
|
+
(_insert1before(v0);v0)
|
128
|
+
end
|
129
|
+
def scan1prev(v)
|
130
|
+
v0 = _delete1before?
|
131
|
+
v0.nil? ? nil :
|
132
|
+
(v!=v0) ? (_insert1before(v0);nil) :
|
133
|
+
(_insert1after(v0);v0)
|
134
|
+
end
|
135
|
+
def modify1next(r)
|
136
|
+
v0 = _delete1after?
|
137
|
+
v0.nil? ? nil :
|
138
|
+
(v = r[v0]).nil? ? (_insert1after(v0);nil) :
|
139
|
+
(_insert1before(v);v0)
|
140
|
+
end
|
141
|
+
def modify1prev(r)
|
142
|
+
v0 = _delete1before?
|
143
|
+
v0.nil? ? nil :
|
144
|
+
(v = r[v0]).nil? ? (_insert1before(v0);nil) :
|
145
|
+
(_insert1after(v);v0)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
|
data/cursor/usenext.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
# $Id: usenext.rb,v 1.12 2005/07/15 22:34:42 eric_mahurin Exp $
|
2
|
+
|
3
|
+
;
|
4
|
+
|
5
|
+
class Cursor
|
6
|
+
# Mixin for derived classes to use these methods as the basis for others:
|
7
|
+
# #read1next, #write1next, #skip1prev,
|
8
|
+
# #_delete1after?, #_insert1before.
|
9
|
+
# See Cursor for a description of these methods.
|
10
|
+
# You may also override methods with the same name as above except the "1" is
|
11
|
+
# replaced with "_". These operate on sequences rather than single elements.
|
12
|
+
module UseNext # :nodoc:
|
13
|
+
protected
|
14
|
+
def _delete1after
|
15
|
+
_delete1after?.nil? ? nil : true
|
16
|
+
end
|
17
|
+
public
|
18
|
+
def delete1after
|
19
|
+
_delete1after && (@positions && _adjust_delete;true)
|
20
|
+
end
|
21
|
+
def delete1after?
|
22
|
+
v0 = _delete1after?
|
23
|
+
v0.nil? || @positions && _adjust_delete
|
24
|
+
v0
|
25
|
+
end
|
26
|
+
def insert1before(v)
|
27
|
+
@positions && _adjust_insert
|
28
|
+
_insert1before(v)
|
29
|
+
end
|
30
|
+
def write1next!(v)
|
31
|
+
write1next(v) || _insert1before(v)
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete1before
|
35
|
+
skip1prev && delete1after
|
36
|
+
end
|
37
|
+
def delete1before?
|
38
|
+
skip1prev && delete1after?
|
39
|
+
end
|
40
|
+
def insert1after(v)
|
41
|
+
insert1before(v)
|
42
|
+
skip1prev
|
43
|
+
end
|
44
|
+
|
45
|
+
def skip1next
|
46
|
+
read1next.nil? ? nil : true
|
47
|
+
end
|
48
|
+
def read1after
|
49
|
+
v0 = read1next
|
50
|
+
v0.nil? || skip1prev
|
51
|
+
v0
|
52
|
+
end
|
53
|
+
def write1after(v)
|
54
|
+
write1next(v) && skip1prev
|
55
|
+
end
|
56
|
+
def write1after!(v)
|
57
|
+
write1next!(v)
|
58
|
+
skip1prev
|
59
|
+
end
|
60
|
+
|
61
|
+
def read1before
|
62
|
+
skip1prev && read1next
|
63
|
+
end
|
64
|
+
def write1before(v)
|
65
|
+
skip1prev && write1next(v)
|
66
|
+
end
|
67
|
+
def write1before!(v)
|
68
|
+
skip1prev ? write1next(v) : insert1before(v)
|
69
|
+
end
|
70
|
+
|
71
|
+
def skip1after
|
72
|
+
skip1next && skip1prev
|
73
|
+
end
|
74
|
+
def skip1before
|
75
|
+
skip1prev && skip1next
|
76
|
+
end
|
77
|
+
|
78
|
+
def read1prev
|
79
|
+
skip1prev && read1after
|
80
|
+
end
|
81
|
+
def write1prev(v)
|
82
|
+
skip1prev && write1after(v)
|
83
|
+
end
|
84
|
+
def write1prev!(v)
|
85
|
+
skip1prev ? write1after(v) : insert1after(v)
|
86
|
+
end
|
87
|
+
def write1next?(v)
|
88
|
+
v0 = read1after
|
89
|
+
v0.nil? || write1next(v)
|
90
|
+
v0
|
91
|
+
end
|
92
|
+
def write1prev?(v)
|
93
|
+
v0 = read1before
|
94
|
+
v0.nil? || write1prev(v)
|
95
|
+
v0
|
96
|
+
end
|
97
|
+
def write1after?(v)
|
98
|
+
v0 = read1after
|
99
|
+
v0.nil? || write1after(v)
|
100
|
+
v0
|
101
|
+
end
|
102
|
+
def write1before?(v)
|
103
|
+
v0 = read1before
|
104
|
+
v0.nil? || write1before(v)
|
105
|
+
v0
|
106
|
+
end
|
107
|
+
def scan1next(v)
|
108
|
+
v0 = read1next
|
109
|
+
(v0.nil? || v==v0) ? v0 : (skip1prev;nil)
|
110
|
+
end
|
111
|
+
def scan1prev(v)
|
112
|
+
v0 = read1before
|
113
|
+
(v0.nil? || v!=v0) ? nil : (skip1prev;v0)
|
114
|
+
end
|
115
|
+
def modify1next(r)
|
116
|
+
v0 = read1after
|
117
|
+
(v0.nil? || (v = r[v0]).nil?) ? nil : (write1next(v);v0)
|
118
|
+
end
|
119
|
+
def modify1prev(r)
|
120
|
+
v0 = read1before
|
121
|
+
(v0.nil? || (v = r[v0]).nil?) ? nil : (write1prev(v);v0)
|
122
|
+
end
|
123
|
+
def position(reverse=false,&code) # :yield:
|
124
|
+
p = Position.new(self,reverse)
|
125
|
+
(@positions||=WeakRefSet.new) << p
|
126
|
+
if code
|
127
|
+
begin
|
128
|
+
code[]
|
129
|
+
ensure
|
130
|
+
begin
|
131
|
+
self.position = p
|
132
|
+
ensure
|
133
|
+
p.close
|
134
|
+
end
|
135
|
+
end
|
136
|
+
else
|
137
|
+
p
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
require 'cursor/usenext/position'
|
144
|
+
|
145
|
+
|