Jason McKesson avatar Jason McKesson committed be261c5

Header file generation basically works now.

Comments (0)

Files changed (16)

---[[Useful style utility functions. This file will contain commonly useful strings and such.
-
-]]
+--[[Useful style utility functions. This file will contain commonly useful strings and functions that generate useful data.]]
 
 local TabbedFile = require "_TabbedFile"
+require "_util"
 
 local common = {}
 
 	return TabbedFile.TabbedFile(hFile, indent)
 end
 
+function common.GetStdTypedefs()
+	return dofile(GetDataFilePath() .. "style_commontypedefs.lua")
+end
+
+function common.WritePassthruData(hFile, strArray)
+	for _, str in ipairs(strArray) do
+		--unindent after #endif
+		if(str:match("^#endif") or str:match("^#elif")) then
+			hFile:dec()
+		end
+	
+		hFile:write(str, "\n")
+		
+		--Indent after #if.
+		if(str:match("^#if") or str:match("^#elif")) then
+			hFile:inc()
+		end
+	end
+end
+
+function common.WriteExternCStart(hFile)
+	hFile:write("#ifdef __cplusplus\n")
+	hFile:write('extern "C" {\n')
+	hFile:write("#endif //__cplusplus\n")
+	hFile:write("\n")
+end
+
+function common.WriteExternCEnd(hFile)
+	hFile:write("#ifdef __cplusplus\n")
+	hFile:write('}\n')
+	hFile:write("#endif //__cplusplus\n")
+	hFile:write("\n")
+end
+
+local function ResolveEnumValue(enum, enumTable)
+	if(enum.copy) then
+		return common.ResolveEnumValue(enumTable[enum.value], enumTable),
+			enum.value;
+	else
+		return enum.value;
+	end
+end
+common.ResolveEnumValue = ResolveEnumValue
+
+function common.GetFuncReturnType(func, typemap)
+	return typemap[func["return"]] or func["return"]
+end
+
+local bIsKindPtr ={
+	value = false,
+	array = true,
+	reference = true,
+};
+
+--Important due to name conflicts. Some names have to re-mapped to others.
+--Won't really affect things.
+local paramNameRemap = {
+	near = "ren_near",
+	far = "ren_far",
+	array = "ren_array",
+};
+
+--Returns the parameter list as a string.
+--Parameter list does not include parenthesis.
+function common.GetFuncParamList(func, typemap, bWriteVarNames)
+	local paramList = {}
+	for i, param in ipairs(func.params) do
+		local parameter = ""
+		local paramType = typemap[param.type] or param.type;
+		local paramName = "";
+		if(bWriteVarNames) then paramName = param.name end
+		if(paramNameRemap[paramName]) then paramName = paramNameRemap[paramName] end
+		
+		if(bIsKindPtr[param.kind]) then
+			if(param.input) then
+				--Input arrays are ALWAYS const.
+				parameter = parameter .. "const ";
+			end
+			parameter = parameter .. string.format("%s *%s",
+				paramType, paramName);
+		else
+			parameter = parameter .. string.format("%s %s",
+				paramType, paramName);
+		end
+		paramList[#paramList + 1] = parameter
+	end
+	
+	return table.concat(paramList, ", ");
+end
+
+--Retrieves the name of the function according to OpenGL.
+function common.GetOpenGLFuncName(func, spec)
+	return spec.FuncNamePrefix() .. func.name
+end
+
+
 return common

StylePointerC.lua

 my_style.header = {}
 my_style.source = {}
 
+function my_style.WriteLargeHeading(hFile, headingName)
+	hFile:write("/*", string.rep("*", #headingName), "*/\n")
+	hFile:write("/*", headingName, "*/\n")
+end
+
+function my_style.WriteSmallHeading(hFile, headingName)
+	hFile:write("/*", headingName, "*/\n")
+end
+
 function my_style.header.CreateFile(basename, options)
-	return common.CreateFile(basename .. ".h", options.indent)
+	local filename = basename .. ".h"
+	return common.CreateFile(filename, options.indent), filename
 end
 
 function my_style.header.MakeIncludeGuard(prefix, specIncl)
 	return str
 end
 
+function my_style.header.WriteStdTypedefs(hFile, specData, options)
+	local defArray = common.GetStdTypedefs()
+	
+	--Use include-guards for the typedefs, since they're common among
+	--headers in this style.
+	
+	hFile:write("#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS\n")
+	hFile:write("#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS\n")
+	hFile:write("\n")
+	hFile:inc()
+	
+	for _, def in ipairs(defArray) do
+		hFile:write(def)
+	end
+	
+	hFile:dec()
+	hFile:write("\n")
+	hFile:write("#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/\n")
+	hFile:write("\n")
+end
+
+function my_style.header.WriteSpecTypedefs(hFile, specData, options)
+	hFile:push()
+	common.WritePassthruData(hFile, specData.funcData.passthru)
+	hFile:write("\n")
+	hFile:pop()
+end
+
+function my_style.header.WriteBeginDecl(hFile, specData, options)
+	common.WriteExternCStart(hFile)
+end
+
+local function GetExtVariableName(ext, spec, options)
+	return options.prefix .. spec.DeclPrefix() .. "ext_" .. ext
+end
+
+function my_style.header.WriteExtVariableDecl(hFile, ext, specData, spec, options)
+	hFile:write("extern int ", GetExtVariableName(ext, spec, options), ";\n");
+end
+
+function my_style.header.WriteBeginEnumDeclBlock(hFile, specData, options)
+end
+
+function my_style.header.WriteEndEnumDeclBlock(hFile, specData, options)
+end
+
+function my_style.header.WriteEnumDecl(hFile, enum, enumTable, spec, options)
+	hFile:fmt("#define %s%s = %s\n",
+		spec.EnumNamePrefix(),
+		enum.name,
+		common.ResolveEnumValue(enum, enumTable))
+end
+
+function my_style.header.WriteEnumPrevDecl(hFile, enum, enumTable, spec, options, extName)
+	hFile:fmt("/*Copied %s%s From: %s*/\n",
+		spec.EnumNamePrefix(),
+		enum.name,
+		extName)
+end
+
+function my_style.header.WriteBeginFuncDeclBlock(hFile, specData, options)
+end
+
+local function GetFuncPtrName(func, spec, options)
+	return options.prefix .. "_ptrc_".. spec.FuncNamePrefix() .. func.name
+end
+
+local function GetFuncPtrDef(hFile, func, typemap, spec, options)
+	return string.format("%s (*%s)(%s)",
+		common.GetFuncReturnType(func, typemap),
+		GetFuncPtrName(func, spec, options),
+		common.GetFuncParamList(func, typemap))
+end
+
+function my_style.header.WriteFuncDecl(hFile, func, typemap, spec, options)
+	--Declare the function pointer.
+	hFile:write("extern ",
+		GetFuncPtrDef(hFile, func, typemap, spec, options),
+		";\n")
+	
+	--#define it to the proper OpenGL name.
+	hFile:fmt("#define %s %s\n",
+		common.GetOpenGLFuncName(func, spec),
+		GetFuncPtrName(func, spec, options))
+end
+
+function my_style.header.WriteEndFuncDeclBlock(hFile, specData, options)
+end
+
+function my_style.header.WriteBeginExtFuncDeclBlock(hFile, extName,
+	spec, options)
+	hFile:fmt("#ifndef %s\n", spec.ExtNamePrefix() .. extName)
+	hFile:fmt("#define %s 1\n", spec.ExtNamePrefix() .. extName)
+end
+
+function my_style.header.WriteEndExtFuncDeclBlock(hFile, extName,
+	spec, options)
+	hFile:fmt("#endif /*%s*/ \n", spec.ExtNamePrefix() .. extName)
+end
+
+local function GetStatusCodeEnumName(spec, options)
+	return string.format("%s%sLoadStatus", options.prefix, spec.DeclPrefix())
+end
+
+local function GetStatusCodeName(name, spec, options)
+	return string.format("%s%s%s", options.prefix, spec.DeclPrefix(), name)
+end
+
+function my_style.header.WriteStatusCodeDecl(hFile, spec, options)
+	hFile:fmt("enum %s\n", GetStatusCodeEnumName(spec, options))
+	hFile:write("{\n")
+	hFile:inc()
+		hFile:write(GetStatusCodeName("LOAD_FAILED", spec, options), " = 0,\n")
+		hFile:write(GetStatusCodeName("LOAD_SUCCEEDED", spec, options), " = 1,\n")
+		hFile:write(GetStatusCodeName("LOAD_PARTIAL", spec, options), " = 2,\n")
+	hFile:dec()
+	hFile:write("};\n")
+end
+
+local function DecorateFuncName(name, spec, options)
+	return string.format("%s%s%s", options.prefix, spec.DeclPrefix(), name)
+end
+
+local function GetLoaderFuncName(spec, options)
+	return DecorateFuncName("LoadFunctions", spec, options)
+end
+
+function my_style.header.WriteFuncLoaderDecl(hFile, spec, options)
+	hFile:fmt("%s %s(%s);\n",
+		GetStatusCodeEnumName(spec, options),
+		GetLoaderFuncName(spec, options),
+		spec.GetLoaderParams())
+end
+
+function my_style.header.WriteVersioningDecls(hFile, spec, options)
+	--Only for GL
+	if(options.spec ~= "gl") then
+		return
+	end
+	
+	hFile:fmt("int %s();\n", DecorateFuncName("GetMinorVersion", spec, options))
+	hFile:fmt("int %s();\n", DecorateFuncName("GetMajorVersion", spec, options))
+	hFile:fmt("int %s(int iMajorVersion, int iMinorVersion);\n",
+		DecorateFuncName("IsVersionGEQ", spec, options))
+end
+
+
+function my_style.header.WriteEndDecl(hFile, specData, options)
+	common.WriteExternCEnd(hFile)
+end
+
 
 --------------------------------------------------
 -- Style retrieval machinery
 require "_LoadLuaSpec"
 require "_util"
 
+local function WriteEnumsFromList(hFile, enumList, enumSeen, listName,
+	options, spec, style, specData)
+	local header = style.header
+	
+	for _, enum in ipairs(enumList) do
+		if(not enumSeen[enum.name]) then
+			header.WriteEnumDecl(hFile, enum,
+				specData.enumtable, spec, options)
+			enumSeen[enum.name] = listName
+		else
+			header.WriteEnumPrevDecl(hFile, enum,
+				specData.enumtable, spec, options,
+				enumSeen[enum.name])
+		end
+	end
+end
+
+local function WriteEnumsForExt(hFile, extName, enumSeen, options, spec,
+	style, specData)
+	local header = style.header
+	
+	if(#specData.extdefs[extName].enums > 0) then
+		style.WriteSmallHeading(hFile, spec.ExtNamePrefix() .. extName)
+		
+		WriteEnumsFromList(hFile, specData.extdefs[extName].enums,
+			enumSeen, extName, options, spec, style, specData)
+		
+		hFile:write("\n")
+		return true
+	end
+	
+	return false
+end
+
+local function GetCoreEnumerators(core, specData, spec, options, version)
+	--Only remove from core profile.
+	if(options.profile ~= "core") then
+		return core.enums
+	end
+
+	local targetVersion = tonumber(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(specData.coreexts[ext] and
+					tonumber(specData.coreexts[ext].version) <= targetVersion) then
+					bShouldWrite = false
+				end
+			end
+		end
+
+		if(bShouldWrite) then
+			enumList[#enumList + 1] = enum;
+		end
+	end
+	return enumList
+end
+
+local function WriteEnumerators(hFile, options, spec, style, specData)
+	local header = style.header
+
+	local extSeen = {}
+	local enumSeen = {}
+	
+	--For each extension, write its enumerators.
+	for _, extName in ipairs(options.extensions) do
+		if(not extSeen[extName]) then
+			extSeen[extName] = true
+			WriteEnumsForExt(hFile, extName, enumSeen,
+				options, spec, style, specData)
+		end
+	end
+	
+	hFile:write("\n")
+	
+	--For each version we are told to export, write the enumerators.
+	if(options.version) then
+		style.WriteSmallHeading(hFile, "Core Enumerators")
+	end
+	local coreExts = spec.GetCoreExts()
+	for _, version in ipairs(spec.GetVersions()) do
+		if(tonumber(version) <= tonumber(options.version)) then
+			--Write any core extensions for that version.
+			if(coreExts[version]) then
+				for _, extName in ipairs(coreExts[version]) do
+					if(not extSeen[extName]) then
+						extSeen[extName] = true
+						WriteEnumsForExt(
+							hFile, extName, enumSeen,
+							options, spec, style, specData)
+					end
+				end
+			end
+			
+			--Write the actual core enumerators.
+			local enumList = GetCoreEnumerators(specData.coredefs[version],
+				specData, spec, options, version)
+				
+			if(#enumList > 0) then
+				style.WriteSmallHeading(hFile, "Version " .. version)
+				
+				WriteEnumsFromList(hFile, enumList, enumSeen,
+					version, options, spec, style, specData)
+
+				hFile:write("\n")
+			end
+		end
+	end
+end
+
+local function WriteFuncDeclsFromList(hFile, funcList, funcSeen,
+	listName, options, spec, style, specData)
+	local header = style.header
+	
+	for _, func in ipairs(funcList) do
+		if(not funcSeen[func.name]) then
+			header.WriteFuncDecl(hFile, func, specData.typemap, spec, options)
+			funcSeen[func.name] = listName
+		end
+	end
+end
+
+local function WriteFuncDeclsForExt(hFile, extName, funcSeen, options, spec,
+	style, specData)
+	local header = style.header
+	if(#specData.extdefs[extName].funcs > 0) then
+		style.WriteSmallHeading(hFile, spec.ExtNamePrefix() .. extName)
+		
+		header.WriteBeginExtFuncDeclBlock(hFile, extName, spec, options)
+		WriteFuncDeclsFromList(hFile, specData.extdefs[extName].funcs,
+			funcSeen, extName, options, spec, style, specData)
+		header.WriteEndExtFuncDeclBlock(hFile, extName, spec, options)
+		hFile:write("\n")
+	end
+end
+
+local function GetCoreFunctions(core, specData, spec, options, version)
+	--Only remove from core profile.
+	if(options.profile ~= "core") then
+		return core.func
+	end
+
+	local targetVersion = tonumber(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
+end
+
+local function WriteFunctionDecls(hFile, options, spec, style, specData)
+	local header = style.header
+	style.WriteSmallHeading(hFile, "Extension Functions")
+
+	local extSeen = {}
+	local funcSeen = {}
+	
+	--For each extension, write their function declarations.
+	for _, extName in ipairs(options.extensions) do
+		if(not extSeen[extName]) then
+			extSeen[extName] = true
+			WriteFuncDeclsForExt(hFile, extName, funcSeen, options,
+				spec, style, specData)
+		end
+	end
+	
+	hFile:write("\n")
+	
+	--For each version we are told to export, write the Functions.
+	if(options.version) then
+		style.WriteSmallHeading(hFile, "Core Functions")
+	end
+	
+	local coreExts = spec.GetCoreExts()
+	for _, version in ipairs(spec.GetVersions()) do
+		if(tonumber(version) <= tonumber(options.version)) then
+			--Write any core extensions for that version.
+			if(coreExts[version]) then
+				for _, extName in ipairs(coreExts[version]) do
+					if(not extSeen[extName]) then
+						extSeen[extName] = true
+						WriteFuncDeclsForExt(hFile, extName, funcSeen,
+							options, spec, style, specData)
+					end
+				end
+			end
+			
+			--Write the actual core functions, if any.
+			local funcList = GetCoreFunctions(specData.coredefs[version],
+				specData, spec, options, version)
+				
+			if(#funcList > 0) then
+				style.WriteSmallHeading(hFile, "Version " .. version)
+				
+				WriteFuncDeclsFromList(hFile, funcList, funcSeen,
+					version, options, spec, style, specData)
+
+				hFile:write("\n")
+			end
+		end
+	end
+end
+
 local function BuildHeader(options, spec, style, specData, basename)
 	local header = style.header
-	local hFile = header.CreateFile(basename, options)
+	local hFile, filename = header.CreateFile(basename, options)
 	
 	--Start include-guards.
 	--IGs are built from style and spec data. The spec provides a string that
 	--Spec-specific initialization comes next. Generally macros and #includes.
 	hFile:rawwrite(spec.GetHeaderInit())
 	
+	--Write the standard typedefs.
+	header.WriteStdTypedefs(hFile, specData, options)
+	
+	--Write the typedefs from the spec.
+	header.WriteSpecTypedefs(hFile, specData, options)
+	
+	--Write any declaration scoping start.
+	header.WriteBeginDecl(hFile, specData, options)
+	
+	--Write the extension variable declarations.
+	style.WriteLargeHeading(hFile, "Extension variable declarations")
+	for _, ext in ipairs(options.extensions) do
+		header.WriteExtVariableDecl(hFile, ext, specData, spec, options)
+	end
+	hFile:write("\n")
+	
+	--Write all enumerators.
+	style.WriteLargeHeading(hFile, "Enumerators")
+	header.WriteBeginEnumDeclBlock(hFile, specData, options)
+
+	WriteEnumerators(hFile, options, spec, style, specData)
+	
+	header.WriteEndEnumDeclBlock(hFile, specData, options)
+	
+	--Write all function declarations
+	style.WriteLargeHeading(hFile, "Functions")
+	header.WriteBeginFuncDeclBlock(hFile, specData, options)
+
+	WriteFunctionDecls(hFile, options, spec, style, specData)
+	
+	header.WriteEndFuncDeclBlock(hFile, specData, options)
+	
+	--Write the function loading stuff.
+	style.WriteLargeHeading(hFile, "Loading Functions")
+	header.WriteStatusCodeDecl(hFile, spec, options)
+	hFile:write("\n")
+	header.WriteFuncLoaderDecl(hFile, spec, options)
+	if(options.version) then
+		hFile:write("\n")
+		header.WriteVersioningDecls(hFile, spec, options)
+	end
+	
+	--Write any declaration scoping end.
+	header.WriteEndDecl(hFile, specData, options)
+	
 	--Ending includeguard.
 	hFile:fmt("#endif //%s\n", inclGuard)
 	hFile:close()
+	
+	return filename
 end
 
 local function Generate(options, specData)
 	"outname")
 	
 local function LoadExtFile(extensions, extfilename)
-	hFile = assert(io.open(extfilename, "rt"), "Could not find the file " .. extfilename)
+	local hFile = assert(io.open(extfilename, "rt"), "Could not find the file " .. extfilename)
 	
 	for line in hFile:lines() do
 		local ext = line:match("(%S+)")
 		if(ext) then
-			table.insert(extensions, ext)
+			if(ext == "#include") then
+				local file = line:match('%#include [%"%<](.+)[%"%>]')
+				assert(file, "Bad #include statement in extension file " ..
+					extfilename)
+				if(file) then
+					--Probably should provide a way to make this
+					--prevent loops. And to use directories.
+					LoadExtFile(extensions, file)
+				end
+			else
+				table.insert(extensions, ext)
+			end
 		end
 	end
 	
 		parseOpts:AssertParse(options.version, "You must specify an OpenGL version to export.")
 	else
 		parseOpts:AssertParse(not options.version, "Versions cannot be specified for wgl/glX")
-		parseOpts:AssertParse(not options.profile, "Profiles cannot be specified for wgl/glX")
 	end
 	
 	options.extensions = options.extensions or {}
 - PlatformSetup: Takes a file and writes out platform-specific setup stuff.
 
 - GetHeaderInit: Nullary function that returns a string to be written to the beginning of a header, just after the include guards.
+
+- DeclPrefix: nullary function that returns the name of a prefix string for declarations.
 ]]
 
 require "_util"
 ---FilePrefix
 function gl_spec.FilePrefix() return "gl_" end
 function wgl_spec.FilePrefix() return "wgl_" end
-function glx_spec.FilePrefix() return "glX_" end
+function glx_spec.FilePrefix() return "glx_" end
+
+local function LoadRun(spec, name)
+	return dofile(GetDataFilePath() .. spec.FilePrefix() .. name .. ".lua")
+end
 
 --Include-guard string.
 function gl_spec.GetIncludeGuardString() return "OPENGL" end
 function wgl_spec.GetIncludeGuardString() return "WINDOWSGL" end
 function glx_spec.GetIncludeGuardString() return "GLXWIN" end
 
+--Declaration prefix.
+function gl_spec.DeclPrefix() return "ogl_" end
+function wgl_spec.DeclPrefix() return "wgl_" end
+function glx_spec.DeclPrefix() return "glx_" end
+
+--Extension name prefix.
+function gl_spec.ExtNamePrefix() return "GL_" end
+function wgl_spec.ExtNamePrefix() return "WGL" end
+function glx_spec.ExtNamePrefix() return "GLX" end
+
+--Enumerator name prefix. This is for defining "proper" GL enumerators.
+function gl_spec.EnumNamePrefix() return "GL_" end
+function wgl_spec.EnumNamePrefix() return "WGL" end
+function glx_spec.EnumNamePrefix() return "GLX" end
+
+--Function name prefix. This is for defining "proper" GL function names.
+function gl_spec.FuncNamePrefix() return "gl" end
+function wgl_spec.FuncNamePrefix() return "wgl" end
+function glx_spec.FuncNamePrefix() return "glX" end
+
+--Parameters given to the loader. No (), just the internals.
+function gl_spec.GetLoaderParams() return "" end
+function wgl_spec.GetLoaderParams() return "HDC *hdc" end
+function glx_spec.GetLoaderParams() return "Display *display, int screen" end
+
+local fileProps =
+{
+	{"GetHeaderInit", "init"},
+	{"GetVersions", "versions"},
+	{"GetCoreExts", "coreexts"},
+}
+
 --Header initialization.
-function gl_spec.GetHeaderInit()
-	return dofile(GetDataFilePath() .. "gl_specinit.lua")
-end
-function wgl_spec.GetHeaderInit()
-	return dofile(GetDataFilePath() .. "wgl_specinit.lua")
-end
-function glx_spec.GetHeaderInit()
-	return dofile(GetDataFilePath() .. "glx_specinit.lua")
+for key, spec in pairs(specTbl) do
+	for _, props in ipairs(fileProps) do
+		spec[props[1]] = function()
+			return dofile(GetDataFilePath() .. spec:FilePrefix() ..
+				"spec" .. props[2] .. ".lua")
+		end
+	end
 end
 
-
+--Get version numbers
 
 
 --------------------------------------------------
 
 This module has a function called GetStyle, which is given a style name. It will return a table of functions that can be evaluated to do different code generation tasks. This table contains:
 
+
+- WriteLargeHeading(hFile, headingName)
+--		Writes a comment heading to the file. A large one.
+
+- WriteSmallHeading(hFile, headingName)
+--		Writes a comment heading to the file. A small one.
+
+
+
 - header.CreateFile(basename, options)
---		basename is the filename sans extension. It opens a TabbedFile from it, using the options in options.
+--		basename is the filename sans extension. It opens a TabbedFile from it, using the options in options. It returns two values: a TabbedFile, and the actual filename used.
 
 - header.MakeIncludeGuard(prefix, specIncl)
 --		specIncl is an include-guard string from the spec. It returns a string that includes the two strings, which is appropriate for use as an include-guard.
 
+- header.WriteStdTypedefs(hFile, specData, options)
+--		Writes the standard typedefs.
 
+- header.WriteSpecTypedefs(hFile, specData, options)
+--		Writes the typedefs from the spec. The "funcData.passthru" section.
+
+- header.WriteBeginDecl(hFile, specData, options)
+--		Writes any style-specific scoping stuff that begins the declaration section. This is useful for things like 'extern "C"' and so forth.
+--	
+
+- header.WriteEndDecl(hFile, specData, options)
+--		Writes any style-specific scoping stuff that ends the declaration section. This is useful for things like 'extern "C"' and so forth.
+
+- header.WriteExtVariableDecl(hFile, ext, specData, spec, options)
+--		Writes the variable declaration for a single extension variable. These are the variables that are exposed so that the user can test to see if an extension loaded.
+
+- header.WriteBeginEnumDeclBlock(hFile, specData, options)
+--		Writes any style-specific scoping stuff that starts the enumerator block. This is for *all* enumerators. This is useful for wrapping all enumerators in an enum declaration.
+
+- header.WriteEndEnumDeclBlock(hFile, specData, options)
+--		Writes any style-specific scoping stuff that ends the enumerator block.
+
+- header.WriteEnumDecl(hFile, enum, enumTable, spec, options)
+--		Writes an enumerator.
+
+- header.WriteEnumPrevDecl(hFile, enum, enumTable, spec, options, extName)
+--		Writes an enumerator that was written previously. Should be written as a comment, as it could conflict. extName is the name of the extension where it was originally written.
+
+- header.WriteBeginFuncDeclBlock(hFile, specData, options)
+--	Write any style-specific scoping stuff that starts the function declaration block.
+
+- header.WriteEndFuncDeclBlock(hFile, specData, options)
+--	Write any style-specific scoping stuff that ends the function declaration block.
+
+- header.WriteBeginExtFuncDeclBlock(hFile, extName, spec, options)
+-- Used for starting the declarations for a partiuclar extension.
+
+- header.WriteEndExtFuncDeclBlock(hFile, extName, spec, options)
+-- Used for ending the declarations for a partiuclar extension.
+
+- header.WriteFuncDecl(hFile, func, typemap, spec, options)
+--	Writes a function declaration. This can include multiple statements, such as a typedef, an extern function pointer declaration, and a #define or whatever.
+
+- header.WriteStatusCodeDecl(hFile, spec, options)
+--	Writes any declarations for status codes as returned from the loader and so forth.
+
+- header.WriteFuncLoaderDecl(hFile, spec, options)
+--	Writes the declaration for the main loading function.
+
+- header.WriteVersioningDecls(hFile, spec, options)
+--	Writes the declarations for any functions used to help the user get versioning info. Will only be called if the spec has versions.
 
 
 If you want to extend this to new styles, then add a module for your style, import it, and register it's module table with the registry. Your module should export a function `Create` which takes no parameters and returns a table as defined above.
 
 - inc: Increments the tab count by the number given, or by 1 if nothing is given.
 - dec: Decrements the tab count by the number given, or by 1 if nothing is given.
+- push: Preserves the current tab count.
+- pop: Restores the previously preserved tab count.
 - fmt: As string.format followed by an indented write
 - write: An indented write; everything is written after the indent.
 - rawfmt: As string.format followed by a NON-indented write.
 	rawset(self, "_indent", self._indent - count)
 end
 
+function members:push()
+	local stack = rawget(self, "_indentStack")
+	stack[#stack + 1] = rawget(self, "_indent")
+end
+
+function members:pop()
+	local stack = rawget(self, "_indentStack")
+	assert(#stack > 0, "Tab stack underflow.")
+	rawset(self, "_indent", stack[#stack])
+	stack[#stack] = nil
+end
+
 function members:fmt(fmt, ...)
 	self:_Indent()
 	local str = fmt:format(...)
 		_hFile = hFile,
 		_indent = 0,
 		_Indent = IndentFunc,
+		_indentStack = {}
 	}
 	
 	if(style == "tab") then

data/gl_speccoreexts.lua

+--[[ This function returns a table of core extensions and the versions they were made core in.
+
+The table is indexed by version number (as a string). In each version is an array of extension names.
+
+This list must be manually updated, as there is no equivalent in the spec files. Just add to the list. When a new version comes out with new core extensions, add a new list and add the local variable name to the master table as shown below.
+]]
+
+
+local coreExts3_0 = {
+	"ARB_vertex_array_object",
+	"ARB_texture_rg",
+	"ARB_texture_compression_rgtc",
+	"ARB_map_buffer_range",
+	"ARB_half_float_vertex",
+	"ARB_framebuffer_sRGB",
+	"ARB_framebuffer_object",
+	"ARB_depth_buffer_float",
+};
+
+local coreExts3_1 = {
+	"ARB_uniform_buffer_object",
+	"ARB_copy_buffer",
+};
+
+local coreExts3_2 = {
+	"ARB_depth_clamp",
+	"ARB_draw_elements_base_vertex",
+	"ARB_fragment_coord_conventions",
+	"ARB_provoking_vertex",
+	"ARB_seamless_cube_map",
+	"ARB_sync",
+	"ARB_texture_multisample",
+	"ARB_vertex_array_bgra",
+};
+
+local coreExts3_3 = {
+	"ARB_texture_rgb10_a2ui",
+	"ARB_texture_swizzle",
+	"ARB_timer_query",
+	"ARB_vertex_type_2_10_10_10_rev",
+	"ARB_blend_func_extended",
+	"ARB_occlusion_query2",
+	"ARB_sampler_objects",
+};
+
+local coreExts4_0 = {
+	"ARB_draw_indirect",
+	"ARB_gpu_shader5",
+	"ARB_gpu_shader_fp64",
+	"ARB_shader_subroutine",
+	"ARB_tessellation_shader",
+	"ARB_transform_feedback2",
+	"ARB_transform_feedback3",
+};
+
+local coreExts4_1 = {
+	"ARB_ES2_compatibility",
+	"ARB_get_program_binary",
+	"ARB_separate_shader_objects",
+	"ARB_vertex_attrib_64bit",
+	"ARB_viewport_array",
+};
+
+local coreExts4_2 = {
+	"ARB_base_instance",
+	"ARB_shading_language_420pack",
+	"ARB_transform_feedback_instanced",
+	"ARB_compressed_texture_pixel_storage",
+	"ARB_conservative_depth",
+	"ARB_internalformat_query",
+	"ARB_map_buffer_alignment",
+	"ARB_shader_atomic_counters",
+	"ARB_shader_image_load_store",
+	"ARB_shading_language_packing",
+	"ARB_texture_storage",
+};
+
+local coreExts4_3 = {
+	"KHR_debug",
+	"ARB_arrays_of_arrays",
+	"ARB_clear_buffer_object",
+	"ARB_compute_shader",
+	"ARB_copy_image",
+	"ARB_ES3_compatibility",
+	"ARB_explicit_uniform_location",
+	"ARB_fragment_layer_viewport",
+	"ARB_framebuffer_no_attachments",
+	"ARB_internalformat_query2",
+	"ARB_invalidate_subdata",
+	"ARB_multi_draw_indirect",
+	"ARB_program_interface_query",
+	"ARB_shader_image_size",
+	"ARB_shader_storage_buffer_object",
+	"ARB_stencil_texturing",
+	"ARB_texture_buffer_range",
+	"ARB_texture_query_levels",
+	"ARB_texture_storage_multisample",
+	"ARB_texture_view",
+	"ARB_vertex_attrib_binding",
+};
+
+return {
+	["3.0"] = coreExts3_0,
+	["3.1"] = coreExts3_1,
+	["3.2"] = coreExts3_2,
+	["3.3"] = coreExts3_3,
+	["4.0"] = coreExts4_0,
+	["4.1"] = coreExts4_1,
+	["4.2"] = coreExts4_2,
+	["4.3"] = coreExts4_3,
+};
+

data/gl_specinit.lua

 	#else
 		#define APIENTRY
 	#endif
-#endif //APIENTRY
+#endif /*APIENTRY*/
 
 #ifndef GLE_FUNCPTR
 	#define GLE_REMOVE_FUNCPTR
 	#else
 		#define GLE_FUNCPTR
 	#endif
-#endif //GLE_FUNCPTR
+#endif /*GLE_FUNCPTR*/
 
 #ifndef GLAPI
 	#define GLAPI extern

data/gl_specversions.lua

+return {
+	"1.1",
+	"1.2",
+	"1.3",
+	"1.4",
+	"1.5",
+	"2.0",
+	"2.1",
+	"3.0",
+	"3.1",
+	"3.2",
+	"3.3",
+	"4.0",
+	"4.1",
+	"4.2",
+	"4.3",
+}

data/glx_speccoreexts.lua

+return {}

data/glx_specversions.lua

+--Initialization text for the 'glX' spec header.
+
+return {}

data/style_commontypedefs.lua

+-- Returns an array of strings, for proper indenting and such.
+
+return {
+	"typedef unsigned int GLenum;\n",
+	"typedef unsigned char GLboolean;\n",
+	"typedef unsigned int GLbitfield;\n",
+	"typedef signed char GLbyte;\n",
+	"typedef short GLshort;\n",
+	"typedef int GLint;\n",
+	"typedef int GLsizei;\n",
+	"typedef unsigned char GLubyte;\n",
+	"typedef unsigned short GLushort;\n",
+	"typedef unsigned int GLuint;\n",
+	"typedef float GLfloat;\n",
+	"typedef float GLclampf;\n",
+	"typedef double GLdouble;\n",
+	"typedef double GLclampd;\n",
+	"#define GLvoid void\n",
+}

data/wgl_speccoreexts.lua

+return {}

data/wgl_specinit.lua

 
 #ifdef GLE_FUNCPTR
 #undef GLE_FUNCPTR
-#endif //GLE_FUNCPTR
+#endif /*GLE_FUNCPTR*/
 #define GLE_FUNCPTR WINAPI
 
 ]]

data/wgl_specversions.lua

+
+return {}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.