[glib] Bug 617947 - glib-mkenums: add @valuenum@ support



commit 47805f4e0cadf35bd6882d7e54374fead25637d2
Author: Ryan Lortie <desrt desrt ca>
Date:   Thu May 6 14:19:58 2010 -0500

    Bug 617947 - glib-mkenums: add @valuenum@ support
    
    Add a @valuenum@ substitution that outputs the integer value of a
    particular enum value.  The value is determined by using (sandboxed)
    perl to evaluate C expression.  If evaluation fails then glib-mkenums
    dies loudly.  Evaluation is only enabled if '@valuenum@' appears in the
    template file, so existing users will not be affected.

 gobject/glib-mkenums.in |   36 ++++++++++++++++++++++++++++++------
 1 files changed, 30 insertions(+), 6 deletions(-)
---
diff --git a/gobject/glib-mkenums.in b/gobject/glib-mkenums.in
index db4ebd3..a3cf558 100755
--- a/gobject/glib-mkenums.in
+++ b/gobject/glib-mkenums.in
@@ -1,6 +1,7 @@
 #! PERL_PATH@ -w
 
 use File::Basename;
+use Safe;
 
 # glib-mkenums.pl 
 # Information about the current enumeration
@@ -21,6 +22,7 @@ my $enumname_prefix;		# prefix of $enumname
 my $enumindex = 0;		# Global enum counter
 my $firstenum = 1;		# Is this the first enumeration per file?
 my @entries;			# [ $name, $val ] for each entry
+my $sandbox = Safe->new;        # sandbox for safe evaluation of expressions
 
 sub parse_trigraph {
     my $opts = shift;
@@ -110,10 +112,10 @@ sub parse_entries {
 	    if (defined $options) {
 		my %options = parse_trigraph($options);
 		if (!defined $options{skip}) {
-		    push @entries, [ $name, $options{nick} ];
+		    push @entries, [ $name, $value, $options{nick} ];
 		}
 	    } else {
-		push @entries, [ $name ];
+		push @entries, [ $name, $value ];
 	    }
 	} elsif (m ^\s*\#@) {
 	    # ignore preprocessor directives
@@ -158,6 +160,7 @@ sub usage {
     print "  \ ENUMPREFIX\@          PREFIX\n";
     print "  \ VALUENAME\@           PREFIX_THE_XVALUE\n";
     print "  \ valuenick\@           the-xvalue\n";
+    print "  \ valuenum\@            the integer value (limited support, Since: 2.26)\n";
     print "  \ type\@                either enum or flags\n";
     print "  \ Type\@                either Enum or Flags\n";
     print "  \ TYPE\@                either ENUM or FLAGS\n";
@@ -331,7 +334,7 @@ while (<>) {
 	# Autogenerate a prefix
 	if (!defined $enum_prefix) {
 	    for (@entries) {
-		my $nick = $_->[1];
+		my $nick = $_->[2];
 		if (!defined $nick) {
 		    my $name = $_->[0];
 		    if (defined $enum_prefix) {
@@ -357,12 +360,12 @@ while (<>) {
 	}
 	
 	for $entry (@entries) {
-	    my ($name,$nick) = @{$entry};
+	    my ($name,$num,$nick) = @{$entry};
             if (!defined $nick) {
  	        ($nick = $name) =~ s/^$enum_prefix//;
 	        $nick =~ tr/_/-/;
 	        $nick = lc($nick);
-	        @{$entry} = ($name, $nick);
+	        @{$entry} = ($name, $num, $nick);
             }
 	}
 	
@@ -454,13 +457,34 @@ while (<>) {
 
 	if (length($vprod)) {
 	    my $prod = $vprod;
+            my $next_num = 0;
 	    
 	    $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
 	    $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
 	    for (@entries) {
-		my ($name,$nick) = @{$_};
+		my ($name,$num,$nick) = @{$_};
 		my $tmp_prod = $prod;
 
+                if ($prod =~ /\ valuenum\@/) {
+                    # only attempt to eval the value if it is requested
+                    # this prevents us from throwing errors otherwise
+                    if (defined $num) {
+                        # use sandboxed perl evaluation as a reasonable
+                        # approximation to C constant folding
+                        $num = $sandbox->reval ($num);
+
+                        # make sure it parsed to an integer
+                        if (!defined $num or $num !~ /^-?\d+$/) {
+                            die "Unable to parse enum value '$num'";
+                        }
+                    } else {
+                        $num = $next_num;
+                    }
+
+                    $tmp_prod =~ s/\ valuenum\@/$num/g;
+                    $next_num = $num + 1;
+                }
+
 		$tmp_prod =~ s/\ VALUENAME\@/$name/g;
 		$tmp_prod =~ s/\ valuenick\@/$nick/g;
 		if ($flags) { $tmp_prod =~ s/\ type\@/flags/g; } else { $tmp_prod =~ s/\ type\@/enum/g; }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]