Jason McKesson avatar Jason McKesson committed 265def8 Merge

Merge with 0.3

Comments (0)

Files changed (2)

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",
-			GenCoreLoaderFuncName(options.version, spec, options))
-		
-		hFile:write("return exts::LoadTest(true, numFailed);\n")
-	else
-		hFile:fmt("return exts::LoadTest(true, 0);\n")
-	end
-
-
-	hFile:dec()
-	hFile:write("}\n")
-end
-
-function my_style.source.WriteVersioningFuncs(hFile, specData, spec, options)
-	hFile:fmt("static int g_major_version = 0;\n")
-	hFile:fmt("static int g_minor_version = 0;\n")
-	hFile:write "\n"
-	
-	if(tonumber(options.version) >= 3.0) then
-		hFile:writeblock([[
-static void GetGLVersion()
-{
-	GetIntegerv(MAJOR_VERSION, &g_major_version);
-	GetIntegerv(MINOR_VERSION, &g_minor_version);
-}
-]])
-	else
-		hFile:writeblock(common.GetParseVersionFromString())
-		hFile:write "\n"
-		
-		hFile:writeblock([[
-static void GetGLVersion()
-{
-	ParseVersionFromString(&g_major_version, &g_minor_version, GetString(VERSION));
-}
-]])
-	end
-	
-	hFile:write "\n"
-	hFile:writeblock([[
-int GetMinorVersion()
-{
-	if(g_major_version == 0)
-		GetGLVersion();
-	return g_major_version;
-}
-]])
-	hFile:write "\n"
-
-	hFile:writeblock([[
-int GetMajorVersion()
-{
-	if(g_major_version == 0) //Yes, check the major version to get the minor one.
-		GetGLVersion();
-	return g_minor_version;
-}
-]])
-	hFile:write "\n"
-	
-	hFile:writeblock([[
-bool IsVersionGEQ(int majorVersion, int minorVersion)
-{
-	if(g_major_version == 0)
-		GetGLVersion();
-		
-	if(majorVersion > g_major_version) return true;
-	if(majorVersion < g_major_version) return false;
-	if(minorVersion >= g_minor_version) return true;
-	return false;
-}
-]])
-
-end
-
-
---------------------------------------------------
--- Style retrieval machinery
-
-local function Create()
-	return common.DeepCopyTable(my_style), common.GetStandardStructure()
-end
-
-return { Create = Create }
+
+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
+