rdoba 0.0.3 → 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +43 -0
- data/CHANGES.md +28 -0
- data/Gemfile +2 -11
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +410 -0
- data/Rakefile +1 -51
- data/lib/rdoba/a.rb +114 -0
- data/lib/rdoba/combinations.rb +59 -0
- data/lib/rdoba/common.rb +190 -0
- data/lib/rdoba/debug.rb +48 -0
- data/lib/rdoba/deploy.rb +80 -0
- data/lib/rdoba/dup.rb +64 -0
- data/lib/rdoba/fenc.rb +17 -0
- data/lib/rdoba/hashorder.rb +66 -0
- data/lib/rdoba/io.rb +160 -0
- data/lib/rdoba/numeric.rb +93 -0
- data/lib/rdoba/re.rb +22 -0
- data/lib/rdoba/require.rb +62 -0
- data/lib/rdoba/roman.rb +45 -0
- data/lib/rdoba/strings.rb +149 -0
- data/lib/rdoba/version.rb +3 -0
- data/lib/rdoba/yaml.rb +48 -0
- data/lib/rdoba.rb +13 -1142
- data/rdoba.gemspec +18 -56
- metadata +38 -59
- data/README.rdoc +0 -19
- data/VERSION +0 -1
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
class Array
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def __comby(i, size)
|
8
|
+
s = "0#{sprintf("%.*b", size, i)}0"
|
9
|
+
v = { :res => [], :c0 => 0, :c1 => 0, :j => 0}
|
10
|
+
|
11
|
+
def up1(v)
|
12
|
+
sub_j = v[:j] + v[:c1] + 1
|
13
|
+
v[:res] << self[v[:j]...sub_j]
|
14
|
+
v[:j] = sub_j
|
15
|
+
v[:c1] = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def up0(v)
|
19
|
+
sub_j = v[:j] + v[:c0] - 1
|
20
|
+
self[v[:j]...sub_j].each do |x| v[:res] << [x] end
|
21
|
+
v[:j] = sub_j
|
22
|
+
end
|
23
|
+
|
24
|
+
s.each_char do |c|
|
25
|
+
if c == '1'
|
26
|
+
v[:c1] += 1
|
27
|
+
up0(v) if v[:c0] > 1
|
28
|
+
v[:c0] = 0
|
29
|
+
else
|
30
|
+
v[:c0] += 1
|
31
|
+
up1(v) if v[:c1] > 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
up0(v) if v[:c0] > 1
|
35
|
+
v[:res]
|
36
|
+
end
|
37
|
+
|
38
|
+
public
|
39
|
+
|
40
|
+
def each_comby(*args)
|
41
|
+
return self if self.empty? or not block_given?
|
42
|
+
if args.include?(:backward)
|
43
|
+
yield [ self.dup ]
|
44
|
+
((1 << (self.size - 1)) - 2).downto(0) do |i|
|
45
|
+
c = __comby(i, self.size - 1)
|
46
|
+
yield c
|
47
|
+
end
|
48
|
+
else
|
49
|
+
0.upto((1 << (self.size - 1)) - 2) do |i|
|
50
|
+
c = __comby(i, self.size - 1)
|
51
|
+
yield c
|
52
|
+
end
|
53
|
+
yield [ self.dup ]
|
54
|
+
end
|
55
|
+
|
56
|
+
return self
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
data/lib/rdoba/common.rb
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
#!/usr/bin/ruby -KU
|
2
|
+
#<Encoding:UTF-8>
|
3
|
+
|
4
|
+
class Object
|
5
|
+
def xor(val1)
|
6
|
+
val0 = (not not self)
|
7
|
+
((val0) and (not val1)) or ((not val0) and (val1))
|
8
|
+
end
|
9
|
+
|
10
|
+
def co(method, *args) #calls any method
|
11
|
+
eval "#{method}(*args)"
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_sym
|
15
|
+
to_s.to_sym
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_opts(opts)
|
19
|
+
v = {}
|
20
|
+
opts.each do |opt|
|
21
|
+
case opt.class.to_s.to_sym
|
22
|
+
when :Hash
|
23
|
+
opt.each do |x,y| v[x] = y end
|
24
|
+
when :Array
|
25
|
+
opt.each do |x| v[x] = true end
|
26
|
+
when :Symbol
|
27
|
+
v[opt] = true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
v
|
31
|
+
end
|
32
|
+
|
33
|
+
def apply_opts(opts)
|
34
|
+
parse_opts(opts).each do |x,y|
|
35
|
+
self.instance_variable_set("@#{x}".to_sym, y)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module Kernel
|
41
|
+
def wait_if(timeout = 30)
|
42
|
+
require 'timeout'
|
43
|
+
|
44
|
+
begin
|
45
|
+
Timeout::timeout(timeout) do
|
46
|
+
while yield(); end
|
47
|
+
end
|
48
|
+
true
|
49
|
+
rescue Timeout::Error
|
50
|
+
false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class NilClass
|
56
|
+
def =~(value)
|
57
|
+
value == nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def +(value)
|
61
|
+
value
|
62
|
+
end
|
63
|
+
|
64
|
+
def <<(value)
|
65
|
+
[ value ]
|
66
|
+
end
|
67
|
+
|
68
|
+
def empty?
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_i
|
73
|
+
0
|
74
|
+
end
|
75
|
+
alias :ord :to_i
|
76
|
+
|
77
|
+
def size
|
78
|
+
0
|
79
|
+
end
|
80
|
+
|
81
|
+
def <=>(value)
|
82
|
+
-1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
class Array
|
88
|
+
def purge
|
89
|
+
self.compact.delete_if {|x| x.empty? }
|
90
|
+
end
|
91
|
+
|
92
|
+
def >>(value = nil)
|
93
|
+
value ? delete(value) : shift
|
94
|
+
end
|
95
|
+
|
96
|
+
alias :__get__ :[]
|
97
|
+
def [](index, *args)
|
98
|
+
return __get__(index.to_i, *args) if index.class == String and index =~ /^\d+$/
|
99
|
+
__get__(index, *args)
|
100
|
+
end
|
101
|
+
|
102
|
+
alias :__set__ :[]=
|
103
|
+
def []=(index, value, *args)
|
104
|
+
return __set__(index.to_i, value, *args) if index.class == String and index =~ /^\d+$/
|
105
|
+
__set__(index, value, *args)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class String
|
110
|
+
def -(str)
|
111
|
+
#TODO make smart search for match in the 'str', when only last subpart matched to 'self'
|
112
|
+
len = self.size
|
113
|
+
bc = ec = nil
|
114
|
+
(0...len).each do |idx|
|
115
|
+
break bc = idx if self[idx] == str[0]
|
116
|
+
end
|
117
|
+
((bc + 1)...len).each do |idx|
|
118
|
+
break ec = idx if self[idx] != str[idx - bc]
|
119
|
+
end if bc
|
120
|
+
(not bc) ? self.clone : (not ec) ? self[0, bc] : self[0, bc] + self[ec, len - ec]
|
121
|
+
end
|
122
|
+
|
123
|
+
alias :__match__ :=~
|
124
|
+
def =~(value)
|
125
|
+
if value.class == String
|
126
|
+
self == value
|
127
|
+
elsif value.class == Regexp
|
128
|
+
value =~ self
|
129
|
+
else
|
130
|
+
__match__(value)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def rmatch(value)
|
135
|
+
self == value || self =~ /^\/([^\/]+)/ && value =~ /#{$1}/
|
136
|
+
end
|
137
|
+
|
138
|
+
def hexdump
|
139
|
+
res= ''
|
140
|
+
i = 0
|
141
|
+
self.each_byte do |byte|
|
142
|
+
res << sprintf("%.2X ", byte)
|
143
|
+
i += 1
|
144
|
+
res << "\n" if i % 16 == 0
|
145
|
+
end
|
146
|
+
res
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class Hash
|
151
|
+
def |(inval)
|
152
|
+
res = self.dup
|
153
|
+
inval.each_pair do |key, val|
|
154
|
+
if val.class == res[key].class
|
155
|
+
if val.class == Hash
|
156
|
+
res[key] |= inval[key]
|
157
|
+
elsif val.class == Array
|
158
|
+
res[key].concat val
|
159
|
+
else
|
160
|
+
res[key] = val
|
161
|
+
end
|
162
|
+
else
|
163
|
+
res[key] = val
|
164
|
+
end
|
165
|
+
end
|
166
|
+
res
|
167
|
+
end
|
168
|
+
|
169
|
+
def reverse!
|
170
|
+
replace(reverse)
|
171
|
+
end
|
172
|
+
|
173
|
+
def reverse
|
174
|
+
h = {}
|
175
|
+
self.each_pair do |key, value|
|
176
|
+
if h.key? value
|
177
|
+
if h[value].class == Array
|
178
|
+
h[value] << key
|
179
|
+
else
|
180
|
+
h[value] = [ h[value], key ]
|
181
|
+
end
|
182
|
+
else
|
183
|
+
h[value] = key
|
184
|
+
end
|
185
|
+
end
|
186
|
+
h
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
data/lib/rdoba/debug.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
class Object
|
4
|
+
attr_reader :debug
|
5
|
+
|
6
|
+
@debug = nil
|
7
|
+
eval "$debug_#{self.class} = 0"
|
8
|
+
|
9
|
+
public
|
10
|
+
|
11
|
+
def debug=(level)
|
12
|
+
@debug = level
|
13
|
+
end
|
14
|
+
|
15
|
+
def dbc(level)
|
16
|
+
level = level.to_i
|
17
|
+
if level > 0
|
18
|
+
clevel = @debug || begin; eval "$debug_#{self.class}"; rescue; nil; end
|
19
|
+
clevel ? (clevel.to_i & level) == level : false
|
20
|
+
else
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def dbp(level, text)
|
26
|
+
Kernel.puts text if dbc(level)
|
27
|
+
end
|
28
|
+
|
29
|
+
def dbg(level, code, vars = {})
|
30
|
+
if dbc(level)
|
31
|
+
if vars
|
32
|
+
vars.each_pair do |var, value|
|
33
|
+
instance_variable_set(var, value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
eval code
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
(1..0xF).each do |x|
|
41
|
+
(1..0xF).each do |y|
|
42
|
+
idx = sprintf "%x%x", x, y
|
43
|
+
eval "def dbp#{idx}(text); dbp(0x#{idx},text); end"
|
44
|
+
eval "def dbg#{idx}(text); dbg(0x#{idx},text); end"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
data/lib/rdoba/deploy.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/ruby -KU
|
2
|
+
#<Encoding:UTF-8>
|
3
|
+
|
4
|
+
require 'rdoba/common'
|
5
|
+
|
6
|
+
class Hash
|
7
|
+
|
8
|
+
def deploy!(vars = {})
|
9
|
+
self.replace deploy(vars)
|
10
|
+
# TODO add variable copy
|
11
|
+
end
|
12
|
+
|
13
|
+
def deploy(vars = {})
|
14
|
+
res = {}
|
15
|
+
|
16
|
+
self.keys.sort do |x,y|
|
17
|
+
if x =~ /=$/
|
18
|
+
y =~ /=$/ ? x <=> y : -1
|
19
|
+
else
|
20
|
+
y !~ /=$/ ? x <=> y : 1
|
21
|
+
end
|
22
|
+
end.each do |key|
|
23
|
+
|
24
|
+
if key =~ /(.*)=$/
|
25
|
+
vars[$1] = self[key]
|
26
|
+
next
|
27
|
+
|
28
|
+
elsif key =~ /(.*)@$/
|
29
|
+
sym = $1
|
30
|
+
eval "res.class.co( :attr_accessor, :#{sym})"
|
31
|
+
eval "res.#{sym} = self[key]"
|
32
|
+
next
|
33
|
+
|
34
|
+
elsif key =~ /^%([^%].*)/
|
35
|
+
next $stderr.puts "Warning: undefined variable " +
|
36
|
+
"#{$1.inspect} found. Ignoring..." unless vars.key?($1)
|
37
|
+
var = vars[$1].dup
|
38
|
+
if var.class == Hash
|
39
|
+
res |= var.deploy(vars)
|
40
|
+
elsif var.class == String
|
41
|
+
res[var] = nil
|
42
|
+
else
|
43
|
+
raise "Undeployable hash #{$1} value class #{var.class}"
|
44
|
+
end
|
45
|
+
next
|
46
|
+
|
47
|
+
elsif key =~ /^%%(.*)/
|
48
|
+
key.replace $1.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
def deploy_value(value, vars)
|
52
|
+
case value.class.to_sym
|
53
|
+
when :String
|
54
|
+
if value =~ /^%([^%].*)/
|
55
|
+
begin; vars[$1].deploy(vars); rescue; nil end
|
56
|
+
elsif value =~ /(.*)%([A-Za-z0-9_А-я]+)(.*)/
|
57
|
+
a = [ $1.to_s, $2.to_s, $3.to_s ]
|
58
|
+
a[1] = begin; vars[a[1]].deploy(vars).to_s; rescue; vars[a[1]] end
|
59
|
+
a.join
|
60
|
+
else
|
61
|
+
value
|
62
|
+
end
|
63
|
+
when :Hash
|
64
|
+
value.deploy(vars)
|
65
|
+
when :Array
|
66
|
+
value.map do |sub|
|
67
|
+
deploy_value(sub, vars)
|
68
|
+
end
|
69
|
+
else
|
70
|
+
value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
value = self[key]
|
75
|
+
res[key] = deploy_value(value, vars)
|
76
|
+
end
|
77
|
+
res
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
data/lib/rdoba/dup.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/ruby -KU
|
2
|
+
#<Encoding:UTF-8>
|
3
|
+
|
4
|
+
class Array
|
5
|
+
alias :__dup__ :dup
|
6
|
+
def dup(opts = {})
|
7
|
+
if (opts.class == Hash ? opts.key?(:recursive) : opts.to_s.to_sym == :recursive)
|
8
|
+
res = []
|
9
|
+
|
10
|
+
def sub_dup(value)
|
11
|
+
if value.class.to_s =~ /(Hash|Array)/
|
12
|
+
value.dup(:recursive)
|
13
|
+
else
|
14
|
+
begin
|
15
|
+
value.dup
|
16
|
+
rescue
|
17
|
+
new = value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
self.each do |value| res << sub_dup(value) end
|
23
|
+
|
24
|
+
res
|
25
|
+
elsif opts.empty?
|
26
|
+
__dup__
|
27
|
+
else
|
28
|
+
raise "Unsupported option(s): #{opts.class == Hash ? opts.keys.join(', ') : opts}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class Hash
|
35
|
+
alias :__dup__ :dup
|
36
|
+
def dup(opts = {})
|
37
|
+
if (opts.class == Hash ? opts.key?(:recursive) : opts.to_s.to_sym == :recursive)
|
38
|
+
res = {}
|
39
|
+
|
40
|
+
def sub_dup(value)
|
41
|
+
if value.class.to_s =~ /(Hash|Array)/
|
42
|
+
value.dup(:recursive)
|
43
|
+
else
|
44
|
+
begin
|
45
|
+
value.dup
|
46
|
+
rescue
|
47
|
+
new = value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
self.each do |key, value| res[ sub_dup(key) ] = sub_dup(value) end
|
53
|
+
|
54
|
+
res
|
55
|
+
elsif opts.empty?
|
56
|
+
__dup__
|
57
|
+
else
|
58
|
+
raise "Unsupported option(s): #{opts.class == Hash ? opts.keys.join(', ') : opts}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
|
data/lib/rdoba/fenc.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/ruby -KU
|
2
|
+
|
3
|
+
class String
|
4
|
+
def fenc
|
5
|
+
if RUBY_VERSION < '1.9'
|
6
|
+
self
|
7
|
+
else
|
8
|
+
return self unless Encoding.default_internal
|
9
|
+
if self.frozen?
|
10
|
+
self.dup.force_encoding(Encoding.default_internal || 'UTF-8').freeze
|
11
|
+
else
|
12
|
+
self.force_encoding(Encoding.default_internal || 'UTF-8')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
class Hash
|
4
|
+
attr_reader :order
|
5
|
+
|
6
|
+
class Each
|
7
|
+
General = 0
|
8
|
+
Pair = 1
|
9
|
+
Key = 2
|
10
|
+
Value = 3
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def each_special(spec)
|
16
|
+
(@order | self.keys).each do |key|
|
17
|
+
if self.has_key? key
|
18
|
+
case spec
|
19
|
+
when Hash::Each::General
|
20
|
+
yield key, self[key]
|
21
|
+
when Hash::Each::Pair
|
22
|
+
yield key, self[key]
|
23
|
+
when Hash::Each::Key
|
24
|
+
yield key
|
25
|
+
when Hash::Each::Value
|
26
|
+
yield self[key]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
public
|
33
|
+
|
34
|
+
def order=(order)
|
35
|
+
return nil if order.class != Array
|
36
|
+
|
37
|
+
@order = order
|
38
|
+
end
|
39
|
+
|
40
|
+
def disorder
|
41
|
+
@order = nil; self
|
42
|
+
end
|
43
|
+
|
44
|
+
alias :__each__ :each
|
45
|
+
alias :__each_pair__ :each_pair
|
46
|
+
alias :__each_key__ :each_key
|
47
|
+
alias :__each_value__ :each_value
|
48
|
+
|
49
|
+
def each(&block)
|
50
|
+
@order ? each_special(Hash::Each::General, &block) : __each__(&block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def each_pair(&block)
|
54
|
+
@order ? each_special(Hash::Each::Pair, &block) : __each_pair__(&block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def each_key(&block)
|
58
|
+
@order ? each_special(Hash::Each::Key, &block) : __each_key__(&block)
|
59
|
+
end
|
60
|
+
|
61
|
+
def each_value(&block)
|
62
|
+
@order ? each_special(Hash::Each::Value, &block) : __each_value__(&block)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
data/lib/rdoba/io.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
#!/usr/bin/ruby -KU
|
2
|
+
#<Encoding:UTF-8>
|
3
|
+
|
4
|
+
require 'strscan'
|
5
|
+
require 'rdoba/re'
|
6
|
+
require 'rdoba/roman'
|
7
|
+
require 'rdoba/numeric'
|
8
|
+
|
9
|
+
module Kernel
|
10
|
+
alias :__sprintf__ :sprintf
|
11
|
+
def sprintf(format, *args)
|
12
|
+
nargs = []
|
13
|
+
nformat = ''
|
14
|
+
|
15
|
+
fmt = format.split('%')
|
16
|
+
nformat = fmt.shift
|
17
|
+
|
18
|
+
while (not fmt.empty?)
|
19
|
+
part = fmt.shift
|
20
|
+
part = '%' + fmt.shift unless part
|
21
|
+
if part =~ /([0-9 #+\-*.]*)([bcdEefGgiopsuXxP])(.*)/ and $2 == 'P'
|
22
|
+
keys = $1 || ''
|
23
|
+
str = $3 || ''
|
24
|
+
if keys =~ /(-)?([0-9*]*)\.?([0-9\*]*)(\+?)/
|
25
|
+
value = args.shift
|
26
|
+
indent = ' ' * ($2 == '*' ? args.shift : $2).to_i
|
27
|
+
plain = value && value.to_p(
|
28
|
+
:padding => ($3 == '*' ? args.shift : $3.empty? ? 1 : $3).to_i,
|
29
|
+
:be => $4.empty? ? nil : true) || ''
|
30
|
+
nformat += ($1 ? plain + indent : indent + plain) + str
|
31
|
+
else
|
32
|
+
nformat += '%' + keys + 'c' + str
|
33
|
+
nargs.push args.shift
|
34
|
+
end
|
35
|
+
else
|
36
|
+
nformat += '%' + part
|
37
|
+
l = $1 =~ /\*/ ? 2 : 1
|
38
|
+
while l > 0
|
39
|
+
nargs.push args.shift
|
40
|
+
l -= 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
__sprintf__(nformat, *nargs).to_p
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class String
|
50
|
+
def scanf_re(format)
|
51
|
+
fss = StringScanner.new(format) # TODO remove scanner in favor of match
|
52
|
+
nformat = ''
|
53
|
+
|
54
|
+
pos = 0
|
55
|
+
argfs = []
|
56
|
+
while fss.scan_until(/%([0-9 #+\-*]*)(?:\.([0-9]+)(\+)?)?([bcdefgiosuxr])/)
|
57
|
+
argfs << [ fss[1], fss[2], fss[3], fss[4] ]
|
58
|
+
# TODO add performing the special case in fss[1]
|
59
|
+
nformat += fss.pre_match[pos..-1].to_res + case fss[4]
|
60
|
+
when 'x'
|
61
|
+
'(?:0[xX])?([a-fA-F0-9]+)'
|
62
|
+
when 'i'
|
63
|
+
'([+\-]?[0-9]+)'
|
64
|
+
when 'u'
|
65
|
+
'([0-9]+)'
|
66
|
+
when 'e'
|
67
|
+
'([+\-]?[0-9]+[eE][+\-]?[0-9]+)'
|
68
|
+
when 'f'
|
69
|
+
'([+\-]?[0-9]+\.[0-9]*)'
|
70
|
+
when 'g'
|
71
|
+
'([+\-]?[0-9]+(?:[eE][+\-]?[0-9]+|\.[0-9]*))'
|
72
|
+
when 'c'
|
73
|
+
fss[2] ? "(.{1,#{fss[2]}})" : "(.)"
|
74
|
+
when 'b'
|
75
|
+
'([01]+)b?'
|
76
|
+
when 'o'
|
77
|
+
'0([0-9]+)'
|
78
|
+
when 'd'
|
79
|
+
'([+\-]?(?:0X)?[A-F0-9.+]+)'
|
80
|
+
when 's'
|
81
|
+
'(.+)'
|
82
|
+
when 'r'
|
83
|
+
'([IVXLCDMivxlcdm]+)'
|
84
|
+
end
|
85
|
+
|
86
|
+
pos = fss.pos
|
87
|
+
end
|
88
|
+
|
89
|
+
nformat += fss.rest
|
90
|
+
|
91
|
+
[ /#{nformat}/, argfs ]
|
92
|
+
end
|
93
|
+
|
94
|
+
(alias :__scanf__ :scanf) if self.instance_methods(false).include?(:scanf)
|
95
|
+
def scanf(format, &block)
|
96
|
+
(re, argfs) = scanf_re(format)
|
97
|
+
|
98
|
+
ss = StringScanner.new(self)
|
99
|
+
res = []
|
100
|
+
rline = []
|
101
|
+
while ss.scan_until(re)
|
102
|
+
argfs.each_index do |i|
|
103
|
+
argf = argfs[i]
|
104
|
+
value = ss[i + 1]
|
105
|
+
rline << case argf[3]
|
106
|
+
when 'x'
|
107
|
+
value.to_i(16)
|
108
|
+
when /[diu]/
|
109
|
+
value.to_i
|
110
|
+
when /[efg]/
|
111
|
+
value.to_f
|
112
|
+
when 'c'
|
113
|
+
argf[2] ? value.to_i(:be) : value.to_i
|
114
|
+
when 'b'
|
115
|
+
value.to_i(2)
|
116
|
+
when 'o'
|
117
|
+
value.to_i(8)
|
118
|
+
when 's'
|
119
|
+
value
|
120
|
+
when 'r'
|
121
|
+
value.rom
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
if block_given?
|
126
|
+
pass = []
|
127
|
+
(1..block.arity).each do |i| pass << "rline[#{i}]" end
|
128
|
+
eval "yield(#{pass.join(', ')})"
|
129
|
+
end
|
130
|
+
|
131
|
+
res << rline
|
132
|
+
end
|
133
|
+
|
134
|
+
res
|
135
|
+
end
|
136
|
+
|
137
|
+
def consolize
|
138
|
+
ss = StringScanner.new(self)
|
139
|
+
res = ''
|
140
|
+
ostr = ''
|
141
|
+
pos = 0
|
142
|
+
|
143
|
+
while ss.scan_until(/\r/)
|
144
|
+
ostr[0...ss.pre_match.size - pos] = ss.pre_match[pos..-1]
|
145
|
+
pos = ss.pos
|
146
|
+
|
147
|
+
if ss.post_match[0] == "\n"[0]
|
148
|
+
res = ostr
|
149
|
+
pos += 1
|
150
|
+
ostr = ''
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
ostr[0...ss.rest.size] = ss.rest
|
156
|
+
res + ostr
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
|