#! /usr/bin/perl

$VERBOSE = 0;

use Getopt::Long;

$USAGE = '  Command Line Options:
    -v[erbose]             -- Optional; Print helpful info to stdout
    -d[ebug]               -- Optional; Print tons of info to stdout
    -h[elp]                -- Optional; Print help on assembly
    -i[nputfile]           -- File that contains MIPS assembly
    -o[outputfile]         -- File in which to write machine code
  Usage:
    hex2bin [-v] -i <filename> -o <filename>
';

do_get_args();
do_open_files();
do_conversion_loop();
exit(0);

sub do_get_args() {
    $VERBOSE = 0;
    $IN_FILE = 0;   $OUT_FILE = 0;

    $num_args = $#ARGV;
    $ops = GetOptions("verbose" => \$VERBOSE,
		      "debug" => \$DEBUG,
		      "help" => \$need_help,
		      "inputfile=s" => \$IN_FILE,
		      "outputfile=s" => \$OUT_FILE);

    if ($need_help == 1) {
	print_help();
	exit(0);
    } elsif ($ops == 0 || $num_args < 3 || $num_args > 5) {
	print STDERR $USAGE;
	exit(0);
    } elsif ($DEBUG) {
	$VERBOSE = 1;
    }
    
    print "[*] Starting hex2bin:\n" if $VERBOSE;
    print "     Options: verbose=$VERBOSE debug=$DEBUG " .
	  "inputfile=$IN_FILE outputfile=$OUT_FILE\n" if $VERBOSE;
}

sub do_open_files() {
    if (!(-e $IN_FILE)) {
	die "ERROR: Cannot find input file $IN_FILE\n";
    } elsif (!open(IN, "<$IN_FILE")) {
	die "ERROR: Cannot open input file $IN_FILE: $!\n";	
    }
    print "     Opened $IN_FILE for reading.\n" if $VERBOSE;

    if (!open(OUT, ">$OUT_FILE")) {
	die "ERROR: Cannot open input file $OUT_FILE: $!\n";	
    }
    print "     Opened $OUT_FILE for writing.\n" if $VERBOSE;
}

sub do_conversion_loop () {
    $lineno = 0;
    while ($line = <IN>) {
	$lineno++;
	chomp($line);
	$template = "^" . "([\\da-fA-F][\\da-fA-F])" x 4 . "\$";
	print "     Parsing line $lineno: \"$line\" => " if $VERBOSE;

	if ($line =~ /$template/) {

	    $str = chr(hex("$1")) . chr(hex("$2")) . chr(hex("$3")) . chr(hex("$4"));
	    printf "\\%3.3o\\%3.3o\\%3.3o\\%3.3o\n", hex("$1"), hex("$2"), hex("$3"), hex("$4") if $VERBOSE;
	    print OUT $str;

	} elsif ($line eq "") {

	    print "ignoring.\n" if $VERBOSE;

	} else {

	    print "ERROR: Invalid input line: $line\n";
	    print " NOTE: All lines must be of the form 'xxxxxxxx' where each\n";
	    print "       'x' is a hexadecimal digit (0-9 a-f A-F)\n";
	    exit(0);

	}
	
    }

    print "     Conversion finished.\n" if $VERBOSE;
    print "[*] hex2bin finished successfully\n" if $VERBOSE;
}

sub print_help () {
print '
HEX2BIN - v0.1

This program converts ascii text files containing 32-bit hex
values on each line into a single stream of binary
equivalents. Thus, an input file like the following

ffffffff
00000000

will be output as a 64-bit file that consists of 32 1s followed
by 32 0s. This is necessary because the text (ascii) character "1"
is actually an 8-bit binary number (00110001) in the file.
';
}

