#!/pkg/vdcv8/tools/Perl/perl/bin/perl -w

# Erzeugt C++ Rümpfe aus Header-Dateien.
# ACHTUNG: Funktioniert NUR mit einzeiligen Methodendefinitionen !!!

# Author: Michael J.M. Wagner, Oktober 2001, sd&m AG

#---------------------------------
# Unterprogramme
#---------------------------------

#---------------------------------
sub schreibeMethode
#---------------------------------
{
	if ($Class eq "")
	{
		die "Keine Klasse gefunden";
	}
	
    my ($Methode) = @_;
    $Methode =~ s/^\s+//;
    $Methode =~ s/;//;
    $Out = "";

    # trenne Bezeichner, die nur im header file gebraucht werden
    if ($Methode =~ s/^virtual *//)
    {
        $Out = "//virtual\n";
    }
    if ($Methode =~ s/^friend *//)
    {
        $Out = "//friend\n";
    }
    if ($Methode =~ s/^final *//)
    {
        $Out = "//final\n";
    }
    if ($Methode =~ s/^static *//)
    {
        $Out = "//static\n";
    }
    
    if ($Methode =~ /^$Class/)
    {
        # constructors
        $Body = $KonstruktorText;
        $Body =~ s/_CLASS_/$Class/g;
        $Out = $Out . $Class . "::" . $Methode . $Body . "\n\n\n";
    }
    elsif ($Methode =~ /^~$Class/)
    {
        # destructors
        $Body = $DestruktorText;
        $Body =~ s/_CLASS_/$Class/g;
        $Out = $Out . $Class . "::" . $Methode . $Body . "\n\n\n";
    }
    elsif ($Methode =~ /operator/)
    {
        # operator
        $Out = $Out . $Methode . "{\n}\n\n\n\n";
    }
    else
    {
        # normal method
        
        # finde Methodennamen
        $MethodName = $Methode;
        $MethodName =~ s/ *\(.+//;
        @Words = split (/\s+/, $MethodName);
        $MethodName = pop (@Words);
        @Words = split (/$MethodName/, $Methode);
        $Argument = pop (@Words);
        $Type = shift (@Words);
        
        # generiere output
        $Body = $MethodenText;
        $Body =~ s/_CLASS_/$Class/g;
        $Body =~ s/_NAME_/$MethodName/g;
        $Out = $Type . $Class . "::" . $MethodName . $Argument . $Body . "\n\n\n";
    }        
    return $Out;
}

#---------------------------------
sub leseHilfsfile
#---------------------------------
{
    my ($Name) = @_;
    open (FILE, $Name);
    $Out = "";
    while ($Zeile = <FILE>)
    {
        if (! ($Zeile =~ /^#/))
        {
            $Out = $Out . $Zeile;
        }
    }
    return $Out;
    print $Out;
    close (FILE);
}

#---------------------------------
# Hauptprogramm
#---------------------------------

# check input params
if (!$ARGV[2] || $ARGV[3])
{
    die "usage: H2C.pl author file.h file.cpp"
}

# Eingabe
$Author     = $ARGV[0];
$Author =~ s/"//g;
$HeaderName = $ARGV[1];
$CFileName  = $ARGV[2];
print "Eingabe:\nAuthor= $Author\nH-Name= $HeaderName\nC-Name= $CFileName\n";

# Lese header file
open (HEADER_FILE, $HeaderName);
@Zeilen = <HEADER_FILE>;

# Lese Hilfsfiles
$HeaderText      = leseHilfsfile ("DateiHeader.tpl");
$KonstruktorText = leseHilfsfile ("Construct.tpl");
$DestruktorText  = leseHilfsfile ("Destruct.tpl");
$MethodenText    = leseHilfsfile ("Method.tpl");

# Öffne Ausgabedateien
open (COUT, ">$CFileName");

$Class = "";
while ($Zeile = shift(@Zeilen))
{
    
    # find class
    $Zeile =~ s/^ +//;
    if ( ($Zeile =~ /^class\b/) && ! ($Zeile =~ /;/) )
    {
        @Worter = split (/\s+/, $Zeile);
        $ClassFound = "0";
        while ($Wort = shift (@Worter))
        {
            print "$Wort\n";
            if ($ClassFound)
            {
                $Class = $Wort;
                $Class =~ s/[{:]//;
                last;
            }
            if ($Wort eq "class")
            {
                $ClassFound = "1";
            }
            else
            {
                $ClassFound = "0";   
            }
        }

        # schreibe file header
        $HeaderText =~ s/_AUTHOR_/$Author/;
        $HeaderText =~ s/_CLASS_/$Class/;
        print COUT "$HeaderText\n\n\n";
        print COUT "//------------------ include ----------------------\n\n";
        print COUT "#include \"$HeaderName\"\n\n";
        print COUT "//------------------ implementation ---------------\n\n\n";
    }
    
    # find methods
    if ( $Zeile =~ /\(.*\);$/)
    {
        $Out = schreibeMethode ($Zeile);
        print COUT $Out;
    }

}

close (HEADER_FILE);
close (COUT);
print "EOF\n";

