#! /usr/local/bin/ruby

## Expat for Ruby sample
## 1998 by yoshidam
##
## XML ファイルのテキスト部だけに対して正規表現検索を行なう。

require 'parsearg'
require 'xmlparser'
require 'uconv'
require 'nkf'

class XMLRetry<Exception; end

def xmlgrep (pattern, file = nil, printfile = 0, printline = 0)

  ## file open
  if !file
    f = $stdin
  else
    begin
      f = open(file, "r")
    rescue
      $stderr.print "#{$0}: #{$!}\n";
      return
    end
  end


  ## read body
  xml = f.read
  f.close

  ## dummy default handler
  parser = XMLParser.new
  def parser.unknownEncoding(e)
    raise XMLRetry, e
  end
  def parser.default
  end

  ## start to parse
  current = 0
  begin
    parser.parse(xml) do |type, name, data|
      case type
      when XMLParser::START_ELEM

      when XMLParser::END_ELEM

      when XMLParser::CDATA
        next if data =~ /^\s*$/;
        data = Uconv.u8toeuc(data)

        if data =~ pattern
          line = parser.line
          print "#{file}:" if (file && printfile == 1)
          print "#{line}:" if printline == 1
          parser.defaultCurrent
          current = 1
        end
      when XMLParser::PI

      else
        next if current == 0
        data.gsub!("\n", "\\n")
        print Uconv.u8toeuc("#{data}\n")
        current = 0
      end
    end
  rescue XMLRetry
    newencoding = nil
    e = $!.to_s
    if e =~ /^iso-2022-jp$/i
      xml = NKF.nkf("-Je", xml)
      newencoding = "EUC-JP"
    end
    parser = XMLParser.new(newencoding)
    def parser.default; end
    retry
  rescue XMLParserError
    line = parser.line
    print "#{$0}: #{$!} (#{file}:#{line})\n"
  end
end

def usage
  $stderr.print "Usage: #{$0} [-n] [-e] <expr> <files...>\n"
  exit 1
end

parseArgs(0, nil, "n", "e:")
if (ARGV.length == 0 && $OPT_e == nil)
  usage
end
if ($OPT_e)
  expr = $OPT_e
else
  expr = ARGV.shift
end

begin
  pattern = Regexp.new(expr);
rescue
  $stderr.print "#{$0}: #{$!}\n"
  exit 1
end

if (ARGV.length > 1)
  ARGV.each do |file|
    xmlgrep(pattern, file, 1, $OPT_n ? 1 : 0)
  end
elsif (ARGV.length == 1)
  xmlgrep(pattern, ARGV[0], 0, $OPT_n ? 1 : 0)
else
  xmlgrep(pattern, nil, 0, $OPT_n ? 1 : 0)
end

__END__
## Local variables:
## mode: ruby
## End:
