Jason McKesson avatar Jason McKesson committed e6d0a54

glLoadGen now a part of the SDK.
With documentation.
glLoad is a component of glLoadGen now.

Comments (0)

Files changed (8)

 \li @ref module_glm "OpenGL Mathematics": Provides useful math classes and functions for OpenGL, using a GLSL-like syntax.
 \li @ref module_glfw "GLFW": A tool for creating and managing an OpenGL window. It can be used to handle input.
 \li @ref module_freeglut "FreeGLUT": A tool for creating and managing an OpenGL window. It can be used to handle input, as well as render a few basic shapes.
+\li @ref module_glloadgen "OpenGL Loader Generator": A tool for generating OpenGL loader code.
 
 The SDK also comes with a number of examples, which are in the <tt>examples</tt> directory.
 

docs/modules.doxy

 **/
 
 /**
+\defgroup module_glloadgen OpenGL Loader Generator
+
+The \ref module_glload "GL Load" module is a very useful tool for loading OpenGL functions. However, it loads all of them. While it does have nice headers that provide only the functions in a specific version, even those headers have clutter because it still provides all of the extensions. Even if you don't use them.
+
+The <a href="https://bitbucket.org/alfonse/glloadgen/wiki/Home">OpenGL Loader Generator</a> is a tool to avoid this. You specify on the command-line (or in files) exactly which extensions you want and what version you want to use. And the files generated will only provide enumerators and functions for those specific extensions and versions.
+
+It is a Lua-based tool, so you will need Lua installed (it is a fast install, as the Lua runtime is very tiny). The <a href="https://bitbucket.org/alfonse/glloadgen/wiki/Command_Line_Options">manual for it</a> is quite complete.
+
+The code generation system is so flexible that it is now used to generate GL Load's headers and source itself.
+**/
+
+/**
 \defgroup module_troubleshooting Troubleshooting
 
 @section trouble_headers Header Inclusion Order

get_externals.lua

 		"",	--If the zip file has a base directory, then name it here. If it doesn't, then just use ""
 		[[https://downloads.sourceforge.net/project/ogl-math/glm-0.9.4.0/glm-0.9.4.0.7z?r=&ts=1354407389&use_mirror=iweb]]
 	},
+
+	{
+		"glLoadGen 1.0.3",	--The name of the component.
+		"glloadgen",		--The output directory to copy the component's data.
+		"glloadgen.7z",		--The filename that will be created in the download director.
+		"glLoadGen_1_0_3",	--If the zip file has a base directory, then name it here. If it doesn't, then just use ""
+		[[https://sourceforge.net/projects/glsdk/files/glLoadGen/glLoadGen_1_0_3.7z/download?use_mirror=superb-dca2]]
+	},
 }
 
 local zipFullName = FindFileInPath("7z.exe");

glloadgen/modules/StructGLLoad.lua

+
+local struct = require "Structure"
+
+--Common set of header stuff.
+local common_ext_struct =
+{ type="group",
+	{ type="filter", name="EnumsPerExtInGroup", optional=true, cond="enum-iter",
+		{ type="enum-iter",
+			{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen_)", },
+			{ type="call", name="UpdateEnumSeen(enumSeen_, enum, extName)" },
+		},
+		{ type="blank", cond="enum-iter"},
+	},
+	{ type="block", name="FuncTypedefs(hFile, spec, options)", optional=true, cond="func-iter",
+		{ type="func-iter",
+			{ type="write", name="FuncTypedef(hFile, func, typemap, spec, options)", },
+		},
+	},
+	{ type="blank", cond="func-iter"},
+	{ type="func-iter",
+		{ type="write", name="FuncDecl(hFile, func, typemap, spec, options)", },
+	},
+	{ type="blank", cond="func-iter"},
+}
+
+--Extension file.
+local ext_file_struct =
+{ type="file", style="ext_hdr", name="GetFilename(basename, spec, options)",
+	{ type="block", name="IncludeGuard",
+		{ type="blank"},
+		{ type="write", name="Typedefs(hFile, specData, spec, options)",},
+		{ type="blank"},
+		{ type="block", name="Extern(hFile, spec, options)",
+			{ type="block", name="ExtVariables(hFile, spec, options)", optional=true,
+				{ type="ext-iter",
+					{ type="write", name="ExtVariable(hFile, extName, spec, options)" },
+				},
+			},
+			{ type="blank"},
+			{ type="filter", name="EnumsAllAtOnce", optional=true,
+				{ type="block", name="Enumerators(hFile, spec, options)",
+					{ type="ext-iter",
+						{ type="enum-iter",
+							{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen_)", },
+							{ type="call", name="UpdateEnumSeen(enumSeen_, enum, extName)" },
+						},
+					},
+				},
+				{ type="blank"},
+			},
+
+			{ type="ext-iter",
+				common_ext_struct,
+			},
+		},
+	},
+}
+
+local decl_header_struct =
+{ type="group",
+-- Internal header files.
+{ type="context", key="enumSeen_", name="EnumSeen",
+{ type="func-seen",
+	--Write the type header file.
+	{ type="file", style="type_hdr", name="GetFilename(basename, spec, options)",
+		{ type="block", name="IncludeGuard(hFile, spec, options)",
+			{ type="write", name="Init(hFile, spec, options)"},
+			{ type="write", name="StdTypedefs(hFile, spec, options)"},
+			{ type="write", name="PassthruTypedefs(hFile, specData, spec, options)"},
+		},
+	},
+	
+	--Write the extension file
+	ext_file_struct,
+	
+	--For each version, write files containing just the core declarations.
+	{ type="version-iter",
+		{ type="filter", name="VersionHasCore(version, specData, spec, options)",
+			{ type="file", style="core_hdr", name="GetFilename(basename, version, spec, options)",
+				{ type="block", name="IncludeGuard(hFile, version, spec, options)",
+					{ type="blank"},
+					{ type="block", name="Extern(hFile, spec, options)",
+						{ type="filter", name="VersionHasCoreEnums(version, specData, spec, options)",
+							{ type="block", name="Enumerators(hFile, spec, options)", optional=true,
+								{ type="enum-iter",
+									{ type="filter", name="CoreEnum(enum)",
+										{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen_)", },
+										{ type="call", name="UpdateEnumSeen(enumSeen_, enum, version)" },
+									},
+								},
+							},
+							{ type="blank", cond="enum-iter"},
+						},
+						{ type="block", name="FuncTypedefs(hFile, spec, options)", optional=true, cond="func-iter",
+							{ type="func-iter",
+								{ type="filter", name="CoreFunc(func)",
+									{ type="write", name="FuncTypedef(hFile, func, typemap, spec, options)", },
+								},
+							},
+						},
+						{ type="blank", cond="func-iter"},
+						{ type="func-iter",
+							{ type="filter", name="CoreFunc(func)",
+								{ type="write", name="FuncDecl(hFile, func, typemap, spec, options)", },
+							},
+						},
+						{ type="blank", cond="func-iter"},
+					},
+				},
+			},
+		},
+	},
+	
+	--For each version, write files containing core declarations that were removed.
+	{ type="version-iter",
+		{ type="filter", name="VersionHasRemoved(version, specData, spec, options)",
+			{ type="file", style="core_hdr", name="GetFilenameRem(basename, version, spec, options)",
+				{ type="block", name="IncludeGuardRem(hFile, version, spec, options)",
+					{ type="blank"},
+					{ type="block", name="Extern(hFile, spec, options)",
+						{ type="filter", name="VersionHasCompEnums(version, specData, spec, options)",
+							{ type="block", name="Enumerators(hFile, spec, options)", optional=true,
+								{ type="enum-iter",
+									{ type="filter", name="CompEnum(enum)",
+										{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen_)", },
+										{ type="call", name="UpdateEnumSeen(enumSeen_, enum, version)" },
+									},
+								},
+							},
+						},
+						{ type="blank", cond="enum-iter"},
+						{ type="block", name="FuncTypedefs(hFile, spec, options)", optional=true, cond="func-iter",
+							{ type="func-iter",
+								{ type="filter", name="CompFunc(func)",
+									{ type="write", name="FuncTypedef(hFile, func, typemap, spec, options)", },
+								},
+							},
+						},
+						{ type="blank", cond="func-iter"},
+						{ type="func-iter",
+							{ type="filter", name="CompFunc(func)",
+								{ type="write", name="FuncDecl(hFile, func, typemap, spec, options)", },
+							},
+						},
+						{ type="blank", cond="func-iter"},
+					},
+				},
+			},
+		},
+	},
+},
+},
+
+}
+
+
+local include_header_struct =
+{ type="group",
+	--Main header files.
+	{ type="version-iter",
+		{ type="file", style="incl_hdr", name="VersionFilenameCore(basename, version, spec, options)",
+			{ type="block", name="IncludeGuardVersionCore(hFile, version, spec, options)",
+				{ type="blank" },
+				{ type="write", name="IncludeIntType(hFile, spec, options)"},
+				{ type="write", name="IncludeIntExts(hFile, spec, options)"},
+				{ type="blank" },
+				{ type="sub-version-iter",
+					{ type="write", name="IncludeIntVersionCore(hFile, sub_version, specData, spec, options)"},
+				},
+			},
+		},
+	},
+
+	--Compatibility headers.
+	{ type="version-iter",
+		{ type="filter", name="VersionHasCompProfile(version)",
+			{ type="file", style="incl_hdr", name="VersionFilenameComp(basename, version, spec, options)",
+				{ type="block", name="IncludeGuardVersionComp(hFile, version, spec, options)",
+					{ type="blank" },
+					{ type="write", name="IncludeIntType(hFile, spec, options)"},
+					{ type="write", name="IncludeIntExts(hFile, spec, options)"},
+					{ type="blank" },
+					{ type="sub-version-iter",
+						{ type="write", name="IncludeIntVersionCore(hFile, sub_version, specData, spec, options)"},
+						{ type="write", name="IncludeIntVersionComp(hFile, sub_version, specData, spec, options)"},
+					},
+				},
+			},
+		},
+	},
+
+	--Header that includes everything.
+	{ type="file", style="incl_hdr", name="AllFilename(basename, spec, options)",
+		{ type="block", name="IncludeGuardAll(hFile, spec, options)",
+			{ type="blank" },
+			{ type="write", name="IncludeIntType(hFile, spec, options)"},
+			{ type="write", name="IncludeIntExts(hFile, spec, options)"},
+			{ type="blank" },
+			{ type="version-iter",
+				{ type="write", name="IncludeIntVersionCore(hFile, version, specData, spec, options)"},
+				{ type="write", name="IncludeIntVersionComp(hFile, version, specData, spec, options)"},
+			},
+		},
+	},
+
+	--Header that includes only core.
+	{ type="file", style="incl_hdr", name="CoreFilename(basename, spec, options)", cond="version-iter",
+		{ type="block", name="IncludeGuardCore(hFile, spec, options)",
+			{ type="blank" },
+			{ type="write", name="IncludeIntType(hFile, spec, options)"},
+			{ type="write", name="IncludeIntExts(hFile, spec, options)"},
+			{ type="blank" },
+			{ type="version-iter",
+				{ type="write", name="IncludeIntVersionCore(hFile, version, specData, spec, options)"},
+			},
+		},
+	},
+}
+
+
+local function CoreLoaderStruct(funcFilter)
+	return
+	{ type="group",
+		{ type="core-ext-iter",
+			{ type="func-iter",
+				{ type="filter", name= funcFilter .. "(func)",
+					{ type="write", name="LoadFunctionCore(hFile, func, typemap, spec, options)", },
+				},
+			},
+		},
+		{ type="func-iter",
+			{ type="filter", name=funcFilter .. "(func)",
+				{ type="write", name="LoadFunctionCore(hFile, func, typemap, spec, options)", },
+			},
+		},
+	}
+end
+
+
+local source_c_struct = 
+{ type="group",
+	{ type="write", name="Includes(hFile, spec, options)" },
+	{ type="blank"},
+	{ type="write", name="PointerLoading(hFile, specData, spec, options)" },
+	{ type="blank"},
+	{ type="ext-iter",
+		{ type="write", name="ExtVariable(hFile, extName, spec, options)" },
+	},
+	{ type="blank"},
+	{ type="func-seen",
+		--Write the extension functions and ext loaders.
+		{ type="ext-iter",
+			{ type="func-iter",
+				{ type="write", name="FuncDef(hFile, func, typemap, spec, options)", },
+			},
+			{ type="blank", cond="func-iter"},
+			{ type="block", name="LoadExtensionFuncs(hFile, extName, spec, options)", cond="func-iter",
+				{ type="func-iter",
+					{ type="write", name="LoadFunction(hFile, func, typemap, spec, options)", },
+				},
+			},
+			{ type="blank", cond="func-iter"},
+		},
+		{ type="blank"},
+		--Write the core functions (not already written) and the individual core loaders.
+		{ type="version-iter",
+			{ type="func-iter",
+				{ type="write", name="FuncDefCond(hFile, func, typemap, spec, options, funcSeen)", },
+			},
+		},
+		{ type="blank", cond="version-iter"},
+		{ type="version-iter",
+			{ type="filter", name="VersionHasCoreFuncs(version, specData, spec, options)",
+				{ type="block", name="LoadCoreFuncs(hFile, version, spec, options)",
+					CoreLoaderStruct("CoreFunc"),
+
+				},
+				{ type="blank"},
+			},
+			{ type="filter", name="VersionHasCompFuncs(version, specData, spec, options)",
+				{ type="block", name="LoadCoreFuncsComp(hFile, version, spec, options)",
+					CoreLoaderStruct("CompFunc"),
+				},
+			},
+		},
+		{ type="blank", cond="version-iter"},
+	},
+	
+	--Write the aggregate core loaders (ie: load all for version X and below)
+	{ type="version-iter",
+		{ type="block", name="LoadAllCoreFunc(hFile, version, spec, options)",
+			{ type="sub-version-iter",
+				{ type="filter", name="VersionHasCoreFuncs(sub_version, specData, spec, options)",
+					{ type="write", name="CallCoreLoad(hFile, sub_version, spec, options)" },
+				},
+				{ type="filter", name="VersionHasCompProfile(version)", neg=true,
+					{ type="filter", name="VersionHasCompFuncs(sub_version, specData, spec, options)",
+						{ type="write", name="CallCoreCompLoad(hFile, sub_version, spec, options)" },
+					},
+				},
+			},
+		},
+		{ type="blank" },
+		{ type="filter", name="VersionHasCompProfile(version)",
+			{ type="block", name="LoadAllCoreCompFunc(hFile, version, spec, options)",
+				{ type="sub-version-iter",
+					{ type="filter", name="VersionHasCoreFuncs(sub_version, specData, spec, options)",
+						{ type="write", name="CallCoreLoad(hFile, sub_version, spec, options)" },
+					},
+					{ type="filter", name="VersionHasCompFuncs(sub_version, specData, spec, options)",
+						{ type="write", name="CallCoreCompLoad(hFile, sub_version, spec, options)" },
+					},
+				},
+			},
+			{ type="blank" },
+		},
+	},
+
+	--Write the main loading function.
+	{ type="write", name="MainLoadPrelim(hFile, specData, spec, options)", },
+	{ type="blank", },
+	{ type="write", name="MainLoader(hFile, specData, spec, options)", },
+	{ type="blank", },
+	{ type="write", name="MainExtraFuncs(hFile, specData, spec, options)", cond="version-iter" },
+}
+
+local source_cpp_struct = 
+{ type="group",
+	--includes
+	{ type="write", name="Includes(hFile, spec, options)", },
+	{ type="blank", },
+
+	{ type="block", name="ExternC(hFile, spec, options)",
+		{ type="ext-iter",
+			{ type="write", name="CExtVarDecl(hFile, extName, spec, options)"},
+		},
+		{ type="blank", },
+		{ type="ext-iter",
+			{ type="func-iter",
+				{ type="write", name="CFuncDecl(hFile, func, typemap, spec, options)"},
+			},
+		},
+		{ type="version-iter",
+			{ type="func-iter",
+				{ type="write", name="CFuncDecl(hFile, func, typemap, spec, options)"},
+			},
+		},
+		{ type="blank", },
+		{ type="write", name="CLoaderFunc(hFile, spec, options)", },
+		{ type="blank", },
+		{ type="write", name="CExtraFuncs(hFile, spec, options)", cond="version-iter"},
+		{ type="blank", cond="version-iter" },
+	},
+	{ type="blank", },
+	{ type="block", name="Definitions(hFile, spec, options)",
+		--define extension variables
+		{ type="block", name="ExtVariables(hFile, spec, options)",
+			{ type="ext-iter",
+				{ type="write", name="ExtVariable(hFile, extName, spec, options)"},
+			},
+		},
+		{ type="blank", },
+		
+		--define pointers
+		{ type="ext-iter",
+			{ type="func-iter",
+				{ type="write", name="FuncDef(hFile, func, typemap, spec, options)"},
+				{type="blank", last=true, },
+			},
+		},
+		
+		{ type="version-iter",
+			{ type="func-iter",
+				{ type="write", name="FuncDef(hFile, func, typemap, spec, options)"},
+				{type="blank", last=true, },
+			},
+		},
+		
+		--function to copy variables from C-version
+		{ type="block", name="CopyExtVariables(hFile, spec, options)",
+			{ type="ext-iter",
+				{ type="write", name="CopyExtVariable(hFile, extName, spec, options)"},
+			},
+		},
+		{ type="blank", },
+		
+		--function to copy pointers from C-version
+		{ type="block", name="CopyFunctionPtrs(hFile, spec, options)",
+			{ type="ext-iter",
+				{ type="func-iter",
+					{ type="write", name="CopyFunctionPtr(hFile, func, typemap, spec, options)"},
+				},
+			},
+			
+			{ type="version-iter",
+				{ type="func-iter",
+					{ type="write", name="CopyFunctionPtr(hFile, func, typemap, spec, options)"},
+				},
+			},
+		},
+		{ type="blank", },
+	},
+	--Loaders et. al.
+	{type="write", name="CopierC(hFile, specData, spec, options)", },
+	{ type="blank", },
+
+	{ type="block", name="SystemDefs(hFile, spec, options)",
+		{ type="write", name="MainLoader(hFile, specData, spec, options)", },
+		{ type="blank", },
+		{ type="write", name="MainExtraFuncs(hFile, specData, spec, options)", cond="version-iter" },
+	},
+}
+
+local my_struct =
+{
+	{ type="group",
+		decl_header_struct,
+		
+		include_header_struct,
+		
+		--Header to load things.
+		{ type="file", style="load_hdr", name="GetFilename(basename, spec, options)",
+			{ type="block", name="IncludeGuard(hFile, spec, options)",
+				{ type="write", name="LoaderDecl(hFile, spec, options)" },
+			}
+		},
+		
+		--Source file.
+		{ type="file", style="source", name="GetFilename(basename, spec, options)",
+			source_c_struct,
+		},
+	},
+	
+	{ type="group", style="cpp",
+		{ type="file", name="GetFilename(basename, spec, options)", style="load_test",
+			{ type="block", name="IncludeGuard(hFile, spec, options)",
+				{ type="write", name="LoadTest(hFile, spec, options)", },
+			},
+		},
+
+		decl_header_struct,
+		
+		include_header_struct,
+		
+		--Header to load things.
+		{ type="file", style="load_hdr", name="GetFilename(basename, spec, options)",
+			{ type="block", name="IncludeGuard(hFile, spec, options)",
+				{ type="write", name="LoaderDecl(hFile, spec, options)" },
+			}
+		},
+		
+		--Source file.
+		{ type="file", style="source", name="GetFilename(basename, spec, options)",
+			source_cpp_struct,
+		},
+	},
+}
+
+
+my_struct = struct.BuildStructure(my_struct)
+
+return my_struct

glloadgen/modules/StyleGLLoad.lua

+local util = require "util"
+local struct = require "StructGLLoad"
+local common = require "CommonStyle"
+local glload = require "glload_util"
+local glload_c = require "glload_util"
+
+local my_style
+
+
+----------------------------------------------------------
+-- Type header.
+local type_hdr = {}
+
+function type_hdr.GetFilename(basename, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory .. glload.GetTypeHeaderBasename(spec, options)
+end
+
+glload.CreateIncludeGuardWriters(type_hdr, "IncludeGuard",
+	function(...) return glload.GetTypeHdrFileIncludeGuard(...) end)
+
+function type_hdr.WriteInit(hFile, spec, options)
+	hFile:rawwrite(spec.GetHeaderInit())
+end
+
+function type_hdr.WriteStdTypedefs(hFile, spec, options)
+	local defArray = common.GetStdTypedefs()
+	
+	--Use include-guards for the typedefs, since they're common among
+	--headers in this style.
+	hFile:write("#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS\n")
+	hFile:write("#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS\n")
+	hFile:write("\n")
+	hFile:inc()
+	
+	for _, def in ipairs(defArray) do
+		hFile:write(def)
+	end
+	
+	hFile:dec()
+	hFile:write("\n")
+	hFile:write("#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/\n")
+	hFile:write("\n")
+end
+
+function type_hdr.WritePassthruTypedefs(hFile, specData, spec, options)
+	common.WritePassthruData(hFile, specData.funcData.passthru)
+end
+
+-----------------------------------------------------------
+-- Extension header.
+local ext_hdr = {}
+
+function ext_hdr.GetFilename(basename, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory .. glload.GetExtsHeaderBasename(spec, options)
+end
+
+function ext_hdr.WriteBlockBeginIncludeGuard(hFile, spec, options)
+	local includeGuard = glload.GetExtFileIncludeGuard(spec, options)
+	hFile:fmt("#ifndef %s\n", includeGuard)
+	hFile:fmt("#define %s\n", includeGuard)
+end
+
+function ext_hdr.WriteBlockEndIncludeGuard(hFile, spec, options)
+	hFile:fmt("#endif /*%s*/\n", glload.GetExtFileIncludeGuard(spec, options))
+end
+
+function ext_hdr.WriteTypedefs(hFile, specData, spec, options)
+--	common.WritePassthruData(hFile, specData.funcData.passthru)
+end
+
+function ext_hdr.WriteBlockBeginExtern(hFile, spec, options)
+	hFile:writeblock(glload.GetBeginExternBlock())
+end
+
+function ext_hdr.WriteBlockEndExtern(hFile, spec, options)
+	hFile:writeblock(glload.GetEndExternBlock())
+end
+
+function ext_hdr.WriteExtVariable(hFile, extName, spec, options)
+	hFile:fmt("extern int %s;\n",
+		glload.GetExtVariableName(extName, spec, options))
+end
+
+function ext_hdr.FilterEnumsPerExtInGroup() return true end
+
+function ext_hdr.WriteEnumerator(hFile, enum, enumTable, spec, options)
+	hFile:fmt("#define %s %s\n",
+		glload.GetEnumeratorName(enum, spec, options),
+		common.ResolveEnumValue(enum, enumTable))
+end
+
+function ext_hdr.WriteFuncTypedef(hFile, func, typemap, spec, options)
+	hFile:fmt(glload.GetTypedefFormat(spec),
+		common.GetFuncReturnType(func, typemap),
+		glload.GetFuncTypedefName(func, spec, options),
+		common.GetFuncParamList(func, typemap))
+end
+
+function ext_hdr.WriteFuncDecl(hFile, func, typemap, spec, options)
+	hFile:fmt("extern %s %s;\n",
+		glload.GetFuncTypedefName(func, spec, options),
+		glload.GetFuncPtrName(func, spec, options))
+	hFile:fmt("#define %s %s\n",
+		spec.FuncNamePrefix() .. func.name,
+		glload.GetFuncPtrName(func, spec, options))
+end
+
+
+-----------------------------------------------------------
+-- Core header.
+local core_hdr = {}
+
+function core_hdr.GetFilename(basename, version, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory .. glload.GetCoreHeaderBasename(version, spec, options)
+end
+
+function core_hdr.GetFilenameRem(basename, version, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory .. glload.GetRemHeaderBasename(version, spec, options)
+end
+
+function core_hdr.WriteBlockBeginIncludeGuard(hFile, version, spec, options)
+	local includeGuard = glload.GetCoreHdrFileIncludeGuard(version, spec, options)
+	hFile:fmt("#ifndef %s\n", includeGuard)
+	hFile:fmt("#define %s\n", includeGuard)
+end
+
+function core_hdr.WriteBlockEndIncludeGuard(hFile, version, spec, options)
+	hFile:fmt("#endif /*%s*/\n", glload.GetCoreHdrFileIncludeGuard(version, spec, options))
+end
+
+function core_hdr.WriteBlockBeginIncludeGuardRem(hFile, version, spec, options)
+	local includeGuard = glload.GetCoreHdrFileIncludeGuard(version, spec, options, true)
+	hFile:fmt("#ifndef %s\n", includeGuard)
+	hFile:fmt("#define %s\n", includeGuard)
+end
+
+function core_hdr.WriteBlockEndIncludeGuardRem(hFile, version, spec, options)
+	hFile:fmt("#endif /*%s*/\n", glload.GetCoreHdrFileIncludeGuard(version, spec, options, true))
+end
+
+function core_hdr.WriteBlockBeginExtern(hFile, spec, options)
+	hFile:writeblock(glload.GetBeginExternBlock())
+end
+
+function core_hdr.WriteBlockEndExtern(hFile, spec, options)
+	hFile:writeblock(glload.GetEndExternBlock())
+end
+
+function core_hdr.WriteEnumerator(hFile, enum, enumTable, spec, options)
+	hFile:fmt("#define %s %s\n",
+		glload.GetEnumeratorName(enum, spec, options),
+		common.ResolveEnumValue(enum, enumTable))
+end
+
+function core_hdr.WriteFuncTypedef(hFile, func, typemap, spec, options)
+	hFile:fmt(glload.GetTypedefFormat(spec),
+		common.GetFuncReturnType(func, typemap),
+		glload.GetFuncTypedefName(func, spec, options),
+		common.GetFuncParamList(func, typemap))
+end
+
+function core_hdr.WriteFuncDecl(hFile, func, typemap, spec, options)
+	hFile:fmt("extern %s %s;\n",
+		glload.GetFuncTypedefName(func, spec, options),
+		glload.GetFuncPtrName(func, spec, options))
+	hFile:fmt("#define %s %s\n",
+		spec.FuncNamePrefix() .. func.name,
+		glload.GetFuncPtrName(func, spec, options))
+end
+
+
+-----------------------------------------------------------
+-- Include header
+local incl_hdr = {}
+
+function incl_hdr.VersionFilenameCore(basename, version, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory ..
+		glload.GetVersionCoreBasename(version, spec, options)
+end
+
+function incl_hdr.VersionFilenameComp(basename, version, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory ..
+		glload.GetVersionCompBasename(version, spec, options)
+end
+
+function incl_hdr.AllFilename(basename, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory .. 
+		glload.GetAllBasename(spec, options)
+end
+
+function incl_hdr.CoreFilename(basename, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory .. 
+		glload.GetCoreBasename(spec, options)
+end
+
+function incl_hdr.WriteBlockBeginIncludeGuardVersionCore(hFile, version, spec, options)
+	local includeGuard = glload.GetInclFileIncludeGuard(version, spec, options)
+	hFile:fmt("#ifndef %s\n", includeGuard)
+	hFile:fmt("#define %s\n", includeGuard)
+end
+
+function incl_hdr.WriteBlockEndIncludeGuardVersionCore(hFile, version, spec, options)
+	hFile:fmt("#endif /*%s*/\n", glload.GetInclFileIncludeGuard(version, spec, options))
+end
+
+function incl_hdr.WriteBlockBeginIncludeGuardVersionComp(hFile, version, spec, options)
+	local includeGuard = glload.GetInclFileCompIncludeGuard(version, spec, options)
+	hFile:fmt("#ifndef %s\n", includeGuard)
+	hFile:fmt("#define %s\n", includeGuard)
+end
+
+function incl_hdr.WriteBlockEndIncludeGuardVersionComp(hFile, version, spec, options)
+	hFile:fmt("#endif /*%s*/\n", glload.GetInclFileCompIncludeGuard(version, spec, options))
+end
+
+function incl_hdr.WriteBlockBeginIncludeGuardAll(hFile, spec, options)
+	local includeGuard = glload.GetInclFileAllIncludeGuard(spec, options)
+	hFile:fmt("#ifndef %s\n", includeGuard)
+	hFile:fmt("#define %s\n", includeGuard)
+end
+
+function incl_hdr.WriteBlockEndIncludeGuardAll(hFile, spec, options)
+	hFile:fmt("#endif /*%s*/\n", glload.GetInclFileAllIncludeGuard(spec, options))
+end
+
+glload.CreateIncludeGuardWriters(incl_hdr, "IncludeGuardCore",
+	function(...) return glload.GetInclFileCoreIncludeGuard(...) end)
+
+function incl_hdr.WriteIncludeIntType(hFile, spec, options)
+	hFile:fmt('#include "%s"\n', glload.GetTypeHeaderBasename(spec, options))
+end
+
+function incl_hdr.WriteIncludeIntExts(hFile, spec, options)
+	hFile:fmt('#include "%s"\n', glload.GetExtsHeaderBasename(spec, options))
+end
+
+function incl_hdr.WriteIncludeIntVersionCore(hFile, sub_version, specData, spec, options)
+	if(not my_style.FilterVersionHasCore(sub_version, specData, spec, options)) then
+		return
+	end
+
+	hFile:fmt('#include "%s"\n', glload.GetCoreHeaderBasename(sub_version, spec, options))
+end
+
+function incl_hdr.WriteIncludeIntVersionComp(hFile, sub_version, specData, spec, options)
+	if(not my_style.FilterVersionHasRemoved(sub_version, specData, spec, options)) then
+		return
+	end
+	
+	hFile:fmt('#include "%s"\n', glload.GetRemHeaderBasename(sub_version, spec, options))
+end
+
+----------------------------------------------------------
+-- Type header.
+local load_hdr = {}
+
+function load_hdr.GetFilename(basename, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory .. glload.GetLoaderBasename(spec, options)
+end
+
+glload.CreateIncludeGuardWriters(load_hdr, "IncludeGuard",
+	function(...) return glload.GetInclFileLoaderIncludeGuard(...) end)
+
+function load_hdr.WriteLoaderDecl(hFile, spec, options)
+	hFile:writeblock(glload.GetLoaderHeaderString(spec, options))
+end
+
+
+----------------------------------------------------------
+-- Source file.
+local source = {}
+
+function source.GetFilename(basename, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.sourceDirectory .. spec.FilePrefix() .. "load.c"
+end
+
+function source.WriteIncludes(hFile, spec, options)
+	hFile:writeblock[[
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+]]
+	hFile:fmt('#include "%s"\n', glload.includeDirectory .. 
+		glload.GetAllBasename(spec, options))
+	hFile:fmt('#include "%s"\n', glload.includeDirectory .. 
+		glload.GetLoaderBasename(spec, options))
+end
+
+function source.WritePointerLoading(hFile, specData, spec, options)
+	hFile:writeblock(spec.GetLoaderFunc())
+end
+
+function source.WriteExtVariable(hFile, extName, spec, options)
+	hFile:fmt("int %s = 0;\n",
+		glload.GetExtVariableName(extName, spec, options))
+end
+
+function source.WriteFuncDef(hFile, func, typemap, spec, options)
+	hFile:fmt("%s %s = NULL;\n",
+		glload.GetFuncTypedefName(func, spec, options),
+		glload.GetFuncPtrName(func, spec, options))
+end
+
+function source.WriteFuncDefCond(hFile, func, typemap, spec, options, funcSeen)
+	if(not funcSeen[func.name]) then
+		source.WriteFuncDef(hFile, func, typemap, spec, options)
+	end
+end
+
+function source.WriteBlockBeginLoadExtensionFuncs(hFile, extName, spec, options)
+	glload.WriteLoaderFuncBegin(hFile,
+		glload.GetLoadExtensionFuncName(extName, spec, options))
+end
+
+function source.WriteBlockEndLoadExtensionFuncs(hFile, extName, spec, options)
+	glload.WriteLoaderFuncEnd(hFile)
+end
+
+function source.WriteLoadFunction(hFile, func, typemap, spec, options)
+	hFile:fmt('%s = (%s)%s("%s");\n',
+		glload.GetFuncPtrName(func, spec, options),
+		glload.GetFuncTypedefName(func, spec, options),
+		common.GetProcAddressName(spec),
+		common.GetOpenGLFuncName(func, spec))
+	hFile:fmt("if(!%s) ++numFailed;\n",
+		glload.GetFuncPtrName(func, spec, options))
+end
+
+function source.WriteBlockBeginLoadCoreFuncs(hFile, version, spec, options)
+	glload.WriteLoaderFuncBegin(hFile,
+		glload.GetLoadCoreFuncName(version, spec, options))
+end
+
+function source.WriteBlockEndLoadCoreFuncs(hFile, version, spec, options)
+	glload.WriteLoaderFuncEnd(hFile)
+end
+
+function source.WriteBlockBeginLoadCoreFuncsComp(hFile, version, spec, options)
+	glload.WriteLoaderFuncBegin(hFile,
+		glload.GetLoadCoreCompFuncName(version, spec, options))
+end
+
+function source.WriteBlockEndLoadCoreFuncsComp(hFile, version, spec, options)
+	glload.WriteLoaderFuncEnd(hFile)
+end
+
+function source.WriteLoadFunctionCore(hFile, func, typemap, spec, options)
+	hFile:fmt('%s = (%s)%s("%s");\n',
+		glload.GetFuncPtrName(func, spec, options),
+		glload.GetFuncTypedefName(func, spec, options),
+		common.GetProcAddressName(spec),
+		common.GetOpenGLFuncName(func, spec))
+		
+	if(func.name:match("EXT$")) then
+		hFile:fmt("/* %s comes from DSA.*/\n",
+			common.GetOpenGLFuncName(func, spec))
+	else
+		hFile:fmt("if(!%s) ++numFailed;\n",
+			glload.GetFuncPtrName(func, spec, options))
+	end
+end
+
+function source.WriteBlockBeginLoadAllCoreFunc(hFile, version, spec, options)
+	glload.WriteLoaderFuncBegin(hFile,
+		glload.GetLoadAllCoreFuncName(version, spec, options))
+end
+
+function source.WriteBlockEndLoadAllCoreFunc(hFile, version, spec, options)
+	glload.WriteLoaderFuncEnd(hFile)
+end
+
+function source.WriteBlockBeginLoadAllCoreCompFunc(hFile, version, spec, options)
+	hFile:fmt("static int %s()\n",
+		glload.GetLoadAllCoreCompFuncName(version, spec, options))
+	hFile:write("{\n")
+	hFile:inc()
+	hFile:write("int numFailed = 0;\n")
+end
+
+function source.WriteBlockEndLoadAllCoreCompFunc(hFile, version, spec, options)
+	hFile:write("return numFailed;\n")
+	hFile:dec()
+	hFile:write("}\n")
+end
+
+function source.WriteCallCoreLoad(hFile, sub_version, spec, options)
+	hFile:fmt("numFailed += %s();\n",
+		glload.GetLoadCoreFuncName(sub_version, spec, options))
+end
+
+function source.WriteCallCoreCompLoad(hFile, sub_version, spec, options)
+	hFile:fmt("numFailed += %s();\n",
+		glload.GetLoadCoreCompFuncName(sub_version, spec, options))
+end
+
+
+
+function source.WriteMainLoadPrelim(hFile, specData, spec, options)
+	--Write the extension function mapping table.
+	common.WriteCMappingTable(hFile, specData, spec, options,
+		glload.GetMapTableStructName(spec, options),
+		"ExtensionTable",
+		glload.GetExtVariableName,
+		glload.GetLoadExtensionFuncName)
+	hFile:write "\n"
+	
+	--Write the function to find entries.
+	common.WriteCFindExtEntryFunc(hFile, specData, spec,
+							options, glload.GetMapTableStructName(spec, options),
+							"ExtensionTable")
+	hFile:write "\n"
+
+	--Write the function to clear the extension variables.
+	common.WriteCClearExtensionVarsFunc(hFile, specData, spec, options,
+		glload.GetExtVariableName,
+		"0")
+	hFile:write "\n"
+
+	--Write a function that loads an extension by name.
+	common.WriteCLoadExtByNameFunc(hFile, specData, spec, options,
+		glload.GetMapTableStructName(spec, options),
+		spec.DeclPrefix() .. "LOAD_SUCCEEDED")
+		
+	if(options.version) then
+		hFile:write "\n"
+		
+		--Write a table that maps from version X.Y profile Z to a loading function.
+		hFile:fmtblock([[
+typedef struct %s%sVersProfToLoaderMap_s
+{
+	int majorVersion;
+	int minorVersion;
+	int compatibilityProfile;
+	PFN_LOADFUNCPOINTERS LoadVersion;
+} %s;
+]], options.prefix, spec.DeclPrefix(), "VersionMapEntry")
+		hFile:write "\n"
+		
+		hFile:write("static VersionMapEntry g_versionMapTable[] =\n")
+		hFile:write("{\n")
+		hFile:inc()
+		local numEntries = 0
+		for _, version in ipairs(spec.GetCoreVersions()) do
+			local major, minor = version:match("(%d+)%.(%d+)")
+			hFile:fmt("{%s, %s, 0, %s},\n",
+				major, minor,
+				glload.GetLoadAllCoreFuncName(version, spec, options))
+			numEntries = numEntries + 1
+			if(my_style.FilterVersionHasCompProfile(version)) then
+				hFile:fmt("{%s, %s, 1, %s},\n",
+					major, minor,
+					glload.GetLoadAllCoreCompFuncName(version, spec, options))
+				numEntries = numEntries + 1
+			end
+		end
+		hFile:dec()
+		hFile:write("};\n")
+		hFile:write "\n"
+		hFile:fmt("static int g_numVersionMapEntries = %i;\n", numEntries)
+		hFile:write "\n"
+		
+		--Write a function to find a map entry and call the loader, returning
+		--the value.
+		hFile:writeblock([[
+static int LoadVersionFromMap(int major, int minor, int compatibilityProfile)
+{
+	int loop = 0;
+	for(; loop < g_numVersionMapEntries; ++loop)
+	{
+		if(
+			(g_versionMapTable[loop].majorVersion == major) &&
+			(g_versionMapTable[loop].minorVersion == minor) &&
+			(g_versionMapTable[loop].compatibilityProfile == compatibilityProfile))
+		{
+			return g_versionMapTable[loop].LoadVersion();
+		}
+	}
+	
+	return -1;
+}
+]])
+		hFile:write "\n"
+		
+		--Write a function to get the current version from a string.
+		hFile:writeblock(common.GetParseVersionFromString())
+		hFile:write "\n"
+		
+		--Write function to load extensions from alist functions.
+		local indexed = spec.GetIndexedExtStringFunc(options);
+		common.FixupIndexedList(specData, indexed)
+		hFile:writeblock(common.GetProcExtsFromExtListFunc(
+			hFile, specData, spec, options,
+			indexed, glload.GetFuncPtrName, glload.GetEnumeratorName))
+		
+	end
+	hFile:write "\n"
+	hFile:writeblock(common.GetProcessExtsFromStringFunc("LoadExtByName(%s)"))
+	
+	hFile:write "\n"
+	hFile:fmt("void %sCopyFromC();\n", spec.DeclPrefix())
+end
+
+function source.WriteMainLoader(hFile, specData, spec, options)
+	if(options.version) then
+		hFile:writeblock[[
+static int g_majorVersion = 0;
+static int g_minorVersion = 0;
+]]
+		hFile:write "\n"
+	end
+
+	hFile:fmt("static int InternalLoad(%s)\n", spec.GetLoaderParams())
+	hFile:write "{\n"
+	hFile:inc()
+	
+	if(options.version) then
+		hFile:writeblock[[
+int numFailed = 0;
+int compProfile = 0;
+
+g_majorVersion = 0;
+g_minorVersion = 0;
+]]
+		hFile:write "\n"
+	end
+	
+	hFile:write("ClearExtensionVars();\n")
+	hFile:write "\n"
+	
+	--Load the extensions. Needs to be done differently based on the removal
+	--of glGetString(GL_EXTENSIONS).
+	if(options.version) then
+		--Get the current version.
+		--To do that, we need certain functions.
+		local strFunc = specData.functable["GetString"]
+		
+		hFile:writeblock(glload.GetInMainFuncLoader(hFile, strFunc, spec, options))
+		strFunc = glload.GetFuncPtrName(strFunc, spec, options)
+		
+		hFile:write "\n"
+		hFile:fmt("ParseVersionFromString(&g_majorVersion, &g_minorVersion, (const char*)%s(GL_VERSION));\n", strFunc)
+		hFile:write "\n"
+		
+		--Load extensions in different ways, based on version.
+		hFile:write("if(g_majorVersion < 3)\n")
+		hFile:write "{\n"
+		hFile:inc()
+		--Load the file from a list of extensions. We already have the string getter.
+		hFile:fmt("ProcExtsFromExtString((const char*)%s(GL_EXTENSIONS));\n", strFunc)
+		hFile:dec()
+		hFile:write "}\n"
+		hFile:write "else\n"
+		hFile:write "{\n"
+		hFile:inc()
+		--Load some additional functions.
+		local indexed = spec.GetIndexedExtStringFunc(options);
+		common.FixupIndexedList(specData, indexed)
+		hFile:writeblock(glload.GetInMainFuncLoader(hFile, indexed[1], spec, options))
+		hFile:writeblock(glload.GetInMainFuncLoader(hFile, indexed[3], spec, options))
+		hFile:write("\n")
+		hFile:write("ProcExtsFromExtList();\n")
+		hFile:dec()
+		hFile:write "}\n"
+	else
+		local extListName, needLoad = spec.GetExtStringFuncName()
+		if(needLoad) then
+			extListName = specData.functable[extListName]
+			
+			hFile:writeblock(glload.GetInMainFuncLoader(hFile, extListName, spec, options))
+
+			extListName = glload.GetFuncPtrName(extListName, spec, options);
+		end
+
+		local function EnumResolve(enumName)
+			return GetEnumName(specData.enumtable[enumName], spec, options)
+		end
+		
+		hFile:write "\n"
+		hFile:fmt("ProcExtsFromExtString((const char *)%s(%s));\n",
+			extListName,
+			spec.GetExtStringParamList(EnumResolve))
+	end
+	
+	hFile:write "\n"
+	--Write the core loading, if any.
+	if(options.version) then
+		--Step 1: figure out if we're core or compatibility. Only applies
+		--to GL 3.1+
+		hFile:writeblock [[
+if(g_majorVersion >= 3)
+{
+	if(g_majorVersion == 3 && g_minorVersion == 0)
+	{ /*Deliberately empty. Core/compatibility didn't exist til 3.1.*/
+	}
+	else if(g_majorVersion == 3 && g_minorVersion == 1)
+	{
+		if(glext_ARB_compatibility)
+			compProfile = 1;
+	}
+	else
+	{
+		GLint iProfileMask = 0;
+		glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &iProfileMask);
+		
+		if(!iProfileMask)
+		{
+			if(glext_ARB_compatibility)
+				compProfile = 1;
+		}
+		else
+		{
+			if(iProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
+				compProfile = 1;
+		}
+	}
+}
+]]
+		hFile:write "\n"
+
+		--Step 2: load the version.
+		local major, minor = options.version:match("(%d+)%.(%d+)")
+
+		hFile:fmtblock([[
+numFailed = LoadVersionFromMap(g_majorVersion, g_minorVersion, compProfile);
+if(numFailed == -1) /*Couldn't find something to load.*/
+{
+	/*Unable to find a compatible one. Load max version+compatibility.*/
+	numFailed = LoadVersionFromMap(%i, %i, 1);
+	if(numFailed == -1) /*Couldn't even load it.*/
+		return %sLOAD_FAILED;
+}
+
+return %sLOAD_SUCCEEDED + numFailed;
+]], major, minor, spec.DeclPrefix(), spec.DeclPrefix())
+		
+	else
+		hFile:fmt("return %s;\n", spec.DeclPrefix() .. "LOAD_SUCCEEDED")
+	end
+	
+	hFile:dec()
+	hFile:write "}\n"
+	
+	hFile:write "\n"
+	
+	hFile:fmt("int %sLoadFunctions(%s)\n", spec.DeclPrefix(), spec.GetLoaderParams())
+	hFile:write "{\n"
+	hFile:inc()
+	hFile:fmtblock(
+[[int numFailed = 0;
+numFailed = InternalLoad(%s);
+]],
+		spec.GetExtStringParamList(function() return "" end))
+	--Call CPP loader.
+	hFile:fmt("%sCopyFromC();\n", spec.DeclPrefix())
+	hFile:write "return numFailed;\n"
+	hFile:dec()
+	hFile:write "}\n"
+end
+
+function source.WriteMainExtraFuncs(hFile, specData, spec, options)
+	local output = [[
+int %<prefix>GetMajorVersion() { return g_majorVersion; }
+int %<prefix>GetMinorVersion() { return g_minorVersion; }
+
+int %<prefix>IsVersionGEQ( int testMajorVersion, int testMinorVersion )
+{
+	if(g_majorVersion > testMajorVersion) return 1;
+	if(g_majorVersion < testMajorVersion) return 0;
+	if(g_minorVersion >= testMinorVersion) return 1;
+	return 0;
+}
+]]
+
+	output = output:gsub("%%<prefix>", spec.DeclPrefix())
+	
+	hFile:writeblock(output)
+end
+
+----------------------------------------------------------
+-- C++ styling.
+
+local cpp = {}
+
+cpp.type_hdr = util.DeepCopyTable(type_hdr)
+cpp.ext_hdr = util.DeepCopyTable(ext_hdr)
+cpp.core_hdr = util.DeepCopyTable(core_hdr)
+cpp.incl_hdr = util.DeepCopyTable(incl_hdr)
+cpp.load_hdr = util.DeepCopyTable(load_hdr)
+cpp.source = {}
+cpp.load_test = {}
+
+function cpp._init()
+	glload = glload.cpp
+end
+
+function cpp._exit()
+	glload = glload_c
+end
+
+
+----------------------------------------------------------
+-- C++ header for LoadTest.
+
+function cpp.load_test.GetFilename(basename, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.headerDirectory .. glload.GetLoadTestBasename(spec, options)
+end
+
+glload.CreateIncludeGuardWriters(cpp.load_test, "IncludeGuard", 
+	function(...) return glload.GetLoadTestFileIncludeGuard(...) end)
+
+function cpp.load_test.WriteLoadTest(hFile, spec, options)
+	glload.WriteNamespaceBegin(hFile, "glload")
+	hFile:writeblock(glload.LoadTestClassDef())
+	glload.WriteNamespaceEnd(hFile, "glload")
+end
+
+
+----------------------------------------------------------
+-- C++ header stuff.
+function cpp.ext_hdr.WriteBlockBeginExtern(hFile, spec, options)
+	hFile:fmt('#include "%s"\n', glload.GetLoadTestBasename(spec, options))
+	glload.WriteNamespaceBegin(hFile, spec.FuncNamePrefix())
+end
+
+function cpp.ext_hdr.WriteBlockEndExtern(hFile, spec, options)
+	glload.WriteNamespaceEnd(hFile)
+end
+
+function cpp.ext_hdr.WriteBlockBeginExtVariables(hFile, spec, options)
+	glload.WriteNamespaceBegin(hFile, "exts")
+end
+
+function cpp.ext_hdr.WriteBlockEndExtVariables(hFile, spec, options)
+	glload.WriteNamespaceEnd(hFile)
+end
+
+function cpp.ext_hdr.WriteExtVariable(hFile, extName, spec, options)
+	hFile:fmt("extern glload::LoadTest %s;\n",
+		glload.GetExtVariableName(extName, spec, options))
+end
+
+function cpp.ext_hdr.FilterEnumsAllAtOnce() return true end
+cpp.ext_hdr.FilterEnumsPerExtInGroup = nil
+
+function cpp.ext_hdr.WriteBlockBeginEnumerators(hFile, spec, options)
+	hFile:write("enum\n")
+	hFile:write "{\n"
+	hFile:inc()
+end
+
+function cpp.ext_hdr.WriteBlockEndEnumerators(hFile, spec, options)
+	hFile:dec()
+	hFile:write "};\n"
+end
+
+function cpp.ext_hdr.WriteEnumerator(hFile, enum, enumTable, spec, options, enumSeen)
+	if(enumSeen[enum.name]) then
+		hFile:fmt("//%s taken from %s\n",
+			enum.name,
+			enumSeen[enum.name])
+	else
+		local enumName = glload.GetCppEnumName(enum)
+		local lenEnum = #enumName
+		local numIndent = 33
+		
+		local numSpaces = numIndent - lenEnum
+		if(numSpaces < 1) then
+			numSpaces = 1
+		end
+
+		hFile:fmt("%s%s= %s,\n",
+			enumName,
+			string.rep(" ", numSpaces),
+			common.ResolveEnumValue(enum, enumTable))
+	end
+end
+
+function cpp.ext_hdr.WriteBlockBeginFuncTypedefs(hFile, spec, options)
+	glload.WriteNamespaceBegin(hFile, glload.GetFuncPtrTypedefNamespace())
+end
+
+function cpp.ext_hdr.WriteBlockEndFuncTypedefs(hFile, spec, options)
+	glload.WriteNamespaceEnd(hFile)
+end
+
+function cpp.ext_hdr.WriteFuncDecl(hFile, func, typemap, spec, options)
+	hFile:fmt("extern %s::%s %s;\n",
+		glload.GetFuncPtrTypedefNamespace(),
+		glload.GetFuncTypedefName(func, spec, options),
+		func.name)
+end
+
+cpp.core_hdr.WriteBlockBeginExtern = cpp.ext_hdr.WriteBlockBeginExtern
+cpp.core_hdr.WriteBlockEndExtern = cpp.ext_hdr.WriteBlockEndExtern
+
+cpp.core_hdr.WriteBlockBeginEnumerators = cpp.ext_hdr.WriteBlockBeginEnumerators
+cpp.core_hdr.WriteBlockEndEnumerators = cpp.ext_hdr.WriteBlockEndEnumerators
+cpp.core_hdr.WriteEnumerator = cpp.ext_hdr.WriteEnumerator
+
+cpp.core_hdr.WriteBlockBeginFuncTypedefs = cpp.ext_hdr.WriteBlockBeginFuncTypedefs
+cpp.core_hdr.WriteBlockEndFuncTypedefs = cpp.ext_hdr.WriteBlockEndFuncTypedefs
+cpp.core_hdr.WriteFuncDecl = cpp.ext_hdr.WriteFuncDecl
+
+
+--------------------------------------------------------------
+-- Source CPP file.
+function cpp.source.GetFilename(basename, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	--The extra _cpp is *on purpose*. Visual Studio checks object files
+	--by filename. So gl_load.c and gl_load.cpp generate the same object file.
+	--This confuses it.
+	return dir .. glload.sourceDirectory .. spec.FilePrefix() .. "load_cpp.cpp"
+end
+
+
+function cpp.source.WriteIncludes(hFile, spec, options)
+	hFile:writeblock([[
+#include <algorithm>
+#include <vector>
+#include <string.h>
+]])
+	hFile:fmt('#include "%s"\n', glload.includeDirectory .. 
+		glload.GetAllBasename(spec, options))
+	hFile:fmt('#include "%s"\n', glload.includeDirectory .. 
+		glload.GetLoaderBasename(spec, options))
+end
+
+function cpp.source.WriteBlockBeginExternC(hFile, spec, options)
+	hFile:writeblock(glload.GetBeginExternBlock())
+end
+
+function cpp.source.WriteBlockEndExternC(hFile, spec, options)
+	hFile:writeblock(glload.GetEndExternBlock())
+end
+
+function cpp.source.WriteCExtVarDecl(hFile, extName, spec, options)
+	hFile:fmt("extern int %s;\n",
+		glload_c.GetExtVariableName(extName, spec, options))
+end
+
+function cpp.source.WriteCFuncDecl(hFile, func, typemap, spec, options)
+	hFile:fmt("extern %s::%s::%s %s;\n",
+		spec.FuncNamePrefix(),
+		glload.GetFuncPtrTypedefNamespace(),
+		glload.GetFuncTypedefName(func, spec, options),
+		glload_c.GetFuncPtrName(func, spec, options))
+end
+
+function cpp.source.WriteCLoaderFunc(hFile, spec, options)
+	hFile:fmt("int %sLoadFunctions(%s);\n",
+		spec.DeclPrefix(),
+		spec.GetLoaderParams())
+end
+
+function cpp.source.WriteCExtraFuncs(hFile, spec, options)
+	hFile:fmtblock([[
+int %sGetMajorVersion();
+int %sGetMinorVersion();
+int %sIsVersionGEQ(int, int);
+]],
+		spec.DeclPrefix(), spec.DeclPrefix(), spec.DeclPrefix())
+
+end
+
+function cpp.source.WriteBlockBeginDefinitions(hFile, spec, options)
+	glload.WriteNamespaceBegin(hFile, spec.FuncNamePrefix())
+end
+
+function cpp.source.WriteBlockEndDefinitions(hFile, spec, options)
+	glload.WriteNamespaceEnd(hFile)
+end
+
+function cpp.source.WriteBlockBeginExtVariables(hFile, spec, options)
+	glload.WriteNamespaceBegin(hFile, "exts")
+end
+
+function cpp.source.WriteBlockEndExtVariables(hFile, spec, options)
+	glload.WriteNamespaceEnd(hFile)
+end
+
+function cpp.source.WriteExtVariable(hFile, extName, spec, options)
+	hFile:fmt("glload::LoadTest %s;\n",
+		glload.GetExtVariableName(extName, spec, options))
+end
+
+function cpp.source.WriteFuncDef(hFile, func, typemap, spec, options)
+	hFile:fmt("%s::%s %s = 0;\n",
+		glload.GetFuncPtrTypedefNamespace(),
+		glload.GetFuncTypedefName(func, spec, options),
+		func.name)
+end
+
+function cpp.source.WriteBlockBeginCopyExtVariables(hFile, spec, options)
+	hFile:write("static void CopyExtensionVariables()\n")
+	hFile:write("{\n")
+	hFile:inc()
+end
+
+function cpp.source.WriteBlockEndCopyExtVariables(hFile, spec, options)
+	hFile:dec()
+	hFile:write("}\n")
+end
+
+function cpp.source.WriteCopyExtVariable(hFile, extName, spec, options)
+	local cppExtVarname = glload.GetExtVariableName(extName, spec, options)
+	local cExtVarname = glload_c.GetExtVariableName(extName, spec, options)
+	
+	hFile:fmt("exts::%s = glload::LoadTest((::%s != 0), ::%s - 1);\n",
+		cppExtVarname,
+		cExtVarname,
+		cExtVarname)
+end
+
+function cpp.source.WriteBlockBeginCopyFunctionPtrs(hFile, spec, options)
+	hFile:write("static void CopyFunctionPointers()\n")
+	hFile:write("{\n")
+	hFile:inc()
+end
+
+function cpp.source.WriteBlockEndCopyFunctionPtrs(hFile, spec, options)
+	hFile:dec()
+	hFile:write("}\n")
+end
+
+function cpp.source.WriteCopyFunctionPtr(hFile, func, typemap, spec, options)
+	hFile:fmt("%s = %s;\n",
+		func.name,
+		glload_c.GetFuncPtrName(func, spec, options))
+end
+
+function cpp.source.WriteBlockBeginSystemDefs(hFile, spec, options)
+	glload.WriteNamespaceBegin(hFile, "glload")
+end
+
+function cpp.source.WriteBlockEndSystemDefs(hFile, spec, options)
+	glload.WriteNamespaceEnd(hFile)
+end
+
+function cpp.source.WriteCopierC(hFile, specData, spec, options)
+	hFile:fmtblock([[
+extern "C" void %sCopyFromC()
+{
+  %s::CopyExtensionVariables();
+  %s::CopyFunctionPointers();
+}
+]],
+	spec.DeclPrefix(), spec.FuncNamePrefix(), spec.FuncNamePrefix())
+end
+
+function cpp.source.WriteMainLoader(hFile, specData, spec, options)
+	hFile:fmt("glload::LoadTest LoadFunctions(%s)\n", spec.GetLoaderParams())
+	hFile:write "{\n"
+	hFile:inc()
+	
+	hFile:fmt("int test = ::%sLoadFunctions(%s);\n",
+		spec.DeclPrefix(),
+		spec.GetExtStringParamList(function() return "" end))
+		
+	hFile:fmtblock([[
+//The C loader will call the above function to copy the variables and such.
+
+if(test == 0)
+	return glload::LoadTest(false, 0);
+return glload::LoadTest(true, test - 1);
+]])
+	
+	hFile:dec()
+	hFile:write "}\n"
+end
+
+function cpp.source.WriteMainExtraFuncs(hFile, specData, spec, options)
+	output = [[
+int GetMajorVersion() { return ::%<prefix>GetMajorVersion(); }
+int GetMinorVersion() { return ::%<prefix>GetMinorVersion(); }
+
+int IsVersionGEQ( int testMajorVersion, int testMinorVersion )
+{
+	return ::%<prefix>IsVersionGEQ(testMajorVersion, testMinorVersion);
+}
+]]
+	output = output:gsub("%%<prefix>", spec.DeclPrefix())
+	
+	hFile:writeblock(output)
+
+end
+
+------------------------------------------------------
+-- Filters
+
+my_style =
+{
+	type_hdr = type_hdr,
+	ext_hdr = ext_hdr,
+	core_hdr = core_hdr,
+	incl_hdr = incl_hdr,
+	load_hdr = load_hdr,
+	source = source,
+	cpp = cpp
+}
+
+function my_style.FilterVersionHasRemoved(version, specData, spec, options)
+	for _, enum in ipairs(specData.coredefs[version].enums) do
+		if(enum.removed) then
+			return true
+		end
+	end
+	
+	for _, func in ipairs(specData.coredefs[version].funcs) do
+		if(func.deprecated) then
+			return true
+		end
+	end
+	
+	return false
+end
+
+function my_style.FilterVersionHasCore(version, specData, spec, options)
+	for _, enum in ipairs(specData.coredefs[version].enums) do
+		if(not enum.removed and not enum.extensions) then
+			return true
+		end
+	end
+	
+	for _, func in ipairs(specData.coredefs[version].funcs) do
+		if(not func.deprecated) then
+			return true
+		end
+	end
+	
+	return false
+end
+
+
+function my_style.FilterVersionHasCompProfile(version)
+	if(tonumber(version) >= 3.1) then
+		return true
+	else
+		return false
+	end
+end
+
+local function HasFunclistAnyCore(funcList)
+	for _, func in ipairs(funcList) do
+		if(not func.deprecated) then
+			return true
+		end
+	end
+	
+	return false
+end
+
+local function HasFunclistAnyComp(funcList)
+	for _, func in ipairs(funcList) do
+		if(func.deprecated) then
+			return true
+		end
+	end
+	
+	return false
+end
+
+function my_style.FilterVersionHasCoreEnums(version, specData, spec, options)
+	for _, enum in ipairs(specData.coredefs[version].enums) do
+		if(not enum.removed and not enum.extensions) then
+			return true
+		end
+	end
+	
+	return false
+end
+
+function my_style.FilterVersionHasCompEnums(version, specData, spec, options)
+	for _, enum in ipairs(specData.coredefs[version].enums) do
+		if(enum.removed and not enum.extensions) then
+			return true
+		end
+	end
+	
+	return false
+end
+
+function my_style.FilterVersionHasCoreFuncs(version, specData, spec, options)
+	local coreExtByVersion = spec.GetCoreExts()
+	if(not coreExtByVersion) then return end
+	
+	local coreExts = coreExtByVersion[version]
+	
+	if(coreExts) then
+		for _, extName in ipairs(coreExts) do
+			if(HasFunclistAnyCore(specData.extdefs[extName].funcs)) then
+				return true
+			end
+		end
+	end
+	
+	if(HasFunclistAnyCore(specData.coredefs[version].funcs)) then
+		return true
+	end
+	
+	return false
+end
+
+function my_style.FilterVersionHasCompFuncs(version, specData, spec, options)
+	local coreExtByVersion = spec.GetCoreExts()
+	if(not coreExtByVersion) then return end
+	
+	local coreExts = coreExtByVersion[version]
+	
+	if(coreExts) then
+		for _, extName in ipairs(coreExts) do
+			if(HasFunclistAnyComp(specData.extdefs[extName].funcs)) then
+				return true
+			end
+		end
+	end
+	
+	if(HasFunclistAnyComp(specData.coredefs[version].funcs)) then
+		return true
+	end
+	
+	return false
+end
+
+function my_style.FilterCoreEnum(enum)
+	return not enum.removed and not enum.extensions
+end
+
+function my_style.FilterCompEnum(enum)
+	return enum.removed and not enum.extensions
+end
+
+function my_style.FilterCoreFunc(func)
+	return not func.deprecated
+end
+
+function my_style.FilterCompFunc(func)
+	return func.deprecated
+end
+
+function my_style.UpdateEnumSeen(enumSeen_, enum, value)
+	enumSeen_[enum.name] = value;
+end
+
+function my_style.StateEnumSeen() return {} end
+
+
+local function Create()
+	return common.DeepCopyTable(my_style), struct
+end
+
+return { Create = Create }

glloadgen/modules/UserStyles.lua

+return
+{
+	glload = require("StyleGLLoad")
+}

glloadgen/modules/glload_util.lua

+
+local util = require "util"
+local common = require "CommonStyle"
+
+local data = {}
+data.cpp = {}
+
+data.internalPrefix = "_int_"
+data.headerDirectory = "include/glload/"
+data.includeDirectory = "glload/" --For inclusions from source.
+data.sourceDirectory = "source/"
+
+
+
+function data.CreateIncludeGuardWriters(tbl, name, Func)
+	tbl["WriteBlockBegin" .. name] = function(hFile, ...)
+		local includeGuard = Func(...)
+		hFile:fmt("#ifndef %s\n", includeGuard)
+		hFile:fmt("#define %s\n", includeGuard)
+	end
+	tbl["WriteBlockEnd" .. name] = function(hFile, ...)
+		local includeGuard = Func(...)
+		hFile:fmt("#endif /*%s*/\n", includeGuard)
+	end
+end
+
+
+-----------------------------------------------
+-- Header filenames
+function data.GetLoaderBasename(spec, options)
+	return spec.FilePrefix() .. "load.h"
+end
+
+function data.GetVersionCoreBasename(version, spec, options)
+	return spec.FilePrefix() .. version:gsub("%.", "_") .. ".h"
+end
+
+function data.GetVersionCompBasename(version, spec, options)
+	return spec.FilePrefix() .. version:gsub("%.", "_") .. "_comp.h"
+end
+
+function data.GetAllBasename(spec, options)
+	return spec.FilePrefix() .. "all.h"
+end
+
+function data.GetCoreBasename(spec, options)
+	return spec.FilePrefix() .. "core.h"
+end
+
+function data.GetTypeHeaderBasename(spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. "type.h"
+end
+
+function data.GetExtsHeaderBasename(spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. "exts.h"
+end
+
+function data.GetCoreHeaderBasename(version, spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. version:gsub("%.", "_") .. ".h"
+end
+
+function data.GetRemHeaderBasename(version, spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. version:gsub("%.", "_") .. "_rem.h"
+end
+
+function data.GetExtVariableName(extName, spec, options)
+	return spec.FuncNamePrefix() .. "ext_" .. extName
+end
+
+function data.GetEnumeratorName(enum, spec, options)
+	return spec.EnumNamePrefix() .. enum.name
+end
+
+function data.GetFuncTypedefName(func, spec, options)
+	local temp = "PFN" .. spec.FuncNamePrefix() .. func.name .. "PROC"
+	return temp:upper()
+end
+
+--Three parameters: the return value, the typedef name, and the params
+function data.GetTypedefFormat(spec)
+	return "typedef %s (" .. spec.GetCodegenPtrType() .. " * %s)(%s);\n"
+end
+
+function data.GetFuncPtrName(func, spec, options)
+	return "_funcptr_" .. spec.FuncNamePrefix() .. func.name
+end
+
+function data.GetTypeHdrFileIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_TYPE" .. "_H"
+end
+
+function data.GetExtFileIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_EXTENSIONS" .. "_H"
+end
+
+function data.GetCoreHdrFileIncludeGuard(version, spec, options, removed)
+	if(removed) then
+		return spec.GetIncludeGuardString() .. "_GEN_CORE_REM" .. version:gsub("%.", "_") .. "_H"
+	else
+		return spec.GetIncludeGuardString() .. "_GEN_CORE_" .. version:gsub("%.", "_") .. "_H"
+	end
+end
+
+function data.GetInclFileIncludeGuard(version, spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_" .. version:gsub("%.", "_") .. "_H"
+end
+
+function data.GetInclFileCompIncludeGuard(version, spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_" .. version:gsub("%.", "_") .. "COMP_H"
+end
+
+function data.GetInclFileAllIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_ALL_H"
+end
+
+function data.GetInclFileCoreIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_CORE_H"
+end
+
+function data.GetInclFileLoaderIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_LOAD_FUNCTIONS_H"
+end
+
+function data.GetBeginExternBlock()
+	return [[
+#ifdef __cplusplus
+extern "C" {
+#endif /*__cplusplus*/
+]]
+end
+
+function data.GetEndExternBlock()
+	return [[
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+]]
+end
+
+function data.WriteLoaderFuncBegin(hFile, funcName)
+	hFile:fmt("static int %s()\n", funcName)
+	hFile:write("{\n")
+	hFile:inc()
+	hFile:write("int numFailed = 0;\n")
+end
+
+function data.WriteLoaderFuncEnd(hFile)
+	hFile:write("return numFailed;\n")
+	hFile:dec()
+	hFile:write("}\n")
+end
+
+function data.GetLoadExtensionFuncName(extName, spec, options)
+	return "LoadExt_" .. extName
+end
+
+function data.GetLoadCoreFuncName(version, spec, options)
+	return "LoadCore_Version_" .. version:gsub("%.", "_")
+end
+
+function data.GetLoadCoreCompFuncName(version, spec, options)
+	return "LoadCore_Version_" .. version:gsub("%.", "_") .. "_Comp"
+end
+
+function data.GetLoadAllCoreFuncName(version, spec, options)
+	return "LoadVersion_" .. version:gsub("%.", "_")
+end
+
+function data.GetLoadAllCoreCompFuncName(version, spec, options)
+	return "LoadVersion_" .. version:gsub("%.", "_") .. "_Comp"
+end
+
+function data.GetMapTableStructName(spec, options)
+	return string.format("%s%sStrToExtMap", options.prefix, spec.DeclPrefix())
+end
+
+function data.GetInMainFuncLoader(hFile, func, spec, options)
+	local ret = ""
+	ret = ret .. string.format('%s = (%s)%s("%s%s");\n',
+		data.GetFuncPtrName(func, spec, options),
+		data.GetFuncTypedefName(func, spec, options),
+		common.GetProcAddressName(spec),
+		spec.FuncNamePrefix(), func.name)
+	ret = ret .. string.format('if(!%s) return %s;\n',
+		data.GetFuncPtrName(func, spec, options),
+		"0")
+	return ret
+end
+
+
+local hdr_extra_spec =
+{
+	wgl = "",
+	glX = "",
+	gl = [=[
+/**
+This function retrieves the major GL version number. Only works after LoadFunctions has been called.
+**/
+int $<prefix>GetMajorVersion();
+
+/**
+This function retrieves the minor GL version number. Only works after LoadFunctions has been called.
+**/
+int $<prefix>GetMinorVersion();
+
+/**Returns non-zero if the current GL version is greater than or equal to the given version.**/
+int $<prefix>IsVersionGEQ(int testMajorVersion, int testMinorVersion);
+]=],
+}
+
+local hdr_desc =
+{
+	wgl = [[Loads function pointers for WGL extensions.]],
+	glX = [[Loads function pointers for GLX extensions.]],
+	gl = [[Loads function pointers for OpenGL. This function will also load the core OpenGL functions (ie: not in extensions). It will only load the version and profile specified by the current OpenGL context. So if you get a 3.2 compatibility context, then it will load only try to load 3.2 compatibility in addition to any available extensions.]],
+}
+
+local hdr_pattern = 
+[=[
+/**
+\file
+\brief C header to include if you want to initialize $<specname>.
+
+**/
+
+/**\addtogroup module_glload_cinter**/
+/**@{**/
+
+/**
+\brief The loading status returned by the loading functions.
+
+**/
+enum
+{
+	$<prefix>LOAD_FAILED = 0,
+	$<prefix>LOAD_SUCCEEDED,
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif /*__cplusplus*/
+
+/**
+\brief Loads all of the function pointers available.
+
+$<desc>
+
+\return Will return $<prefix>LOAD_FAILED if the loading failed entirely and nothing was loaded. Returns $<prefix>LOAD_SUCCEEDED if the loading process worked as planned. If it is neither, then the (return value - $<prefix>LOAD_SUCCEEDED) is the number of core functions that fialed to load.
+**/
+int $<prefix>LoadFunctions($<params>);
+
+$<extra>
+/**@}**/
+
+#ifdef __cplusplus
+}
+#endif /*__cplusplus*/
+]=]
+
+function data.GetLoaderHeaderString(spec, options)
+	local ret = hdr_pattern
+	ret = ret:gsub("%$%<extra%>", hdr_extra_spec[options.spec])
+	ret = ret:gsub("%$%<specname%>", spec.DisplayName())
+	ret = ret:gsub("%$%<prefix%>", spec.DeclPrefix())
+	ret = ret:gsub("%$%<desc%>", hdr_desc[options.spec])
+	ret = ret:gsub("%$%<params%>", spec.GetLoaderParams())
+	return ret
+end
+
+
+----------------------------------------------------------------------------
+-- CPP-specific
+data.cpp = util.DeepCopyTable(data)
+
+function data.cpp.GetLoadTestBasename(spec, options)
+	return data.internalPrefix .. "load_test.hpp"
+end
+
+function data.cpp.GetLoaderBasename(spec, options)
+	return spec.FilePrefix() .. "load.hpp"
+end
+
+function data.cpp.GetVersionCoreBasename(version, spec, options)
+	return spec.FilePrefix() .. version:gsub("%.", "_") .. ".hpp"
+end
+
+function data.cpp.GetVersionCompBasename(version, spec, options)
+	return spec.FilePrefix() .. version:gsub("%.", "_") .. "_comp.hpp"
+end
+
+function data.cpp.GetAllBasename(spec, options)
+	return spec.FilePrefix() .. "all.hpp"
+end
+
+function data.cpp.GetCoreBasename(spec, options)
+	return spec.FilePrefix() .. "core.hpp"
+end
+
+function data.cpp.GetTypeHeaderBasename(spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. "type.hpp"
+end
+
+function data.cpp.GetExtsHeaderBasename(spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. "exts.hpp"
+end
+
+function data.cpp.GetCoreHeaderBasename(version, spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. version:gsub("%.", "_") .. ".hpp"
+end
+
+function data.cpp.GetRemHeaderBasename(version, spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. version:gsub("%.", "_") .. "_rem.hpp"
+end
+
+function data.cpp.GetLoadTestFileIncludeGuard(spec, options)
+	return "GENERATED_LOAD_TEST_HPP"
+end
+
+function data.cpp.GetTypeHdrFileIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_TYPE" .. "_HPP"
+end
+
+function data.cpp.GetExtFileIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_EXTENSIONS" .. "_HPP"
+end
+
+function data.cpp.GetCoreHdrFileIncludeGuard(version, spec, options, removed)
+	if(removed) then
+		return spec.GetIncludeGuardString() .. "_GEN_CORE_REM" .. version:gsub("%.", "_") .. "_HPP"
+	else
+		return spec.GetIncludeGuardString() .. "_GEN_CORE_" .. version:gsub("%.", "_") .. "_HPP"
+	end
+end
+
+function data.cpp.GetInclFileIncludeGuard(version, spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_" .. version:gsub("%.", "_") .. "_HPP"
+end
+
+function data.cpp.GetInclFileCompIncludeGuard(version, spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_" .. version:gsub("%.", "_") .. "COMP_HPP"
+end
+
+function data.cpp.GetInclFileAllIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_ALL_HPP"
+end
+
+function data.cpp.GetInclFileCoreIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_CORE_HPP"
+end
+
+function data.cpp.GetInclFileLoaderIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_LOAD_FUNCTIONS_HPP"
+end
+
+function data.cpp.GetExtVariableName(extName, spec, options)
+	return "var_" .. extName
+end
+
+function data.cpp.WriteNamespaceBegin(hFile, namespace)
+	hFile:fmt("namespace %s\n", namespace)
+	hFile:write("{\n")
+	hFile:inc()
+end
+
+function data.cpp.WriteNamespaceEnd(hFile)
+	hFile:dec()
+	hFile:write("}\n")
+end
+
+function data.cpp.LoadTestClassDef()
+	return [[
+class LoadTest
+{
+private:
+	//Safe bool idiom. Joy!
+	typedef void (LoadTest::*bool_type)() const;
+	void big_long_name_that_really_doesnt_matter() const {}
+	
+public:
+	operator bool_type() const
+	{
+		return m_isLoaded ? &LoadTest::big_long_name_that_really_doesnt_matter : 0;
+	}
+	
+	int GetNumMissing() const {return m_numMissing;}
+	
+	LoadTest() : m_isLoaded(false), m_numMissing(0) {}
+	LoadTest(bool isLoaded, int numMissing) : m_isLoaded(isLoaded), m_numMissing(isLoaded ? numMissing : 0) {}
+private:
+	bool m_isLoaded;
+	int m_numMissing;
+};
+]]
+end
+
+function data.cpp.GetFuncTypedefName(func, spec, options)
+	local temp = "Proc_" .. spec.FuncNamePrefix() .. func.name
+	return temp
+end
+
+function data.cpp.GetFuncPtrTypedefNamespace()
+	return "_detail"
+end
+
+function data.cpp.GetCppEnumName(enum)
+	return common.GetCppEnumName(enum)
+end
+
+local cpp_hdr_extra_spec =
+{
+	wgl = "",
+	glX = "",
+	gl = [=[
+		/**
+		This function retrieves the major GL version number. Only works after LoadFunctions has been called.
+		**/
+		int GetMajorVersion();
+
+		/**
+		This function retrieves the minor GL version number. Only works after LoadFunctions has been called.
+		**/
+		int GetMinorVersion();
+
+		/**Returns non-zero if the current GL version is greater than or equal to the given version.**/
+		int IsVersionGEQ(int testMajorVersion, int testMinorVersion);
+]=],
+}
+
+local hdr_pattern = 
+[=[
+/**
+\file
+\brief C++ header to include if you want to initialize $<specname>.
+
+**/
+
+#include "$<loadtest>"
+
+///\addtogroup module_glload_cppinter
+///@{
+
+///The core namespace for the C++ interface for the OpenGL initialization functions.
+namespace glload
+{
+	/**
+	\brief Loads all of the function pointers available.
+
+$<desc>
+
+	\return A sys::LoadTest object that defines whether the loading was successful.
+	**/
+	glload::LoadTest LoadFunctions($<params>);
+
+$<extra>
+}
+///@}
+]=]
+
+function data.cpp.GetLoaderHeaderString(spec, options)
+	local ret = hdr_pattern
+	ret = ret:gsub("%$%<extra%>", cpp_hdr_extra_spec[options.spec])
+	ret = ret:gsub("%$%<specname%>", spec.DisplayName())
+	ret = ret:gsub("%$%<prefix%>", spec.DeclPrefix())
+	ret = ret:gsub("%$%<desc%>", hdr_desc[options.spec])
+	ret = ret:gsub("%$%<params%>", spec.GetLoaderParams())
+	ret = ret:gsub("%$%<funcspec%>", spec.FuncNamePrefix())	
+	ret = ret:gsub("%$<loadtest>", data.cpp.GetLoadTestBasename(spec, options))
+	return ret
+end
+
+
+
+
+
+return data
 	"glimg/Test", "glload/Test",
 	"glutil/Test", "glmesh/Test",
 	"glm/doc/build",
+	"glloadgen/docs", "glloadgen/test",
 	"caps",