#!/usr/bin/perl -w
#
# A simple utility to create a C++ file given an rc2 file
# containing one or more stringtables.
#
# Usage: $0 rc2file
# Input: rc2file.rc2
# Output: rc2file_st.cpp, rc2file_st.h
#
# The .cpp file contains a std::map<int, TCHAR *> named rc2fileST
# The .h file contains a declaration of same.

use strict;
use warnings;
use locale;

sub usage {
    print "Usage: $0 rc2file\n";
    exit 1;
}

&usage unless ($#ARGV == 0);
my $BASE = $ARGV[0];
my $RC2FILE;
my $CPPFILE;
my $HFILE;
my %MAP;

# accept both filename.rc2 and filename as input
if ($BASE =~ m/(.+)\.rc2/) {
    $BASE = $1;
}
$RC2FILE = "${BASE}.rc2";
$CPPFILE = "${BASE}_st.cpp";
$HFILE = "${BASE}_st.h";

my $B = uc($BASE);
my $b = lc($BASE);

my $include;


&ReadRC2File;
&WriteHFile;
&WriteCPPFile;
exit 0;
#-----------------------------------------------------------------
sub ReadRC2File {
    my $inST = 0;
    open(RC2, "<$RC2FILE") || die "Couldn't open $RC2FILE\n";
    while (<RC2>) {
        if (m/^#include.*/) {
            $include = $_;
            $include =~ s,\\,/,g;
        } elsif (m/^\s*STRINGTABLE\s*$/) {
            $inST = 1;
        } elsif ($inST == 1 && m/^\s*BEGIN\s*$/) {
            $inST = 2;
        } elsif ($inST == 2 && m/^\s*END\s*$/) {
            $inST = 0;
        } elsif ($inST == 2 && m/^\s*(\w+)\s+(\".+\")[^"]*/) {
            $MAP{$1} = $2;
        }
    }
    close(RC2);
}

sub WriteHFile {
    open(H, ">$HFILE") || die "Couldn't open $HFILE\n";
    print H <<"EOT";
#ifndef __${B}_ST_H
#define __${B}_ST_H
/**
 * Declaration of string table map
 * Derived from $RC2FILE
 * Generated by $0
 */
#include <map>
#include "../os/typedefs.h" // for definition of TCHAR
extern std::map<int, const TCHAR *> ${b}_st;
#endif /* __${B}_ST_H */
EOT
    close(H);
}

sub WriteCPPFile {
    open(CPP, ">$CPPFILE") || die "Couldn't open $CPPFILE\n";
    print CPP <<"PREAMBLE";
/**
 * Definition of string table map
 * Derived from $RC2FILE
 * Generated by $0
 */

#ifdef UNICODE
#define _(x) L ## x
#else
#define _(x) x
#endif

#include "$HFILE"
#include <utility>
${include}

using namespace std;

namespace {
  pair<int, const TCHAR *> Pairs[] = {
PREAMBLE
# print %MAP, sorted by constant name, just to be consistent
    my $key;
    foreach $key (sort keys %MAP) {
        print CPP "    make_pair($key, _($MAP{$key})),\n";
}
    print CPP <<"POSTAMBLE";
  }; // Pairs array
}; // anonymous namespace

map<int, const TCHAR *> ${b}_st(Pairs, Pairs + sizeof(Pairs)/sizeof(Pairs[0]));
POSTAMBLE
    close(CPP);
}


