source: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/string.rb@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 6.6 KB
Line 
1##
2# String
3#
4# ISO 15.2.10
5class String
6 include Comparable
7 ##
8 # Calls the given block for each line
9 # and pass the respective line.
10 #
11 # ISO 15.2.10.5.15
12 def each_line(rs = "\n", &block)
13 return to_enum(:each_line, rs, &block) unless block
14 return block.call(self) if rs.nil?
15 rs = rs.to_str
16 offset = 0
17 rs_len = rs.length
18 this = dup
19 while pos = this.index(rs, offset)
20 block.call(this[offset, pos + rs_len - offset])
21 offset = pos + rs_len
22 end
23 block.call(this[offset, this.size - offset]) if this.size > offset
24 self
25 end
26
27 # private method for gsub/sub
28 def __sub_replace(pre, m, post)
29 s = ""
30 i = 0
31 while j = index("\\", i)
32 break if j == length-1
33 t = case self[j+1]
34 when "\\"
35 "\\"
36 when "`"
37 pre
38 when "&", "0"
39 m
40 when "'"
41 post
42 when "1", "2", "3", "4", "5", "6", "7", "8", "9"
43 ""
44 else
45 self[j, 2]
46 end
47 s += self[i, j-i] + t
48 i = j + 2
49 end
50 s + self[i, length-i]
51 end
52
53 ##
54 # Replace all matches of +pattern+ with +replacement+.
55 # Call block (if given) for each match and replace
56 # +pattern+ with the value of the block. Return the
57 # final value.
58 #
59 # ISO 15.2.10.5.18
60 def gsub(*args, &block)
61 return to_enum(:gsub, *args) if args.length == 1 && !block
62 raise ArgumentError, "wrong number of arguments" unless (1..2).include?(args.length)
63
64 pattern, replace = *args
65 plen = pattern.length
66 if args.length == 2 && block
67 block = nil
68 end
69 if !replace.nil? || !block
70 replace = replace.to_str
71 end
72 offset = 0
73 result = []
74 while found = index(pattern, offset)
75 result << self[offset, found - offset]
76 offset = found + plen
77 result << if block
78 block.call(pattern).to_s
79 else
80 replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "")
81 end
82 if plen == 0
83 result << self[offset, 1]
84 offset += 1
85 end
86 end
87 result << self[offset..-1] if offset < length
88 result.join
89 end
90
91 ##
92 # Replace all matches of +pattern+ with +replacement+.
93 # Call block (if given) for each match and replace
94 # +pattern+ with the value of the block. Modify
95 # +self+ with the final value.
96 #
97 # ISO 15.2.10.5.19
98 def gsub!(*args, &block)
99 raise RuntimeError, "can't modify frozen String" if frozen?
100 return to_enum(:gsub!, *args) if args.length == 1 && !block
101 str = self.gsub(*args, &block)
102 return nil if str == self
103 self.replace(str)
104 end
105
106 ##
107 # Calls the given block for each match of +pattern+
108 # If no block is given return an array with all
109 # matches of +pattern+.
110 #
111 # ISO 15.2.10.5.32
112 def scan(reg, &block)
113 ### *** TODO *** ###
114 unless Object.const_defined?(:Regexp)
115 raise NotImplementedError, "scan not available (yet)"
116 end
117 end
118
119 ##
120 # Replace only the first match of +pattern+ with
121 # +replacement+. Call block (if given) for each
122 # match and replace +pattern+ with the value of the
123 # block. Return the final value.
124 #
125 # ISO 15.2.10.5.36
126 def sub(*args, &block)
127 unless (1..2).include?(args.length)
128 raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 2)"
129 end
130
131 pattern, replace = *args
132 pattern = pattern.to_str
133 if args.length == 2 && block
134 block = nil
135 end
136 if !block
137 replace = replace.to_str
138 end
139 result = []
140 this = dup
141 found = index(pattern)
142 return this unless found
143 result << this[0, found]
144 offset = found + pattern.length
145 result << if block
146 block.call(pattern).to_s
147 else
148 replace.__sub_replace(this[0, found], pattern, this[offset..-1] || "")
149 end
150 result << this[offset..-1] if offset < length
151 result.join
152 end
153
154 ##
155 # Replace only the first match of +pattern+ with
156 # +replacement+. Call block (if given) for each
157 # match and replace +pattern+ with the value of the
158 # block. Modify +self+ with the final value.
159 #
160 # ISO 15.2.10.5.37
161 def sub!(*args, &block)
162 raise RuntimeError, "can't modify frozen String" if frozen?
163 str = self.sub(*args, &block)
164 return nil if str == self
165 self.replace(str)
166 end
167
168 ##
169 # Call the given block for each character of
170 # +self+.
171 def each_char(&block)
172 pos = 0
173 while pos < self.size
174 block.call(self[pos])
175 pos += 1
176 end
177 self
178 end
179
180 ##
181 # Call the given block for each byte of +self+.
182 def each_byte(&block)
183 bytes = self.bytes
184 pos = 0
185 while pos < bytes.size
186 block.call(bytes[pos])
187 pos += 1
188 end
189 self
190 end
191
192 ##
193 # Modify +self+ by replacing the content of +self+.
194 # The portion of the string affected is determined using the same criteria as +String#[]+.
195 def []=(*args)
196 anum = args.size
197 if anum == 2
198 pos, value = args
199 case pos
200 when String
201 posnum = self.index(pos)
202 if posnum
203 b = self[0, posnum.to_i]
204 a = self[(posnum + pos.length)..-1]
205 self.replace([b, value, a].join(''))
206 else
207 raise IndexError, "string not matched"
208 end
209 when Range
210 head = pos.begin
211 tail = pos.end
212 tail += self.length if tail < 0
213 unless pos.exclude_end?
214 tail += 1
215 end
216 return self[head, tail-head]=value
217 else
218 pos += self.length if pos < 0
219 if pos < 0 || pos > self.length
220 raise IndexError, "index #{args[0]} out of string"
221 end
222 b = self[0, pos.to_i]
223 a = self[pos + 1..-1]
224 self.replace([b, value, a].join(''))
225 end
226 return value
227 elsif anum == 3
228 pos, len, value = args
229 pos += self.length if pos < 0
230 if pos < 0 || pos > self.length
231 raise IndexError, "index #{args[0]} out of string"
232 end
233 if len < 0
234 raise IndexError, "negative length #{len}"
235 end
236 b = self[0, pos.to_i]
237 a = self[pos + len..-1]
238 self.replace([b, value, a].join(''))
239 return value
240 else
241 raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)"
242 end
243 end
244
245 ##
246 # ISO 15.2.10.5.3
247 def =~(re)
248 raise TypeError, "type mismatch: String given" if re.respond_to? :to_str
249 re =~ self
250 end
251
252 ##
253 # ISO 15.2.10.5.27
254 def match(re, &block)
255 if re.respond_to? :to_str
256 if Object.const_defined?(:Regexp)
257 r = Regexp.new(re)
258 r.match(self, &block)
259 else
260 raise NotImplementedError, "String#match needs Regexp class"
261 end
262 else
263 re.match(self, &block)
264 end
265 end
266end
267
268##
269# String is comparable
270#
271# ISO 15.2.10.3
272module Comparable; end
273class String
274 include Comparable
275end
Note: See TracBrowser for help on using the repository browser.