]> granicus.if.org Git - multimarkdown/commitdiff
ADDED: Add enum mapping tool
authorFletcher T. Penney <fletcher@fletcherpenney.net>
Tue, 24 Jan 2017 23:55:41 +0000 (18:55 -0500)
committerFletcher T. Penney <fletcher@fletcherpenney.net>
Tue, 24 Jan 2017 23:55:41 +0000 (18:55 -0500)
tools/enumsToPerl.pl [new file with mode: 0755]

diff --git a/tools/enumsToPerl.pl b/tools/enumsToPerl.pl
new file mode 100755 (executable)
index 0000000..1a40cec
--- /dev/null
@@ -0,0 +1,167 @@
+#!/usr/bin/perl
+
+# enumsToPerl:
+# This Perl script creates a Perl version of the enum's that are in
+# the C/C++ header file supplied as the first command-line argument.
+# The second command-line argument specifies the filepath to the
+# module file that is to be created.
+# Sample usage:
+# perl enumsToPerl MyEnums.h MyEnums.pm
+#
+# Cameron Hayne (macdev@hayne.net)  May 2009
+
+use strict;
+use warnings;
+use File::Basename;
+
+# getEnumsFromString:
+sub getEnumsFromString($)
+{
+    my ($str) = @_;
+    
+    # strip C & C++ style comments
+    # (regex from: http://perldoc.perl.org/perlfaq6.html)
+    $str =~ s#/\*[^*]*\*+([^/*][^*]*\*+)*/
+             |//[^\n]*
+             |q("(\\.|[^"\\])*" | '(\\.|[^'\\])*' | .[^/"'\\]*)
+             #defined $2 ? $2 : ""#gsex;
+    
+    my @enums = ();
+    while ($str =~ /(enum\s+(\w+)\s*{([^}]*)}\s*;)/g)
+    {
+        my $enumDecl = $1;
+        my $enumName = $2;
+        my $enumBody = $3;
+        
+        my $enum = {};
+        $enum->{name} = $enumName;
+        $enum->{pairs} = [];
+        push(@enums, $enum);
+        
+        my $prevValue = -1;
+        while ($enumBody =~ /(\w+)\s*(?:=\s*(.+))?,?/g)
+        {
+            my $name = $1;
+            my $value = $2;
+            if (defined($value))
+            {
+                $value = eval($value);
+            }
+            else
+            {
+                $value = $prevValue + 1;
+            }
+            $prevValue = $value;
+            
+            push(@{$enum->{pairs}}, [$name, $value]);
+        }
+    }
+    
+    return @enums;
+}
+
+# writePerlCodeForEnums:
+sub writePerlCodeForEnums($$@)
+{
+    my ($filehandle, $useHex, @enums) = @_;
+    
+    print $filehandle "# Enums:\n";
+    print $filehandle "# -----------------------------------------\n";
+    
+    my $format = $useHex ? "\t'%s' => 0x%02x,\n"
+                         : "\t'%s' => %d,\n";
+
+    foreach my $enum (@enums)
+    {
+        my $enumName = $enum->{name};
+        print $filehandle "our %$enumName = (\n";
+        foreach my $pair (@{$enum->{pairs}})
+        {
+            my $name = $pair->[0];
+            my $value = $pair->[1];
+            
+            printf $filehandle ($format, $name, $value);
+        }
+        print $filehandle ");\n";
+        print $filehandle "\n";
+    }
+}
+
+# writePerlCodeForReverseEnums:
+sub writePerlCodeForReverseEnums($$@)
+{
+    my ($filehandle, $useHex, @enums) = @_;
+    
+    print $filehandle "# Reverse Enums:\n";
+    print $filehandle "# -----------------------------------------\n";
+    
+    my $format = $useHex ? "\t0x%02x => '%s',\n"
+                         : "\t%d => '%s',\n";
+
+    foreach my $enum (@enums)
+    {
+        my $enumName = $enum->{name} . "REVERSE";
+        print $filehandle "our %$enumName = (\n";
+        foreach my $pair (@{$enum->{pairs}})
+        {
+            my $name = $pair->[0];
+            my $value = $pair->[1];
+            printf $filehandle ($format, $value, $name);
+        }
+        print $filehandle ");\n";
+        print $filehandle "\n";
+    }
+}
+
+sub writePerlCodeForModule($$$@)
+{
+    my ($filehandle, $headerFile, $moduleName, @enums) = @_;
+    
+    my $time = localtime();
+    my $moduleStart = << "EOT";
+# This Perl module was generated: $time
+# by using the 'enumsToPerl' script on the following header file:
+# $headerFile
+
+package $moduleName;
+EOT
+    my $moduleCode = <<'EOT';
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = do {
+    no strict 'refs';
+    map { '%' . $_ } keys %{ __PACKAGE__ . '::' };
+};
+
+EOT
+
+    print $filehandle "$moduleStart\n";
+    print $filehandle "$moduleCode\n";
+}
+
+# MAIN
+{
+    die "Usage: enumsToPerl headerFile moduleFile\n" unless scalar(@ARGV) == 2;
+    my $headerFile = $ARGV[0];
+    my $moduleFile = $ARGV[1];
+    die "Can't read header file '$headerFile'" unless -r $headerFile;
+    my ($basename, $dirname, $ext) = fileparse($moduleFile, qr/\.[^.]*/);
+    die "Can't create module file '$moduleFile'" unless -w $dirname;
+    my $moduleName = $basename;
+           
+    undef $/;  # slurp mode
+    open(HEADERFILE, "< $headerFile")
+           or die "Can't open header file '$headerFile' : $!\n";
+    my $contents = <HEADERFILE>;
+    close(HEADERFILE) or die "Failed to close header file: $!\n";
+    
+    open(MODULEFILE, "> $moduleFile")
+           or die "Can't open module file '$moduleFile' for writing: $!\n";
+    my @enums = getEnumsFromString($contents);
+    my $useHex = 0;
+    writePerlCodeForModule(*MODULEFILE, $headerFile, $moduleName, @enums);
+    writePerlCodeForEnums(*MODULEFILE, $useHex, @enums);
+    writePerlCodeForReverseEnums(*MODULEFILE, $useHex, @enums);
+    close(MODULEFILE) or die "Failed to close module file: $!\n";
+}
+