#!/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 (<FILE>) {
		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 (<FILE>) {
		if ( /^(\S+)\*\s+at\s+(\S+)\?\s+bus\s+\?/)  {  
		    $start = $2;  # $BIaDL$H5U(B
		    $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 $B$r8+$F(B bus $B$r=&$C$F$*$/(B
$B<!$N$h$&$J>l9g(B:

  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} $B$K=P$FMh$?$b$N$O!"(BGENERIC $B$b8+$k(B
   ($BNc(B) isa at pcib?
(2) bus ? $B$H$"$k>l9g$O5U8~(B
    pci*    at ppb? bus ?
   $B$N>l9g(B ppb -> pci
