From 67a6662032d0a7c4af07f44c2046cd0ed2d7d253 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 20 Sep 2019 12:42:53 +0900 Subject: Removed Scanf from the ruby repository. --- NEWS | 1 + doc/maintainers.rdoc | 3 - doc/standard_library.rdoc | 1 - lib/scanf.gemspec | 24 - lib/scanf.rb | 776 --------------------- spec/ruby/library/scanf/io/block_scanf_spec.rb | 7 - spec/ruby/library/scanf/io/fixtures/date.txt | 4 - spec/ruby/library/scanf/io/fixtures/helloworld.txt | 1 - spec/ruby/library/scanf/io/scanf_spec.rb | 35 - spec/ruby/library/scanf/io/shared/block_scanf.rb | 28 - spec/ruby/library/scanf/string/block_scanf_spec.rb | 7 - spec/ruby/library/scanf/string/scanf_spec.rb | 53 -- .../library/scanf/string/shared/block_scanf.rb | 25 - test/scanf/data.txt | 6 - test/scanf/test_scanf.rb | 305 -------- test/scanf/test_scanfblocks.rb | 82 --- test/scanf/test_scanfio.rb | 28 - tool/sync_default_gems.rb | 4 +- 18 files changed, 2 insertions(+), 1388 deletions(-) delete mode 100644 lib/scanf.gemspec delete mode 100644 lib/scanf.rb delete mode 100644 spec/ruby/library/scanf/io/block_scanf_spec.rb delete mode 100644 spec/ruby/library/scanf/io/fixtures/date.txt delete mode 100644 spec/ruby/library/scanf/io/fixtures/helloworld.txt delete mode 100644 spec/ruby/library/scanf/io/scanf_spec.rb delete mode 100644 spec/ruby/library/scanf/io/shared/block_scanf.rb delete mode 100644 spec/ruby/library/scanf/string/block_scanf_spec.rb delete mode 100644 spec/ruby/library/scanf/string/scanf_spec.rb delete mode 100644 spec/ruby/library/scanf/string/shared/block_scanf.rb delete mode 100644 test/scanf/data.txt delete mode 100644 test/scanf/test_scanf.rb delete mode 100644 test/scanf/test_scanfblocks.rb delete mode 100644 test/scanf/test_scanfio.rb diff --git a/NEWS b/NEWS index 365e18b0ab..459d205750 100644 --- a/NEWS +++ b/NEWS @@ -329,6 +329,7 @@ RubyGems:: * Removed unmaintained libraries. * CMath + * Scanf === Stdlib compatibility issues (excluding feature bug fixes) diff --git a/doc/maintainers.rdoc b/doc/maintainers.rdoc index 370dce509a..c2e3600e26 100644 --- a/doc/maintainers.rdoc +++ b/doc/maintainers.rdoc @@ -220,9 +220,6 @@ Zachary Scott (zzak) [lib/rss.rb, lib/rss/*] Kouhei Sutou (kou) https://github.com/ruby/rss -[lib/scanf.rb] - David A. Black (dblack) - https://github.com/ruby/scanf [lib/shell.rb, lib/shell/*] Keiju ISHITSUKA (keiju) https://github.com/ruby/shell diff --git a/doc/standard_library.rdoc b/doc/standard_library.rdoc index b11ca9300d..3edfa8a96c 100644 --- a/doc/standard_library.rdoc +++ b/doc/standard_library.rdoc @@ -87,7 +87,6 @@ Racc:: A LALR(1) parser generator written in Ruby. RDoc:: Produces HTML and command-line documentation for Ruby REXML:: An XML toolkit for Ruby RSS:: Family of libraries that support various formats of XML "feeds" -Scanf:: A Ruby implementation of the C function scanf(3) Shell:: An idiomatic Ruby interface for common UNIX shell commands Synchronizer:: A module that provides a two-phase lock with a counter ThreadsWait:: Watches for termination of multiple threads diff --git a/lib/scanf.gemspec b/lib/scanf.gemspec deleted file mode 100644 index e845427215..0000000000 --- a/lib/scanf.gemspec +++ /dev/null @@ -1,24 +0,0 @@ -# coding: utf-8 -# frozen_string_literal: true - -Gem::Specification.new do |spec| - spec.name = "scanf" - spec.version = "1.0.0" - spec.authors = ["David Alan Black"] - spec.email = ['dblack@superlink.net'] - - spec.summary = "scanf is an implementation of the C function scanf(3)." - spec.description = "scanf is an implementation of the C function scanf(3)." - spec.homepage = "https://github.com/ruby/scanf" - spec.license = "BSD-2-Clause" - - spec.files = ["lib/scanf.rb"] - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } - spec.require_paths = ["lib"] - spec.required_ruby_version = ">= 2.3.0" - - spec.add_development_dependency "bundler", "~> 1.14" - spec.add_development_dependency "rake", "~> 10.0" - spec.add_development_dependency "test-unit" -end diff --git a/lib/scanf.rb b/lib/scanf.rb deleted file mode 100644 index 23ebbbd842..0000000000 --- a/lib/scanf.rb +++ /dev/null @@ -1,776 +0,0 @@ -# frozen_string_literal: false -# scanf for Ruby -# -#-- -# $Release Version: 1.1.2 $ -# $Revision$ -# $Id$ -# $Author$ -#++ -# -# == Description -# -# scanf is an implementation of the C function scanf(3), modified as necessary -# for Ruby compatibility. -# -# The methods provided are String#scanf, IO#scanf, and -# Kernel#scanf. Kernel#scanf is a wrapper around STDIN.scanf. IO#scanf -# can be used on any IO stream, including file handles and sockets. -# scanf can be called either with or without a block. -# -# Scanf scans an input string or stream according to a format, as -# described below in Conversions, and returns an array of matches between -# the format and the input. The format is defined in a string, and is -# similar (though not identical) to the formats used in Kernel#printf and -# Kernel#sprintf. -# -# The format may contain conversion specifiers, which tell scanf -# what form (type) each particular matched substring should be converted -# to (e.g., decimal integer, floating point number, literal string, -# etc.) The matches and conversions take place from left to right, and -# the conversions themselves are returned as an array. -# -# The format string may also contain characters other than those in the -# conversion specifiers. Whitespace (blanks, tabs, or newlines) in the -# format string matches any amount of whitespace, including none, in -# the input. Everything else matches only itself. -# -# Scanning stops, and scanf returns, when any input character fails to -# match the specifications in the format string, or when input is -# exhausted, or when everything in the format string has been -# matched. All matches found up to the stopping point are returned in -# the return array (or yielded to the block, if a block was given). -# -# -# == Basic usage -# -# require 'scanf' -# -# # String#scanf and IO#scanf take a single argument, the format string -# array = a_string.scanf("%d%s") -# array = an_io.scanf("%d%s") -# -# # Kernel#scanf reads from STDIN -# array = scanf("%d%s") -# -# == Block usage -# -# When called with a block, scanf keeps scanning the input, cycling back -# to the beginning of the format string, and yields a new array of -# conversions to the block every time the format string is matched -# (including partial matches, but not including complete failures). The -# actual return value of scanf when called with a block is an array -# containing the results of all the executions of the block. -# -# str = "123 abc 456 def 789 ghi" -# str.scanf("%d%s") { |num,str| [ num * 2, str.upcase ] } -# # => [[246, "ABC"], [912, "DEF"], [1578, "GHI"]] -# -# == Conversions -# -# The single argument to scanf is a format string, which generally -# includes one or more conversion specifiers. Conversion specifiers -# begin with the percent character ('%') and include information about -# what scanf should next scan for (string, decimal number, single -# character, etc.). -# -# There may be an optional maximum field width, expressed as a decimal -# integer, between the % and the conversion. If no width is given, a -# default of `infinity' is used (with the exception of the %c specifier; -# see below). Otherwise, given a field width of n for a given -# conversion, at most n characters are scanned in processing -# that conversion. Before conversion begins, most conversions skip -# whitespace in the input string; this whitespace is not counted -# against the field width. -# -# The following conversions are available. -# -# [%] -# Matches a literal `%'. That is, `%%' in the format string matches a -# single input `%' character. No conversion is done, and the resulting -# '%' is not included in the return array. -# -# [d] -# Matches an optionally signed decimal integer. -# -# [u] -# Same as d. -# -# [i] -# Matches an optionally signed integer. The integer is read in base -# 16 if it begins with `0x' or `0X', in base 8 if it begins with `0', -# and in base 10 other- wise. Only characters that correspond to the -# base are recognized. -# -# [o] -# Matches an optionally signed octal integer. -# -# [x, X] -# Matches an optionally signed hexadecimal integer, -# -# [a, e, f, g, A, E, F, G] -# Matches an optionally signed floating-point number. -# -# [s] -# Matches a sequence of non-white-space character. The input string stops at -# whitespace or at the maximum field width, whichever occurs first. -# -# [c] -# Matches a single character, or a sequence of n characters if a -# field width of n is specified. The usual skip of leading white -# space is suppressed. To skip whitespace first, use an explicit space in -# the format. -# -# [[] -# Matches a nonempty sequence of characters from the specified set -# of accepted characters. The usual skip of leading whitespace is -# suppressed. This bracketed sub-expression is interpreted exactly like a -# character class in a Ruby regular expression. (In fact, it is placed as-is -# in a regular expression.) The matching against the input string ends with -# the appearance of a character not in (or, with a circumflex, in) the set, -# or when the field width runs out, whichever comes first. -# -# === Assignment suppression -# -# To require that a particular match occur, but without including the result -# in the return array, place the assignment suppression flag, which is -# the star character ('*'), immediately after the leading '%' of a format -# specifier (just before the field width, if any). -# -# == scanf for Ruby compared with scanf in C -# -# scanf for Ruby is based on the C function scanf(3), but with modifications, -# dictated mainly by the underlying differences between the languages. -# -# === Unimplemented flags and specifiers -# -# * The only flag implemented in scanf for Ruby is '*' (ignore -# upcoming conversion). Many of the flags available in C versions of -# scanf(3) have to do with the type of upcoming pointer arguments, and are -# meaningless in Ruby. -# -# * The n specifier (store number of characters consumed so far in -# next pointer) is not implemented. -# -# * The p specifier (match a pointer value) is not implemented. -# -# === Altered specifiers -# -# [o, u, x, X] -# In scanf for Ruby, all of these specifiers scan for an optionally signed -# integer, rather than for an unsigned integer like their C counterparts. -# -# === Return values -# -# scanf for Ruby returns an array of successful conversions, whereas -# scanf(3) returns the number of conversions successfully -# completed. (See below for more details on scanf for Ruby's return -# values.) -# -# == Return values -# -# Without a block, scanf returns an array containing all the conversions -# it has found. If none are found, scanf will return an empty array. An -# unsuccessful match is never ignored, but rather always signals the end -# of the scanning operation. If the first unsuccessful match takes place -# after one or more successful matches have already taken place, the -# returned array will contain the results of those successful matches. -# -# With a block scanf returns a 'map'-like array of transformations from -# the block -- that is, an array reflecting what the block did with each -# yielded result from the iterative scanf operation. (See "Block -# usage", above.) -# -# == Current limitations and bugs -# -# When using IO#scanf under Windows, make sure you open your files in -# binary mode: -# -# File.open("filename", "rb") -# -# so that scanf can keep track of characters correctly. -# -# Support for character classes is reasonably complete (since it -# essentially piggy-backs on Ruby's regular expression handling of -# character classes), but users are advised that character class testing -# has not been exhaustive, and that they should exercise some caution -# in using any of the more complex and/or arcane character class -# idioms. -# -# == License and copyright -# -# Copyright:: (c) 2002-2003 David Alan Black -# License:: Distributed on the same licensing terms as Ruby itself -# -# == Warranty disclaimer -# -# This software is provided "as is" and without any express or implied -# warranties, including, without limitation, the implied warranties of -# merchantability and fitness for a particular purpose. -# -# == Credits and acknowledgements -# -# scanf was developed as the major activity of the Austin Ruby Codefest -# (Austin, Texas, August 2002). -# -# Principal author:: David Alan Black (mailto:dblack@superlink.net) -# Co-author:: Hal Fulton (mailto:hal9000@hypermetrics.com) -# Project contributors:: Nolan Darilek, Jason Johnston -# -# Thanks to Hal Fulton for hosting the Codefest. -# -# Thanks to Matz for suggestions about the class design. -# -# Thanks to Gavin Sinclair for some feedback on the documentation. -# -# The text for parts of this document, especially the Description and -# Conversions sections, above, were adapted from the Linux Programmer's -# Manual manpage for scanf(3), dated 1995-11-01. -# -# == Bugs and bug reports -# -# scanf for Ruby is based on something of an amalgam of C scanf -# implementations and documentation, rather than on a single canonical -# description. Suggestions for features and behaviors which appear in -# other scanfs, and would be meaningful in Ruby, are welcome, as are -# reports of suspicious behaviors and/or bugs. (Please see "Credits and -# acknowledgements", above, for email addresses.) - -module Scanf - # :stopdoc: - - # ==Technical notes - # - # ===Rationale behind scanf for Ruby - # - # The impetus for a scanf implementation in Ruby comes chiefly from the fact - # that existing pattern matching operations, such as Regexp#match and - # String#scan, return all results as strings, which have to be converted to - # integers or floats explicitly in cases where what's ultimately wanted are - # integer or float values. - # - # ===Design of scanf for Ruby - # - # scanf for Ruby is essentially a -to- converter. - # - # When scanf is called, a FormatString object is generated from the - # format string ("%d%s...") argument. The FormatString object breaks the - # format string down into atoms ("%d", "%5f", "blah", etc.), and from - # each atom it creates a FormatSpecifier object, which it - # saves. - # - # Each FormatSpecifier has a regular expression fragment and a "handler" - # associated with it. For example, the regular expression fragment - # associated with the format "%d" is "([-+]?\d+)", and the handler - # associated with it is a wrapper around String#to_i. scanf itself calls - # FormatString#match, passing in the input string. FormatString#match - # iterates through its FormatSpecifiers; for each one, it matches the - # corresponding regular expression fragment against the string. If - # there's a match, it sends the matched string to the handler associated - # with the FormatSpecifier. - # - # Thus, to follow up the "%d" example: if "123" occurs in the input - # string when a FormatSpecifier consisting of "%d" is reached, the "123" - # will be matched against "([-+]?\d+)", and the matched string will be - # rendered into an integer by a call to to_i. - # - # The rendered match is then saved to an accumulator array, and the - # input string is reduced to the post-match substring. Thus the string - # is "eaten" from the left as the FormatSpecifiers are applied in - # sequence. (This is done to a duplicate string; the original string is - # not altered.) - # - # As soon as a regular expression fragment fails to match the string, or - # when the FormatString object runs out of FormatSpecifiers, scanning - # stops and results accumulated so far are returned in an array. - - class FormatSpecifier - - attr_reader :re_string, :matched_string, :conversion, :matched - - private - - def skip; /^\s*%\*/.match(@spec_string); end - - def extract_float(s) - return nil unless s &&! skip - if /\A(?[-+]?)0[xX](?\.\h+|\h+(?:\.\h*)?)[pP](?[-+]?\d+)/ =~ s - f1, f2 = frac.split('.') - f = f1.hex - if f2 - len = f2.length - if len > 0 - f += f2.hex / (16.0 ** len) - end - end - (sign == ?- ? -1 : 1) * Math.ldexp(f, exp.to_i) - elsif /\A([-+]?\d+)\.([eE][-+]\d+)/ =~ s - ($1 << $2).to_f - else - s.to_f - end - end - def extract_decimal(s); s.to_i if s &&! skip; end - def extract_hex(s); s.hex if s &&! skip; end - def extract_octal(s); s.oct if s &&! skip; end - def extract_integer(s); Integer(s) if s &&! skip; end - def extract_plain(s); s unless skip; end - - def nil_proc(s); nil; end - - public - - def to_s - @spec_string - end - - def count_space? - /(?:\A|\S)%\*?\d*c|%\d*\[/.match(@spec_string) - end - - def initialize(str) - @spec_string = str - h = '[A-Fa-f0-9]' - - @re_string, @handler = - case @spec_string - - # %[[:...:]] - when /%\*?(\[\[:[a-z]+:\]\])/ - [ "(#{$1}+)", :extract_plain ] - - # %5[[:...:]] - when /%\*?(\d+)(\[\[:[a-z]+:\]\])/ - [ "(#{$2}{1,#{$1}})", :extract_plain ] - - # %[...] - when /%\*?\[([^\]]*)\]/ - yes = $1 - if /^\^/.match(yes) then no = yes[1..-1] else no = '^' + yes end - [ "([#{yes}]+)(?=[#{no}]|\\z)", :extract_plain ] - - # %5[...] - when /%\*?(\d+)\[([^\]]*)\]/ - yes = $2 - w = $1 - [ "([#{yes}]{1,#{w}})", :extract_plain ] - - # %i - when /%\*?i/ - [ "([-+]?(?:(?:0[0-7]+)|(?:0[Xx]#{h}+)|(?:[1-9]\\d*)))", :extract_integer ] - - # %5i - when /%\*?(\d+)i/ - n = $1.to_i - s = "(" - if n > 1 then s += "[1-9]\\d{1,#{n-1}}|" end - if n > 1 then s += "0[0-7]{1,#{n-1}}|" end - if n > 2 then s += "[-+]0[0-7]{1,#{n-2}}|" end - if n > 2 then s += "[-+][1-9]\\d{1,#{n-2}}|" end - if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end - if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end - s += "\\d" - s += ")" - [ s, :extract_integer ] - - # %d, %u - when /%\*?[du]/ - [ '([-+]?\d+)', :extract_decimal ] - - # %5d, %5u - when /%\*?(\d+)[du]/ - n = $1.to_i - s = "(" - if n > 1 then s += "[-+]\\d{1,#{n-1}}|" end - s += "\\d{1,#{$1}})" - [ s, :extract_decimal ] - - # %x - when /%\*?[Xx]/ - [ "([-+]?(?:0[Xx])?#{h}+)", :extract_hex ] - - # %5x - when /%\*?(\d+)[Xx]/ - n = $1.to_i - s = "(" - if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end - if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end - if n > 1 then s += "[-+]#{h}{1,#{n-1}}|" end - s += "#{h}{1,#{n}}" - s += ")" - [ s, :extract_hex ] - - # %o - when /%\*?o/ - [ '([-+]?[0-7]+)', :extract_octal ] - - # %5o - when /%\*?(\d+)o/ - [ "([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})", :extract_octal ] - - # %f - when /%\*?[aefgAEFG]/ - [ '([-+]?(?:0[xX](?:\.\h+|\h+(?:\.\h*)?)[pP][-+]?\d+|\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))', :extract_float ] - - # %5f - when /%\*?(\d+)[aefgAEFG]/ - [ '(?=[-+]?(?:0[xX](?:\.\h+|\h+(?:\.\h*)?)[pP][-+]?\d+|\d+(?![\d.])|\d*\.\d*(?:[eE][-+]?\d+)?))' + - "(\\S{1,#{$1}})", :extract_float ] - - # %5s - when /%\*?(\d+)s/ - [ "(\\S{1,#{$1}})", :extract_plain ] - - # %s - when /%\*?s/ - [ '(\S+)', :extract_plain ] - - # %c - when /\s%\*?c/ - [ "\\s*(.)", :extract_plain ] - - # %c - when /%\*?c/ - [ "(.)", :extract_plain ] - - # %5c (whitespace issues are handled by the count_*_space? methods) - when /%\*?(\d+)c/ - [ "(.{1,#{$1}})", :extract_plain ] - - # %% - when /%%/ - [ '(\s*%)', :nil_proc ] - - # literal characters - else - [ "(#{Regexp.escape(@spec_string)})", :nil_proc ] - end - - @re_string = '\A' + @re_string - end - - def to_re - Regexp.new(@re_string,Regexp::MULTILINE) - end - - def match(str) - @matched = false - s = str.dup - s.sub!(/\A\s+/,'') unless count_space? - res = to_re.match(s) - if res - @conversion = send(@handler, res[1]) - @matched_string = @conversion.to_s - @matched = true - end - res - end - - def letter - @spec_string[/%\*?\d*([a-z\[])/, 1] - end - - def width - @spec_string[/%\*?(\d+)/, 1]&.to_i - end - - def mid_match? - return false unless @matched - cc_no_width = letter == '[' &&! width - c_or_cc_width = (letter == 'c' || letter == '[') && width - width_left = c_or_cc_width && (matched_string.size < width) - - return width_left || cc_no_width - end - - end - - class FormatString - - attr_reader :string_left, :last_spec_tried, - :last_match_tried, :matched_count, :space - - SPECIFIERS = 'diuXxofFeEgGscaA' - REGEX = / - # possible space, followed by... - (?:\s* - # percent sign, followed by... - % - # another percent sign, or... - (?:%| - # optional assignment suppression flag - \*? - # optional maximum field width - \d* - # named character class, ... - (?:\[\[:\w+:\]\]| - # traditional character class, or... - \[[^\]]*\]| - # specifier letter. - [#{SPECIFIERS}])))| - # or miscellaneous characters - [^%\s]+/ix - - def initialize(str) - @specs = [] - @i = 1 - s = str.to_s - return unless /\S/.match(s) - @space = true if /\s\z/.match(s) - @specs.replace s.scan(REGEX).map {|spec| FormatSpecifier.new(spec) } - end - - def to_s - @specs.join('') - end - - def prune(n=matched_count) - n.times { @specs.shift } - end - - def spec_count - @specs.size - end - - def last_spec - @i == spec_count - 1 - end - - def match(str) - accum = [] - @string_left = str - @matched_count = 0 - - @specs.each_with_index do |spec,i| - @i=i - @last_spec_tried = spec - @last_match_tried = spec.match(@string_left) - break unless @last_match_tried - @matched_count += 1 - - accum << spec.conversion - - @string_left = @last_match_tried.post_match - break if @string_left.empty? - end - return accum.compact - end - end - # :startdoc: -end - -class IO - - #:stopdoc: - # The trick here is doing a match where you grab one *line* - # of input at a time. The linebreak may or may not occur - # at the boundary where the string matches a format specifier. - # And if it does, some rule about whitespace may or may not - # be in effect... - # - # That's why this is much more elaborate than the string - # version. - # - # For each line: - # - # Match succeeds (non-emptily) - # and the last attempted spec/string sub-match succeeded: - # - # could the last spec keep matching? - # yes: save interim results and continue (next line) - # - # The last attempted spec/string did not match: - # - # are we on the next-to-last spec in the string? - # yes: - # is fmt_string.string_left all spaces? - # yes: does current spec care about input space? - # yes: fatal failure - # no: save interim results and continue - # no: continue [this state could be analyzed further] - # - #:startdoc: - - # Scans the current string until the match is exhausted, - # yielding each match as it is encountered in the string. - # A block is not necessary though, as the results will simply - # be aggregated into the final array. - # - # "123 456".block_scanf("%d") - # # => [123, 456] - # - # If a block is given, the value from that is returned from - # the yield is added to an output array. - # - # "123 456".block_scanf("%d") do |digit,| # the ',' unpacks the Array - # digit + 100 - # end - # # => [223, 556] - # - # See Scanf for details on creating a format string. - # - # You will need to require 'scanf' to use IO#scanf. - def scanf(str,&b) #:yield: current_match - return block_scanf(str,&b) if b - return [] unless str.size > 0 - - start_position = pos rescue 0 - matched_so_far = 0 - source_buffer = "" - result_buffer = [] - final_result = [] - - fstr = Scanf::FormatString.new(str) - - loop do - if eof || (tty? &&! fstr.match(source_buffer)) - final_result.concat(result_buffer) - break - end - - source_buffer << gets - - current_match = fstr.match(source_buffer) - - spec = fstr.last_spec_tried - - if spec.matched - if spec.mid_match? - result_buffer.replace(current_match) - next - end - - elsif (fstr.matched_count == fstr.spec_count - 1) - if /\A\s*\z/.match(fstr.string_left) - break if spec.count_space? - result_buffer.replace(current_match) - next - end - end - - final_result.concat(current_match) - - matched_so_far += source_buffer.size - source_buffer.replace(fstr.string_left) - matched_so_far -= source_buffer.size - break if fstr.last_spec - fstr.prune - end - - begin - seek(start_position + matched_so_far, IO::SEEK_SET) - rescue Errno::ESPIPE, Errno::EINVAL - end - - soak_up_spaces if fstr.last_spec && fstr.space - - return final_result - end - - private - - def soak_up_spaces - c = getc - ungetc(c) if c - until eof ||! c || /\S/.match(c.chr) - c = getc - end - ungetc(c) if (c && /\S/.match(c.chr)) - end - - def block_scanf(str) - final = [] -# Sub-ideal, since another FS gets created in scanf. -# But used here to determine the number of specifiers. - fstr = Scanf::FormatString.new(str) - last_spec = fstr.last_spec - begin - current = scanf(str) - break if current.empty? - final.push(yield(current)) - end until eof || fstr.last_spec_tried == last_spec - return final - end -end - -class String - - # :section: scanf - # - # You will need to require 'scanf' to use these methods - - # Scans the current string. If a block is given, it - # functions exactly like block_scanf. - # - # arr = "123 456".scanf("%d%d") - # # => [123, 456] - # - # require 'pp' - # - # "this 123 read that 456 other".scanf("%s%d%s") {|m| pp m} - # - # # ["this", 123, "read"] - # # ["that", 456, "other"] - # # => [["this", 123, "read"], ["that", 456, "other"]] - # - # See Scanf for details on creating a format string. - # - # You will need to require 'scanf' to use String#scanf - def scanf(fstr,&b) #:yield: current_match - if b - block_scanf(fstr,&b) - else - fs = - if fstr.is_a? Scanf::FormatString - fstr - else - Scanf::FormatString.new(fstr) - end - fs.match(self) - end - end - - # Scans the current string until the match is exhausted - # yielding each match as it is encountered in the string. - # A block is not necessary as the results will simply - # be aggregated into the final array. - # - # "123 456".block_scanf("%d") - # # => [123, 456] - # - # If a block is given, the value from that is returned from - # the yield is added to an output array. - # - # "123 456".block_scanf("%d") do |digit,| # the ',' unpacks the Array - # digit + 100 - # end - # # => [223, 556] - # - # See Scanf for details on creating a format string. - # - # You will need to require 'scanf' to use String#block_scanf - def block_scanf(fstr) #:yield: current_match - fs = Scanf::FormatString.new(fstr) - str = self.dup - final = [] - begin - current = str.scanf(fs) - final.push(yield(current)) unless current.empty? - str = fs.string_left - end until current.empty? || str.empty? - return final - end -end - -module Kernel - private - # Scans STDIN for data matching +format+. See IO#scanf for details. - # - # See Scanf for details on creating a format string. - # - # You will need to require 'scanf' to use Kernel#scanf. - def scanf(format, &b) #:doc: - STDIN.scanf(format ,&b) - end -end diff --git a/spec/ruby/library/scanf/io/block_scanf_spec.rb b/spec/ruby/library/scanf/io/block_scanf_spec.rb deleted file mode 100644 index 2c1e242cf6..0000000000 --- a/spec/ruby/library/scanf/io/block_scanf_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require_relative '../../../spec_helper' -require_relative 'shared/block_scanf' -require 'scanf' - -describe "IO#block_scanf" do - it_behaves_like :scanf_io_block_scanf, :block_scanf -end diff --git a/spec/ruby/library/scanf/io/fixtures/date.txt b/spec/ruby/library/scanf/io/fixtures/date.txt deleted file mode 100644 index a1bd635c0c..0000000000 --- a/spec/ruby/library/scanf/io/fixtures/date.txt +++ /dev/null @@ -1,4 +0,0 @@ -Beethoven 1770 -Bach 1685 -Handel 1685 - diff --git a/spec/ruby/library/scanf/io/fixtures/helloworld.txt b/spec/ruby/library/scanf/io/fixtures/helloworld.txt deleted file mode 100644 index 3b18e512db..0000000000 --- a/spec/ruby/library/scanf/io/fixtures/helloworld.txt +++ /dev/null @@ -1 +0,0 @@ -hello world diff --git a/spec/ruby/library/scanf/io/scanf_spec.rb b/spec/ruby/library/scanf/io/scanf_spec.rb deleted file mode 100644 index 94e999335e..0000000000 --- a/spec/ruby/library/scanf/io/scanf_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require_relative '../../../spec_helper' -require_relative 'shared/block_scanf' -require 'scanf' - -describe "IO#scanf" do - before :each do - @hw = File.open(File.dirname(__FILE__) + '/fixtures/helloworld.txt', 'r') - @data = File.open(File.dirname(__FILE__) + '/fixtures/date.txt', 'r') - end - - after :each do - @hw.close unless @hw.closed? - @data.close unless @data.closed? - end - - it "returns an array containing the input converted in the specified type" do - @hw.scanf("%s%s").should == ["hello", "world"] - @data.scanf("%s%d").should == ["Beethoven", 1770] - end - - it "returns an array containing the input converted in the specified type with given maximum field width" do - @hw.scanf("%2s").should == ["he"] - @data.scanf("%2c").should == ["Be"] - end - - it "returns an empty array when a wrong specifier is passed" do - @hw.scanf("%a").should == [] - @hw.scanf("%1").should == [] - @data.scanf("abc").should == [] - end -end - -describe "IO#scanf with block" do - it_behaves_like :scanf_io_block_scanf, :scanf -end diff --git a/spec/ruby/library/scanf/io/shared/block_scanf.rb b/spec/ruby/library/scanf/io/shared/block_scanf.rb deleted file mode 100644 index 8c5bffb93b..0000000000 --- a/spec/ruby/library/scanf/io/shared/block_scanf.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'scanf' - -describe :scanf_io_block_scanf, shared: true do - before :each do - @data= File.open(File.dirname(__FILE__) + '/../fixtures/date.txt', 'r') - end - - after :each do - @data.close unless @data.closed? - end - - it "passes each match to the block as an array" do - res = @data.send(@method, "%s%d") { |name, year| "#{name} was born in #{year}." } - res.should == ["Beethoven was born in 1770.", "Bach was born in 1685.", "Handel was born in 1685."] - end - - it "keeps scanning the input and cycling back to the beginning of the input string" do - a = [] - @data.send(@method, "%s"){|w| a << w} - a.should == [["Beethoven"], ["1770"], ["Bach"], ["1685"], ["Handel"], ["1685"]] - end - - it "returns an empty array when a wrong specifier is passed" do - a = [] - @data.send(@method, "%z"){|w| a << w} - a.empty?.should be_true - end -end diff --git a/spec/ruby/library/scanf/string/block_scanf_spec.rb b/spec/ruby/library/scanf/string/block_scanf_spec.rb deleted file mode 100644 index d5c42cb395..0000000000 --- a/spec/ruby/library/scanf/string/block_scanf_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require_relative '../../../spec_helper' -require_relative 'shared/block_scanf' -require 'scanf' - -describe "String#block_scanf" do - it_behaves_like :scanf_string_block_scanf, :block_scanf -end diff --git a/spec/ruby/library/scanf/string/scanf_spec.rb b/spec/ruby/library/scanf/string/scanf_spec.rb deleted file mode 100644 index fbe2590476..0000000000 --- a/spec/ruby/library/scanf/string/scanf_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -require_relative '../../../spec_helper' -require_relative 'shared/block_scanf' -require 'scanf' - -describe "String#scanf" do - it "returns an array containing the input converted in the specified type" do - "hello world".scanf("%s").should == ["hello"] - "hello world".scanf("%s%d").should == ["hello"] - "hello world".scanf("%s%c").should == ["hello", " "] - "hello world".scanf("%c%s").should == ["h", "ello"] - "hello world".scanf("%s%s").should == ["hello", "world"] - "hello world".scanf("%c").should == ["h"] - "123".scanf("%s").should == ["123"] - "123".scanf("%c").should == ["1"] - "123".scanf("%d").should == [123] - "123".scanf("%u").should == [123] - "123".scanf("%o").should == [83] - "123".scanf("%x").should == [291] - "123".scanf("%i").should == [123] - "0123".scanf("%i").should == [83] - "123".scanf("%f").should == [123.0] - "0X123".scanf("%i").should == [291] - "0x123".scanf("%i").should == [291] - end - - it "returns an array containing the input converted in the specified type with given maximum field width" do - "hello world".scanf("%2s").should == ["he"] - "hello world".scanf("%2c").should == ["he"] - "123".scanf("%2s").should == ["12"] - "123".scanf("%2c").should == ["12"] - "123".scanf("%2d").should == [12] - "123".scanf("%2u").should == [12] - "123".scanf("%2o").should == [10] - "123".scanf("%2x").should == [18] - "123".scanf("%2i").should == [12] - "0123".scanf("%2i").should == [1] - "123".scanf("%2f").should == [12.0] - "0X123".scanf("%2i").should == [0] - "0X123".scanf("%3i").should == [1] - "0X123".scanf("%4i").should == [18] - end - - it "returns an empty array when a wrong specifier is passed" do - "hello world".scanf("%a").should == [] - "123".scanf("%1").should == [] - "123".scanf("abc").should == [] - "123".scanf(:d).should == [] - end -end - -describe "String#scanf with block" do - it_behaves_like :scanf_string_block_scanf, :scanf -end diff --git a/spec/ruby/library/scanf/string/shared/block_scanf.rb b/spec/ruby/library/scanf/string/shared/block_scanf.rb deleted file mode 100644 index 25ab3f442a..0000000000 --- a/spec/ruby/library/scanf/string/shared/block_scanf.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'scanf' - -describe :scanf_string_block_scanf, shared: true do - it "passes each match to the block as an array" do - a = [] - "hello world".send(@method, "%s%s"){|w| a << w} - a.should == [["hello", "world"]] - end - - it "keeps scanning the input and cycling back to the beginning of the input string" do - a = [] - "hello world".send(@method, "%s"){|w| a << w} - a.should == [["hello"], ["world"]] - - string = "123 abc 456 def 789 ghi" - s = string.send(@method, "%d%s"){|num,str| [num * 2, str.upcase]} - s.should == [[246, "ABC"], [912, "DEF"], [1578, "GHI"]] - end - - it "returns an empty array when a wrong specifier is passed" do - a = [] - "hello world".send(@method, "%z"){|w| a << w} - a.empty?.should be_true - end -end diff --git a/test/scanf/data.txt b/test/scanf/data.txt deleted file mode 100644 index 302cfd0089..0000000000 --- a/test/scanf/data.txt +++ /dev/null @@ -1,6 +0,0 @@ -this is 33 a fun -little input file - -with - -characters diff --git a/test/scanf/test_scanf.rb b/test/scanf/test_scanf.rb deleted file mode 100644 index 988ff99adc..0000000000 --- a/test/scanf/test_scanf.rb +++ /dev/null @@ -1,305 +0,0 @@ -# frozen_string_literal: false -# $Id$ -# -# scanf for Ruby -# -# Unit tests -# - -require 'scanf.rb' -require 'test/unit' -require 'tempfile' - -# Comment out either of these lines to skip those tests. - -class TestStringScanf < Test::Unit::TestCase;end -class TestIOScanf < Test::Unit::TestCase;end - -module ScanfTests - - def tests - [ - -# Scratchpad - [ "%2[a]", "nbc", []], - [ "%*d %*3d %*s", "123 +456 abc", [] ], - [ "%d%c", "123 x", [ 123, " " ] ], - [ "%d%c", "123x", [ 123, "x" ] ], - [ "%d %c", "123x", [ 123, "x" ] ], - [ "%d %c", "123 x", [ 123, "x" ] ], - -# Testing failures - [ "%x", "x", [] ], - [ "%2x", "x", [] ], - [ "%i", "x", [] ], -# ]; end; def nothing; [ - [ "%2i", "x", [] ], - [ "%2o", "x", [] ], - [ "%d", "x", [] ], - [ "%2d", "x", [] ], - [ "%3d", "+x3", [] ], - [ "%d%[abc]", "eabc", [] ], - [ "%d\n%[abc]", "\neabc", [] ], - [ "%d%[^abc]", "ghiabc", [ ] ], - [ "%d%[abc]", "abc", [] ], - [ "%d%s", "", [] ], - [ "%d%s", "blah 123 string", [] ], - [ "%[\n]", "abc\n", [] ], - [ "%f", "x", [] ], - [ "%f", "z", [] ], - [ "%f", "z3.2534", [] ], - [ "", "", [] ], - [ "", "abc 123", [] ], - [ '%[^\\w]%c', "a...1", [] ], - -# Testing 'x' - [ "%3x", "0xz", [0] ], - -# Testing 'i' - [ "%3i", "097", [0] ], - [ "%3i", "0xz", [0] ], - [ "%1i", "3", [ 3 ] ], - [ "%2i", "07", [ 7 ] ], - [ "%2i", "0a", [ 0 ] ], - -# Testing 'c' - [ "%3c", "abc", [ "abc" ] ], - [ "%3c", "a\nb", [ "a\nb" ] ], - [ "%3c", "a\nbcd", [ "a\nb" ] ], - [ "%c\n\n", "x\n\n", [ "x" ] ], - [ "%c", "\n", [ "\n" ] ], - [ "%c", "x\n", [ "x" ] ], - [ "%2c", " 123", [" 1"] ], - [ " %c", " x", ["x"] ], - [ "%c", " x", [" "] ], - [ "%c", "123", ["1"] ], - [ "%2c", "123", ["12"] ], - [ "%5c", "a\nb\n\n", [ "a\nb\n\n" ] ], - [ "%6c", "a\nb\n\nx", [ "a\nb\n\nx" ] ], - [ "%5c", "ab\ncd", [ "ab\ncd" ] ], - -# Testing 'o' - [ "%3o", "0xz", [0] ], - -# Testing 'd' - [ "%d", "\n123", [ 123 ] ], - [ "%d", "\n\n123", [ 123 ] ], - [ "%1d", "2", [2] ], - -# Mixed tests -# Includes: -# whitespace/newline -# mixed integer bases -# various mixed specifiers - - [ "%[^\\w]%c", "...1", [ "...", "1"] ], - [ "%[abc\n]%d", "a\n\nb\n\nc 123", [ "a\n\nb\n\nc", 123 ] ], - [ "%[abc\n]%d", "a\n\nb\n\nc \t 123", [ "a\n\nb\n\nc", 123 ] ], - [ "%[abc\t]%d", "a\t\tb\t\tc 123", [ "a\t\tb\t\tc", 123 ] ], - [ "%d%3[abc\n]", "123a\nbeaab", [ 123, "a\nb" ] ], - [ "%d%20c", "42 is the key", [ 42, " is the key" ] ], - [ "%d %20c", "42 is the key", [ 42, "is the key" ] ], - [ "%d%3[^abc\n]%d", "123de\nf123", [ 123, "de" ] ], - [ "%d %4c", "3abc", [ 3, "abc" ] ], - [ "%f%d\n%[abc]", "1\neabc", [1.0] ], - [ "%d%3[abc]", "123aaab", [ 123, "aaa" ] ], - [ "%d%3[abc]", "123 aaab", [ 123 ] ], - [ "%d%3[abc]", "123aeaab", [ 123, "a" ] ], - [ "%d%[^abc]", "123defabc", [123, "def" ] ], - [ "%d%3[^abc]", "123defdef", [ 123, "def" ] ], - [ "%d%3[^abc] ", "123defdef ", [ 123, "def" ] ], - [ "%d%3[^abc]ghi", "123defghi", [ 123, "def" ] ], - [ "%d%3[^abc]", "123adefdef", [ 123 ] ], - [ "%d%3[^abc]", "123deafdef", [ 123, "de" ] ], - [ "%d%3[^abc\n]", "123de\nf", [ 123, "de" ] ], - [ "%s%c%c%s", "abc\n\ndef", ["abc", "\n","\n", "def" ] ], - [ "%c%d", "\n\n123", [ "\n",123 ] ], - [ "%s%c%d", "abc\n123", [ "abc", "\n", 123 ] ], - [ "%s%c%d", "abc\n\n123", [ "abc", "\n", 123 ] ], - [ "%c%d", "\t\n123", [ "\t",123 ] ], - [ "%s%c%d", "abc\t\n123", [ "abc", "\t", 123 ] ], - [ "%3c%d", "abc123", [ "abc", 123 ] ], - [ "%3c\n%d", "abc123", [ "abc", 123 ] ], - [ "%3c\n%d", "abc 123", [ "abc", 123 ] ], - [ "%3c %d", "abc123", [ "abc", 123 ] ], - [ "%3c\t%d", "abc \n 123", [ "abc", 123 ] ], - [ "%3c\t%d", "abc \n 123 ", [ "abc", 123 ] ], - [ "%3c%d", "a\nb123", [ "a\nb", 123 ] ], - [ "%f%3c", "1.2x\ny", [ 1.2, "x\ny"] ], - [ "%d\n%d\n%d", "123 456 789", [ 123,456,789 ] ], - [ "%d\n%i%2d%x\n%d", "123 0718932", [ 123, 071, 89, 0x32] ], - [ "%c\n%c", "x y", [ "x", "y" ] ], - [ "%c\t%c", "x y", [ "x", "y" ] ], - [ "%s\n%s", "x y", [ "x", "y" ] ], - [ "%s%s\n", "x y", [ "x", "y" ] ], - [ "%c\n\n%c", "x\n\ny", [ "x", "y" ] ], - [ "%s%d%d", "abc\n123\n456", [ "abc", 123, 456 ] ], - [ "%3s%c%3c%d", "1.2x\n\ny123", [ "1.2", "x", "\n\ny", 123 ] ], - [ "%c\n%c", "x\n\ny", [ "x", "y" ] ], - [ "%c %c", "x\n\ny", [ "x", "y" ] ], - [ "%s\n\n%c", "x\n\ny", [ "x", "y" ] ], - [ "%s\n\n%s", "x\n\ny", [ "x", "y" ] ], - [ "%d\n\n%d", "23\n\n45", [ 23, 45 ] ], - [ "%d\n%d", "23\n\n45", [ 23, 45 ] ], - [ "%c\n\n%c", "x y", [ "x", "y" ] ], - [ "%c%c", "x\n\ny", [ "x", "\n" ] ], - [ "%c%c", "x\n", [ "x", "\n" ] ], - [ "%d%c%c%d", "345 678", [ 345, " ", " ", 678] ], - [ "%d %c%s", "123 x hello", [123, "x", "hello"] ], - [ "%d%2c", "654 123", [654," 1"] ], - [ "%5c%s", "a\nb\n\nxyz", [ "a\nb\n\n","xyz" ] ], - [ "%s%[ xyz]%d", "hello x 32", ["hello", " x ", 32] ], - [ "%5s%8[a-z]%d", "helloblahblah 32", ["hello", "blahblah", 32] ], - [ '%s%[abcde\\s]%d', "hello badea 32", ["hello", " badea ", 32] ], - [ '%d%[\\s]%c', "123 \n\t X", [ 123," \n\t ", "X"] ], - [ "%4s%2c%c", "1.2x\n\ny", [ "1.2x", "\n\n","y"] ], - [ "%f%c %3c%d", "1.2x\n\ny123", [ 1.2, "x", "y12", 3 ] ], - [ "%s%5c", "abc ab\ncd", [ "abc", " ab\nc" ] ], - [ "%5c%f", "ab\ncd1.2", [ "ab\ncd",1.2 ] ], - [ "%5c%c", "ab\ncd1", [ "ab\ncd","1" ] ], - [ "%f%c%2c%d", "1.2x\ny123", [ 1.2, "x", "\ny", 123 ] ], - [ "%f%c%3c", "1.2x\ny123", [ 1.2, "x", "\ny1"] ], - [ "%s\n%s", "blah\n\nand\nmore stuff", [ "blah", "and" ] ], - [ "%o%d%x", "21912a3", [ "21".oct, 912, "a3".hex ] ], - [ "%3o%4d%3x", "21912a3", [ "21".oct, 912, "a3".hex ] ], - [ "%3o%4d%5x", "2191240xa3", [ "21".oct, 9124, "a3".hex ] ], - [ "%3d%3x", "12abc", [12, "abc".hex] ], - [ "%s%i%d", "hello +0xdef 123", [ "hello", "def".hex, 123] ], - [ "%s%i%d", "hello -0xdef 123", [ "hello", -"def".hex, 123] ], - [ "%s%i%i%i%i", "hello 012 -012 100 1", [ "hello", 10, -10, 100, 1 ] ], - [ "%s%i%i%i%i", "hello 012 0x12 100 1", [ "hello", 10, 18, 100, 1 ] ], - [ "%s%5i%3i%4i", "hello 0x123 123 0123", [ "hello", "0x123".hex, 123,"0123".oct] ], - [ "%s%3i%4i", "hello 1230123", [ "hello", 123,"0123".oct] ], - [ "%s%3i", "hello 1230", [ "hello", 123] ], - [ "%s%5x%d", "hello 0xdef 123", [ "hello", "def".hex, 123] ], - [ "%s%6x%d", "hello +0xdef 123", [ "hello", "def".hex, 123] ], - [ "%s%6x%d", "hello -0xdef 123", [ "hello", -"def".hex, 123] ], - [ "%s%4x%d", "hello -def 123", [ "hello", -"def".hex, 123] ], - [ "%s%3x%d", "hello def 123", [ "hello", "def".hex, 123] ], - [ "%s%x%d", "hello -def 123", [ "hello", -"def".hex, 123] ], - [ "%s%x%d", "hello -0xdef 123", [ "hello", -"def".hex, 123] ], - [ "%s%x%d", "hello 0xdef 123", [ "hello", "def".hex, 123] ], - [ "%s%d%x%s", "hello 123 abc def", [ "hello", 123, "abc".hex, "def"] ], - [ "%s%d%o%d", "hello 012 012 100", [ "hello", 12, 10, 100 ] ], - [ "%s%d%o%d", "hello 012 -012 100", [ "hello", 12, -10, 100 ] ], - [ "%s%o%x%d", "hello 012 0x12 100", [ "hello", 10, 18, 100 ] ], - [ "%s%d%o%d", "hello 012 +01288", [ "hello", 12, 10, 88 ] ], - [ "%f %d %s", "12.3e23 45 string", ["12.3e23".to_f, 45, "string"] ], - [ "%f %d %s", "12.3e+23 45 string", ["12.3e23".to_f, 45, "string"] ], - [ "%f %d %s", "12.3e-23 45 string", ["12.3e-23".to_f, 45, "string"] ], - [ "%f %d %s", "-12.3e-23 45 string", ["-12.3e-23".to_f, 45, "string"] ], - [ "%f %d %s", "12.e23 45 string", ["12.e23".to_f, 45, "string"] ], - [ "%5f %d %s", "1.2e23 string", ["1.2e2".to_f, 3, "string"] ], - [ "%5f%d %s", "1.2e23 string", ["1.2e2".to_f, 3, "string"] ], - [ "%5f%d %d %s", "1.2e23 45 string", ["1.2e2".to_f, 3, 45, "string"] ], - [ "%6f %d %d %s", "+1.2e23 45 string", ["1.2e2".to_f, 3, 45, "string"] ], - [ "%d %d", "123 \n 345", [123, 345] ], - [ "%d %*d", "123 \n 345", [123] ], - [ "%d %3d789", "123 +45789", [123, 45] ], - [ "%d %3d%d", "123 +456789", [123, 45, 6789] ], - [ "%d %3dabc", "123 456abc", [123, 456] ], - [ "%d %s", "123abc", [123, "abc"] ], - [ "%d%s %s", "123 abc def", [123, "abc", "def"] ], - [ "%s%s", "abc123 def", ["abc123", "def"] ], - [ "%s%s %s", "123 abc def", ["123", "abc", "def"] ], - [ "%s%%%s", "abc % def", ["abc", "def"] ], - [ "%d %3d %s", "+123 456abc", [123, 456, "abc"] ], - [ "%d %3d %s", "123 456abc", [123, 456, "abc"] ], - [ "%d %3d %s", "123 +456 abc", [123, 45, "6"] ], - [ "%d %3d %s", "-123-456abc", [-123, -45, "6abc"] ], - [ "%dabc%d", "123abc345", [123, 345] ], - [ "%d%5s%d", "123 abcde12", [123, "abcde", 12] ], - [ "%5d%5s%5d", "12345abcde67890", [12345, "abcde", 67890] ], - [ "%5d%*5s%5d", "12345abcde67890", [12345, 67890] ], - [ " 12345%5s%5d", "12345abcde67890", [ "abcde", 67890] ], - [ "%5dabcde%5d", "12345abcde67890", [ 12345, 67890] ], - [ "%s%%%*s", "abc % def", ["abc"] ], - [ "%*6s %d", "string 123", [123] ], - [ "%d %*3d %s", "-123-456abc", [-123, "6abc"] ], - [ "%d%s", "123", [123] ], - [ "%s%d", "abc", ["abc"] ], - [ "%f%x", "3.2e45x", ["3.2e45x".to_f] ], - [ "%*5f%d %d %s", "1.2e23 45 string", [3, 45, "string"] ], - [ "%5f%*d %d %s", "1.2e23 45 string", ["1.2e2".to_f, 45, "string"] ], - [ "%*5f%*d %*d %s", "1.2e23 45 string", ["string"] ], - [ "%f %*d %s", "12.e23 45 string", ["12.e23".to_f, "string"] ], - [ "%s %f %s %d %x%c%c%c%c", - "float: 1.2e23 dec/hex: 135a23 abc", - ["float:", "1.2e23".to_f, "dec/hex:", 135, "a23".hex, " ", "a", "b", "c" ] ], - -# Testing 's' - [ "%s\n", "blah\n\n\n", [ "blah" ] ], - -# Testing '[' - [ "%[a\nb]", "a\nb", [ "a\nb" ] ], - [ "%[abc]", "acb", [ "acb" ] ], - [ "%[abc\n]", "a\nb", [ "a\nb" ] ], - [ "%[^abc]", "defabc", [ "def" ] ], - [ "%[-abc]", "abc-cba", [ "abc-cba" ] ], - [ "%[\n]", "\n", [ "\n" ] ], - [ "%[\n]", "\nabc", [ "\n" ] ], - [ "%[\n\t]", "\t\n", [ "\t\n" ] ], - [ "%[a-f]", "abczef", [ "abc" ] ], - [ "%d%3[[:lower:]] %f", "123ade1.2", [ 123,"ade",1.2 ] ], - [ "%d%3[[:lower:]] %f", "123ad1.2", [ 123,"ad",1.2 ] ], - [ "%d%3[[:lower:]] %f", "123 ad1.2", [ 123 ] ], - [ "%d%[[:lower:]]", "123abcdef1.2", [ 123, "abcdef" ] ], - [ "%[[:lower:]]%d", "abcdef123", [ "abcdef", 123 ] ], - [ "%[[:digit:]]%[[:alpha:]]", "123abcdef", [ "123", "abcdef" ] ], - [ "%[[:digit:]]%d", "123 123", [ "123", 123 ] ], - [ "%[[:upper:]]", "ABCdefGHI", [ "ABC" ] ], - -# Testing 'f' - [ "%2f", "x", [] ], - [ "%F", "1.23e45", [1.23e+45] ], - [ "%e", "3.25ee", [3.25] ], - [ "%E", "3..25", [3.0] ], - [ "%g", "+3.25", [3.25] ], - [ "%G", "+3.25e2", [325.0] ], - [ "%f", "3.z", [3.0] ], - [ "%a", "0X1P+10", [1024.0] ], - [ "%a", "0X1P10", [1024.0] ], - [ "%A", "0x1.deadbeefp+99", [1.1851510441583988e+30] ], - -# Testing embedded matches including literal '[' behavior - [",%d,%f", ",10,1.1", [10,1.1] ], - [" ,%d,%f", " ,10,1.1", [10,1.1] ], - ["[%d,%f", "[10,1.1", [10,1.1] ], - [" [%d,%f", " [10,1.1", [10,1.1] ], - - ] - end - - def each_test - self.tests.each do |test| - format, string, = test - yield test, "#{string.dump}(#{format.dump})" - end - end -end - -class TestStringScanf - include Scanf - extend ScanfTests - - self.each_test do |test, i| - define_method("test_#{i}") do || - assert_equal(test[2], test[1].scanf(test[0])) - end - end -end - -class TestIOScanf - include Scanf - extend ScanfTests - - self.each_test do |test, i| - define_method("test_#{i}") do || - Tempfile.create("iotest.dat") do |fh| - fh.print test[1] - fh.rewind - assert_equal(test[2], fh.scanf(test[0])) - end - end - end -end diff --git a/test/scanf/test_scanfblocks.rb b/test/scanf/test_scanfblocks.rb deleted file mode 100644 index 1c2265a825..0000000000 --- a/test/scanf/test_scanfblocks.rb +++ /dev/null @@ -1,82 +0,0 @@ -# frozen_string_literal: false -# $Id$ -# -# scanf for Ruby -# -# Some not very comprehensive tests of block behavior. - - -require 'test/unit' -require 'scanf' -require 'tmpdir' - -class TestScanfBlock < Test::Unit::TestCase - - def setup - @str = <<-EOS - Beethoven 1770 - Bach 1685 - Handel 1685 - Scarlatti 1685 - Brahms 1833 - EOS - end - -alias set_up setup - def test_str1 - res = @str.scanf("%s%d") { |name, year| "#{name} was born in #{year}." } - assert_equal(res, - [ "Beethoven was born in 1770.", - "Bach was born in 1685.", - "Handel was born in 1685.", - "Scarlatti was born in 1685.", - "Brahms was born in 1833." ]) - end - - def test_str2 - names = @str.scanf("%s%d") { |name, year| name.upcase } - assert_equal(names, ["BEETHOVEN", "BACH", "HANDEL", "SCARLATTI", "BRAHMS"]) - end - - def test_str3 - assert_equal("".scanf("%d%f%s") {}, []) - end - - def test_str4 - assert_equal("abc".scanf("%d%f%s") {}, []) - end - - def test_str5 - assert_equal("abc".scanf("") {}, []) - end - - def test_io1 - fn = "#{Dir.tmpdir}/iotest.dat.#{$$}" - File.open(fn, "w") { |fh| fh.puts(@str) } - fh = File.open(fn, "rb") - res = fh.scanf("%s%d") { |name, year| "#{name} was born in #{year}." } - - assert_equal( - [ "Beethoven was born in 1770.", - "Bach was born in 1685.", - "Handel was born in 1685.", - "Scarlatti was born in 1685.", - "Brahms was born in 1833." ],res) - fh.close - ensure - File.delete(fn) - end - - def test_io2 - fn = "#{Dir.tmpdir}/iotest.dat.#{$$}" - File.open(fn, "w").close - fh = File.open(fn,"rb") - assert_equal(fh.scanf("") {}, []) - fh.seek(0) - assert_equal(fh.scanf("%d%f%s") {}, []) - fh.close - ensure - File.delete(fn) - end - -end diff --git a/test/scanf/test_scanfio.rb b/test/scanf/test_scanfio.rb deleted file mode 100644 index fdd5928c9e..0000000000 --- a/test/scanf/test_scanfio.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: false -# $Id$ -# -# scanf for Ruby -# -# Ad hoc tests of IO#scanf (needs to be expanded) - -require 'test/unit' -require 'scanf' - -class TestScanfIO < Test::Unit::TestCase - def test_io - File.open(File.join(File.dirname(__FILE__), "data.txt"), "r") do |fh| - assert_equal(0, fh.pos) - assert_equal(["this", "is"], fh.scanf("%s%s")) - assert_equal([33, "little"], fh.scanf("%da fun%s")) - end - end - - def test_pipe_scanf - IO.pipe do |r, w| - w.write('a') - w.close - assert_equal([], r.scanf('a')) - end - end -end - diff --git a/tool/sync_default_gems.rb b/tool/sync_default_gems.rb index 1905b947d6..13a1e7f26e 100644 --- a/tool/sync_default_gems.rb +++ b/tool/sync_default_gems.rb @@ -19,7 +19,6 @@ # * https://github.com/ruby/date # * https://github.com/ruby/zlib # * https://github.com/ruby/fcntl -# * https://github.com/ruby/scanf # * https://github.com/ruby/strscan # * https://github.com/ruby/ipaddr # * https://github.com/ruby/logger @@ -62,7 +61,6 @@ $repositories = { date: 'ruby/date', zlib: 'ruby/zlib', fcntl: 'ruby/fcntl', - scanf: 'ruby/scanf', strscan: 'ruby/strscan', ipaddr: 'ruby/ipaddr', logger: 'ruby/logger', @@ -220,7 +218,7 @@ def sync_default_gems(gem) cp_r(Dir.glob("#{upstream}/ext/racc/cparse/*"), "ext/racc/cparse") cp_r("#{upstream}/test", "test/racc") `git checkout ext/racc/cparse/README` - when "rexml", "rss", "matrix", "irb", "csv", "shell", "logger", "ostruct", "scanf", "webrick", "fileutils", "forwardable", "prime", "tracer", "ipaddr", "mutex_m", "sync" + when "rexml", "rss", "matrix", "irb", "csv", "shell", "logger", "ostruct", "webrick", "fileutils", "forwardable", "prime", "tracer", "ipaddr", "mutex_m", "sync" sync_lib gem else end -- cgit v1.2.3