cursor 0.6 → 0.8
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.
- 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
|
+
|