#!/bin/perl
# Valentin Heinitz, 2010-03-20
# Script for making C++ class which converts enum to string.
# Version: 0.03
# This script is Public Domain. Copy, modify and redistribute it as you want.
# The software is provided "as is", without warranty of any kind.
#
# Call it from Source-code root-directory with command-line:
# perl enum2string.pl > <ToStringClassFileName.h>
use strict;
use warnings;
#Found enum types will be added to this list
my @etypes=();
#Found includes will be added to this list
my @includes=();
# Pattern for searching enum types and corresponding include-file.
my $pat="^[^\t]+\t([^\t]+)\t.*enum:([a-zA-Z_][a-zA-Z0-9_]*)";
my $file = "tags";
system "ctags -R *";
open T, ">tmp" or die "couldn't open tmp\n";
open F, $file or die "couldn't open $file\n";
#Replacing MS-Windows paths by UNIX paths (for includes)
while (<F>) {
$_ =~ s/\\/\//;
print T "$_";
}
close F;
close T;
$file="tmp";
open F, $file or die "couldn't open $file\n";
while (<F>) {
if (my ($m) = m/$pat/){
push @etypes, $2;
push @includes, $1;
#print "$_\n";
}
}
close F;
#Class name to be generated. Change as you like, or set from argument
my $clName = 'EnumToString';
#Remove duplicates from enum type list
my %hlp1 = ();
my @uniqenums = grep { ! $hlp1{$_} ++ } @etypes;
#Remove duplicates from include list
my %hlp2 = ();
my @uniqinc = grep { ! $hlp2{$_} ++ } @includes;
print "#ifndef _H_G__$clName\n";
print "#define _H_G__$clName\n\n";
print "#include <iostream>\nusing std::cout;\n";
foreach my $inc (@uniqinc)
{
print "#include \"$inc\"\n";
}
print "\n\n";
print "class $clName {\n";
print " $clName(); // utility class, no instances\n\n";
print "public:\n";
foreach my $k (@uniqenums)
{
$pat = "^([a-zA-Z0-9_]*)\t.*e\tenum:$k";
print " static const char * toString( $k en ) {\n";
print " switch( en ) {\n";
open F, $file or die "couldn't open $file\n";
while (<F>) {
if (my ($m) = m/$pat/){
print " case $1: return \"$1\";\n";
}
}
close F;
print " }\n";
print " return \"???\";\n";
print " }\n\n";
}
#Test
print "static void testEnum2String() {\n";
foreach my $k (@uniqenums)
{
$pat = "^([a-zA-Z0-9_]*)\t.*e\tenum:$k";
print " std::cout << \"Enums of $k:\\n\";\n";
open F, $file or die "couldn't open $file\n";
while (<F>) {
if (my ($m) = m/$pat/){
print " std::cout <<\" \"<< toString( $1 ) <<\" -> \" << $1 <<\"\\n\";\n";
}
}
close F;
}
print " }\n\n";
print "};\n\n";
print "#endif\n";