rdoba 0.0.3 → 0.1
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/.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
|
+
|