#!/usr/bin/perl -w

#
# Prefuse XML Generator
# Pedram Amini
#
# This script will parse input from call_mapper.idc. 'cat' a bunch of files and
# pipe it to this script to generate a Prefuse XML file. The output from this
# script must be piped through a 'sort -r | uniq' to remove duplicates.
#
# Example:
#
#     $ cat kernel32.calls | gen_prefuse_xml.pl | sort -r | uniq > kernel32.xml
#
#     for i in `ls *.calls|cut -d'.' -f1`; do cat $i.dll.calls | \
#         ../gen_prefuse_xml.pl | sort -r | uniq > 2003SP1_$i.xml; done
#
# Encapulsate the XML definition with the opening tag:
#
#     <graph directed="0">
#
# And the closing tag:
#
#     </graph>
#

use strict;
$|++;

while (<>)
{
    s/\r//;
    s/\n//;

    # if func has no call chain.
    if (!/,/)
    {
        # create a node and process the next line.
        # XXX - uncomment the next line if you wish to display chain-less nodes.
        #print "<node id=\"$_\" label=\"$_\"/>\n";
        next;
    }

    # extract the api and the call chain.
    my ($func, @call_chain)  = split /,/;

    # create a node for the func.
    print "<node id=\"$func\" label=\"$func\"/>\n";

    # create a node for each function in the call chain.
    for (my $i = 0; $i <= $#call_chain; $i++)
    {
        print "<node id=\"$call_chain[$i]\" label=\"$call_chain[$i]\"/>\n";
    }

    # create edges from the func to each member of the call chain.
    for (my $i = 0; $i <= $#call_chain; $i++)
    {
        print "<edge label=\"\" source=\"$func\" target=\"$call_chain[$i]\"/>\n";
    }
}
