3
# A very simple task further complicated by the fact that some people
4
# can't read, others use legacy Operating Systems, and others don't give
5
# a damn about using a halfway decent text editor.
7
# The code to parse the _template_ is so simple and straightforward...
8
# yet the code to parse the real spec files is this mess.
11
bitfield => "GLbitfield",
12
boolean => "GLboolean",
13
# fsck up in EXT_vertex_array
14
Boolean => "GLboolean",
32
# ARB VBO introduces these
33
sizeiptrARB => "GLsizeiptrARB",
34
intptrARB => "GLintptrARB",
36
# ARB shader objects introduces these, charARB is at least 8 bits,
37
# handleARB is at least 32 bits
38
charARB => "GLcharARB",
39
handleARB => "GLhandleARB",
41
# GLX 1.3 defines new types which might not be available at compile time
42
#GLXFBConfig => "void*",
43
#GLXFBConfigID => "XID",
44
#GLXContextID => "XID",
48
# Weird stuff for some SGIX extension
49
#GLXFBConfigSGIX => "void*",
50
#GLXFBConfigIDSGIX => "XID",
57
my $section_re = qr{^[A-Z]};
58
my $function_re = qr{^(.+) ([a-z][a-z0-9_]*) \((.+)\)$}i;
59
my $token_re = qr{^([A-Z0-9][A-Z0-9_]*):?\s+((?:0x)?[0-9A-F]+)(.*)$};
60
my $prefix_re = qr{^(?:AGL | GLX | WGL)_}x;
61
my $eofnc_re = qr{ \);?$ | ^$ }x;
62
my $function_re = qr{^(.+) ([a-z][a-z0-9_]*) \((.+)\)$}i;
63
my $prefix_re = qr{^(?:gl | agl | wgl | glX)}x;
64
my $types_re = __compile_wordlist_cap(keys %typemap);
65
my $voidtype_re = __compile_wordlist_cap(keys %void_typemap);
70
my $self = { section => {} };
71
$self->{filename} = shift;
73
open(my $fh, "<$self->{filename}") or die "Can't open $self->{filename}";
76
my $s = $self->{section};
78
$content =~ s{[ \t]+$}{}mg;
79
# Join lines that end with a word-character and ones that *begin*
81
$content =~ s{(\w)\n(\w)}{$1 $2}sg;
83
foreach (split /\n/, $content)
88
s/^Name String$/Name Strings/; # Fix common mistake
92
elsif (defined $section and exists $s->{$section})
94
s{^\s+}{}mg; # Remove leading whitespace
95
$s->{$section} .= $_ . "\n";
99
$s->{$_} =~ s{(?:^\n+|\n+$)}{}s foreach keys %$s;
107
keys %{$self->{section}};
113
$self->{section}->{Name};
119
split("\n", $self->{section}->{"Name Strings"});
126
foreach (split /\n/, $self->{section}->{"New Tokens"})
128
next unless /$token_re/;
129
my ($name, $value) = ($1, $2);
130
$name =~ s{^}{GL_} unless $name =~ /$prefix_re/;
131
$tokens{$name} = $value;
143
foreach (split /\n/, $self->{section}->{"New Procedures and Functions"})
145
push @fnc, $_ unless ($_ eq "" or $_ eq "None");
147
next unless /$eofnc_re/;
149
if (__normalize_proto(@fnc) =~ /$function_re/)
151
my ($return, $name, $parms) = ($1, $2, $3);
152
if (!__ignore_function($name, $extname))
154
$name =~ s/^/gl/ unless $name =~ /$prefix_re/;
155
if ($name =~ /^gl/ && $name !~ /^glX/)
157
$return =~ s/$types_re/$typemap{$1}/g;
158
$return =~ s/$voidtype_re/$void_typemap{$1}/g;
159
$parms =~ s/$types_re/$typemap{$1}/g;
160
$parms =~ s/$voidtype_re/$void_typemap{$1}/g;
162
$functions{$name} = {
174
sub __normalize_proto
176
local $_ = join(" ", @_);
177
s/\s+/ /g; # multiple whitespace -> single space
178
s/\s*\(\s*/ \(/; # exactly one space before ( and none after
179
s/\s*\)\s*/\)/; # no after before or after )
180
s/\s*\*([a-zA-Z])/\* $1/; # "* identifier" XXX: g missing?
181
s/\*wgl/\* wgl/; # "* wgl" XXX: why doesn't the
182
s/\*glX/\* glX/; # "* glX" previous re catch this?
183
s/\.\.\./void/; # ... -> void
184
s/;$//; # remove ; at the end of the line
188
sub __ignore_function
195
my $regex = join('', @_);
199
sub __compile_wordlist_cap
201
__compile_regex('\b(', join('|', @_), ')\b');
3
# A very simple task further complicated by the fact that some people
4
# can't read, others use legacy Operating Systems, and others don't give
5
# a damn about using a halfway decent text editor.
7
# The code to parse the _template_ is so simple and straightforward...
8
# yet the code to parse the real spec files is this mess.
11
bitfield => "GLbitfield",
12
boolean => "GLboolean",
13
# fsck up in EXT_vertex_array
14
Boolean => "GLboolean",
32
# ARB VBO introduces these
33
sizeiptrARB => "GLsizeiptrARB",
34
intptrARB => "GLintptrARB",
36
# ARB shader objects introduces these, charARB is at least 8 bits,
37
# handleARB is at least 32 bits
38
charARB => "GLcharARB",
39
handleARB => "GLhandleARB",
41
# GLX 1.3 defines new types which might not be available at compile time
42
#GLXFBConfig => "void*",
43
#GLXFBConfigID => "XID",
44
#GLXContextID => "XID",
48
# Weird stuff for some SGIX extension
49
#GLXFBConfigSGIX => "void*",
50
#GLXFBConfigIDSGIX => "XID",
57
my $section_re = qr{^[A-Z]};
58
my $function_re = qr{^(.+) ([a-z][a-z0-9_]*) \((.+)\)$}i;
59
my $token_re = qr{^([A-Z0-9][A-Z0-9_]*):?\s+((?:0x)?[0-9A-F]+)(.*)$};
60
my $prefix_re = qr{^(?:AGL | GLX | WGL)_}x;
61
my $eofnc_re = qr{ \);?$ | ^$ }x;
62
my $function_re = qr{^(.+) ([a-z][a-z0-9_]*) \((.+)\)$}i;
63
my $prefix_re = qr{^(?:gl | agl | wgl | glX)}x;
64
my $types_re = __compile_wordlist_cap(keys %typemap);
65
my $voidtype_re = __compile_wordlist_cap(keys %void_typemap);
70
my $self = { section => {} };
71
$self->{filename} = shift;
73
open(my $fh, "<$self->{filename}") or die "Can't open $self->{filename}";
76
my $s = $self->{section};
78
$content =~ s{[ \t]+$}{}mg;
79
# Join lines that end with a word-character and ones that *begin*
81
$content =~ s{(\w)\n(\w)}{$1 $2}sg;
83
foreach (split /\n/, $content)
88
s/^Name String$/Name Strings/; # Fix common mistake
92
elsif (defined $section and exists $s->{$section})
94
s{^\s+}{}mg; # Remove leading whitespace
95
$s->{$section} .= $_ . "\n";
99
$s->{$_} =~ s{(?:^\n+|\n+$)}{}s foreach keys %$s;
107
keys %{$self->{section}};
113
$self->{section}->{Name};
119
split("\n", $self->{section}->{"Name Strings"});
126
foreach (split /\n/, $self->{section}->{"New Tokens"})
128
next unless /$token_re/;
129
my ($name, $value) = ($1, $2);
130
$name =~ s{^}{GL_} unless $name =~ /$prefix_re/;
131
$tokens{$name} = $value;
143
foreach (split /\n/, $self->{section}->{"New Procedures and Functions"})
145
push @fnc, $_ unless ($_ eq "" or $_ eq "None");
147
next unless /$eofnc_re/;
149
if (__normalize_proto(@fnc) =~ /$function_re/)
151
my ($return, $name, $parms) = ($1, $2, $3);
152
if (!__ignore_function($name, $extname))
154
$name =~ s/^/gl/ unless $name =~ /$prefix_re/;
155
if ($name =~ /^gl/ && $name !~ /^glX/)
157
$return =~ s/$types_re/$typemap{$1}/g;
158
$return =~ s/$voidtype_re/$void_typemap{$1}/g;
159
$parms =~ s/$types_re/$typemap{$1}/g;
160
$parms =~ s/$voidtype_re/$void_typemap{$1}/g;
162
$functions{$name} = {
174
sub __normalize_proto
176
local $_ = join(" ", @_);
177
s/\s+/ /g; # multiple whitespace -> single space
178
s/\s*\(\s*/ \(/; # exactly one space before ( and none after
179
s/\s*\)\s*/\)/; # no after before or after )
180
s/\s*\*([a-zA-Z])/\* $1/; # "* identifier" XXX: g missing?
181
s/\*wgl/\* wgl/; # "* wgl" XXX: why doesn't the
182
s/\*glX/\* glX/; # "* glX" previous re catch this?
183
s/\.\.\./void/; # ... -> void
184
s/;$//; # remove ; at the end of the line
188
sub __ignore_function
195
my $regex = join('', @_);
199
sub __compile_wordlist_cap
201
__compile_regex('\b(', join('|', @_), ')\b');