#!/usr/pkg/bin/perl # $Header: /home/makoto/perl/cvsroot/perl/graphviz/gram2dot,v 1.18 2006/08/23 00:40:27 makoto Exp $ # # (1) read the files of argument # (2) generate input files for dot graphviz tool # # Usage: # perl this_file files.${ARCH} GENERIC > this.dot # use strict; my $node_seq = 0; my %HASH = (); my ($start,$end,$B,$E); my %DONE = (); sub arrow($$$){ my $start= shift ; my $end = shift ; my $color = shift ; $start =~ s/ //g; $end =~ s/ //g; if ( $DONE{"$end -> $start"} == 0){ print "$end -> $start"; if ($color) { print "[color=$color]";} print ";\n"; $DONE{"$end -> $start"}++; } } sub make_title (@) { # making title string # pick the last three fragment of path (leaf) my @files = @_; my $title = ''; foreach my $file (@files) { my $leaf; my @leaf = split('/',$file); $leaf = $leaf[$#leaf - 2] . '/'. $leaf[$#leaf - 1] . '/'. $leaf[$#leaf] ; # /a/b/c/d => 4, pick 2 and 3 and 4 $title .= ' '. $leaf; } return $title . ' -- ' . scalar(localtime(time())); } # --------------------------------- # S U B M A I N # --------------------------------- sub main (@){ print "digraph hierarchy {\n"; my @files = @_; my $title = make_title(@files); # will be used at the bottom foreach my $file ( @files ) { if ( $file =~ /file/ ) { # file type is files.* open(FILE, $file) || die "problem opening file($file): $!\n"; while () { if ( /^attach\s+(\S+)\s+at\s+(\S+)/) { $start = $1; $end = $2; $end =~ s/://; ### newsmips conf/files.newsmips:attach le at hb: le24 ## attach ki2c at obio, uni_n foreach my $i (split(',', $end)) { arrow($start,$i,'green'); } } # P C I special ... some kind of HARDCODE .. elsif ( /device\s+(.*): (.*)/ ) { # files.ibmnws:device pchb: pcibus $start = $1; $end = $2; foreach my $i (split(',', $end)) { $i =~ s/ //; $i =~ s/bus//; $start =~ s/\{.*\}//; arrow($i,$start,'brown'); } } } close(FILE); } else { print STDERR "reading $file\n"; open(FILE, "$file") || die "problem opening file($file): $!\n"; print " // info from $file\n"; while () { if ( /^(\S+)\*\s+at\s+(\S+)\?\s+bus\s+\?/) { $start = $2; # 普通と逆 $end = $1; arrow($start,$end,"blue"); } elsif ( /^(\S+)[0]\s+at\s+(\S+)[0]\s+bus\s+\?/) { $start = $1; $end = $2; arrow($start,$end,"blue"); } elsif ( /^(pci.*)\*\s+at\s+(\S+)\?/) { $start = $1; $end = $2; arrow($start,$end,"blue"); } elsif ( /(\S+)\*\s+at\s+(\S+)\?/ ) { $start = $1; $end = $2; if ( $HASH{$start}) { arrow($start,$end,"blue"); } } } } close(FILE); } print "label =\"$title\";\n"; print "}\n"; } # --------------------------------- # M A I N # --------------------------------- main (@ARGV); __END__ (files.macppc) device bm: ifnet, ether, arp, mii, mii_bitbang device mainbus: mainbus device grackle: pcibus + this pcibus is refered only in GENERIC (sample output) digraph simple_hierarchy { B [label="Hello"] // node B E [label="World !"] // node E B->E [label=" graphviz and dot ", fontcolor=darkgreen] // edge B->E } 1. GENERIC を見て bus を拾っておく 次のような場合: grep pci /export/20060702-new/checkout/src/sys/arch/prep/conf/GENERIC pci0 at mainbus0 bus ? pci* at pchb? bus ? pci* at ppb? bus ? pchb* at pci? dev ? function ? # PCI-Host bridges ppb* at pci? dev ? function ? # PCI-PCI bridges + pcib* at pci? dev ? function ? # PCI-ISA bridges pceb* at pci? dev ? function ? # PCI-EISA bridges + isa* at pcib? # ISA on PCI-ISA bridge (1) files.${ARCH} に出て来たものは、GENERIC も見る (例) isa at pcib? (2) bus ? とある場合は逆向 pci* at ppb? bus ? の場合 ppb -> pci