From: Fletcher T. Penney Date: Tue, 24 Jan 2017 23:55:41 +0000 (-0500) Subject: ADDED: Add enum mapping tool X-Git-Tag: 0.1.1a^2~13 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9f1c2fe21cca0b64399c3366c2a47cdb00611db9;p=multimarkdown ADDED: Add enum mapping tool --- diff --git a/tools/enumsToPerl.pl b/tools/enumsToPerl.pl new file mode 100755 index 0000000..1a40cec --- /dev/null +++ b/tools/enumsToPerl.pl @@ -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 = ; + 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"; +} +