source: fedkit/genviz.pl @ 5e71d34

Last change on this file since 5e71d34 was 7c3008e, checked in by Ted Faber <faber@…>, 17 years ago

checkpoint

  • Property mode set to 100644
File size: 2.5 KB
Line 
1#!/usr/bin/perl
2
3use strict;
4
5use XML::Parser;
6use IO::File;
7use IO::Pipe;
8
9sub genviz {
10    my($file, $outfile)= @_;
11    my %nodes;
12    my $chars;
13    my $in_node;
14    my $in_lan;
15    my $lan;
16    my %links;
17    my %lans;
18    my $rv;
19    my $dotfile = "/tmp/split$$.dot";
20    my $neato = "/usr/local/bin/neato";
21    my $g = new IO::File(">$dotfile") || return;
22    my $p = new IO::Pipe() || return;
23    my $out = new IO::File(">$outfile");
24
25    sub start_element { 
26        my($expat, $element) = @_;
27        $in_node++ if $element eq "node";
28        if ( $element eq "lan" ) {
29            $in_lan++;
30            $lan = {};
31        }
32    }
33
34    sub end_element {
35        my($expat, $element) = @_;
36
37        $in_node = 0 if $element eq "node";
38        $nodes{$chars} = "node" if $in_node && $element eq "vname";
39        if ($in_lan) {
40            if ( $element ne "lan") {
41                $lan->{$element} = $chars if $element =~/(vname|vnode)/;
42            }
43            else {
44                $in_lan = 0;
45                my $vname = $lan->{'vname'};
46                if ( $links{$vname} && @{$links{$vname}} ==2 ) {
47                    # this link needs to be a lan
48                    $nodes{$vname} = "lan";
49                    $lans{$lan->{'vname'}} = ();
50                    foreach my $l (@{$links{$vname}}) {
51                        push(@{$lans{$vname}}, $l);
52                    }
53                    push(@{$lans{$vname}}, $lan->{'vnode'});
54                    $links{$vname} = ();
55                    $lan={};
56                    return;
57                }
58                if ( $lans{$vname} && @{$lans{$vname}}) {
59                    push(@{$lans{$vname}}, $lan->{'vnode'});
60                    $lan = {};
61                    return;
62                }
63                $links{$vname} = () unless $links{$vname};
64                push(@{$links{$vname}}, $lan->{'vnode'});
65                $lan = {};
66                return;
67            }
68        }
69    }
70    sub found_chars { 
71        my($expat, $data) = @_;
72        $chars = $data;
73    }
74
75    my $parser = new XML::Parser(Handlers => { 
76            Start => \&start_element, 
77            End => \&end_element,
78            Char => \&found_chars
79        });
80
81    print "$file\n";
82    $parser->parsefile($file);
83
84    print $g "graph G {\n";
85    foreach my $n (keys %nodes) {
86        print $g "\t$n\n";
87    }
88    foreach my $l (keys %links) {
89        print $g "\t", join(" -- ", @{$links{$l}}), "\n";
90    }
91    foreach my $l (keys %lans) {
92        foreach my $n (@{$lans{$l}}) {
93            print $g "\t $n -- $l\n";
94        }
95    }
96    print $g "}\n";
97    $g->close();
98    $p->reader("$neato  -Gstart=rand -Gepsilon=0.005 -Gmaxiter=20000 " .
99        "-Gpack=true $dotfile");
100    print $out "<vis>\n";
101    while (<$p>) {
102        /^\s*(\w+)\s+\[.*pos=\"(\d+),(\d+)\"/ && do {
103            my ($n, $x, $y) = ($1, $2, $3);
104
105            print "<node><name>$n</name><x>$x</x><y>$y</y><type>$nodes{$n}". 
106                "</type></node>\n" if $nodes{$n};
107        };
108    }
109    print $out "</vis>\n";
110    $p->close();
111    unlink("$dotfile");
112}
113
114genviz($ARGV[0], $ARGV[1]);
Note: See TracBrowser for help on using the repository browser.