#!/usr/bin/perl -w

print "
/* Auto-generated file... Do not edit ! */

#include \"config.h\"
#include \"wine_gl.h\"

#include \"opengl_ext.h\"

";

#
# First, create a hash-table with all function defined in opengl32.spec
#
%opengl_std = ();
open(SPEC, "dlls/opengl32/opengl32.spec") || die "Could not open spec file";
foreach (<SPEC>) {
    if (($_ =~ /@/) && ($_ !~ /wgl/)) {
	($name) = ($_ =~ /stdcall (\w*)\(/);
	$opengl_std{$name} = 1;
    }
}
close(SPEC);

#
# Now, the functions from the include file
#
%opengl_ext = ();
open(INC, "/home/ulmer/OpenGL/glext_proto.h") || die "Could not open GL/glext.h";
while ($line = <INC>) {
    if ($line =~ /extern.*APIENTRY/) {
	# Start of a function declaration
	($ret, $name, $args) = ($line =~ /extern (\w*) APIENTRY *(\w*) *\((.*)\)/);
	
	# Now, remove all function already defined in opengl32.spec
	if ($opengl_std{$name}) {
	    # Do nothing as we already have these functions
	} else {
	    # Now, get the typedef name (the line after)
	    ($typedef_name) = (<INC> =~ /\(APIENTRY *\* *(\w*) *\)/);

	    # After that, parse the arguments
	    @args = split /,/, $args;
	    $args_ref = [];
	    foreach (@args) {
		push @$args_ref, $_;
	    }
	    $opengl_ext{$name} = [ $ret, $typedef_name, $args_ref ];
	}
    }
}
close(INC);

#
# After that, generate the file itself....
#
print "/* These will be filled during a wglGetProcAddress call */\n";
$num = 0;
foreach $name (sort keys(%opengl_ext)) {
    $ref = $opengl_ext{$name};
    $arg_ref = $$ref[2];
    @larg = @$arg_ref;

    print "$$ref[0] (*func_$name)(";
    $farg = shift @larg;
    print "$farg";
    foreach (@larg) {
	print ", $_";
    }    
    print ") = (void *) 0xdeadbeef;\n";
    $num++;
}
print "\n";

print "/* The function prototypes */\n";
foreach $name (sort keys(%opengl_ext)) {
    $ref = $opengl_ext{$name};
    $arg_ref = $$ref[2];
    @larg = @$arg_ref;
    print "$$ref[0] WINAPI wine_$name(";

    $farg = shift @larg;
    print "$farg";
    foreach (@larg) {
	print ", $_";
    }
    print ") ;\n";
}
print "\n";


print "/* The table giving the correspondance between names and functions */\n";
print "int extension_registry_size = $num;\n";
print "OpenGL_extension extension_registry[] = {\n";
foreach $name (sort keys(%opengl_ext)) {
    $num--;
    print "  { \"$name\", (void *) wine_$name, (void **) (&func_$name) }";
    if ($num) {
	print ",";
    }
    print "\n";
}
print "};\n";
print "\n";

print "/* Now, the function declarations */\n";
foreach $name (sort keys(%opengl_ext)) {
    $ref = $opengl_ext{$name};
    $arg_ref = $$ref[2];
    print "$$ref[0] WINAPI wine_$name(";

    $farg = shift @$arg_ref;
    $num = 0;
    if ($farg !~ /void/) {
	print "$farg arg_0";
	$num++;
	foreach (@$arg_ref) {
	    print ", $_ arg_$num";
	    $num++;
	}
    }
    print ") {\n";
    if ($$ref[0] !~ /void/) {
	print "  $$ref[0] ret;\n"
    }
    print "  ENTER_GL();\n";
    print "  ";
    if ($$ref[0] !~ /void/) {
	print "  ret = ";
    }
    print "func_$name(";
    if ($num > 0) {
	print "arg_0";
	for ($i = 1; $i < $num; $i++) {
	    print ", arg_$i";
	}
    }
    print ");\n";
    print "  LEAVE_GL();\n";
    if ($$ref[0] !~ /void/) {
	print "  return ret;\n"
    }
    print "}\n\n";
}
