From a245738ba4dfca86d047fec345c39c76311e49f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20Sch=C3=BCller?= Date: Tue, 22 Oct 2013 23:27:09 +0200 Subject: [PATCH] opengl32: Use opengl xml registry files. To: wine-patches@winehq.org --- dlls/opengl32/make_opengl | 436 ++++++++++++++++++++-------------------------- 1 Datei geändert, 189 Zeilen hinzugefügt(+), 247 Zeilen entfernt(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index fedf2a6..3d6d138 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -7,10 +7,8 @@ use strict; # # - It needs files from the OpenGL extension registry: # -# http://www.opengl.org/registry/api/gl.spec -# http://www.opengl.org/registry/api/gl.tm -# http://www.opengl.org/registry/api/wgl.tm -# http://www.opengl.org/registry/api/wglext.spec +# https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/api/gl.xml +# https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/api/wgl.xml # # If they are not found in the current directory the script will # attempt to download them from there. @@ -65,6 +63,8 @@ use strict; my $spec_file = "opengl32.spec"; my $norm_file = "opengl_norm.c"; my $ext_file = "opengl_ext.c"; +my $wgl_driver_file = "../../include/wine/wgl_driver.h"; +my $wgl_file = "../../include/wine/wgl.h"; # Set to 0 for removing the ENTER / LEAVE GL calls my $gen_thread_safe = 0; @@ -76,34 +76,12 @@ my $gen_traces = 1; # # List of categories to put in the 'opengl_norm.c' file # -my %cat_1_0 = ( "display-list" => 1, - "drawing" => 1, - "drawing-control" => 1, - "feedback" => 1, - "framebuf" => 1, - "misc" => 1, - "modeling" => 1, - "pixel-op" => 1, - "pixel-rw" => 1, - "state-req" => 1, - "xform" => 1, - "VERSION_1_0" => 1, - "VERSION_1_0_DEPRECATED" => 1 ); -my %cat_1_1 = ( %cat_1_0, - "VERSION_1_1" => 1, - "VERSION_1_1_DEPRECATED" => 1 ); -my %cat_1_2 = ( %cat_1_1, - "VERSION_1_2" => 1, - "VERSION_1_2_DEPRECATED" => 1 ); -my %cat_1_3 = ( %cat_1_2, - "VERSION_1_3" => 1, - "VERSION_1_3_DEPRECATED" => 1 ); -my %cat_1_4 = ( %cat_1_3, - "VERSION_1_4" => 1, - "VERSION_1_4_DEPRECATED" => 1 ); -my %cat_1_5 = ( %cat_1_4, - "VERSION_1_5" => 1, - "VERSION_1_5_DEPRECATED" => 1 ); +my %cat_1_0 = ( "GL_VERSION_1_0" => 1 ); +my %cat_1_1 = ( %cat_1_0, "GL_VERSION_1_1" => 1 ); +my %cat_1_2 = ( %cat_1_1, "GL_VERSION_1_2" => 1 ); +my %cat_1_3 = ( %cat_1_2, "GL_VERSION_1_3" => 1 ); +my %cat_1_4 = ( %cat_1_3, "GL_VERSION_1_4" => 1 ); +my %cat_1_5 = ( %cat_1_4, "GL_VERSION_1_5" => 1 ); my %norm_categories = (); @@ -117,13 +95,16 @@ my %debug_conv = "GLbyte" => "%d", "GLclampd" => "%f", "GLclampf" => "%f", + "GLclampx" => "%d", "GLdouble" => "%f", "GLenum" => "%d", "GLfloat" => "%f", + "GLfixed" => "%d", "GLint" => "%d", "GLshort" => "%d", "GLsizei" => "%d", "GLstring" => "%s", + "GLsync" => "%p", "GLubyte" => "%d", "GLuint" => "%d", "GLushort" => "%d", @@ -134,11 +115,15 @@ my %debug_conv = "GLsizeiptr" => "%ld", "GLhandleARB" => "%d", "GLcharARB" => "%c", + "GLuint64" => "%s,wine_dbgstr_longlong(%s)", + "GLuint64EXT" => "%s,wine_dbgstr_longlong(%s)", + "GLint64EXT" => "%s,wine_dbgstr_longlong(%s)", "GLvoid" => "(void)", "_GLfuncptr" => "%p", "GLDEBUGPROC" => "%p", "GLDEBUGPROCARB" => "%p", "GLDEBUGPROCAMD" => "%p", + "GLDEBUGPROCKHR" => "%p", "GLvdpauSurfaceNV" => "%ld", "int" => "%d", "unsigned int" => "%u", @@ -166,11 +151,14 @@ my %arg_conv = "GLchar" => [ "long", "char" ], "GLclampd" => [ "double", "double" ], "GLclampf" => [ "float", "float" ], + "GLclampx" => [ "long", "int" ], "GLdouble" => [ "double", "double" ], "GLenum" => [ "long", "unsigned int" ], "GLfloat" => [ "float", "float" ], + "GLfixed" => [ "long", "int" ], "GLint" => [ "long", "int" ], "GLint64" => [ "int64", "INT64" ], + "GLint64EXT" => [ "int64", "INT64" ], "GLintptr" => [ "long", "INT_PTR" ], "GLshort" => [ "long", "short" ], "GLsizei" => [ "long", "int" ], @@ -180,6 +168,7 @@ my %arg_conv = "GLubyte" => [ "long", "unsigned char" ], "GLuint" => [ "long", "unsigned int" ], "GLuint64" => [ "int64", "UINT64" ], + "GLuint64EXT" => [ "int64", "UINT64" ], "GLushort" => [ "long", "unsigned short" ], "GLvoid" => [ "void", "void" ], "GLcharARB" => [ "long", "char" ], @@ -203,15 +192,16 @@ sub ConvertType($) "GLDEBUGPROC" => "void *", "GLDEBUGPROCARB" => "void *", "GLDEBUGPROCAMD" => "void *", + "GLDEBUGPROCKHR" => "void *", "HPBUFFERARB" => "struct wgl_pbuffer *", "HPBUFFEREXT" => "struct wgl_pbuffer *", ); foreach my $org (reverse sort keys %hash) { - if ($type =~ /$org/) { - my ($before, $after) = ($type =~ /^(.*)$org(.*)$/); - return "$before$hash{$org}$after"; - } + if ($type =~ /$org/) { + my ($before, $after) = ($type =~ /^(.*)$org(.*)$/); + return "$before$hash{$org}$after"; + } } return $type; } @@ -227,10 +217,10 @@ sub ConvertVarName($) "far" => "farParam" ); foreach my $org (keys %hash) { - if ($type =~ /$org/) { - my ($before, $after) = ($type =~ /^(.*)$org(.*)$/); - return "$before$hash{$org}$after"; - } + if ($type =~ /$org/) { + my ($before, $after) = ($type =~ /^(.*)$org(.*)$/); + return "$before$hash{$org}$after"; + } } return $type; } @@ -253,22 +243,22 @@ sub GenerateThunk($$$$) # If for opengl_norm.c, generate a nice heading otherwise Patrik won't be happy :-) # Patrik says: Well I would be even happier if a (OPENGL32.@) was added as well. Done. :-) if ($comment eq 1) { - $ret = "$ret/***********************************************************************\n"; - $ret = "$ret * $name (OPENGL32.\@)\n"; - $ret = "$ret */\n"; + $ret = "$ret/***********************************************************************\n"; + $ret = "$ret * $name (OPENGL32.\@)\n"; + $ret = "$ret */\n"; } - $ret = $ret . ConvertType($func_ref->[0]) . " WINAPI $name( "; + $ret .= ConvertType($func_ref->[0]) . " WINAPI $name( "; for (my $i = 0; $i < @{$func_ref->[1]}; $i++) { - ## Quick debug code :-) - ## print $func_ref->[1]->[$i]->[1] . "\n"; - my $type = $func_ref->[1]->[$i]->[0]; - my $name = ConvertVarName($func_ref->[1]->[$i]->[1]); - $ret .= ConvertType($type) . " $name"; - $call_arg .= $name; - if ($type =~ /\*/) { - $trace_arg .= "%p"; + ## Quick debug code :-) + ## print $func_ref->[1]->[$i]->[1] . "\n"; + my $type = $func_ref->[1]->[$i]->[0]; + my $name = ConvertVarName($func_ref->[1]->[$i]->[1]); + $ret .= ConvertType($type) . " $name"; + $call_arg .= $name; + if ($type =~ /\*/) { + $trace_arg .= "%p"; $trace_call_arg .= $name; - } elsif (defined $debug_conv{$type}) { + } elsif (defined $debug_conv{$type}) { if ($debug_conv{$type} =~ /(.*),(.*)/) { $trace_arg .= $1; @@ -279,40 +269,40 @@ sub GenerateThunk($$$$) $trace_arg .= $debug_conv{$type}; $trace_call_arg .= $name; } - } - else { printf "Unknown type %s\n", $type; } - if ($i+1 < @{$func_ref->[1]}) { - $ret .= ", "; - $call_arg .= ", "; - $trace_call_arg .= ", "; - $trace_arg .= ", "; - } else { - $ret .= " "; - $call_arg .= " "; - $trace_call_arg .= " "; - } + } + else { printf "Unknown type %s\n", $type; } + if ($i+1 < @{$func_ref->[1]}) { + $ret .= ", "; + $call_arg .= ", "; + $trace_call_arg .= ", "; + $trace_arg .= ", "; + } else { + $ret .= " "; + $call_arg .= " "; + $trace_call_arg .= " "; + } } $ret .= 'void ' if (!@{$func_ref->[1]}); $ret .= ") {\n"; $ret .= " const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;\n"; if ($func_ref->[0] ne "void" && $gen_thread_safe) { - $ret = "$ret " . ConvertType($func_ref->[0]) . " ret_value;\n"; + $ret = "$ret " . ConvertType($func_ref->[0]) . " ret_value;\n"; } if ($gen_traces) { - $ret = "$ret TRACE(\"($trace_arg)\\n\""; - if ($trace_arg ne "") { - $ret .= ", $trace_call_arg"; - } - $ret = "$ret);\n"; + $ret = "$ret TRACE(\"($trace_arg)\\n\""; + if ($trace_arg ne "") { + $ret .= ", $trace_call_arg"; + } + $ret = "$ret);\n"; } if ($gen_thread_safe) { - $ret .= " ENTER_GL();\n"; + $ret .= " ENTER_GL();\n"; $ret .= " "; if ($func_ref->[0] ne "void") { $ret .= "ret_value = "; } $ret .= "funcs->$prefix.p_$name( $call_arg);\n"; - $ret .= " LEAVE_GL();\n"; + $ret .= " LEAVE_GL();\n"; if ($func_ref->[0] ne "void") { $ret .= " return ret_value;\n" } @@ -339,10 +329,10 @@ sub generate_null_func($$) $ret = "static " . ConvertType($func_ref->[0]) . " null_$name( "; for (my $i = 0; $i < @{$func_ref->[1]}; $i++) { - my $type = $func_ref->[1]->[$i]->[0]; - my $name = ConvertVarName($func_ref->[1]->[$i]->[1]); - $ret .= ConvertType($type) . " $name"; - $ret .= "," if ($i+1 < @{$func_ref->[1]}); + my $type = $func_ref->[1]->[$i]->[0]; + my $name = ConvertVarName($func_ref->[1]->[$i]->[1]); + $ret .= ConvertType($type) . " $name"; + $ret .= "," if ($i+1 < @{$func_ref->[1]}); $ret .= " "; } $ret .= 'void ' if (!@{$func_ref->[1]}); @@ -366,7 +356,7 @@ sub get_func_proto($$$) $ret .= " " . sprintf($format,$name) . "("; for (my $i = 0; $i < @{$func->[1]}; $i++) { - $ret .= ConvertType($func->[1]->[$i]->[0]); + $ret .= ConvertType($func->[1]->[$i]->[0]); $ret .= "," if ($i+1 < @{$func->[1]}); } $ret .= "void" unless @{$func->[1]}; @@ -402,42 +392,9 @@ if ($version eq "1.0") { # # Fetch the registry files # --f "gl.spec" || system "wget http://www.opengl.org/registry/api/gl.spec" || die "cannot download gl.spec"; --f "gl.tm" || system "wget http://www.opengl.org/registry/api/gl.tm" || die "cannot download gl.tm"; --f "wgl.tm" || system "wget http://www.opengl.org/registry/api/wgl.tm" || die "cannot download wgl.tm"; --f "wglext.spec" || system "wget http://www.opengl.org/registry/api/wglext.spec" || die "cannot download wglext.spec"; --f "enum.spec" || system "wget http://www.opengl.org/registry/api/enum.spec" || die "cannot download enum.spec"; --f "enumext.spec" || system "wget http://www.opengl.org/registry/api/enumext.spec" || die "cannot download enumext.spec"; +-f "gl.xml" || system "wget https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/api/gl.xml" || die "cannot download gl.xml"; +-f "wgl.xml" || system "wget https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/api/wgl.xml" || die "cannot download wgl.xml"; -# -# First, create a mapping between the pseudo types used in the spec file -# and OpenGL types using the 'gl.tm' file. -# -my %pseudo_to_opengl = (); - -sub load_types($) -{ - my $file = shift; - open TYPES, "<$file" or die "Could not open $file"; - while (my $line = ) { - if ($line !~ /\w*\#/) { - my ($pseudo, $opengl) = ($line =~ /(\w*),\*,\*,\s*(.*),\*,\*/); - $pseudo_to_opengl{$pseudo} = $opengl; - } - } - close TYPES; -} - -load_types( "wgl.tm" ); -load_types( "gl.tm" ); - -# This is to override the 'void' -> '*' bogus conversion -$pseudo_to_opengl{"void"} = "void"; -$pseudo_to_opengl{"sync"} = "GLvoid*"; -$pseudo_to_opengl{"Int64"} = "INT64"; -$pseudo_to_opengl{"UInt64"} = "UINT64"; -$pseudo_to_opengl{"Int64EXT"} = "INT64"; -$pseudo_to_opengl{"UInt64EXT"} = "UINT64"; # # Then, create the list of all OpenGL functions using the 'gl.spec' @@ -645,138 +602,126 @@ my %supported_wgl_extensions = "WGL_WINE_pixel_format_passthrough" => 1, ); -sub parse_registry_file($) +my %enums = (); + +sub parse_variable($) { - my $file = shift; - my @arg_names; - my %arg_types; - open REGISTRY, "<$file" or die "cannot open $file"; - while (my $line = ) { - next unless ($line =~ /^\w*\(.*\)/); - - # Get the function name (NOTE: the 'gl' prefix needs to be added later) - my ($funcname, $args) = ($line =~ /^(\w*)\((.*)\)/); - # and the argument names - @arg_names = split /\s*,\s*/, $args; - - # After get : - # - the return type - # - category (the extension the function is part of) - # - the argument types - # - the category the function belongs - %arg_types = (); - my $category = ""; - my $ret_type = ""; - while (1) { - $line = ; - unless (defined($line)) { - last; - } elsif ($line =~ /^\s*$/) { - if (($category eq "") || ($ret_type eq "")) { - die "Missing 'category' line in function $funcname.\n"; - } - last; - } elsif ($line =~ /\t*return\t+(\w*)/) { - ($ret_type) = ($line =~ /\t*return\s*(\w*)/); - $ret_type = $pseudo_to_opengl{$ret_type}; - unless (defined($ret_type)) { - die "Unsupported return type in function $funcname\n"; - } - } elsif ($line =~ /^\t*category/) { - ($category) = ($line =~ /^\t*category\s*([\w-]*)/); - } elsif ($line =~ /^\t*param/) { - my ($name, $base_type, $dir, $ext) = ($line =~ /\t*param\s*(\w*)\s*(\w*) (in|out)\s+(.*)/); - my $ptr = 0; - unless (defined($name)) { - chomp $line; - die "Broken spec file line $line in function $funcname\n"; - } - - if ($ext =~ /array/) { - # This is a pointer - $ptr = 1; - } elsif ($ext =~ /reference/) { - # This is a pointer - $ptr = 1; - } elsif ($ext =~ /value/) { - # And this a 'normal' value - $ptr = 0; - } else { - chomp $line; - die "Unsupported type : $line in function $funcname\n"; - } - # Get the 'real' type and append a '*' in case of a pointer - my $type = $pseudo_to_opengl{$base_type}; - unless (defined($type)) { - chomp $line; - die "Unsupported return type in function $funcname for type $base_type (line $line)\n"; - } - if ($ptr) { - $type .= "*"; - $type = "const $type" if $dir eq "in"; - } - - $arg_types{$name} = $type; - } - } - - # Now, build the argument reference - my $arg_ref = [ ]; - for (my $i = 0; $i < @arg_names; $i++) { - unless (defined($arg_types{$arg_names[$i]})) { - print "@arg_names\n"; - foreach (sort keys %arg_types) { - print "$_ => $arg_types{$_}\n"; - } - die "Undefined type for $arg_names[$i] in function $funcname\n"; - } - - push @$arg_ref, [ $arg_types{$arg_names[$i]}, $arg_names[$i] ]; - } - - # Now, put in one or the other hash table - if ($norm_categories{$category}) { - $norm_functions{"gl$funcname"} = [ $ret_type, $arg_ref ]; - } elsif ($file =~ /^wgl/) { - if (defined $supported_wgl_extensions{"WGL_$category"}) { - $ext_functions{"wgl$funcname"} = [ $ret_type, $arg_ref, "WGL_$category" ]; + my $p = shift; + my $ptype = ''; + my $pname = ''; + my $pnamebefore = ''; + my $pnameafter = ''; + + while (my ($k, $v) = each($p)){ + if ($k eq 'ptype') { + $ptype = ${$v}[0]; + } elsif ($k eq 'name') { + $pname = ${$v}[0]; + } elsif ($k eq 'content') { + if (ref($v) eq 'ARRAY') { + my @n = @{$v}; + $pnamebefore = $n[0]; + $pnameafter = $n[1] if (@n > 0); + } else { + $pnameafter = $v; } - } else { - $ext_functions{"gl$funcname"} = [ $ret_type, $arg_ref, "GL_$category" ]; - } + } } - close REGISTRY; + $ptype = $pnamebefore . $ptype . $pnameafter; + $ptype =~ s/ \*/\*/g; + $ptype =~ s/ $//g; + return [ $ptype, $pname ]; } sub parse_enum_file($$) { - my ($file, $enums) = @_; - open FILE, "<$file" or die "cannot open $file"; - while () + my ($file, $generate_enums) = @_; + + use XML::Simple; + my $xml = new XML::Simple; + my $data = $xml->XMLin($file, ForceArray => 1); + + my %functions; + + # save all functions + for my $command ( @{${$data->{commands}}[0]->{'command'}} ) { + my $name = ''; + my $ret = ''; + my $params = []; + my @alias = ''; + + while (my ($k, $v) = each($command)){ + if ($k eq 'param') { + push(@$params, parse_variable($_)) for (@{$v}); + } elsif ($k eq 'proto') { + ($ret, $name) = @{parse_variable(${$v}[0])}; + } elsif ($k eq 'alias') { + @alias = keys $v; + } + } + + $functions{$name} = [ $ret, $params ]; + $functions{$_} = [ $ret, $params ] for ( @alias ); + } + + # save all enums from gl.xml, we don't need the ones from wgl + if ($generate_enums) { - chomp; - next if /^#/; - if (/^\t([0-9A-Z_]+)\s*=\s*(((0x[0-9A-Fa-f]+)|([0-9]+))([uUlL]+)?)/) - { - ${$enums}{"GL_$1"} = $2; - next; + for my $enum ( @{$data->{'enums'}} ) { + if (ref($enum->{'enum'}) eq "HASH") { + while (my ($k, $v) = each($enum->{'enum'})){ + $enums{$k} = $v->{'value'}; + } + } } } - close FILE; -} -parse_registry_file( "gl.spec" ); -parse_registry_file( "wglext.spec" ); + # generate norm functions, functions in newer gl versions are saved as extensions + while (my ($k, $v) = each($data->{feature})) { + if ($norm_categories{$k}) { + for(keys %{${$v->{require}}[0]->{command}}) { + $norm_functions{$_} = $functions{$_}; + } + } else { + # only gl or also gles? + if ($v->{api} eq "gl") { + for (keys %{${$v->{require}}[0]->{command}}) { + $ext_functions{$_} = [$functions{$_}[0], $functions{$_}[1], $k]; + } + } + } + } -my %enums = (); -parse_enum_file( "enum.spec", \%enums ); -parse_enum_file( "enumext.spec", \%enums ); + # generate extension functions + while (my ($k, $v) = each(${$data->{extensions}}[0]->{extension})) { + # only gl or also gles? + if ($v->{supported} =~ /^gl(\||$)/) { + for my $extension (@{$v->{require}}) { + for (keys %{$extension->{command}}) { + if (!$ext_functions{$_} && !$norm_functions{$_}) { + $ext_functions{$_} = [$functions{$_}[0], $functions{$_}[1], $k]; + } + } + } + } + elsif ($v->{supported} =~ /^wgl$/) { + for (keys %{${$v->{require}}[0]->{command}}) { + if (defined $supported_wgl_extensions{$k}) { + $ext_functions{$_} = [ $functions{$_}[0], $functions{$_}[1], $k ]; + } + } + } + } +} + +parse_enum_file( "gl.xml", 1 ); +parse_enum_file( "wgl.xml", 0 ); # # Get the current wgl_driver.h version # my $wgl_version = 0; -open HEADER, "<../../include/wine/wgl_driver.h" or die "cannot open wgl_driver.h"; +open HEADER, "<$wgl_driver_file" or die "cannot open $wgl_driver_file"; while (
) { next unless /^#define WINE_WGL_DRIVER_VERSION (\d+)/; @@ -788,8 +733,8 @@ close HEADER; # # Generate the wgl_driver.h file # -open HEADER, ">../../include/wine/wgl_driver.h" or die "cannot create wgl_driver.h"; -print HEADER "/* Automatically generated from http://www.opengl.org/registry/api files; DO NOT EDIT! */\n\n"; +open HEADER, ">$wgl_driver_file" or die "cannot create $wgl_driver_file"; +print HEADER "/* Auto-generated file... Do not edit ! */\n\n"; print HEADER "#ifndef __WINE_WGL_DRIVER_H\n"; print HEADER "#define __WINE_WGL_DRIVER_H\n\n"; print HEADER "#ifndef WINE_GLAPI\n"; @@ -841,8 +786,8 @@ close HEADER; # # Generate the wgl.h file # -open HEADER, ">../../include/wine/wgl.h" or die "cannot create wgl.h"; -print HEADER "/* Automatically generated from http://www.opengl.org/registry/api files; DO NOT EDIT! */\n\n"; +open HEADER, ">$wgl_file" or die "cannot create $wgl_file"; +print HEADER "/* Auto-generated file... Do not edit ! */\n\n"; print HEADER "#ifndef __WINE_WGL_H\n"; print HEADER "#define __WINE_WGL_H\n\n"; @@ -875,19 +820,19 @@ close HEADER; # # Now, generate the output files. First, the spec file. # -open(SPEC, ">$spec_file"); +open(SPEC, ">$spec_file") or die "cannot create $spec_file"; foreach (sort keys %norm_functions) { my $args=" "; for (my $i = 0; $i < @{$norm_functions{$_}->[1]}; $i++) { - my $type = $norm_functions{$_}->[1]->[$i]->[0]; - if ($type =~ /\*/) { - $args .= "ptr "; - } elsif (defined($arg_conv{$type})) { - $args .= "$@$arg_conv{$type}[0] "; - } else { - die "No conversion for GL type $type...\n"; - } + my $type = $norm_functions{$_}->[1]->[$i]->[0]; + if ($type =~ /\*/) { + $args .= "ptr "; + } elsif (defined($arg_conv{$type})) { + $args .= "$@$arg_conv{$type}[0] "; + } else { + die "No conversion for GL type $type...\n"; + } } $args = substr($args,1,-1); print SPEC "@ stdcall $_($args)\n"; @@ -924,7 +869,7 @@ close(SPEC); # # After the spec file, the opengl_norm.c file # -open(NORM, ">$norm_file"); +open(NORM, ">$norm_file") or die "cannot create $norm_file"; print NORM " /* Auto-generated file... Do not edit ! */ @@ -967,7 +912,7 @@ close(NORM); # # Finally, more complex, the opengl_ext.c file # -open(EXT, ">$ext_file"); +open(EXT, ">$ext_file") or die "cannot create $ext_file"; print EXT " /* Auto-generated file... Do not edit ! */ @@ -1000,10 +945,7 @@ my $i = 0; foreach (sort keys %ext_functions) { my $func_ref = $ext_functions{$_}; print EXT " { \"$_\", \"$func_ref->[2]\", $_ }"; - if ($i != $count-1) { - print EXT ","; - } - $i++; + print EXT "," if ($i++ != $count-1); print EXT "\n"; } print EXT "};\n"; -- 1.7.11.7