Commits

Jason McKesson committed 4b5707c Merge

Merge

Comments (0)

Files changed (8)

 {
 	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=core -style=pointer_cpp -stdext=extfiles/gl_ubiquitous.txt $<dir>test/ptr_cpp/test]],
 	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=core -style=pointer_c -stdext=extfiles/gl_ubiquitous.txt $<dir>test/ptr_c/test]],
+	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=compatibility -style=pointer_cpp -stdext=extfiles/gl_ubiquitous.txt $<dir>test/ptr_cpp_comp/test]],
+	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=compatibility -style=pointer_c -stdext=extfiles/gl_ubiquitous.txt $<dir>test/ptr_c_comp/test]],
 	[[lua $<dir>LoadGen.lua -spec=gl -version=4.3 -profile=compatibility -style=glload -extfile=$<dir>allgl.txt $<dir>test/glload_c/test]],
 	[[lua $<dir>LoadGen.lua -spec=gl -version=4.3 -profile=compatibility -style=glload -extfile=$<dir>allgl.txt $<dir>test/glload_cpp/test]],
 	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=compatibility -style=noload_cpp  -stdext=extfiles/gl_ubiquitous.txt $<dir>test/noload_cpp/test]],
 	{
 		[[lua $<dir>LoadGen.lua -spec=wgl -style=pointer_cpp -stdext=extfiles/wgl_common.txt $<dir>test/ptr_cpp/test]],
 		[[lua $<dir>LoadGen.lua -spec=wgl -style=pointer_c -stdext=extfiles/wgl_common.txt $<dir>test/ptr_c/test]],
+		[[lua $<dir>LoadGen.lua -spec=wgl -style=pointer_cpp -stdext=extfiles/wgl_common.txt $<dir>test/ptr_cpp_comp/test]],
+		[[lua $<dir>LoadGen.lua -spec=wgl -style=pointer_c -stdext=extfiles/wgl_common.txt $<dir>test/ptr_c_comp/test]],
 		[[lua $<dir>LoadGen.lua -spec=wgl -style=glload -extfile=$<dir>allwgl.txt $<dir>test/glload_c/test]],
 		[[lua $<dir>LoadGen.lua -spec=wgl -style=glload -extfile=$<dir>allwgl.txt $<dir>test/glload_cpp/test]],
 		[[lua $<dir>LoadGen.lua -spec=wgl -style=noload_cpp  -stdext=extfiles/wgl_common.txt $<dir>test/noload_cpp/test]],
 	{
 		[[lua $<dir>LoadGen.lua -spec=glX -style=pointer_cpp -stdext=extfiles/glx_common.txt $<dir>test/ptr_cpp/test]],
 		[[lua $<dir>LoadGen.lua -spec=glX -style=pointer_c -stdext=extfiles/glx_common.txt $<dir>test/ptr_c/test]],
+		[[lua $<dir>LoadGen.lua -spec=glX -style=pointer_cpp -stdext=extfiles/glx_common.txt $<dir>test/ptr_cpp_comp/test]],
+		[[lua $<dir>LoadGen.lua -spec=glX -style=pointer_c -stdext=extfiles/glx_common.txt $<dir>test/ptr_c_comp/test]],
 		[[lua $<dir>LoadGen.lua -spec=glX -style=glload -extfile=$<dir>allglx.txt $<dir>test/glload_c/test]],
 		[[lua $<dir>LoadGen.lua -spec=glX -style=glload -extfile=$<dir>allglx.txt $<dir>test/glload_cpp/test]],
 		[[lua $<dir>LoadGen.lua -spec=glX -style=noload_cpp -stdext=extfiles/glx_common.txt $<dir>test/noload_cpp/test]],
 
 Copyright (C) 2011-2012 by Jason L. McKesson
 
-The source code in this distribution is licensed under the terms of the MIT license, as stated below:
+The source code in this distribution is licensed under the terms of the MIT license, as stated below. The source code generated by this tool is yours to do with as you will.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
+glLoadGenerator, version 1.0
+
+
+Please see the documentation available on the web at https://bitbucket.org/alfonse/glloadgen/wiki/Home for detailed information on how to use this software.
+
+The license for this distribution is available in the `License.txt` file.
+
+
+Usage
+-----
+
+This loader generation system is used to create OpenGL headers and loading code for your specific needs. Rather than getting every extension and core enumerator/function all in one massive header, you get only what you actually want and ask for.
+
+The scripts in this package are licensed under the terms of the MIT License. You will need to have Lua installed for this to work.
+
+To use the code generator, with Lua in your path (assuming that "lua" is the name of your Lua executable), type this:
+
+ lua LoadGen.lua -style=pointer_c -spec=gl -version=3.3 -profile=core core_3_3
+
+This tells the system to generate a header/source pair for OpenGL ("-spec=gl", as opposed to WGL or GLX), for version 3.3, the core profile. It will generate it in the "pointer_c" style, which means that it will use function pointer-style, with C linkage and source files. Such code is usable from C and C++, or other languages that can interface with C.
+
+The option "core_3_3" is the basic component of the filename that will be used for the generation. Since it is generating OpenGL loaders (again, as opposed to WGL or GLX), it will generate files named "gl_core_3_3.*", where * is the extension used by the particular style.
+
+The above command line will generate "gl_core_3_3.h" and "gl_core_3_3.c" files. Simply include them in your project; there is no library to build, no unresolved extenals to filter through. They just work.

modules/Structure.lua

-
-local util = require "util"
-local TabbedFile = require "TabbedFile"
-
-local actionTypes = {}
-local conditionals = {}
-
--------------------------------
--- Action base-class
-local action = {}
-
-function action:Process(context)
-	--Allow start-of-iteration only data to parse.
-	if(self.first) then
-		--Note that it's *specifically* equal to false. Being 'nil' isn't enough.
-		if(context._first == false) then
-			return
-		end
-	end
-	
-	--Allow end-if-iteration only data to parse.
-	if(self.last) then
-		--Note that it's *specifically* equal to false. Being 'nil' isn't enough.
-		if(context._last == false) then
-			return
-		end
-	end
-	
-	--Conditional
-	if(self._cond) then
-		if(not conditionals[self._cond](context)) then
-			return
-		end
-	end
-	
-	--NO MORE RETURNS FROM THIS POINT FORWARD!
-	if(self.newStyle) then
-		context:PushStyle(self.newStyle)
-	end
-	
-	local noChildren = nil
-	if(self.PreProcess) then
-		noChildren = self:PreProcess(context)
-	end
-
-	if(not noChildren) then
-		self:ProcessChildren(context)
-	end
-
-	if(self.PostProcess) then
-		self:PostProcess(context)
-	end
-	
-	if(self.newStyle) then
-		context:PopStyle()
-	end
-end
-
-function action:ProcessChildren(context)
-	for _, action in ipairs(self) do
-		--Preserve the first value.
-		local oldFirst = context._first
-		local oldLast = context._last
-		action:Process(context)
-		context._first = oldFirst
-		context._last = oldLast
-	end
-end
-
-local valueResolvers =
-{
-	enum = function(enum) return enum.name end,
-	func = function(func) return func.name end,
-	spec = function(spec) return spec.FuncNamePrefix() end,
-}
-
-local function ResolveValue(context, value)
-	--Find every occurrance of %chars, and try to turn that into a context variable.
-	local possibleVars = {}
-	for var in value:gmatch("%%([_%a][_%w]*)") do
-		possibleVars[var] = true
-	end
-	
-	for var, _ in pairs(possibleVars) do
-		if(not context[var]) then
-			return nil, "The variable " .. var .. " from the value string was not found.\n" .. value
-		end
-		
-		local replace = context[var]
-		if(type(replace) ~= "string") then
-			local str = tostring(replace)
-			if(str) then
-				replace = str
-			elseif(valueResolvers[var]) then
-				replace = valueResolvers[var](replace)
-			elseif(type(replace) == "table" and replace._ValueResolve) then
-				replace = replace:_ValueResolve()
-			end
-		end
-		
-		if(type(replace) ~= "string") then
-			return nil, "Could not convert the variable " .. var .. " into a string."
-		end
-		
-		value = value:gsub("%%" .. var, replace)
-	end
-	
-	return value
-end
-
-function action:CallFunction(context, name)
-	name = name or self.name
-	self:Assert(name, "Unknown function name.")
-	local style = context:FindStyleForFunc(name)
-	
-	if(not style) then
-		if(self.optional) then
-			return
-		else
-			self:Assert(nil, "The style does not have a function " .. name)
-		end
-	end
-	
-	if(self.value) then
-		context.value = self:Assert(ResolveValue(context, self.value))
-	end
-	
-	local paramList = {}
-	for _, param in ipairs(self.params) do
-		assert(context[param], "The function " .. name ..
-			" need a parameter " .. param .. " which doesn't exist at this point")
-		paramList[#paramList + 1] = context[param]
-	end
-	
-	local rets = { style[name](unpack(paramList)) }
-
-	if(self.value) then
-		context.value = nil
-	end
-
-	return unpack(rets)
-end
-
-function action:Assert(...)
-	local test, text = ...
-	if(not test) then
-		local msg = ": " .. text
-		if(self.name) then
-			msg = self._actionType .. "." .. self.name .. msg
-		else
-			msg = self._actionType .. msg
-		end
-		assert(test, msg)
-	end
-	
-	return ...
-end
-
---Iterates over the list, setting the second element returned from the iterator
---as the given context table key.
-function action:IterateChildren(context, list, key, PostProc)
-	PostProc = PostProc or function() end
-	
-	local oldVal = context[key]
-	for _, val in ipairs(list) do
-		context[key] = val
-		context._first = (_ == 1)
-		context._last = (_ == #list)
-		self:ProcessChildren(context)
-		PostProc(context, val)
-	end
-	context[key] = oldVal
-end
-
-local function CreateAction(data, actionType)
-	local act = {}
-	util.DeepCopyTable(action, act)
-	
-	assert(actionType, "No name given for action type")
-	
-	--Create custom param list.
-	if(data.name) then
-		local name, params = data.name:match("([_%w]+)%s*%((.*)%)")
-		if(name) then
-			local paramList = {}
-			for param in params:gmatch("([_%a][_%w]*)") do
-				paramList[#paramList + 1] = param
-			end
-			params = paramList
-		else
-			name = data.name
-		end
-		
-		act.name = name
-		act.params = params
-	end
-	
-	if(data.cond) then
-		assert(conditionals[data.cond], "Unknown conditional " .. data.cond)
-		act._cond = data.cond
-	end
-	
-	act.newStyle = data.style
-	act.optional = data.optional
-	act.value = data.value
-	
-	--Make child actions recursively.
-	for _, child in ipairs(data) do
-		assert(actionTypes[child.type], "Unknown command type " .. child.type)
-		act[#act + 1] = actionTypes[child.type](child)
-	end
-	
-	if(data.first) then
-		act.first = true
-	end
-	
-	if(data.last) then
-		act.last = true
-	end
-	
-	act._actionType = actionType
-	
-	return act
-end
-
-local function MakeActionType(typeName, typeTable, PostInitFunc)
-	actionTypes[typeName] = function(data)
-		local act = CreateAction(data, typeName)
-		util.DeepCopyTable(typeTable, act)
-		
-		PostInitFunc(act, data)
-		
-		return act
-	end
-end
-
-
--------------------------------------
--- Group Action
-local groupAction = {}
-
-MakeActionType("group", groupAction, function(self, data)
-end)
-
-
--------------------------------------
--- Call Action
-local callAction = {}
-
-function callAction:PreProcess(context)
-	self:CallFunction(context, self.name)
-end
-
-MakeActionType("call", callAction, function(self, data)
-	self.params = self.params or {}
-end)
-
-
--------------------------------------
--- Context Action
-local contextAction = {}
-
-function contextAction:PreProcess(context)
-	self:Assert(context[self.key] == nil,
-		"Attempt to nest the context variable " .. self.key)
-
-	if(self.data) then
-		context[self.key] = self.data
-	else
-		context[self.key] = self:CallFunction(context, self.name)
-	end
-end
-
-function contextAction:PostProcess(context)
-	if(self.dispose) then
-		local style = context:FindStyleForFunc(self.dispose)
-		self:Assert(style,
-			string.format("Could not find the disposal function %s for %s.",
-			self.dispose, self.key))
-			
-		style[self.dispose](context[self.key])
-	end
-	context[self.key] = nil
-end
-
-MakeActionType("context", contextAction, function(self, data)
-	assert(data.key, "Context actions must have a `key`.")
-	assert(data.key:match("%_$"), "Context action keys must end in `_`.")
-	self.key = data.key
-	self.data = data.data
-	if(self.name) then
-		self.name = "State" .. self.name
-	end
-	self.dispose = data.dispose
-	if(self.dispose) then
-		self.dispose = "Dispose" .. self.dispose
-	end
-
-	assert(self.data or self.name, "Context actions must have either `data` or `name`.")
-
-	self.params = self.params or {}
-end)
-
-
--------------------------------------------
--- Filter Action
-local filterAction = {}
-
-function filterAction:PreProcess(context)
-	local shouldFilter = self:CallFunction(context, self.name)
-	if(self.neg) then
-		shouldFilter = not shouldFilter
-	end
-	return not shouldFilter
-end
-
-MakeActionType("filter", filterAction, function(self, data)
-	assert(data.name, "Filter actions must have a `name`")
-	self.name = "Filter" .. self.name
-	self.neg = data.neg
-	self.params = self.params or {}
-end)
-
-
-----------------------------
--- File Action
-local fileAction = {}
-
-function fileAction:PreProcess(context)
-	self:Assert(context.hFile == nil, "You cannot nest `file` blocks.")
-
-	local filename = self:CallFunction(context)
-	
-	context.hFile = util.CreateFile(filename, context.options.indent)
-end
-
-function fileAction:PostProcess(context)
-	context.hFile:close()
-	context.hFile = nil
-end
-
-MakeActionType("file", fileAction, function(self, data)
-	assert(data.style, "File actions must have a `style`")
-	assert(data.name, "File actions need a name to call.")
-
-	self.params = self.params or {"basename", "options"}
-end)
-
-
--------------------------------------
--- Block Action
-local blockAction = {}
-
-function blockAction:PreProcess(context)
-	assert(context.hFile, "Cannot write a block outside of a file. " .. self.name)
-	self:CallFunction(context, "WriteBlockBegin" .. self.name)
-end
-
-function blockAction:PostProcess(context)
-	self:CallFunction(context, "WriteBlockEnd" .. self.name)
-end
-
-MakeActionType("block", blockAction, function(self, data)
-	assert(data.name, "Block actions must have a `name`")
-
-	self.params = self.params or {"hFile", "spec", "options"}
-end)
-
-
-------------------------------------------
--- Write Action
-local writeAction = {}
-
-function writeAction:PreProcess(context)
-	assert(context.hFile, "Cannot write data outside of a file.")
-	self:CallFunction(context)
-end
-
-MakeActionType("write", writeAction, function(self, data)
-	assert(data.name, "Write actions must have a `name`")
-	self.name = "Write" .. self.name
-	self.params = self.params or {"hFile", "specData", "spec", "options"}
-end)
-
-
-------------------------------------------
--- Blank Action
-local blankAction = {}
-
-function blankAction:PreProcess(context)
-	self:Assert(context.hFile, "Blanks must be in files.")
-	context.hFile:write("\n")
-end
-
-MakeActionType("blank", blankAction, function(self, data)
-end)
-
-
----------------------------------------------
--- Extension Iterator Action
-local extIterAction = {}
-
-function extIterAction:PreProcess(context)
-	self:Assert(context.extName == nil, "Cannot nest ext-iter actions.")
-	self:IterateChildren(context, context.options.extensions, "extName")
-	return true --Stops regular child processing.
-end
-
-MakeActionType("ext-iter", extIterAction, function(self, data)
-end)
-
-conditionals["ext-iter"] = function(context)
-	return #context.options.extensions ~= 0
-end
-
-
------------------------------------------------
--- Version Iterator
-local versionIterAction = {}
-
-function versionIterAction:PreProcess(context)
-	self:Assert(context.version == nil, "Cannot nest version-iter actions.")
-	local rawVersionList = context.spec.GetVersions()
-	local versionList = {}
-	for _, version in ipairs(rawVersionList) do
-		if(tonumber(version) <= tonumber(context.options.version)) then
-			versionList[#versionList + 1] = version
-		end
-	end
-
-	self:IterateChildren(context, versionList, "version")
-	return true --Stops regular child processing.
-end
-
-MakeActionType("version-iter", versionIterAction, function(self, data)
-end)
-
-conditionals["version-iter"] = function(context)
-	return #context.spec.GetVersions() ~= 0
-end
-
-
------------------------------------------------
--- Sub-Version Iterator
-local subVersionIterAction = {}
-
-function subVersionIterAction:PreProcess(context)
-	self:Assert(context.sub_version == nil, "Cannot nest sub-version-iter actions.")
-	self:Assert(context.version, "Must put sub-version-iter inside versions.")
-	local rawVersionList = context.spec.GetVersions()
-	local versionList = {}
-	for _, version in ipairs(rawVersionList) do
-		if(tonumber(version) <= tonumber(context.version)) then
-			versionList[#versionList + 1] = version
-		end
-	end
-
-	self:IterateChildren(context, versionList, "sub_version")
-	return true --Stops regular child processing.
-end
-
-MakeActionType("sub-version-iter", subVersionIterAction, function(self, data)
-end)
-
-
----------------------------------------------
--- Core Extension Iterator Action
-local coreExtIterAction = {}
-
-function coreExtIterAction:PreProcess(context)
-	self:Assert(context.version, "Must put this in a version iterator")
-	self:Assert(context.extName == nil, "Cannot nest core-ext-iter actions.")
-	local coreExts = context._coreExts
-	if(coreExts[context.version]) then
-		self:IterateChildren(context, coreExts[context.version], "extName")
-	end
-	return true --Stops regular child processing.
-end
-
-MakeActionType("core-ext-iter", coreExtIterAction, function(self, data)
-end)
-
-conditionals["core-ext-iter"] = function(context)
-	assert(context.version, "Cannot have a core-ext-iter conditional outside of a version.")
-	return context._coreExts[context.version] ~= nil
-end
-
-
----------------------------------------------
--- Core Extension Iterator Action, culled against the requested extensions.
-local coreExtCullIterAction = {}
-
-local function BuildCulledExtList(context)
-	local coreExts = context._coreExts
-	if(coreExts[context.version]) then
-		local extList = {}
-		for _, ext in ipairs(coreExts[context.version]) do
-			if(not context._extTbl[ext]) then
-				extList[#extList + 1] = ext
-			end
-		end
-		return extList
-	else
-		return {}
-	end
-end
-
-function coreExtCullIterAction:PreProcess(context)
-	self:Assert(context.version, "Must put core-ext-cull-iters in a version")
-	self:Assert(context.extName == nil, "Cannot nest core-ext-cull-iter actions.")
-	local extList = BuildCulledExtList(context)
-	if(#extList > 0) then
-		self:IterateChildren(context, extList, "extName")
-	end
-	return true --Stops regular child processing.
-end
-
-MakeActionType("core-ext-cull-iter", coreExtCullIterAction, function(self, data)
-end)
-
-conditionals["core-ext-cull-iter"] = function(context)
-	assert(context.version, "Cannot have a core-ext-cull-iter conditional outside of a version.")
-	return #BuildCulledExtList(context) > 0
-end
-
-
-----------------------------------------------
--- Enum Seen Action
-local enumSeenAction = {}
-
-function enumSeenAction:PreProcess(context)
-	self:Assert(context.enumSeen == nil, "Cannot nest enum-seen actions.")
-	context.enumSeen = {}
-end
-
-function enumSeenAction:PostProcess(context)
-	context.enumSeen = nil
-end
-
-MakeActionType("enum-seen", enumSeenAction, function(self, data)
-end)
-
-
------------------------------------------------
--- Enumerator Iterator
-local enumIterAction = {}
-
-local function GetEnumList(context)
-	if(context.extName) then
-		--Get enum list for the extension.
-		return context.specData.extdefs[context.extName].enums, context.extName
-	else
-		--Build list from core version.
-		local core = context.specData.coredefs[context.version];
-		
-		if(context.options.profile ~= "core") then
-			return core.enums, context.version
-		end
-
-		local targetVersion = tonumber(context.options.version)
-		local enumList = {};
-		for i, enum in ipairs(core.enums) do
-			local bShouldWrite = true;
-			
-			if(enum.removed and tonumber(enum.removed) <= targetVersion) then
-				bShouldWrite = false
-			end
-
-			--Very oddball logic to handle ARB_tessellation_shader's
-			--ability to bring back GL_QUADS.
-			--Remove the enumeration if all of the following
-			--	The enum is from a core extension
-			--	That extension is not core for the version we're writing
-			if(enum.extensions) then
-				for _, ext in ipairs(enum.extensions) do
-					if(context.specData.coreexts[ext] and
-						tonumber(context.specData.coreexts[ext].version) <= targetVersion) then
-						bShouldWrite = false
-					end
-				end
-			end
-
-			if(bShouldWrite) then
-				enumList[#enumList + 1] = enum;
-			end
-		end
-		return enumList, context.version
-	end
-end
-
-function enumIterAction:PreProcess(context)
-	self:Assert(context.version or context.extName, "Enumeration iterators must go within a version or extension iterator.")
-
-	local enumList, source = GetEnumList(context)
-	
-	if(not source) then
-		print(context.version, context.extName)
-	end
-
-	context.enumTable = context.specData.enumtable
-	self:IterateChildren(context, enumList, "enum",
-		function(context, enum)
-			if(context.enumSeen) then
-				context.enumSeen[enum.name] = source
-			end
-		end)
-	context.enumTable = nil
-	return true --Stops regular child processing.
-end
-
-MakeActionType("enum-iter", enumIterAction, function(self, data)
-end)
-
-conditionals["enum-iter"] = function(context)
-	assert(context.version or context.extName, "Cannot have an enum-iter conditional outside of a version or extension iterator.")
-
-	return #GetEnumList(context) > 0
-end
-
-----------------------------------------------
--- Func Seen Action
-local funcSeenAction = {}
-
-function funcSeenAction:PreProcess(context)
-	self:Assert(context.funcSeen == nil, "Cannot nest func-seen actions.")
-	context.funcSeen = {}
-end
-
-function funcSeenAction:PostProcess(context)
-	context.funcSeen = nil
-end
-
-MakeActionType("func-seen", funcSeenAction, function(self, data)
-end)
-
-
------------------------------------------------
--- Function Iterator
-local funcIterAction = {}
-
-local function GetFuncList(context)
-	if(context.extName) then
-		--Get function list for the extension.
-		return context.specData.extdefs[context.extName].funcs, context.extName
-	else
-		--Build list from core version.
-		local core = context.specData.coredefs[context.version];
-		
-		if(context.options.profile ~= "core") then
-			return core.funcs
-		end
-
-		local targetVersion = tonumber(context.options.version)
-		local funcList = {};
-		for i, func in ipairs(core.funcs) do
-			local bShouldWrite = true;
-			
-			if(func.deprecated and tonumber(func.deprecated) <= targetVersion) then
-				bShouldWrite = false
-			end
-
-			--Fortuantely, a function can't be both from a version and an extension
-			if(func.category and not string.match(func.category, "^VERSION")) then
-				bShouldWrite = false
-			end
-
-			if(bShouldWrite) then
-				funcList[#funcList + 1] = func;
-			end
-		end
-		return funcList, context.version
-	end
-end
-
-function funcIterAction:PreProcess(context)
-	self:Assert(context.version or context.extName, "Function iterators must go within a version or extension iterator.")
-
-	local funcList, source = GetFuncList(context)
-
-	context.typemap = context.specData.typemap
-	self:IterateChildren(context, funcList, "func",
-		function(context, func)
-			if(context.funcSeen) then
-				context.funcSeen[func.name] = source
-			end
-		end)
-	context.typemap = nil
-	return true --Stops regular child processing.
-end
-
-MakeActionType("func-iter", funcIterAction, function(self, data)
-end)
-
-conditionals["func-iter"] = function(context)
-	assert(context.version or context.extName, "Cannot have a func-iter conditional outside of a version or extension iterator.")
-
-	return #GetFuncList(context) > 0
-end
-
-conditionals["core-funcs"] = function(context)
-	return context.options.spec == "gl"
-end
-
-
-
-local struct = {}
-
-function struct.BuildStructure(structure)
-	local actions = {}
-	for _, data in ipairs(structure) do
-		assert(actionTypes[data.type], "Unknown command type " .. data.type)
-		actions[#actions + 1] = actionTypes[data.type](data)
-	end
-	
-	actions.Proc = function(basename, style, specData, spec, options)
-		local context = {}
-		context.basename = basename
-		context.style = style
-		context.specData = specData
-		context.spec = spec
-		context.options = options
-		
-		context._coreExts = spec.GetCoreExts()
-		context._extTbl = util.InvertTable(options.extensions)
-		context._styles = { style }
-		
-		function context:GetStyle()
-			return context._styles[#context._styles]
-		end
-		
-		function context:FindStyleForFunc(funcName)
-			for i = #context._styles, 1, -1 do
-				if(context._styles[i][funcName]) then
-					return context._styles[i]
-				end
-			end
-			
-			return nil
-		end
-		
-		function context:PushStyle(newStyleName)
-			--Find the style in the stack, from top to bottom.
-			local ix = nil
-			for styleIx = #context._styles, 1, -1 do
-				if(context._styles[styleIx][newStyleName]) then
-					ix = styleIx
-					break;
-				end
-			end
-			assert(ix, "Could not find a style named " .. newStyleName)
-			
-			table.insert(context._styles, context._styles[ix][newStyleName])
-			context.style = context._styles[#context._styles]
-			
-			if(context.style._init) then
-				context.style._init()
-			end
-		end
-		
-		function context:PopStyle()
-			local ret = context._styles[#context._styles]
-			context._styles[#context._styles] = nil
-			context.style = context._styles[#context._styles]
-
-			if(ret._exit) then
-				ret._exit()
-			end
-			return ret
-		end
-		
-		for _, action in ipairs(actions) do
-			action:Process(context)
-		end
-	end
-	
-	return actions
-end
-
-return struct
+
+local util = require "util"
+local TabbedFile = require "TabbedFile"
+
+local actionTypes = {}
+local conditionals = {}
+
+-------------------------------
+-- Action base-class
+local action = {}
+
+function action:Process(context)
+	--Allow start-of-iteration only data to parse.
+	if(self.first) then
+		--Note that it's *specifically* equal to false. Being 'nil' isn't enough.
+		if(context._first == false) then
+			return
+		end
+	end
+	
+	--Allow end-if-iteration only data to parse.
+	if(self.last) then
+		--Note that it's *specifically* equal to false. Being 'nil' isn't enough.
+		if(context._last == false) then
+			return
+		end
+	end
+	
+	--Conditional
+	if(self._cond) then
+		if(not conditionals[self._cond](context)) then
+			return
+		end
+	end
+	
+	--NO MORE RETURNS FROM THIS POINT FORWARD!
+	if(self.newStyle) then
+		context:PushStyle(self.newStyle)
+	end
+	
+	local noChildren = nil
+	if(self.PreProcess) then
+		noChildren = self:PreProcess(context)
+	end
+
+	if(not noChildren) then
+		self:ProcessChildren(context)
+	end
+
+	if(self.PostProcess) then
+		self:PostProcess(context)
+	end
+	
+	if(self.newStyle) then
+		context:PopStyle()
+	end
+end
+
+function action:ProcessChildren(context)
+	for _, action in ipairs(self) do
+		--Preserve the first value.
+		local oldFirst = context._first
+		local oldLast = context._last
+		action:Process(context)
+		context._first = oldFirst
+		context._last = oldLast
+	end
+end
+
+local valueResolvers =
+{
+	enum = function(enum) return enum.name end,
+	func = function(func) return func.name end,
+	spec = function(spec) return spec.FuncNamePrefix() end,
+}
+
+local function ResolveValue(context, value)
+	--Find every occurrance of %chars, and try to turn that into a context variable.
+	local possibleVars = {}
+	for var in value:gmatch("%%([_%a][_%w]*)") do
+		possibleVars[var] = true
+	end
+	
+	for var, _ in pairs(possibleVars) do
+		if(not context[var]) then
+			return nil, "The variable " .. var .. " from the value string was not found.\n" .. value
+		end
+		
+		local replace = context[var]
+		if(type(replace) ~= "string") then
+			local str = tostring(replace)
+			if(str) then
+				replace = str
+			elseif(valueResolvers[var]) then
+				replace = valueResolvers[var](replace)
+			elseif(type(replace) == "table" and replace._ValueResolve) then
+				replace = replace:_ValueResolve()
+			end
+		end
+		
+		if(type(replace) ~= "string") then
+			return nil, "Could not convert the variable " .. var .. " into a string."
+		end
+		
+		value = value:gsub("%%" .. var, replace)
+	end
+	
+	return value
+end
+
+function action:CallFunction(context, name)
+	name = name or self.name
+	self:Assert(name, "Unknown function name.")
+	local style = context:FindStyleForFunc(name)
+	
+	if(not style) then
+		if(self.optional) then
+			return
+		else
+			self:Assert(nil, "The style does not have a function " .. name)
+		end
+	end
+	
+	if(self.value) then
+		context.value = self:Assert(ResolveValue(context, self.value))
+	end
+	
+	local paramList = {}
+	for _, param in ipairs(self.params) do
+		assert(context[param], "The function " .. name ..
+			" need a parameter " .. param .. " which doesn't exist at this point")
+		paramList[#paramList + 1] = context[param]
+	end
+	
+	local rets = { style[name](unpack(paramList)) }
+
+	if(self.value) then
+		context.value = nil
+	end
+
+	return unpack(rets)
+end
+
+function action:Assert(...)
+	local test, text = ...
+	if(not test) then
+		local msg = ": " .. text
+		if(self.name) then
+			msg = self._actionType .. "." .. self.name .. msg
+		else
+			msg = self._actionType .. msg
+		end
+		assert(test, msg)
+	end
+	
+	return ...
+end
+
+--Iterates over the list, setting the second element returned from the iterator
+--as the given context table key.
+function action:IterateChildren(context, list, key, PostProc)
+	PostProc = PostProc or function() end
+	
+	local oldVal = context[key]
+	for _, val in ipairs(list) do
+		context[key] = val
+		context._first = (_ == 1)
+		context._last = (_ == #list)
+		self:ProcessChildren(context)
+		PostProc(context, val)
+	end
+	context[key] = oldVal
+end
+
+local function CreateAction(data, actionType)
+	local act = {}
+	util.DeepCopyTable(action, act)
+	
+	assert(actionType, "No name given for action type")
+	
+	--Create custom param list.
+	if(data.name) then
+		local name, params = data.name:match("([_%w]+)%s*%((.*)%)")
+		if(name) then
+			local paramList = {}
+			for param in params:gmatch("([_%a][_%w]*)") do
+				paramList[#paramList + 1] = param
+			end
+			params = paramList
+		else
+			name = data.name
+		end
+		
+		act.name = name
+		act.params = params
+	end
+	
+	if(data.cond) then
+		assert(conditionals[data.cond], "Unknown conditional " .. data.cond)
+		act._cond = data.cond
+	end
+	
+	act.newStyle = data.style
+	act.optional = data.optional
+	act.value = data.value
+	
+	--Make child actions recursively.
+	for _, child in ipairs(data) do
+		assert(actionTypes[child.type], "Unknown command type " .. child.type)
+		act[#act + 1] = actionTypes[child.type](child)
+	end
+	
+	if(data.first) then
+		act.first = true
+	end
+	
+	if(data.last) then
+		act.last = true
+	end
+	
+	act._actionType = actionType
+	
+	return act
+end
+
+local function MakeActionType(typeName, typeTable, PostInitFunc)
+	actionTypes[typeName] = function(data)
+		local act = CreateAction(data, typeName)
+		util.DeepCopyTable(typeTable, act)
+		
+		PostInitFunc(act, data)
+		
+		return act
+	end
+end
+
+
+-------------------------------------
+-- Group Action
+local groupAction = {}
+
+MakeActionType("group", groupAction, function(self, data)
+end)
+
+
+-------------------------------------
+-- Call Action
+local callAction = {}
+
+function callAction:PreProcess(context)
+	self:CallFunction(context, self.name)
+end
+
+MakeActionType("call", callAction, function(self, data)
+	self.params = self.params or {}
+end)
+
+
+-------------------------------------
+-- Context Action
+local contextAction = {}
+
+function contextAction:PreProcess(context)
+	self:Assert(context[self.key] == nil,
+		"Attempt to nest the context variable " .. self.key)
+
+	if(self.data) then
+		context[self.key] = self.data
+	else
+		context[self.key] = self:CallFunction(context, self.name)
+	end
+end
+
+function contextAction:PostProcess(context)
+	if(self.dispose) then
+		local style = context:FindStyleForFunc(self.dispose)
+		self:Assert(style,
+			string.format("Could not find the disposal function %s for %s.",
+			self.dispose, self.key))
+			
+		style[self.dispose](context[self.key])
+	end
+	context[self.key] = nil
+end
+
+MakeActionType("context", contextAction, function(self, data)
+	assert(data.key, "Context actions must have a `key`.")
+	assert(data.key:match("%_$"), "Context action keys must end in `_`.")
+	self.key = data.key
+	self.data = data.data
+	if(self.name) then
+		self.name = "State" .. self.name
+	end
+	self.dispose = data.dispose
+	if(self.dispose) then
+		self.dispose = "Dispose" .. self.dispose
+	end
+
+	assert(self.data or self.name, "Context actions must have either `data` or `name`.")
+
+	self.params = self.params or {}
+end)
+
+
+-------------------------------------------
+-- Filter Action
+local filterAction = {}
+
+function filterAction:PreProcess(context)
+	local shouldFilter = self:CallFunction(context, self.name)
+	if(self.neg) then
+		shouldFilter = not shouldFilter
+	end
+	return not shouldFilter
+end
+
+MakeActionType("filter", filterAction, function(self, data)
+	assert(data.name, "Filter actions must have a `name`")
+	self.name = "Filter" .. self.name
+	self.neg = data.neg
+	self.params = self.params or {}
+end)
+
+
+----------------------------
+-- File Action
+local fileAction = {}
+
+function fileAction:PreProcess(context)
+	self:Assert(context.hFile == nil, "You cannot nest `file` blocks.")
+
+	local filename = self:CallFunction(context)
+	
+	context.hFile = util.CreateFile(filename, context.options.indent)
+end
+
+function fileAction:PostProcess(context)
+	context.hFile:close()
+	context.hFile = nil
+end
+
+MakeActionType("file", fileAction, function(self, data)
+	assert(data.style, "File actions must have a `style`")
+	assert(data.name, "File actions need a name to call.")
+
+	self.params = self.params or {"basename", "options"}
+end)
+
+
+-------------------------------------
+-- Block Action
+local blockAction = {}
+
+function blockAction:PreProcess(context)
+	assert(context.hFile, "Cannot write a block outside of a file. " .. self.name)
+	self:CallFunction(context, "WriteBlockBegin" .. self.name)
+end
+
+function blockAction:PostProcess(context)
+	self:CallFunction(context, "WriteBlockEnd" .. self.name)
+end
+
+MakeActionType("block", blockAction, function(self, data)
+	assert(data.name, "Block actions must have a `name`")
+
+	self.params = self.params or {"hFile", "spec", "options"}
+end)
+
+
+------------------------------------------
+-- Write Action
+local writeAction = {}
+
+function writeAction:PreProcess(context)
+	assert(context.hFile, "Cannot write data outside of a file.")
+	self:CallFunction(context)
+end
+
+MakeActionType("write", writeAction, function(self, data)
+	assert(data.name, "Write actions must have a `name`")
+	self.name = "Write" .. self.name
+	self.params = self.params or {"hFile", "specData", "spec", "options"}
+end)
+
+
+------------------------------------------
+-- Blank Action
+local blankAction = {}
+
+function blankAction:PreProcess(context)
+	self:Assert(context.hFile, "Blanks must be in files.")
+	context.hFile:write("\n")
+end
+
+MakeActionType("blank", blankAction, function(self, data)
+end)
+
+
+---------------------------------------------
+-- Extension Iterator Action
+local extIterAction = {}
+
+function extIterAction:PreProcess(context)
+	self:Assert(context.extName == nil, "Cannot nest ext-iter actions.")
+	self:IterateChildren(context, context.options.extensions, "extName")
+	return true --Stops regular child processing.
+end
+
+MakeActionType("ext-iter", extIterAction, function(self, data)
+end)
+
+conditionals["ext-iter"] = function(context)
+	return #context.options.extensions ~= 0
+end
+
+
+-----------------------------------------------
+-- Version Iterator
+local versionIterAction = {}
+
+function versionIterAction:PreProcess(context)
+	self:Assert(context.version == nil, "Cannot nest version-iter actions.")
+	local rawVersionList = context.spec.GetVersions()
+	local versionList = {}
+	for _, version in ipairs(rawVersionList) do
+		if(tonumber(version) <= tonumber(context.options.version)) then
+			versionList[#versionList + 1] = version
+		end
+	end
+
+	self:IterateChildren(context, versionList, "version")
+	return true --Stops regular child processing.
+end
+
+MakeActionType("version-iter", versionIterAction, function(self, data)
+end)
+
+conditionals["version-iter"] = function(context)
+	return #context.spec.GetVersions() ~= 0
+end
+
+
+-----------------------------------------------
+-- Sub-Version Iterator
+local subVersionIterAction = {}
+
+function subVersionIterAction:PreProcess(context)
+	self:Assert(context.sub_version == nil, "Cannot nest sub-version-iter actions.")
+	self:Assert(context.version, "Must put sub-version-iter inside versions.")
+	local rawVersionList = context.spec.GetVersions()
+	local versionList = {}
+	for _, version in ipairs(rawVersionList) do
+		if(tonumber(version) <= tonumber(context.version)) then
+			versionList[#versionList + 1] = version
+		end
+	end
+
+	self:IterateChildren(context, versionList, "sub_version")
+	return true --Stops regular child processing.
+end
+
+MakeActionType("sub-version-iter", subVersionIterAction, function(self, data)
+end)
+
+
+---------------------------------------------
+-- Core Extension Iterator Action
+local coreExtIterAction = {}
+
+function coreExtIterAction:PreProcess(context)
+	self:Assert(context.version, "Must put this in a version iterator")
+	self:Assert(context.extName == nil, "Cannot nest core-ext-iter actions.")
+	local coreExts = context._coreExts
+	if(coreExts[context.version]) then
+		self:IterateChildren(context, coreExts[context.version], "extName")
+	end
+	return true --Stops regular child processing.
+end
+
+MakeActionType("core-ext-iter", coreExtIterAction, function(self, data)
+end)
+
+conditionals["core-ext-iter"] = function(context)
+	assert(context.version, "Cannot have a core-ext-iter conditional outside of a version.")
+	return context._coreExts[context.version] ~= nil
+end
+
+
+---------------------------------------------
+-- Core Extension Iterator Action, culled against the requested extensions.
+local coreExtCullIterAction = {}
+
+local function BuildCulledExtList(context)
+	local coreExts = context._coreExts
+	if(coreExts[context.version]) then
+		local extList = {}
+		for _, ext in ipairs(coreExts[context.version]) do
+			if(not context._extTbl[ext]) then
+				extList[#extList + 1] = ext
+			end
+		end
+		return extList
+	else
+		return {}
+	end
+end
+
+function coreExtCullIterAction:PreProcess(context)
+	self:Assert(context.version, "Must put core-ext-cull-iters in a version")
+	self:Assert(context.extName == nil, "Cannot nest core-ext-cull-iter actions.")
+	local extList = BuildCulledExtList(context)
+	if(#extList > 0) then
+		self:IterateChildren(context, extList, "extName")
+	end
+	return true --Stops regular child processing.
+end
+
+MakeActionType("core-ext-cull-iter", coreExtCullIterAction, function(self, data)
+end)
+
+conditionals["core-ext-cull-iter"] = function(context)
+	assert(context.version, "Cannot have a core-ext-cull-iter conditional outside of a version.")
+	return #BuildCulledExtList(context) > 0
+end
+
+
+----------------------------------------------
+-- Enum Seen Action
+local enumSeenAction = {}
+
+function enumSeenAction:PreProcess(context)
+	self:Assert(context.enumSeen == nil, "Cannot nest enum-seen actions.")
+	context.enumSeen = {}
+end
+
+function enumSeenAction:PostProcess(context)
+	context.enumSeen = nil
+end
+
+MakeActionType("enum-seen", enumSeenAction, function(self, data)
+end)
+
+
+-----------------------------------------------
+-- Enumerator Iterator
+local enumIterAction = {}
+
+local function GetEnumList(context)
+	if(context.extName) then
+		--Get enum list for the extension.
+		return context.specData.extdefs[context.extName].enums, context.extName
+	else
+		--Build list from core version.
+		local core = context.specData.coredefs[context.version];
+		
+		if(context.options.profile ~= "core") then
+			return core.enums, context.version
+		end
+
+		local targetVersion = tonumber(context.options.version)
+		local enumList = {};
+		for i, enum in ipairs(core.enums) do
+			local bShouldWrite = true;
+			
+			if(enum.removed and tonumber(enum.removed) <= targetVersion) then
+				bShouldWrite = false
+			end
+
+			--Very oddball logic to handle ARB_tessellation_shader's
+			--ability to bring back GL_QUADS.
+			--Remove the enumeration if all of the following
+			--	The enum is from a core extension
+			--	That extension is not core for the version we're writing
+			if(enum.extensions) then
+				for _, ext in ipairs(enum.extensions) do
+					if(context.specData.coreexts[ext] and
+						tonumber(context.specData.coreexts[ext].version) <= targetVersion) then
+						bShouldWrite = false
+					end
+				end
+			end
+
+			if(bShouldWrite) then
+				enumList[#enumList + 1] = enum;
+			end
+		end
+		return enumList, context.version
+	end
+end
+
+function enumIterAction:PreProcess(context)
+	self:Assert(context.version or context.extName, "Enumeration iterators must go within a version or extension iterator.")
+
+	local enumList, source = GetEnumList(context)
+	
+	if(not source) then
+		print(context.version, context.extName)
+	end
+
+	context.enumTable = context.specData.enumtable
+	self:IterateChildren(context, enumList, "enum",
+		function(context, enum)
+			if(context.enumSeen) then
+				context.enumSeen[enum.name] = source
+			end
+		end)
+	context.enumTable = nil
+	return true --Stops regular child processing.
+end
+
+MakeActionType("enum-iter", enumIterAction, function(self, data)
+end)
+
+conditionals["enum-iter"] = function(context)
+	assert(context.version or context.extName, "Cannot have an enum-iter conditional outside of a version or extension iterator.")
+
+	return #GetEnumList(context) > 0
+end
+
+----------------------------------------------
+-- Func Seen Action
+local funcSeenAction = {}
+
+function funcSeenAction:PreProcess(context)
+	self:Assert(context.funcSeen == nil, "Cannot nest func-seen actions.")
+	context.funcSeen = {}
+end
+
+function funcSeenAction:PostProcess(context)
+	context.funcSeen = nil
+end
+
+MakeActionType("func-seen", funcSeenAction, function(self, data)
+end)
+
+
+-----------------------------------------------
+-- Function Iterator
+local funcIterAction = {}
+
+local function GetFuncList(context)
+	if(context.extName) then
+		--Get function list for the extension.
+		return context.specData.extdefs[context.extName].funcs, context.extName
+	else
+		--Build list from core version.
+		local core = context.specData.coredefs[context.version];
+		
+		if(context.options.profile ~= "core") then
+			return core.funcs, context.version
+		end
+
+		local targetVersion = tonumber(context.options.version)
+		local funcList = {};
+		for i, func in ipairs(core.funcs) do
+			local bShouldWrite = true;
+			
+			if(func.deprecated and tonumber(func.deprecated) <= targetVersion) then
+				bShouldWrite = false
+			end
+
+			--Fortuantely, a function can't be both from a version and an extension
+			if(func.category and not string.match(func.category, "^VERSION")) then
+				bShouldWrite = false
+			end
+
+			if(bShouldWrite) then
+				funcList[#funcList + 1] = func;
+			end
+		end
+		return funcList, context.version
+	end
+end
+
+function funcIterAction:PreProcess(context)
+	self:Assert(context.version or context.extName, "Function iterators must go within a version or extension iterator.")
+
+	local funcList, source = GetFuncList(context)
+
+	context.typemap = context.specData.typemap
+	self:IterateChildren(context, funcList, "func",
+		function(context, func)
+			if(context.funcSeen) then
+				context.funcSeen[func.name] = source
+			end
+		end)
+	context.typemap = nil
+	return true --Stops regular child processing.
+end
+
+MakeActionType("func-iter", funcIterAction, function(self, data)
+end)
+
+conditionals["func-iter"] = function(context)
+	assert(context.version or context.extName, "Cannot have a func-iter conditional outside of a version or extension iterator.")
+
+	return #GetFuncList(context) > 0
+end
+
+conditionals["core-funcs"] = function(context)
+	return context.options.spec == "gl"
+end
+
+
+
+local struct = {}
+
+function struct.BuildStructure(structure)
+	local actions = {}
+	for _, data in ipairs(structure) do
+		assert(actionTypes[data.type], "Unknown command type " .. data.type)
+		actions[#actions + 1] = actionTypes[data.type](data)
+	end
+	
+	actions.Proc = function(basename, style, specData, spec, options)
+		local context = {}
+		context.basename = basename
+		context.style = style
+		context.specData = specData
+		context.spec = spec
+		context.options = options
+		
+		context._coreExts = spec.GetCoreExts()
+		context._extTbl = util.InvertTable(options.extensions)
+		context._styles = { style }
+		
+		function context:GetStyle()
+			return context._styles[#context._styles]
+		end
+		
+		function context:FindStyleForFunc(funcName)
+			for i = #context._styles, 1, -1 do
+				if(context._styles[i][funcName]) then
+					return context._styles[i]
+				end
+			end
+			
+			return nil
+		end
+		
+		function context:PushStyle(newStyleName)
+			--Find the style in the stack, from top to bottom.
+			local ix = nil
+			for styleIx = #context._styles, 1, -1 do
+				if(context._styles[styleIx][newStyleName]) then
+					ix = styleIx
+					break;
+				end
+			end
+			assert(ix, "Could not find a style named " .. newStyleName)
+			
+			table.insert(context._styles, context._styles[ix][newStyleName])
+			context.style = context._styles[#context._styles]
+			
+			if(context.style._init) then
+				context.style._init()
+			end
+		end
+		
+		function context:PopStyle()
+			local ret = context._styles[#context._styles]
+			context._styles[#context._styles] = nil
+			context.style = context._styles[#context._styles]
+
+			if(ret._exit) then
+				ret._exit()
+			end
+			return ret
+		end
+		
+		for _, action in ipairs(actions) do
+			action:Process(context)
+		end
+	end
+	
+	return actions
+end
+
+return struct

modules/StylePointerCPP.lua

-
-local common = require "CommonStyle"
-local util = require "util"
-
-local my_style = {}
-my_style.header = {}
-my_style.source = {}
-
-----------------------------------------------------
--- Global styling functions.
-function my_style.WriteLargeHeading(hFile, headingName)
-	hFile:write(string.rep("/", 6 + #headingName), "\n")
-	hFile:write("// ", headingName, "\n")
-	hFile:write(string.rep("/", 6 + #headingName), "\n")
-end
-
-function my_style.WriteSmallHeading(hFile, headingName)
-	hFile:write("// ", headingName, "\n")
-end
-
-------------------------------------------------------
--- Header styling functions
-
-function my_style.header.GetFilename(basename, options)
-	return basename .. ".hpp"
-end
-
-	local function GenIncludeGuardName(hFile, spec, options)
-		local str = "POINTER_CPP_GENERATED_HEADER" ..
-			spec.GetIncludeGuardString() .. "_HPP"
-
-		if(#options.prefix > 0) then
-			return options.prefix:upper() .. "_" .. str
-		end
-		
-		return str
-	end
-
-function my_style.header.WriteBlockBeginIncludeGuard(hFile, spec, options)
-	local inclGuard = GenIncludeGuardName(hFile, spec, options)
-	
-	hFile:fmt("#ifndef %s\n", inclGuard)
-	hFile:fmt("#define %s\n", inclGuard)
-end
-
-function my_style.header.WriteBlockEndIncludeGuard(hFile, spec, options)
-	hFile:fmt("#endif //%s\n", GenIncludeGuardName(hFile, spec, options))
-end
-
-function my_style.header.WriteInit(hFile, spec, options)
-	hFile:rawwrite(spec.GetHeaderInit())
-end
-
-function my_style.header.WriteStdTypedefs(hFile, specData, spec, options)
-	local defArray = common.GetStdTypedefs()
-	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")
-end
-
-function my_style.header.WriteSpecTypedefs(hFile, specData, spec, options)
-	hFile:push()
-	common.WritePassthruData(hFile, specData.funcData.passthru)
-	hFile:pop()
-end
-
-	local function StartNamespace(hFile, namespaceName)
-		hFile:fmt("namespace %s\n", namespaceName or "")
-		hFile:write("{\n")
-		hFile:inc()
-	end
-
-	local function EndNamespace(hFile, namespaceName)
-		hFile:dec()
-		hFile:fmt("} //namespace %s\n", namespaceName or "")
-	end
-
-function my_style.header.WriteBlockBeginDecl(hFile, spec, options)
-	if(#options.prefix > 0) then
-		StartNamespace(hFile, options.prefix)
-	end
-	StartNamespace(hFile, spec.FuncNamePrefix())
-end
-
-function my_style.header.WriteBlockEndDecl(hFile, spec, options)
-	EndNamespace(hFile, spec.FuncNamePrefix())
-	if(#options.prefix > 0) then
-		EndNamespace(hFile, options.prefix)
-	end
-end
-
-	local extBlockNamespace = "exts"
-	local extVariableTypeDefinition = [[
-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(numMissing) {}
-private:
-	bool m_isLoaded;
-	int m_numMissing;
-};
-]]
-
-function my_style.header.WriteBlockBeginExtVarDecl(hFile, spec, options)
-	StartNamespace(hFile, extBlockNamespace)
-	hFile:writeblock(extVariableTypeDefinition)
-	hFile:write("\n")
-end
-
-function my_style.header.WriteBlockEndExtVarDecl(hFile, spec, options)
-	EndNamespace(hFile, extBlockNamespace)
-end
-
-	local function GenExtensionVarName(extName, spec, options)
-		return "var_" .. extName;
-	end
-
-function my_style.header.WriteExtVariableDecl(hFile, extName,
-	specData, spec, options)
-	hFile:fmt("extern LoadTest %s;\n",
-		GenExtensionVarName(extName, spec, options));
-end
-
-function my_style.header.WriteBlockBeginEnumDecl(hFile, spec, options)
-	hFile:write("enum\n")
-	hFile:write("{\n")
-	hFile:inc()
-end
-
-function my_style.header.WriteBlockEndEnumDecl(hFile, spec, options)
-	hFile:dec()
-	hFile:write("};\n")
-end
-
-	local function GenEnumName(enum)
-		return common.GetCppEnumName(enum)
-	end
-
-function my_style.header.WriteEnumDecl(hFile, enum, enumTable, spec, options,
-	enumSeen)
-	if(enumSeen[enum.name]) then
-		hFile:fmt("//%s taken from ext: %s\n", enum.name, extName)
-	else
-	
-		local enumName = GenEnumName(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 my_style.header.WriteBlockBeginFuncDecl(hFile, spec, options)
-	--Block containing all spec function declarations.
-end
-
-function my_style.header.WriteBlockEndFuncDecl(hFile, spec, options)
-	--Block containing all spec function declarations.
-end
-
-function my_style.header.WriteBlockBeginExtFuncDecl(hFile, extName, spec, options)
-	--Block containing all spec function declarations for a particular extension.
-	--Useful for include-guards around extension function pointers.
-end
-
-function my_style.header.WriteBlockEndExtFuncDecl(hFile, extName, spec, options)
-	--Block containing all spec function declarations for a particular extension.
-end
-
-	local function GenFuncPtrName(func, spec, options)
-		return func.name
-	end
-
-	local function GenFuncPtrTypedefName(func, spec, options)
-		return "PFN" .. GenFuncPtrName(func, spec, options):upper()
-	end
-
-	local function WriteFuncPtrTypedefStmt(hFile, func, typemap, spec, options)
-		hFile:fmt("typedef %s (%s *%s)(%s);\n",
-			common.GetFuncReturnType(func, typemap),
-			spec.GetCodegenPtrType(),
-			GenFuncPtrTypedefName(func, spec, options),
-			common.GetFuncParamList(func, typemap))
-	end
-
-	local function GenFuncPtrDefDirect(func, typemap, spec, options)
-		return string.format("%s (%s *%s)(%s)",
-			common.GetFuncReturnType(func, typemap),
-			spec.GetCodegenPtrType(),
-			GenFuncPtrName(func, spec, options),
-			common.GetFuncParamList(func, typemap, true))
-	end
-
-	local function GenFuncPtrDefTypedef(func, typemap, spec, options)
-		return string.format("%s %s",
-			GenFuncPtrTypedefName(func, spec, options),
-			GenFuncPtrName(func, spec, options))
-	end
-
-function my_style.header.WriteFuncDecl(hFile, func, typemap, spec, options)
-	hFile:write("extern ",
-		GenFuncPtrDefDirect(func, typemap, spec, options),
-		";\n")
-end
-
-function my_style.header.WriteBlockBeginSysDecl(hFile, spec, options)
-	StartNamespace(hFile, "sys")
-end
-
-function my_style.header.WriteBlockEndSysDecl(hFile, spec, options)
-	EndNamespace(hFile, "sys")
-end
-
-function my_style.header.WriteUtilityDecls(hFile, spec, options)
-	--Write declarations for public utility stuff. Enums for return values, etc.
-end
-
-function my_style.header.WriteMainLoaderFuncDecl(hFile, spec, options)
-	hFile:fmt("%s::LoadTest LoadFunctions(%s);\n", extBlockNamespace, spec.GetLoaderParams())
-end
-
-function my_style.header.WriteVersioningFuncDecls(hFile, spec, options)
-	hFile:writeblock([[
-int GetMinorVersion();
-int GetMajorVersion();
-bool IsVersionGEQ(int majorVersion, int minorVersion);
-]])
-end
-
---------------------------------------------------
--- Source code styling functions.
-function my_style.source.GetFilename(basename, options)
-	return basename .. ".cpp"
-end
-
-function my_style.source.WriteIncludes(hFile, basename, spec, options)
-	hFile:writeblock([[
-#include <algorithm>
-#include <vector>
-#include <string.h>
-]])
-
-	local base = util.ParsePath(my_style.header.GetFilename(basename, options))
-	hFile:fmt('#include "%s"\n', base)
-end
-
-function my_style.source.WriteLoaderData(hFile, spec, options)
-	hFile:writeblock(spec.GetLoaderFunc())
-end
-
-function my_style.source.WriteBlockBeginDef(hFile, spec, options)
-	if(#options.prefix > 0) then
-		StartNamespace(hFile, options.prefix)
-	end
-	StartNamespace(hFile, spec.FuncNamePrefix())
-end
-
-function my_style.source.WriteBlockEndDef(hFile, spec, options)
-	EndNamespace(hFile, spec.FuncNamePrefix())
-	if(#options.prefix > 0) then
-		EndNamespace(hFile, options.prefix)
-	end
-end
-
-function my_style.source.WriteBlockBeginExtVarDef(hFile, spec, options)
-	StartNamespace(hFile, extBlockNamespace)
-end
-
-function my_style.source.WriteBlockEndExtVarDef(hFile, spec, options)
-	EndNamespace(hFile, extBlockNamespace)
-end
-
-function my_style.source.WriteExtVariableDef(hFile, extName,
-	specData, spec, options)
-	hFile:fmt("LoadTest %s;\n",
-		GenExtensionVarName(extName, spec, options));
-end
-
-function my_style.source.WriteBlockBeginExtFuncDef(hFile, extName, spec, options)
-	--Block containing the extension function definitions and load function
-	--for the functions in the extension `extName`.
-end
-
-function my_style.source.WriteBlockEndExtFuncDef(hFile, extName, spec, options)
-	--Block containing the extension function definitions and load function
-	--for the functions in the extension `extName`.
-end
-
-function my_style.source.WriteFuncDef(hFile, func, typemap, spec, options)
-	WriteFuncPtrTypedefStmt(hFile, func, typemap, spec, options)
-	hFile:write(GenFuncPtrDefTypedef(func, typemap, spec, options),
-		" = 0;\n")
-end
-
-	local function GenExtLoaderFuncName(extName, spec, options)
-		return "Load_" .. extName;
-	end
-
-function my_style.source.WriteBlockBeginExtLoader(hFile, extName, spec, options)
-	hFile:fmt("static int %s()\n", GenExtLoaderFuncName(extName, spec, options))
-	hFile:write("{\n")
-	hFile:inc()
-	hFile:write("int numFailed = 0;\n")
-end
-
-function my_style.source.WriteBlockEndExtLoader(hFile, extName, spec, options)
-	hFile:write "return numFailed;\n"
-	hFile:dec()
-	hFile:write("}\n")
-end
-
-function my_style.source.WriteExtFuncLoader(hFile, func, typemap, spec, options)
-	hFile:fmt('%s = reinterpret_cast<%s>(%s("%s%s"));\n',
-		GenFuncPtrName(func, spec, options),
-		GenFuncPtrTypedefName(func, spec, options),
-		common.GetProcAddressName(spec),
-		spec.FuncNamePrefix(), func.name)
-	hFile:fmt('if(!%s) ++numFailed;\n', GenFuncPtrName(func, spec, options))
-end
-
-function my_style.source.WriteBlockBeginCoreFuncDef(hFile, version, spec, options)
-	--Block containing the core functions for `version`.
-	--The block also contains the loading function for this version.
-end
-
-function my_style.source.WriteBlockEndCoreFuncDef(hFile, version, spec, options)
-	--Block containing the core functions for `version`.
-end
-
-	local function GenCoreLoaderFuncName(version, spec, options)
-		return "LoadCoreFunctions"
-	end
-
-function my_style.source.WriteBlockBeginCoreLoader(hFile, version, spec, options)
-	hFile:fmt("static int %s()\n", GenCoreLoaderFuncName(version, spec, options))
-	hFile:write("{\n")
-	hFile:inc()
-	hFile:write("int numFailed = 0;\n")
-
-end
-
-function my_style.source.WriteBlockEndCoreLoader(hFile, version, spec, options)
-	hFile:write "return numFailed;\n"
-	hFile:dec()
-	hFile:write("}\n")
-end
-
-function my_style.source.WriteCoreFuncLoader(hFile, func, typemap, spec, options)
-	hFile:fmt('%s = reinterpret_cast<%s>(%s("%s%s"));\n',
-		GenFuncPtrName(func, spec, options),
-		GenFuncPtrTypedefName(func, spec, options),
-		common.GetProcAddressName(spec),
-		spec.FuncNamePrefix(), func.name)
-		
-	--Special hack for DSA_EXT functions in core functions.
-	--They do not count against the loaded count.
-	if(func.name:match("EXT$")) then
-		hFile:write("//An EXT_direct_state_access-based function. Don't count it if it fails to load.\n")
-	else
-		hFile:fmt('if(!%s) ++numFailed;\n', GenFuncPtrName(func, spec, options))
-	end
-end
-
-function my_style.source.WriteExtStringFuncDef(hFile, specData, spec, options, funcSeen)
-	if(funcSeen[spec.GetExtStringFuncName()]) then
-		return
-	end
-	
-	--Check to see if its something we have to load.
-	local function FindFuncName(funcName)
-		for _, func in ipairs(specData.funcData.functions) do
-			if(func.name == funcName) then
-				return func
-			end
-		end
-		
-		return nil
-	end
-	
-	local extStringFunc = FindFuncName(spec.GetExtStringFuncName())
-
-	if(extStringFunc) then
-		hFile:write("\n")
-		local typemap = specData.typemap
-		WriteFuncPtrTypedefStmt(hFile, extStringFunc, typemap, spec, options)
-		hFile:write("static ", GenFuncPtrDefTypedef(extStringFunc, typemap, spec, options),
-			" = 0;\n")
-		hFile:write("\n")
-	end
-end
-
-function my_style.source.WriteBlockBeginSysDef(hFile, spec, options)
-	StartNamespace(hFile, "sys")
-end
-
-function my_style.source.WriteBlockEndSysDef(hFile, spec, options)
-	EndNamespace(hFile, "sys")
-end
-
-function my_style.source.WriteUtilityDefs(hFile, specData, spec, options)
-	--Write our mapping table definitions.
-	StartNamespace(hFile)
-	hFile:writeblock[[
-typedef int (*PFN_LOADEXTENSION)();
-struct MapEntry
-{
-	MapEntry(const char *_extName, exts::LoadTest *_extVariable)
-		: extName(_extName)
-		, extVariable(_extVariable)
-		, loaderFunc(0)
-		{}
-		
-	MapEntry(const char *_extName, exts::LoadTest *_extVariable, PFN_LOADEXTENSION _loaderFunc)
-		: extName(_extName)
-		, extVariable(_extVariable)
-		, loaderFunc(_loaderFunc)
-		{}
-	
-	const char *extName;
-	exts::LoadTest *extVariable;
-	PFN_LOADEXTENSION loaderFunc;
-};
-
-struct MapCompare
-{
-	MapCompare(const char *test_) : test(test_) {}
-	bool operator()(const MapEntry &other) { return strcmp(test, other.extName) == 0; }
-	const char *test;
-};
-
-]]
-
-	--Write the table initialization function.
-	hFile:write "void InitializeMappingTable(std::vector<MapEntry> &table)\n"
-	hFile:write "{\n"
-	hFile:inc()
-	hFile:fmt("table.reserve(%i);\n", #options.extensions)
-	for _, extName in ipairs(options.extensions) do
-		if(#specData.extdefs[extName].funcs > 0) then
-			hFile:fmt('table.push_back(MapEntry("%s", &exts::%s, %s));\n',
-				spec.ExtNamePrefix() .. extName,
-				GenExtensionVarName(extName, spec, options),
-				GenExtLoaderFuncName(extName, spec, options))
-		else
-			hFile:fmt('table.push_back(MapEntry("%s", &exts::%s));\n',
-				spec.ExtNamePrefix() .. extName,
-				GenExtensionVarName(extName, spec, options))
-		end
-	end
-	hFile:dec()
-	hFile:write "}\n"
-	hFile:write "\n"
-	
-	--Write the function to clear the extension variables.
-	hFile:fmt("void ClearExtensionVars()\n")
-	hFile:write("{\n")
-	hFile:inc()
-	for _, extName in ipairs(options.extensions) do
-		hFile:fmt('exts::%s = exts::LoadTest();\n',
-			GenExtensionVarName(extName, spec, options))
-	end
-	hFile:dec()
-	hFile:write("}\n")
-	hFile:write "\n"
-	
-	--Write a function that loads an extension by name. It is called when
-	--processing, so it should also set the extension variable based on the load.
-	hFile:writeblock([[
-void LoadExtByName(std::vector<MapEntry> &table, const char *extensionName)
-{
-	std::vector<MapEntry>::iterator entry = std::find_if(table.begin(), table.end(), MapCompare(extensionName));
-	
-	if(entry != table.end())
-	{
-		if(entry->loaderFunc)
-			(*entry->extVariable) = exts::LoadTest(true, entry->loaderFunc());
-		else
-			(*entry->extVariable) = exts::LoadTest(true, 0);
-	}
-}
-]])
-	EndNamespace(hFile)
-	hFile:write "\n"
-end
-
-	local function GenQualifier(spec, options)
-		local ret = ""
-		if(#options.prefix > 0) then
-			ret = options.prefix .. "::"
-		end
-		ret = ret .. spec.FuncNamePrefix() .. "::"
-		return ret
-	end
-
-	local function GenQualifiedEnumName(enum, spec, options)
-		return GenQualifier(spec, options) .. GenEnumName(enum, spec, options)
-	end
-	
-	local function GenQualifiedFuncPtrName(func, spec, options)
-		return GenQualifier(spec, options) .. GenFuncPtrName(func, spec, options)
-	end
-	
-	local function WriteAncillaryFuncs(hFile, specData, spec, options)
-		local indexed = spec.GetIndexedExtStringFunc(options);
-		if(indexed) then
-			for _, func in ipairs(specData.funcData.functions) do
-				if(indexed[1] == func.name) then
-					indexed[1] = func
-				end
-				if(indexed[3] == func.name) then
-					indexed[3] = func
-				end
-			end
-			for _, enum in ipairs(specData.enumerations) do
-				if(indexed[2] == enum.name) then
-					indexed[2] = enum
-				end
-				if(indexed[4] == enum.name) then
-					indexed[4] = enum
-				end
-			end
-		
-			hFile:writeblock([[
-static void ProcExtsFromExtList(std::vector<MapEntry> &table)
-{
-	GLint iLoop;
-	GLint iNumExtensions = 0;
-	]] .. GenQualifiedFuncPtrName(indexed[1], spec, options)
-	.. [[(]] .. GenQualifiedEnumName(indexed[2], spec, options)
-	.. [[, &iNumExtensions);
-
-	for(iLoop = 0; iLoop < iNumExtensions; iLoop++)
-	{
-		const char *strExtensionName = (const char *)]] ..
-		GenQualifiedFuncPtrName(indexed[3], spec, options) ..
-		[[(]] .. GenQualifiedEnumName(indexed[4], spec, options) .. [[, iLoop);
-		LoadExtByName(table, strExtensionName);
-	}
-}
-]])
-		else
-			hFile:writeblock(common.GetProcessExtsFromStringFunc(
-				"LoadExtByName(table, %s)", ", std::vector<MapEntry> &table"))
-		end
-		
-		hFile:write "\n"
-
-		return indexed
-	end
-
-	
-	local function WriteInMainFuncLoader(hFile, func, spec, options)
-		hFile:fmt('%s = reinterpret_cast<%s>(%s("%s%s"));\n',
-			GenFuncPtrName(func, spec, options),
-			GenFuncPtrTypedefName(func, spec, options),
-			common.GetProcAddressName(spec),
-			spec.FuncNamePrefix(), func.name)
-		hFile:fmt('if(!%s) return exts::LoadTest();\n',
-			GenFuncPtrName(func, spec, options))
-	end
-
-function my_style.source.WriteMainLoaderFunc(hFile, specData, spec, options)
-	StartNamespace(hFile)
-	local indexed = WriteAncillaryFuncs(hFile, specData, spec, options)
-	EndNamespace(hFile)
-	
-	hFile:write "\n"
-	
-	hFile:fmt("exts::LoadTest LoadFunctions(%s)\n", spec.GetLoaderParams())
-	hFile:write("{\n")
-	hFile:inc()
-	hFile:writeblock[[
-ClearExtensionVars();
-std::vector<MapEntry> table;
-InitializeMappingTable(table);
-]]
-	hFile:write("\n")
-	
-	if(indexed) then
-		WriteInMainFuncLoader(hFile, indexed[1], spec, options)
-		WriteInMainFuncLoader(hFile, indexed[3], spec, options)
-		hFile:write("\n")
-		hFile:write("ProcExtsFromExtList(table);\n")
-	else
-		local extListName, needLoad = spec.GetExtStringFuncName()
-		if(needLoad) then
-			for _, func in ipairs(specData.funcData.functions) do
-				if(extListName == func.name) then
-					extListName = func
-					break
-				end
-			end
-			
-			WriteInMainFuncLoader(hFile, extListName, spec, options)
-			
-			extListName = GenQualifiedFuncPtrName(extListName, spec, options);
-		end
-
-		local function EnumResolve(enumName)
-			return GenQualifiedEnumName(specData.enumtable[enumName], spec, options)
-		end
-		
-		hFile:write "\n"
-		hFile:fmt("ProcExtsFromExtString((const char *)%s(%s), table);\n",
-			extListName,
-			spec.GetExtStringParamList(EnumResolve))
-	end
-	
-	if(options.version) then
-		hFile:write "\n"
-		hFile:fmt("int numFailed = %s();\n",
-			G