#!/usr/bin/perl
#
# (C) 2006 Gregor Jehle <gjehle@gmail.com>
#
# GCC / MSCL Precompiler Output Include Depths Mapper
#
# Usage:
#       gcc -E <file.c> | perl e2html.pl
#       cl /P <file.c> | perl e2html.pl
#

print <<HTML;
<html><head>
<style type="text/css">
div {
border: 1px solid black;
margin: 2 0 2 15;
padding: 2px;
font-family: sans-serif, fixed, monospace;
font-size: 12px;
}
</style>
<title>GCC/MSCL Include Depths Map</title>
</head><body><div>
HTML

@istack = (); # only needed for MSCL

$GNU = 0;
$stylecheck = 0;
$leftout = 0;

while(<STDIN>)
{
        $line = $_;
        chomp($line);chomp($line);
        $line =~ s/\r//g;
        $line =~ s/\</\&lt\;/g;
        $line =~ s/\>/\&gt\;/g;

        if (!$stylecheck)
        {
                if($line =~ /\#line/)
                {
                        $GNU = 0; # MS CL
                        $stylecheck = 1;
                }
                elsif($line =~ /\#\s/)
                {
                        $GNU = 1; # GCC
                        $stylecheck = 1;
                }
                else
                {
                        die("UNABLE TO DETECT COMPILER FLAVOR!\n");
                }
        }


                if ($GNU)
                {
                        # GNU STYLE
                        #
                        while(<STDIN>)
                        {
                                $line = $_;
                                chomp($line);chomp($line);
                                $line =~ s/\</\&lt\;/g;
                                $line =~ s/\>/\&gt\;/g;
                                $line =~ s/\r//g;

                                if($line =~ /\# \d+ "[^"]+\s?(.+)/)
                                {
                                        $flags = $1;
                                        if($flags =~ /1/)
                                        {
                                                # new include
                                                print "<div><b>$line</b><br>\n";
                                        }
                                        if($flags =~ /2/)
                                        {
                                                # returned from include
                                                print "<em>$line</em></div>\n";
                                        }
                                }
                                else
                                {
                                        if(length($line)>=1)
                                        {
                                                # don't print the empty lines, just those with content
                                                print $line;
                                                print "<br>\n";
                                        }
                                }
                        }
                }
                else # !GNU
                {
                        # MS CL STYLE
                        #
                        if($line =~ /^\s*\#line (\d+) "([^"]+)/)
                        {
                                $lineno = $1;
                                $include = $2;

                                if ($lineno == 1)
                                {
                                        # a new include
                                        $leftout = 0;
                                        push(@istack,$include);
                                        print "<div><b>$line</b><br>\n";
                                }
                                elsif ($istack[$#istack] eq $include)
                                {
                                        # we're still in the same include
                                        # this is just a notice that some code got ommited
                                        if(!$leftout)
                                        {
                                                $leftout = 1;
                                                print "<strong>[...]</strong><br>";
                                        }
                                }
                                elsif ($istack[$#istack-1] eq $include)
                                {
                                        # we have returned from an include file
                                        $leftout = 0;
                                        $pinclude = pop(@istack);
                                        print "<em>$pinclude</em></div>$line<br>\n";
                                }
                                else
                                {
                                        die("unexpected #line directive, something went wrong:\n$line\n");
                                }
                        }
                        else
                        {
                                # remove tabs and spaces from the beginning
                                $line =~ s/^\s+//;
                                if(length($line)>=1)
                                {
                                        # don't print the empty lines, just those with content
                                        $leftout = 0;
                                        print $line;
                                        print "<br>";
                                }
                        }
                }

}


print <<HTML;
</div></body>
</html>
HTML