ColdCore-3.1/
ColdCore-3.1/bin/
ColdCore-3.1/dbbin/
ColdCore-3.1/root/
ColdCore-3.1/root/html/
ColdCore-3.1/root/html/jlogin/
ColdCore-3.1/root/logs/
#!/usr/bin/perl -w
#
## Created for the third time from scratch (I lost the first two iterations
## in hard drive crashes) on May 26 1997 -- Brandon Gillespie
##
## This does not just accept the defined textdump format, it ONLY accepts
## the named textdump format from Genesis-1.1-STABLE, mainly because I'm
## lazy and really thats all you should be using for this.  Furthermore,
## its not very forgiving about whitespace, as a standard textdump should
## be.  If your textdump has been manually altered from whatever Genesis
## would normally output, you should run it through a compile/decompile
## with coldcc first.
##
##        -Brandon
##

if ($] < 5) {
    die("This program requires perl 5.002 or greater.\n");
}

$ver = "1.0";
$help = "brandon\@cold.org";
$syn = "Syntax: $0 [-t=textdump] [-s=srcdir]";
$input  = "textdump";   
$src = "src"; 
$showstatus = 1;
while ($#ARGV != -1) {
    $_ = shift;
    if (/^-t/) {
        if (s/^-t=//) {
            $input = $_;
        } else {
            $input = shift || die("$syn\nNo followup argument to '-t'\n");
        }   
    } elsif (/^-s/) {
        if (s/^-s=//) { 
            $src = $_;
        } else {
            $src = shift || die("$syn\nNo followup argument to '-s'\n");
        }
    } elsif (/^-q/) {
        $showstatus = 0;
    } else {
        die("$syn\nInvalid argument '$_'\n");
    }
}

$core = "$src/+CORE";
$idx = "$src/+INDEX";

    
select(STDOUT); $| = 1;

sub abort {
    $msg = $_[0];
    $msg =~ s/\n/\n\*\* /;
    die("\n** $msg\n** Aborted.. Contact $help for help.\n");
}

if (!-e $src) {
    mkdir($src, 0755);
} elsif (!-d $src) {
    die("Source location '$src' exists but is not a directory.\n");
} elsif (!-w $src) {
    die("Source location '$src' exists but is not writable.\n");
}

open(IDX, ">$idx") || die("Unable to open index: $!\n");
open(CORE, ">$core") || die("Unable to open core index: $!\n");

## where is input coming from
print "Textdump Splitter and Sorter version $ver\nSplitting '$input' into '$src'\n";
open(IN, $input) || die("Unable to open input file '$input': $!\n");

### progress meter: just guess really well, no reason to spend lots
### of time making it absolutely correct.
my $avglines = -s $input;
## average 45 chars per line *shrug*
$avglines = ($avglines / 45) / 50;
$printed =0;
if ($showstatus) {
    print
    "          0% |-------25%-------------50%--------------75%-------| 100%\r";
    print "Progress: 0% |";
}

my $next = $avglines;
sub finish_progress {
    if ($showstatus) {
        while ($printed < 50) {
            $printed++;
            print "#";
        }
        print "\n";
    }
}

sub progress {
    if ($showstatus) {
        if ($next <= $.) {
            ## abort.. die, our averages were off?
            ($printed == 49) && return;
            print "#";
            $next += $avglines;
            $printed++;
        }
    }
}

## lets have at it
$obj = "";
$parents = "";
$file = "";
%vars = ();
%methods = ();
%mcode = ();
%natives = ();
$ISCORE = 0;

while (<IN>) {
    chomp;
    if (!$_) {
        next;
    }

    s/^new //;

    ###############################################################
    ### object
    ###############################################################
    if (s/^object //) {
        print_object();
        progress();
        if (/^#(\d+)/) {
            abort("Object #$1 without name found at line $.\n(Or this textdump wasn't created with the -# option to coldcc)");
        }
        if (!s/^\$([a-z0-9_]+)[;:]//i) {
            abort("Unable to identify object at line $.");
        }
        $obj = $1;
        $parents = $_;
        $parents =~ s/^\s+//;
        $parents =~ s/;$//;
        $file = "$src/${obj}.cdc";
        if (-e $file) {
            abort("File already exists for object $obj, perhaps this textdump has\nalready been decompiled?");
        }
        next;
    }

    !$file && abort("Directives found before object definition\n");

    ###############################################################
    ### variables
    ###############################################################
    if (s/^var //) {
        if (/^\$root flags = /) {
            if (/'core[],]/) {
                $ISCORE = 1;
            } else {
                $ISCORE = 0;
            }
        }

        if (/^\$has_commands local /) {
            s/ = #\[\[/ = \\\n  #[[/;
            s/\]\]\]\]\]\]\], +/]]]]]]],\\\n  /g;
            s/\n  (\["[^"]+",) \[\[/\n  $1\\\n    [[/gm;
        }

        if (!s/^\$([a-z0-9_]+)\s+//i) {
            &warn("Invalid ancestor found defining variable, ignoring");
            next;
        }
        $def = $1;
        if (!s/^([a-z0-9_]+)\s+=\s+//i) {
            &warn("Invalid variable definition, ignoring");
            next;
        }
        $var = $1;
        s/;$//;
        $data = $_;

        $key = "${def}:${var}";
        if (exists($vars{$key})) {
            abort("Bug? Key $key already exists in vars dict");
        }
        $vars{$key} = $data;
        next;
    }

    ###############################################################
    ### natives
    ###############################################################
    if (/^bind_native\s+\.([a-z0-9_]+)\(\)\s+\.([a-z0-9_]+)\(\)/i) {
        $native = $1;
        $alt = $2;
        $natives{$native} = $alt;
        next;
    }

    ###############################################################
    ### method
    ###############################################################
    if (s/^(root|driver|frob|private|public|protected)\s+method\s+//) {
        $access = $1;
        if (!s/\.([a-z0-9_]+)\(\)\s*//i) {
            abort("Invalid method definition");
        }
        $method = $1;
        $end = "";
        if (/:\s*([^{;]+)([{;])/) {
            $flags = $1;
            $end = $2;
        } elsif (/\s*([{;])/) {
            $flags = "";
            $end = $1;
        } else {
            abort("Method not terminated correctly");
        }

        $key = "$method";
        if (exists($methods{$key})) {
            abort("Bug? Key $key already exists in method dict");
        }
        $methods{$key} = "$access:$flags";

        $code = "";
        if ($end eq "{") {
            $terminated = 0;
            while (<IN>) {
                if (/^};$/) {
                    $terminated = 1;
                    last;
                }
                $code .= $_;
            }
            if (!$terminated) {
                abort("Textdump ends in method definition");
            }
        }

        $mcode{$key} = $code;
        next;
    }

    abort("Unknown directive: $_\n");
}

print_object();

finish_progress();

sub print_object {
    !$obj && return;

    if ($ISCORE) {
        print CORE "$obj\n";
    } else {
        print IDX "$obj\n";
    }

    open(OUT, ">$file") || abort("Unable to open $file: $!");

    print OUT "\n";
    if ($obj ne "root" && $obj ne "sys") {
        print OUT "new ";
    }

    print OUT "object \$$obj";
    if ($parents) {
        print OUT ": $parents";
    }
    print OUT ";\n\n";

    for $key (sort(keys(%vars))) {
        ($def, $var) = split(/:/, $key);
        print OUT "var \$$def $var = $vars{$key};\n";
    }
    print OUT "\n";

    for $key (sort(keys(%methods))) {
        ($access, $flags) = split(/:/, $methods{$key});
        $code = $mcode{$key};
        print OUT "$access method .$key()";
        if ($flags) {
            print OUT ": $flags";
        }
        if ($code) {
            print OUT " {\n$code};\n\n";
        } else {
            print OUT ";\n\n";
        }
    }

    for $key (sort(keys(%natives))) {
        print OUT "bind_native .$key() .$natives{$key}();\n";
    }
    print OUT "\n";

    close(OUT);
    %vars = ();
    %methods = ();
    %mcode = ();
    %natives = ();
    $ISCORE = 0;
}

sub warn {
    $msg = $_[0];
    print(STDERR "\bLine $.: $msg\n");
}