#!@PERL_PATH@ -w
use File::Basename;
+use Safe;
# glib-mkenums.pl
# Information about the current enumeration
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;
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
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";
# 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) {
}
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);
}
}
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; }