mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 15:36:17 +01:00
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.
This commit is contained in:
parent
7aa71527e5
commit
47805f4e0c
@ -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; }
|
||||
|
Loading…
Reference in New Issue
Block a user