mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-27 06:26:15 +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
|
#!@PERL_PATH@ -w
|
||||||
|
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
|
use Safe;
|
||||||
|
|
||||||
# glib-mkenums.pl
|
# glib-mkenums.pl
|
||||||
# Information about the current enumeration
|
# Information about the current enumeration
|
||||||
@ -21,6 +22,7 @@ my $enumname_prefix; # prefix of $enumname
|
|||||||
my $enumindex = 0; # Global enum counter
|
my $enumindex = 0; # Global enum counter
|
||||||
my $firstenum = 1; # Is this the first enumeration per file?
|
my $firstenum = 1; # Is this the first enumeration per file?
|
||||||
my @entries; # [ $name, $val ] for each entry
|
my @entries; # [ $name, $val ] for each entry
|
||||||
|
my $sandbox = Safe->new; # sandbox for safe evaluation of expressions
|
||||||
|
|
||||||
sub parse_trigraph {
|
sub parse_trigraph {
|
||||||
my $opts = shift;
|
my $opts = shift;
|
||||||
@ -110,10 +112,10 @@ sub parse_entries {
|
|||||||
if (defined $options) {
|
if (defined $options) {
|
||||||
my %options = parse_trigraph($options);
|
my %options = parse_trigraph($options);
|
||||||
if (!defined $options{skip}) {
|
if (!defined $options{skip}) {
|
||||||
push @entries, [ $name, $options{nick} ];
|
push @entries, [ $name, $value, $options{nick} ];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
push @entries, [ $name ];
|
push @entries, [ $name, $value ];
|
||||||
}
|
}
|
||||||
} elsif (m@^\s*\#@) {
|
} elsif (m@^\s*\#@) {
|
||||||
# ignore preprocessor directives
|
# ignore preprocessor directives
|
||||||
@ -158,6 +160,7 @@ sub usage {
|
|||||||
print " \@ENUMPREFIX\@ PREFIX\n";
|
print " \@ENUMPREFIX\@ PREFIX\n";
|
||||||
print " \@VALUENAME\@ PREFIX_THE_XVALUE\n";
|
print " \@VALUENAME\@ PREFIX_THE_XVALUE\n";
|
||||||
print " \@valuenick\@ 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";
|
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
|
# Autogenerate a prefix
|
||||||
if (!defined $enum_prefix) {
|
if (!defined $enum_prefix) {
|
||||||
for (@entries) {
|
for (@entries) {
|
||||||
my $nick = $_->[1];
|
my $nick = $_->[2];
|
||||||
if (!defined $nick) {
|
if (!defined $nick) {
|
||||||
my $name = $_->[0];
|
my $name = $_->[0];
|
||||||
if (defined $enum_prefix) {
|
if (defined $enum_prefix) {
|
||||||
@ -357,12 +360,12 @@ while (<>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for $entry (@entries) {
|
for $entry (@entries) {
|
||||||
my ($name,$nick) = @{$entry};
|
my ($name,$num,$nick) = @{$entry};
|
||||||
if (!defined $nick) {
|
if (!defined $nick) {
|
||||||
($nick = $name) =~ s/^$enum_prefix//;
|
($nick = $name) =~ s/^$enum_prefix//;
|
||||||
$nick =~ tr/_/-/;
|
$nick =~ tr/_/-/;
|
||||||
$nick = lc($nick);
|
$nick = lc($nick);
|
||||||
@{$entry} = ($name, $nick);
|
@{$entry} = ($name, $num, $nick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,13 +457,34 @@ while (<>) {
|
|||||||
|
|
||||||
if (length($vprod)) {
|
if (length($vprod)) {
|
||||||
my $prod = $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/\\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;
|
$prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
|
||||||
for (@entries) {
|
for (@entries) {
|
||||||
my ($name,$nick) = @{$_};
|
my ($name,$num,$nick) = @{$_};
|
||||||
my $tmp_prod = $prod;
|
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/\@VALUENAME\@/$name/g;
|
||||||
$tmp_prod =~ s/\@valuenick\@/$nick/g;
|
$tmp_prod =~ s/\@valuenick\@/$nick/g;
|
||||||
if ($flags) { $tmp_prod =~ s/\@type\@/flags/g; } else { $tmp_prod =~ s/\@type\@/enum/g; }
|
if ($flags) { $tmp_prod =~ s/\@type\@/flags/g; } else { $tmp_prod =~ s/\@type\@/enum/g; }
|
||||||
|
Loading…
Reference in New Issue
Block a user