Add optional deleter expression to GL function definitions.

The expression follows the function definition separated by a ~ character,
and is a simple boolean expression built with operators && and || from the
elementary expressions "core" "forward" or a GL version number like "3.2".

Parentheses are not supported, && binds stronger than || and may be ommited,
i.e. "3.2 core" is equivalent to "3.2 && core".
This commit is contained in:
Matthias Bentrup 2015-02-05 09:53:34 +01:00 committed by Nigel Stewart
parent 60f39ed9fd
commit ca4cfd556f
5 changed files with 125 additions and 6 deletions

View File

@ -9,7 +9,7 @@
my %regex = ( my %regex = (
extname => qr/^[A-Z][A-Za-z0-9_]+$/, extname => qr/^[A-Z][A-Za-z0-9_]+$/,
exturl => qr/^http.+$/, exturl => qr/^http.+$/,
function => qr/^(.+) ([a-z][a-z0-9_]*) \((.+)\)$/i, function => qr/^(.+) ([a-z][a-z0-9_]*) \((.+)\)\s*(~.*)?$/i,
token => qr/^([A-Z][A-Z0-9_x]*)\s+((?:0x)?[0-9A-Fa-f]+|[A-Z][A-Z0-9_]*)$/, token => qr/^([A-Z][A-Z0-9_x]*)\s+((?:0x)?[0-9A-Fa-f]+|[A-Z][A-Z0-9_]*)$/,
type => qr/^typedef\s+(.+)$/, type => qr/^typedef\s+(.+)$/,
exact => qr/.*;$/, exact => qr/.*;$/,
@ -122,10 +122,11 @@ sub parse_ext($)
} }
elsif (/$regex{function}/) elsif (/$regex{function}/)
{ {
my ($return, $name, $parms) = ($1, $2, $3); my ($return, $name, $parms, $deleted) = ($1, $2, $3, $4);
$functions{$name} = { $functions{$name} = {
rtype => $return, rtype => $return,
parms => $parms, parms => $parms,
deleted => $deleted,
}; };
} else { } else {
print STDERR "'$_' matched no regex.\n"; print STDERR "'$_' matched no regex.\n";

View File

@ -12,9 +12,18 @@ use warnings;
do 'bin/make.pl'; do 'bin/make.pl';
our %defined = ();
# function pointer declaration # function pointer declaration
sub make_pfn_decl($%) sub make_pfn_decl($%)
{ {
our %defined;
if( $defined{$_[0]} ) # avoid duplicate definitions
{
return "";
}
$defined{$_[0]} = 1;
return "PFN" . (uc $_[0]) . "PROC " . prefixname($_[0]) . " = NULL;"; return "PFN" . (uc $_[0]) . "PROC " . prefixname($_[0]) . " = NULL;";
} }

View File

@ -24,20 +24,89 @@ sub make_type($$)
return "@_;" return "@_;"
} }
sub make_condition($)
{
my $condition = "";
my $needop = 0;
for my $tok (split(/\s+/, $_[0])) {
if ($tok eq "~") {
# ignore
} elsif ($tok eq '&&') {
$condition .= ' && ';
$needop = 0;
} elsif ($tok eq '||') {
$condition .= ") || (";
$needop = 0;
} else {
if ($needop) {
$condition .= ' && ';
}
if ($tok =~ /^\d/) {
# GL Version
$tok =~ s/[.]/_/g;
$condition .= "GL_VERSION_${tok}";
} elsif ($tok eq "core") {
$condition .= " 0 ";
} elsif ($tok eq "forward") {
$condition .= " 0 ";
}
$needop = 1;
}
}
# optimize expression
$condition = "(" . $condition . ")";
$condition =~ s/[(][^)]* 0 [^)]*[)]/ 0 /g;
$condition =~ s/\|\|\s*0\s*//g;
$condition =~ s/\s*0\s*\|\|//g;
$condition =~ s/\s+0\s+/ 0 /g;
if ($condition eq " 0 ") {
return "1";
} else {
return "!($condition)";
}
}
# function pointer type declaration # function pointer type declaration
sub make_pfn_type($%) sub make_pfn_type($%)
{ {
our $api; our $api;
return join(' ', "typedef", $_[1]->{rtype}, my $prefix = "";
my $suffix = "";
if ($_[1]->{deleted})
{
$prefix = "#if " . make_condition($_[1]->{deleted}) . "\n";
if ($prefix eq "#if 1\n") {
$prefix = ""; # if optimized away
} else {
$suffix = "\n#endif";
}
}
return $prefix . join(' ', "typedef", $_[1]->{rtype},
"($api * PFN" . (uc $_[0]) . "PROC)", "($api * PFN" . (uc $_[0]) . "PROC)",
"(" . $_[1]->{parms} . ")") . ";"; "(" . $_[1]->{parms} . ")") . ";" . $suffix;
} }
# function name alias # function name alias
sub make_pfn_alias($%) sub make_pfn_alias($%)
{ {
our $type; our $type;
return join(" ", "#define", $_[0], $type . "EW_GET_FUN(" . prefixname($_[0]) . ")") my $prefix = "";
my $suffix = "";
if ($_[1]->{deleted})
{
$prefix = "#if " . make_condition($_[1]->{deleted}) . "\n";
if ($prefix eq "#if 1\n") {
$prefix = ""; # if optimized away
} else {
$suffix = "\n#endif";
}
}
return $prefix . join(" ", "#define", $_[0], $type . "EW_GET_FUN(" . prefixname($_[0]) . ")") . $suffix;
} }
my @extlist = (); my @extlist = ();

View File

@ -18,7 +18,38 @@ do 'bin/make.pl';
sub make_pfn_def_init($%) sub make_pfn_def_init($%)
{ {
#my $name = prefixname($_[0]); #my $name = prefixname($_[0]);
return " r = ((" . $_[0] . " = (PFN" . (uc $_[0]) . "PROC)glewGetProcAddress((const GLubyte*)\"" . $_[0] . "\")) == NULL) || r;"; my $condition = "";
if ($_[1]{deleted}) {
my $needop = 0;
for my $tok (split(/\s+/, $_[1]{deleted})) {
if ($tok eq "~") {
# ignore
} elsif ($tok eq '&&') {
$condition .= ' && ';
$needop = 0;
} elsif ($tok eq '||') {
$condition .= ') || (';
$needop = 0;
} else {
if ($needop) {
$condition .= ' && ';
}
if ($tok =~ /^\d/) {
# GL Version
$tok =~ s/[.]/_/g;
$condition .= "GLEW_VERSION_${tok}";
} elsif ($tok eq "core") {
$condition .= "(context_profile & GL_CONTEXT_CORE_PROFILE_BIT)";
} elsif ($tok eq "forward") {
$condition .= "(context_flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)";
}
$needop = 1;
}
}
$condition = "if( !(($condition)) ) ";
}
return " ${condition}r = ((" . $_[0] . " = (PFN" . (uc $_[0]) . "PROC)glewGetProcAddress((const GLubyte*)\"" . $_[0] . "\")) == NULL) || r;";
} }
sub make_reuse_call($%) sub make_reuse_call($%)

View File

@ -12,10 +12,19 @@ use warnings;
do 'bin/make.pl'; do 'bin/make.pl';
our %defined = ();
# function pointer declaration # function pointer declaration
sub make_pfn_decl($%) sub make_pfn_decl($%)
{ {
our $export; our $export;
our %defined;
if( $defined{$_[0]} ) # avoid duplicate definitions
{
return "";
}
$defined{$_[0]} = 1;
return $export . " PFN" . (uc $_[0]) . "PROC " . prefixname($_[0]) . ";"; return $export . " PFN" . (uc $_[0]) . "PROC " . prefixname($_[0]) . ";";
} }