diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:57:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:57:58 +0000 |
commit | be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97 (patch) | |
tree | 9754ff1ca740f6346cf8483ec915d4054bc5da2d /web/server/h2o/libh2o/deps/mruby/mrblib/string.rb | |
parent | Initial commit. (diff) | |
download | netdata-upstream.tar.xz netdata-upstream.zip |
Adding upstream version 1.44.3.upstream/1.44.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'web/server/h2o/libh2o/deps/mruby/mrblib/string.rb')
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby/mrblib/string.rb | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/deps/mruby/mrblib/string.rb b/web/server/h2o/libh2o/deps/mruby/mrblib/string.rb new file mode 100644 index 00000000..4c6114ec --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrblib/string.rb @@ -0,0 +1,275 @@ +## +# String +# +# ISO 15.2.10 +class String + include Comparable + ## + # Calls the given block for each line + # and pass the respective line. + # + # ISO 15.2.10.5.15 + def each_line(rs = "\n", &block) + return to_enum(:each_line, rs, &block) unless block + return block.call(self) if rs.nil? + rs = rs.to_str + offset = 0 + rs_len = rs.length + this = dup + while pos = this.index(rs, offset) + block.call(this[offset, pos + rs_len - offset]) + offset = pos + rs_len + end + block.call(this[offset, this.size - offset]) if this.size > offset + self + end + + # private method for gsub/sub + def __sub_replace(pre, m, post) + s = "" + i = 0 + while j = index("\\", i) + break if j == length-1 + t = case self[j+1] + when "\\" + "\\" + when "`" + pre + when "&", "0" + m + when "'" + post + when "1", "2", "3", "4", "5", "6", "7", "8", "9" + "" + else + self[j, 2] + end + s += self[i, j-i] + t + i = j + 2 + end + s + self[i, length-i] + end + + ## + # Replace all matches of +pattern+ with +replacement+. + # Call block (if given) for each match and replace + # +pattern+ with the value of the block. Return the + # final value. + # + # ISO 15.2.10.5.18 + def gsub(*args, &block) + return to_enum(:gsub, *args) if args.length == 1 && !block + raise ArgumentError, "wrong number of arguments" unless (1..2).include?(args.length) + + pattern, replace = *args + plen = pattern.length + if args.length == 2 && block + block = nil + end + if !replace.nil? || !block + replace = replace.to_str + end + offset = 0 + result = [] + while found = index(pattern, offset) + result << self[offset, found - offset] + offset = found + plen + result << if block + block.call(pattern).to_s + else + replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "") + end + if plen == 0 + result << self[offset, 1] + offset += 1 + end + end + result << self[offset..-1] if offset < length + result.join + end + + ## + # Replace all matches of +pattern+ with +replacement+. + # Call block (if given) for each match and replace + # +pattern+ with the value of the block. Modify + # +self+ with the final value. + # + # ISO 15.2.10.5.19 + def gsub!(*args, &block) + raise RuntimeError, "can't modify frozen String" if frozen? + return to_enum(:gsub!, *args) if args.length == 1 && !block + str = self.gsub(*args, &block) + return nil if str == self + self.replace(str) + end + + ## + # Calls the given block for each match of +pattern+ + # If no block is given return an array with all + # matches of +pattern+. + # + # ISO 15.2.10.5.32 + def scan(reg, &block) + ### *** TODO *** ### + unless Object.const_defined?(:Regexp) + raise NotImplementedError, "scan not available (yet)" + end + end + + ## + # Replace only the first match of +pattern+ with + # +replacement+. Call block (if given) for each + # match and replace +pattern+ with the value of the + # block. Return the final value. + # + # ISO 15.2.10.5.36 + def sub(*args, &block) + unless (1..2).include?(args.length) + raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 2)" + end + + pattern, replace = *args + pattern = pattern.to_str + if args.length == 2 && block + block = nil + end + unless block + replace = replace.to_str + end + result = [] + this = dup + found = index(pattern) + return this unless found + result << this[0, found] + offset = found + pattern.length + result << if block + block.call(pattern).to_s + else + replace.__sub_replace(this[0, found], pattern, this[offset..-1] || "") + end + result << this[offset..-1] if offset < length + result.join + end + + ## + # Replace only the first match of +pattern+ with + # +replacement+. Call block (if given) for each + # match and replace +pattern+ with the value of the + # block. Modify +self+ with the final value. + # + # ISO 15.2.10.5.37 + def sub!(*args, &block) + raise RuntimeError, "can't modify frozen String" if frozen? + str = self.sub(*args, &block) + return nil if str == self + self.replace(str) + end + + ## + # Call the given block for each character of + # +self+. + def each_char(&block) + pos = 0 + while pos < self.size + block.call(self[pos]) + pos += 1 + end + self + end + + ## + # Call the given block for each byte of +self+. + def each_byte(&block) + bytes = self.bytes + pos = 0 + while pos < bytes.size + block.call(bytes[pos]) + pos += 1 + end + self + end + + ## + # Modify +self+ by replacing the content of +self+. + # The portion of the string affected is determined using the same criteria as +String#[]+. + def []=(*args) + anum = args.size + if anum == 2 + pos, value = args + case pos + when String + posnum = self.index(pos) + if posnum + b = self[0, posnum.to_i] + a = self[(posnum + pos.length)..-1] + self.replace([b, value, a].join('')) + else + raise IndexError, "string not matched" + end + when Range + head = pos.begin + tail = pos.end + tail += self.length if tail < 0 + unless pos.exclude_end? + tail += 1 + end + return self[head, tail-head]=value + else + pos += self.length if pos < 0 + if pos < 0 || pos > self.length + raise IndexError, "index #{args[0]} out of string" + end + b = self[0, pos.to_i] + a = self[pos + 1..-1] + self.replace([b, value, a].join('')) + end + return value + elsif anum == 3 + pos, len, value = args + pos += self.length if pos < 0 + if pos < 0 || pos > self.length + raise IndexError, "index #{args[0]} out of string" + end + if len < 0 + raise IndexError, "negative length #{len}" + end + b = self[0, pos.to_i] + a = self[pos + len..-1] + self.replace([b, value, a].join('')) + return value + else + raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)" + end + end + + ## + # ISO 15.2.10.5.3 + def =~(re) + raise TypeError, "type mismatch: String given" if re.respond_to? :to_str + re =~ self + end + + ## + # ISO 15.2.10.5.27 + def match(re, &block) + if re.respond_to? :to_str + if Object.const_defined?(:Regexp) + r = Regexp.new(re) + r.match(self, &block) + else + raise NotImplementedError, "String#match needs Regexp class" + end + else + re.match(self, &block) + end + end +end + +## +# String is comparable +# +# ISO 15.2.10.3 +module Comparable; end +class String + include Comparable +end |