デバイスの認識状況

現在認識しているデバイスを視覚的に分かりやすく表示できないものか。
とりあえずdmesgの内容から木構造で表示してみた。
ファイル: make_device_tree.sh

#!/bin/sh
# $Id: make_device_tree.sh,v 1.1 2005/05/16 15:57:18 s-tanaka Exp $

dmesg | tr : ' ' | awk '/^[a-z0-9]+ at/ { print $3 "," $1 }' | ./pair_tree.rb

ファイル: pair_tree.rb

#!/usr/bin/env ruby
# $Id: pair_tree.rb,v 1.1 2005/05/16 15:57:18 s-tanaka Exp $

class MultiMap
  def initialize
    @table = {}
  end

  def []=(key, values)
    values = [values] if values.class != Array
    @table[key] ||= []
    @table[key] += values
    @table[key].uniq!
  end

  def [](key)
    @table[key]    
  end

  def each(&block)
    @table.each(&block)
  end
end

class MultiMapTreeWalker
  def initialize(map)
    @map = map
  end

  def walk(key, ends = {}, level = 0, lastf = true)
    ends[level] = lastf
    puts(prefix(ends, level, lastf) + key)

    values = @map[key]
    return unless values

    values.each_index do |i|
      walk(values[i], ends, level + 1, values.size - 1 == i)
    end
  end

  def prefix(ends, level, lastf)
    ret = ''
    level.times do |i|
      ret += ends[i] ? '    ' : '|   '
    end
    ret += lastf ? '`-- ' : '|-- '
    ret
  end
  private :prefix
end

root = nil
map = MultiMap.new
while line = ARGF.gets
  parent, child = line.chomp.split(/,/)
  root = parent unless root
  map[parent] = child
end

MultiMapTreeWalker.new(map).walk(root)

僕のノートPC(ThinkPad 570) + デバイスいっぱいで実行した結果がこちら。

$ ./make_device_tree.sh
`-- mainbus0
    |-- cpu0
    |-- pci0
    |   |-- pchb0
    |   |   `-- agp0
    |   |-- ppb0
    |   |   `-- pci1
    |   |       `-- vga0
    |   |           `-- wsdisplay0
    |   |-- cbb0
    |   |   `-- cardslot0
    |   |       |-- cardbus0
    |   |       `-- pcmcia0
    |   |           `-- com1
    |   |-- cbb1
    |   |   `-- cardslot1
    |   |       |-- cardbus1
    |   |       `-- pcmcia1
    |   |           `-- wdc0
    |   |               `-- atabus2
    |   |                   `-- wd1
    |   |-- clcs0
    |   |   |-- audio0
    |   |   `-- midi
    |   |-- pcib0
    |   |   `-- isa0
    |   |       |-- lpt2
    |   |       |-- com0
    |   |       |-- pckbc0
    |   |       |   |-- pckbd0
    |   |       |   |   `-- wskbd0
    |   |       |   `-- pms0
    |   |       |       `-- wsmouse0
    |   |       |-- pcppi0
    |   |       |   |-- midi0
    |   |       |   |-- spkr0
    |   |       |   `-- sysbeep0
    |   |       |-- isapnp0
    |   |       |-- npx0
    |   |       `-- fdc0
    |   |           `-- fd0
    |   |-- piixide0
    |   |   |-- atabus0
    |   |   |   `-- wd0
    |   |   `-- atabus1
    |   |       `-- atapibus0
    |   |           `-- cd0
    |   `-- uhci0
    |       `-- usb0
    |           `-- uhub0
    |               |-- ugen0
    |               `-- umass0
    |                   `-- scsibus0
    |                       `-- sd0
    `-- apm0

なんちゃらほげほげブリッジとかまだまだよくわからんデバイスいっぱいだ。要勉強。
そういえば、Rubyって複数の値を持てるHashって標準で持っていないのかな。今回は適当にでっちアップした。