# # $Id: lineinput.rb 3723 2007-03-28 21:34:13Z aamine $ # # Copyright (c) 2002-2007 Minero Aoki # # This program is free software. # You can distribute/modify this program under the terms of # the GNU LGPL, Lesser General Public License version 2.1. # require 'stringio' # Utility class for line-wise file parsing class LineInput def LineInput.for_string(s) new(StringIO.new(s)) end def initialize(f) @input = f @buf = [] @lineno = 0 @eof_p = false end def inspect "\#<#{self.class} file=#{@input.inspect} line=#{lineno()}>" end def eof? @eof_p end def path @input.path end def lineno @lineno end def gets unless @buf.empty? @lineno += 1 return @buf.pop end return nil if @eof_p # to avoid ARGF blocking. line = @input.gets @eof_p = true unless line @lineno += 1 line end def ungets(line) return unless line @lineno -= 1 @buf.push line line end def peek line = gets() ungets line if line line end def next? peek() ? true : false end def skip_blank_lines n = 0 while line = gets() unless line.strip.empty? ungets line return n end n += 1 end n end def gets_if(re, index = nil) line = gets() if not line or not (re =~ line) ungets line return nil end return $~[index] if index line end def gets_unless(re) line = gets() if not line or re =~ line ungets line return nil end line end def each while line = gets() yield line end end def while_match(re) while line = gets() unless re =~ line ungets line return end yield line end nil end def getlines_while(re) buf = [] while_match(re) do |line| buf.push line end buf end alias span getlines_while # from Haskell def until_match(re) while line = gets() if re =~ line ungets line return end yield line end nil end def getlines_until(re) buf = [] until_match(re) do |line| buf.push line end buf end alias break getlines_until # from Haskell def until_terminator(re) while line = gets() return if re =~ line # discard terminal line yield line end nil end def getblock(term_re) buf = [] until_terminator(term_re) do |line| buf.push line end buf end end