|
kusano |
7d535a |
#!/usr/bin/perl
|
|
kusano |
7d535a |
##
|
|
kusano |
7d535a |
## Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org=""></mmagallo[]debian>
|
|
kusano |
7d535a |
## Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee="" org=""></milan>
|
|
kusano |
7d535a |
##
|
|
kusano |
7d535a |
## This program is distributed under the terms and conditions of the GNU
|
|
kusano |
7d535a |
## General Public License Version 2 as published by the Free Software
|
|
kusano |
7d535a |
## Foundation or, at your option, any later version.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
use strict;
|
|
kusano |
7d535a |
use warnings;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
sub compile_regex
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
my $regex = join('', @_);
|
|
kusano |
7d535a |
return qr/$regex/
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my @sections = (
|
|
kusano |
7d535a |
"Name",
|
|
kusano |
7d535a |
"Name Strings?",
|
|
kusano |
7d535a |
"New Procedures and Functions",
|
|
kusano |
7d535a |
"New Tokens",
|
|
kusano |
7d535a |
"Additions to Chapter.*",
|
|
kusano |
7d535a |
);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my %typemap = (
|
|
kusano |
7d535a |
bitfield => "GLbitfield",
|
|
kusano |
7d535a |
boolean => "GLboolean",
|
|
kusano |
7d535a |
# fsck up in EXT_vertex_array
|
|
kusano |
7d535a |
Boolean => "GLboolean",
|
|
kusano |
7d535a |
byte => "GLbyte",
|
|
kusano |
7d535a |
clampd => "GLclampd",
|
|
kusano |
7d535a |
clampf => "GLclampf",
|
|
kusano |
7d535a |
double => "GLdouble",
|
|
kusano |
7d535a |
enum => "GLenum",
|
|
kusano |
7d535a |
# Intel fsck up
|
|
kusano |
7d535a |
Glenum => "GLenum",
|
|
kusano |
7d535a |
float => "GLfloat",
|
|
kusano |
7d535a |
half => "GLhalf",
|
|
kusano |
7d535a |
int => "GLint",
|
|
kusano |
7d535a |
short => "GLshort",
|
|
kusano |
7d535a |
sizei => "GLsizei",
|
|
kusano |
7d535a |
ubyte => "GLubyte",
|
|
kusano |
7d535a |
uint => "GLuint",
|
|
kusano |
7d535a |
ushort => "GLushort",
|
|
kusano |
7d535a |
DMbuffer => "void *",
|
|
kusano |
7d535a |
# Nvidia video output fsck up
|
|
kusano |
7d535a |
int64EXT => "GLint64EXT",
|
|
kusano |
7d535a |
uint64EXT=> "GLuint64EXT",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# ARB VBO introduces these.
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
sizeiptr => "GLsizeiptr",
|
|
kusano |
7d535a |
intptr => "GLintptr",
|
|
kusano |
7d535a |
sizeiptrARB => "GLsizeiptrARB",
|
|
kusano |
7d535a |
intptrARB => "GLintptrARB",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# ARB shader objects introduces these, charARB is at least 8 bits,
|
|
kusano |
7d535a |
# handleARB is at least 32 bits
|
|
kusano |
7d535a |
charARB => "GLcharARB",
|
|
kusano |
7d535a |
handleARB => "GLhandleARB",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
char => "GLchar",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# OpenGL 3.2 and GL_ARB_sync
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
int64 => "GLint64",
|
|
kusano |
7d535a |
uint64 => "GLuint64",
|
|
kusano |
7d535a |
sync => "GLsync",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# AMD_debug_output
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
DEBUGPROCAMD => "GLDEBUGPROCAMD",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# ARB_debug_output
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
DEBUGPROCARB => "GLDEBUGPROCARB",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# KHR_debug
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
DEBUGPROC => "GLDEBUGPROC",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
vdpauSurfaceNV => "GLvdpauSurfaceNV",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# GLX 1.3 defines new types which might not be available at compile time
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
#GLXFBConfig => "void*",
|
|
kusano |
7d535a |
#GLXFBConfigID => "XID",
|
|
kusano |
7d535a |
#GLXContextID => "XID",
|
|
kusano |
7d535a |
#GLXWindow => "XID",
|
|
kusano |
7d535a |
#GLXPbuffer => "XID",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# Weird stuff to some SGIX extension
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
#GLXFBConfigSGIX => "void*",
|
|
kusano |
7d535a |
#GLXFBConfigIDSGIX => "XID",
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my %voidtypemap = (
|
|
kusano |
7d535a |
void => "GLvoid",
|
|
kusano |
7d535a |
);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my %taboo_tokens = (
|
|
kusano |
7d535a |
GL_ZERO => 1,
|
|
kusano |
7d535a |
);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# list of function definitions to be ignored, unless they are being defined in
|
|
kusano |
7d535a |
# the given spec. This is an ugly hack arround the fact that people writing
|
|
kusano |
7d535a |
# spec files seem to shut down all brain activity while they are at this task.
|
|
kusano |
7d535a |
#
|
|
kusano |
7d535a |
# This will be moved to its own file eventually.
|
|
kusano |
7d535a |
#
|
|
kusano |
7d535a |
# (mem, 2003-03-19)
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my %fnc_ignore_list = (
|
|
kusano |
7d535a |
"BindProgramARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ColorSubTableEXT" => "EXT_color_subtable",
|
|
kusano |
7d535a |
"DeleteProgramsARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"GenProgramsARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"GetProgramEnvParameterdvARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"GetProgramEnvParameterfvARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"GetProgramLocalParameterdvARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"GetProgramLocalParameterfvARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"GetProgramStringARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"GetProgramivARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"IsProgramARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ProgramEnvParameter4dARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ProgramEnvParameter4dvARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ProgramEnvParameter4fARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ProgramEnvParameter4fvARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ProgramLocalParameter4dARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ProgramLocalParameter4dvARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ProgramLocalParameter4fARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ProgramLocalParameter4fvARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"ProgramStringARB" => "ARB_vertex_program",
|
|
kusano |
7d535a |
"glXCreateContextAttribsARB" => "ARB_create_context_profile",
|
|
kusano |
7d535a |
"wglCreateContextAttribsARB" => "WGL_ARB_create_context_profile",
|
|
kusano |
7d535a |
);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my %regex = (
|
|
kusano |
7d535a |
eofnc => qr/(?:\);?$|^$)/, # )$ | );$ | ^$
|
|
kusano |
7d535a |
extname => qr/^[A-Z][A-Za-z0-9_]+$/,
|
|
kusano |
7d535a |
none => qr/^\(none\)$/,
|
|
kusano |
7d535a |
function => qr/^(.+) ([a-z][a-z0-9_]*) \((.+)\)$/i,
|
|
kusano |
7d535a |
prefix => qr/^(?:[aw]?gl|glX)/, # gl | agl | wgl | glX
|
|
kusano |
7d535a |
tprefix => qr/^(?:[AW]?GL|GLX)_/, # GL_ | AGL_ | WGL_ | GLX_
|
|
kusano |
7d535a |
section => compile_regex('^(', join('|', @sections), ')$'), # sections in spec
|
|
kusano |
7d535a |
token => qr/^([A-Z0-9][A-Z0-9_x]*):?\s+((?:0x)?[0-9A-F]+)(.*)$/, # define tokens
|
|
kusano |
7d535a |
types => compile_regex('\b(', join('|', keys %typemap), ')\b'), # var types
|
|
kusano |
7d535a |
voidtype => compile_regex('\b(', keys %voidtypemap, ')\b '), # void type
|
|
kusano |
7d535a |
);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# reshapes the the function declaration from multiline to single line form
|
|
kusano |
7d535a |
sub normalize_prototype
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
local $_ = join(" ", @_);
|
|
kusano |
7d535a |
s/\s+/ /g; # multiple whitespace -> single space
|
|
kusano |
7d535a |
s/\<.*\>//g; # remove <comments> from direct state access extension</comments>
|
|
kusano |
7d535a |
s/\<.*$//g; # remove incomplete <comments> from direct state access extension</comments>
|
|
kusano |
7d535a |
s/\s*\(\s*/ \(/; # exactly one space before ( and none after
|
|
kusano |
7d535a |
s/\s*\)\s*/\)/; # no space before or after )
|
|
kusano |
7d535a |
s/\s*\*([a-zA-Z])/\* $1/; # "* identifier"
|
|
kusano |
7d535a |
s/\*wgl/\* wgl/; # "* wgl"
|
|
kusano |
7d535a |
s/\*glX/\* glX/; # "* glX"
|
|
kusano |
7d535a |
s/\.\.\./void/; # ... -> void
|
|
kusano |
7d535a |
s/;$//; # remove ; at the end of the line
|
|
kusano |
7d535a |
return $_;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# Ugly hack to work arround the fact that functions are declared in more
|
|
kusano |
7d535a |
# than one spec file.
|
|
kusano |
7d535a |
sub ignore_function($$)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
return exists($fnc_ignore_list{$_[0]}) && $fnc_ignore_list{$_[0]} ne $_[1]
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
sub parse_spec($)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
my $filename = shift;
|
|
kusano |
7d535a |
my $extname = "";
|
|
kusano |
7d535a |
my $vendortag = "";
|
|
kusano |
7d535a |
my @extnames = ();
|
|
kusano |
7d535a |
my %functions = ();
|
|
kusano |
7d535a |
my %tokens = ();
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my $section = "";
|
|
kusano |
7d535a |
my @fnc = ();
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my %proc = (
|
|
kusano |
7d535a |
"Name" => sub {
|
|
kusano |
7d535a |
if (/^([a-z0-9]+)_([a-z0-9_]+)/i)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
$extname = "$1_$2";
|
|
kusano |
7d535a |
$vendortag = $1;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
},
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
"Name Strings" => sub {
|
|
kusano |
7d535a |
# Add extension name to extension list
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# Initially use $extname if (none) specified
|
|
kusano |
7d535a |
if (/$regex{none}/)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
$_ = $extname;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
if (/$regex{extname}/)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
# prefix with "GL_" if prefix not present
|
|
kusano |
7d535a |
s/^/GL_/ unless /$regex{tprefix}/o;
|
|
kusano |
7d535a |
# Add extension name to extension list
|
|
kusano |
7d535a |
push @extnames, $_;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
},
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
"New Procedures and Functions" => sub {
|
|
kusano |
7d535a |
# if line matches end of function
|
|
kusano |
7d535a |
if (/$regex{eofnc}/)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
# add line to function declaration
|
|
kusano |
7d535a |
push @fnc, $_;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# if normalized version of function looks like a function
|
|
kusano |
7d535a |
if (normalize_prototype(@fnc) =~ /$regex{function}/)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
# get return type, name, and arguments from regex
|
|
kusano |
7d535a |
my ($return, $name, $parms) = ($1, $2, $3);
|
|
kusano |
7d535a |
if (!ignore_function($name, $extname))
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
# prefix with "gl" if prefix not present
|
|
kusano |
7d535a |
$name =~ s/^/gl/ unless $name =~ /$regex{prefix}/;
|
|
kusano |
7d535a |
# is this a pure GL function?
|
|
kusano |
7d535a |
if ($name =~ /^gl/ && $name !~ /^glX/)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
# apply typemaps
|
|
kusano |
7d535a |
$return =~ s/$regex{types}/$typemap{$1}/og;
|
|
kusano |
7d535a |
$return =~ s/void\*/GLvoid */og;
|
|
kusano |
7d535a |
$parms =~ s/$regex{types}/$typemap{$1}/og;
|
|
kusano |
7d535a |
$parms =~ s/$regex{voidtype}/$voidtypemap{$1}/og;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
# add to functions hash
|
|
kusano |
7d535a |
$functions{$name} = {
|
|
kusano |
7d535a |
rtype => $return,
|
|
kusano |
7d535a |
parms => $parms,
|
|
kusano |
7d535a |
};
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
# reset function declaration
|
|
kusano |
7d535a |
@fnc = ();
|
|
kusano |
7d535a |
} elsif ($_ ne "" and $_ ne "None") {
|
|
kusano |
7d535a |
# if not eof, add line to function declaration
|
|
kusano |
7d535a |
push @fnc, $_
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
},
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
"New Tokens" => sub {
|
|
kusano |
7d535a |
if (/$regex{token}/)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
my ($name, $value) = ($1, $2);
|
|
kusano |
7d535a |
# prefix with "GL_" if prefix not present
|
|
kusano |
7d535a |
$name =~ s/^/GL_/ unless $name =~ /$regex{tprefix}/;
|
|
kusano |
7d535a |
# Add (name, value) pair to tokens hash, unless it's taboo
|
|
kusano |
7d535a |
$tokens{$name} = $value unless exists $taboo_tokens{$name};
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
},
|
|
kusano |
7d535a |
);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# Some people can't read, the template clearly says "Name String_s_"
|
|
kusano |
7d535a |
$proc{"Name String"} = $proc{"Name Strings"};
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# Open spec file
|
|
kusano |
7d535a |
open SPEC, "<$filename" or return;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# For each line of SPEC
|
|
kusano |
7d535a |
while(<spec>)</spec>
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
# Delete trailing newline character
|
|
kusano |
7d535a |
chomp;
|
|
kusano |
7d535a |
# Remove trailing white spaces
|
|
kusano |
7d535a |
s/\s+$//;
|
|
kusano |
7d535a |
# If starts with a capital letter, it must be a new section
|
|
kusano |
7d535a |
if (/^[A-Z]/)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
# Match section name with one of the predefined names
|
|
kusano |
7d535a |
$section = /$regex{section}/o ? $1 : "default";
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
# Line is internal to a section
|
|
kusano |
7d535a |
# Remove leading whitespace
|
|
kusano |
7d535a |
s/^\s+//;
|
|
kusano |
7d535a |
# Call appropriate section processing function if it exists
|
|
kusano |
7d535a |
&{$proc{$section}} if exists $proc{$section};
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
close SPEC;
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
return ($extname, \@extnames, \%tokens, \%functions);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
#----------------------------------------------------------------------------------------
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my @speclist = ();
|
|
kusano |
7d535a |
my %extensions = ();
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my $ext_dir = shift;
|
|
kusano |
7d535a |
my $reg_http = "http://www.opengl.org/registry/specs/";
|
|
kusano |
7d535a |
#my $reg_http = "http://oss.sgi.com/projects/ogl-sample/";
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
# Take command line arguments or read list from file
|
|
kusano |
7d535a |
if (@ARGV)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
@speclist = @ARGV;
|
|
kusano |
7d535a |
} else {
|
|
kusano |
7d535a |
local $/; #???
|
|
kusano |
7d535a |
@speclist = split "\n", (<>);
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
foreach my $spec (sort @speclist)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
my ($extname, $extnames, $tokens, $functions) = parse_spec($spec);
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
foreach my $ext (@{$extnames})
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
my $info = "$ext_dir/" . $ext;
|
|
kusano |
7d535a |
open EXT, ">$info";
|
|
kusano |
7d535a |
print EXT $ext . "\n"; # Extension name
|
|
kusano |
7d535a |
my $specname = $spec;
|
|
kusano |
7d535a |
$specname =~ s/registry\///;
|
|
kusano |
7d535a |
print EXT $reg_http . $specname . "\n"; # Extension info URL
|
|
kusano |
7d535a |
print EXT $ext . "\n"; # Extension string
|
|
kusano |
7d535a |
|
|
kusano |
7d535a |
my $prefix = $ext;
|
|
kusano |
7d535a |
$prefix =~ s/^(.+?)(_.+)$/$1/;
|
|
kusano |
7d535a |
foreach my $token (sort { hex ${$tokens}{$a} <=> hex ${$tokens}{$b} } keys %{$tokens})
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
if ($token =~ /^$prefix\_.*/i)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
print EXT "\t" . $token . " " . ${\%{$tokens}}{$token} . "\n";
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
foreach my $function (sort keys %{$functions})
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
if ($function =~ /^$prefix.*/i)
|
|
kusano |
7d535a |
{
|
|
kusano |
7d535a |
print EXT "\t" . ${$functions}{$function}{rtype} . " " . $function . " (" . ${$functions}{$function}{parms} . ")" . "\n";
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
close EXT;
|
|
kusano |
7d535a |
}
|
|
kusano |
7d535a |
}
|