~ubuntu-branches/ubuntu/utopic/sage/utopic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#! /usr/bin/perl -w

# This file generates three source files required to build sage
# This first part of this file extracts the extension names, the #defines
# and the function names. This process also creates a cutsom glext.h file 
# for use in sage The remaining parts of the file write the header and 
# code file.

# Input Filenames
$GLEXT_FILE="glext.h";
# Output Filenames
$GLEXT_SAGE_FILE="sage/sage_fptr.h";
$SAGE_HEADER_FILE="sage/sage.h";
$SAGE_CODE_FILE="sage/sage.c";
$LICENSE_FILE="templates/license";

#regular expressions
$FUNCTION_REGEXP="([A-Za-z*]*) APIENTRY ([a-zA-Z0-9]*) (.*)";
$DEFINE_REGEXP="\#define (GL_[A-Za-z0-9_]*) 1\$";
$VERSION_REGEXP="\#ifndef (GL_[A-Za-z0-9_]*)";
$TOKEN_REGEXP="\#define (GL_[A-Za-z0-9_]*)[ \t]*((0x[0-9A-F]*)\|(GL_.*))\$";
$TYPES_REGEXP="typedef ([ A-Za-z0-9_*]*)[ \t]*(GL[A-Za-z0-9_]*);";

#flag checking whether we need to add an endif or not
$WAIT_FOR_ENDIF="false";

# Open glext.h for input
open (GLEXT, "<$GLEXT_FILE") or die "Cannot open $GLEXT_FILE\n";
#loop through every line in glext.h
while (<GLEXT>) {
  if  ($_ =~ m|$VERSION_REGEXP|) {
    push(@FUNCTION_HEADER_DEF, $_); # write into header
    $WAIT_FOR_ENDIF="true"; # we now need to write a corresponding endif when its next found
  } elsif  ($_ =~ m|$TYPES_REGEXP|) {
    push(@FUNCTION_HEADER_DEF, $_); # write into header
    $WAIT_FOR_ENDIF="true"; # we now need to write a corresponding endif when its next found
  } elsif ($_ =~ m|$FUNCTION_REGEXP|) {
    ($RET, $FUNCTION, $ARGS) = ($_ =~ m|$FUNCTION_REGEXP|); # Extract function name
    $PFN_FUNCTION = "SAGE_PFN".uc($FUNCTION)."PROC"; # make the typedef name
    push(@TYPEDEFS, "typedef $RET (APIENTRYP $PFN_FUNCTION) $ARGS\n");

    push(@FUNCTION_HEADER_FPTR , "SAGEAPI $PFN_FUNCTION SAGE_$FUNCTION;\n"); # declare function for header
    push(@FUNCTION_HEADER_DEF, "#ifndef $FUNCTION\n");
    push(@FUNCTION_HEADER_DEF, "#define $FUNCTION SAGE_$FUNCTION\n");
    push(@FUNCTION_HEADER_DEF, "#endif\n\n");
#    push (@FUNCTION_CODE, "$PFN_FUNCTION SAGE_$FUNCTION = NULL;\n"); # declaraion of function in c file
    push (@FUNCTION_CODE, "$PFN_FUNCTION SAGE_$FUNCTION = ($PFN_FUNCTION)&badfunc;\n"); # declaraion of function in c file
#    push (@FUNCTION_INIT,"  SAGE_$FUNCTION = ($PFN_FUNCTION)SDL_GL_GetProcAddress(\"$FUNCTION\");\n"); # linkup function ptr 
    push (@FUNCTION_INIT,"  SAGE_$FUNCTION = ($PFN_FUNCTION)getPtr(\"$FUNCTION\");\n"); # linkup function ptr 
  # Grab #defines
  } elsif  ($_ =~ m|$DEFINE_REGEXP|) {
    ($DEF) = ($_ =~ m|$DEFINE_REGEXP|); # extract #define name
    if ($DEF =~ m|GL_VERSION|) {
      # ignore GL_VERSION for BOOLS def
    } else  {
      push (@BOOLS, $DEF);
    }
    push(@FUNCTION_HEADER_DEF, $_); # write into header
  } elsif  ($_ =~ m|$TOKEN_REGEXP|) {
    push(@FUNCTION_HEADER_DEF, $_); # write into header
  # grab endif if required
  } elsif ($_ =~ m|\#endif|) { # write the endif now we have it
    if ($WAIT_FOR_ENDIF eq "true") {
      $WAIT_FOR_ENDIF="false";
      push(@FUNCTION_HEADER_DEF, "#endif\n\n");
    }
  }
}
#copy into two arrays - we use this twice (prob a better way to do this)
for (@BOOLS) {
  push(@BOOLS_DEF, $_);
  push(@BOOLS_ENUM, $_);
}


## Begin writing output files


## This header file just contains the function pointer prototypes.
print "Writing $GLEXT_SAGE_FILE\n";
# Open our glext.h for output
open (GLEXT_SAGE, ">$GLEXT_SAGE_FILE") or die "Cannot open $GLEXT_SAGE_FILE\n";


print GLEXT_SAGE "/* This file is autogenerated by build_sage.pl */\n";
open (LICENSE, "<$LICENSE_FILE") or die "Can't open: $LICENSE_FILE\n";
while(<LICENSE>) { print GLEXT_SAGE $_; }
close LICENSE;

print GLEXT_SAGE "\n";
print GLEXT_SAGE "#ifndef GLEXT_SAGE_H\n";
print GLEXT_SAGE "#define GLEXT_SAGE_H 1\n";
print GLEXT_SAGE "\n";

print GLEXT_SAGE "#ifndef APIENTRY\n";
print GLEXT_SAGE "#define APIENTRY\n";
print GLEXT_SAGE "#endif\n\n";

print GLEXT_SAGE "#ifndef APIENTRYP\n";
print GLEXT_SAGE "#define APIENTRYP APIENTRY *\n";
print GLEXT_SAGE "#endif\n\n";

for (@TYPEDEFS) {
  print GLEXT_SAGE $_;
}

print GLEXT_SAGE "#endif\n";
close GLEXT_SAGE;

# This file contains all the definitions from glext.h
# This file is reponsible for defining the numeric constants used by applications
# to determine whether a particular extension has been found.
# This file also transparently #defines normal function names as the functio npointer
# if is not already defined. Some care needs to be taken to ensure that standard functions
# are properly guarded against by version number rather than name.

open (SAGE_HEADER, ">$SAGE_HEADER_FILE") or die "Can't open: $SAGE_HEADER_FILE\n";
print "Writing $SAGE_HEADER_FILE\n";
#Write autogen comment
print SAGE_HEADER "/* This file is autogenerated by build_sage.pl */\n";

#Write license header
open (LICENSE, "<$LICENSE_FILE") or die "Can't open: $LICENSE_FILE\n";
while(<LICENSE>) { print SAGE_HEADER $_; }
close LICENSE;
print SAGE_HEADER "\n";

# Write header check
print SAGE_HEADER "#ifndef SAGE_H\n";
print SAGE_HEADER "#define SAGE_H 1\n";
print SAGE_HEADER "\n";

print SAGE_HEADER "#ifdef __glext_h_ \n";
print SAGE_HEADER "#error glext.h has already been included.\n";
print SAGE_HEADER "#endif\n\n";

print SAGE_HEADER "#define __glext_h_ 1\n\n";

# Write defines for use in extensions array
$INDEX = 0; # Set counter to zero
for (@BOOLS_ENUM) {
  print SAGE_HEADER "#define ".uc($_)." $INDEX\n"; # write a #define
  $INDEX = $INDEX + 1; # increment counter
}
# This allows use to determine the size of the extensions array
print SAGE_HEADER "#define SAGE_LAST_EXTENSION ".$INDEX."\n\n";

#include the SAGEAPI stuff
print SAGE_HEADER "#include <sage/header.h>\n";
print SAGE_HEADER "#include <sage/GL.h>\n";
# This is required to define ptrdiff_t
print SAGE_HEADER "#include <stddef.h>\n";
#define the extensions array
print SAGE_HEADER "SAGEAPI int sage_ext[SAGE_LAST_EXTENSION];\n\n";


#print all the token definitions
for (@FUNCTION_HEADER_DEF) {
  print SAGE_HEADER $_;
}

## Include prototypes.
## By now all the OpenGL types should have been defined.
printf SAGE_HEADER "\n";
print SAGE_HEADER "#include <$GLEXT_SAGE_FILE>\n\n";
printf SAGE_HEADER "\n";

#print the function declarations and #if's generated from glext.h
for (@FUNCTION_HEADER_FPTR) {
  print SAGE_HEADER $_;
}

#add the init function prototype
print SAGE_HEADER "\nSAGEAPI int sage_init(void);\n\n";
#endif for header check
print SAGE_HEADER "#endif\n";
#close file handle
close SAGE_HEADER;

# Write the code file

#open code file for writing
open (SAGE_CODE, ">$SAGE_CODE_FILE") or die "Can't open: $SAGE_CODE_FILE\n";
print "Writing $SAGE_CODE_FILE\n";

#Write autogen comment
print SAGE_CODE "/* This file is autogenerated by build_sage.pl */\n";

#Write license header
open (LICENSE, "<$LICENSE_FILE") or die "Can't open: $LICENSE_FILE\n";
while(<LICENSE>) { print SAGE_CODE $_; }
close LICENSE;
print SAGE_CODE "\n";

#write the #includes
print SAGE_CODE "#include <$SAGE_HEADER_FILE>\n";
print SAGE_CODE "#include \"SDL.h\"\n";
print SAGE_CODE "#include <sage/utility.h>\n";
print SAGE_CODE "#include <stdlib.h>\n";
print SAGE_CODE "\n";
print SAGE_CODE "static void badfunc(void*v, ...) {\n";
print SAGE_CODE "  fprintf(stderr, \"Error: You have tried to call a sage function pointer that is NULL.\\n\");\n";
print SAGE_CODE "  fflush(stderr);\n";
print SAGE_CODE "  abort();\n";
print SAGE_CODE "}\n";
print SAGE_CODE "\n";
print SAGE_CODE "static void* getPtr(const char *func) {\n";
print SAGE_CODE "  void *p = SDL_GL_GetProcAddress(func);\n";
print SAGE_CODE "  if (p == NULL) p = &badfunc;\n";
print SAGE_CODE "  return p;\n";
print SAGE_CODE "}\n";
print SAGE_CODE "\n";

#start writing the function pointer declarations
for (@FUNCTION_CODE) {
  print SAGE_CODE $_;
}
print SAGE_CODE "\n";

# declare the extension array
print SAGE_CODE "int sage_ext[SAGE_LAST_EXTENSION];\n\n";

#start writing the init function
print SAGE_CODE "int sage_init(void) {\n";
## Gets the glExtension string each time init is called.
print SAGE_CODE "  GLubyte *ext_str = (GLubyte*)glGetString(GL_EXTENSIONS);\n";
print SAGE_CODE "  if (ext_str == NULL) {\n";
print SAGE_CODE "    fprintf(stderr, \"Sage Error: Could not get extension string\\n\");\n";
print SAGE_CODE "    return 1;\n";
print SAGE_CODE "  }\n";
## Write the code to hook up the function pointers.
for (@FUNCTION_INIT) {
  print SAGE_CODE $_;
}

# start writing the extension check code
for (@BOOLS_DEF) {
  print SAGE_CODE "  sage_ext[".uc($_)."] = isExtensionSupported(\"$_\", ext_str);\n";
}
#write closing brace for function
print SAGE_CODE "  return 0;\n";
print SAGE_CODE "}\n";
#close file handle
close SAGE_CODE;