Commits

Jason McKesson committed 07f302f

GL Load style generates C++ headers. Now need the source file.

Comments (0)

Files changed (5)

modules/LoadLuaSpec.lua

 -- enums: An array of enumerators. These enumerators are the entries in the main enum array.
 -- funcs: An array of functions. These functions are the entries in the main funcData array.
 - enumtable: A table of enumerators, indexed by their names.
+- functable: A table of functions, indexed by their names.
 - coreexts: A table of core extensions, indexed by extension name. The value of these entries are:
 -- name: The core extension's name.
 -- version: the version that extension became core in. The version is a string.
 	specData.extdefs = {};
 	specData.coredefs = {};
 	specData.enumtable = {};
+	specData.functable = {}
 	local extdefs = specData.extdefs;
 	local coredefs = specData.coredefs;
 	local enumtable = specData.enumtable;
+	local functable = specData.functable
 	
 	--HACK! Change 1.0 version in functions to 1.1, to match enums.
 	for i, func in ipairs(specData.funcData.functions) do
 	end
 
 	for i, func in ipairs(specData.funcData.functions) do
+		functable[func.name] = func;
+	
 		--This is here to make sure that the category is an actual extension,
 		--not a verison number.
 		if(extdefs[func.category]) then

modules/StructGLLoad.lua

 --Common set of header stuff.
 local common_ext_struct =
 { type="group",
-	{ type="enum-iter",
-		{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options)", },
+	{ type="filter", name="EnumsPerExtInGroup", optional=true, cond="enum-iter",
+		{ type="enum-iter",
+			{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen)", },
+		},
+		{ type="blank", cond="enum-iter"},
 	},
-	{ type="blank", cond="enum-iter"},
-	{ type="func-iter",
-		{ type="write", name="FuncTypedef(hFile, func, typemap, spec, options)", },
+	{ type="block", name="FuncTypedefs(hFile, spec, options)", optional=true, cond="func-iter",
+		{ type="func-iter",
+			{ type="write", name="FuncTypedef(hFile, func, typemap, spec, options)", },
+		},
 	},
 	{ type="blank", cond="func-iter"},
 	{ type="func-iter",
 		{ type="write", name="Typedefs(hFile, specData, spec, options)",},
 		{ type="blank"},
 		{ type="block", name="Extern(hFile, spec, options)",
-			{ type="ext-iter",
-				{ type="write", name="ExtVariable(hFile, extName, spec, options)" },
+			{ type="block", name="ExtVariables(hFile, spec, options)", optional=true,
+				{ type="ext-iter",
+					{ type="write", name="ExtVariable(hFile, extName, spec, options)" },
+				},
 			},
 			{ type="blank"},
+			{ type="filter", name="EnumsAllAtOnce", optional=true,
+				{ type="block", name="Enumerators(hFile, spec, options)",
+					{ type="ext-iter",
+						{ type="enum-iter",
+							{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen)", },
+						},
+					},
+				},
+				{ type="blank"},
+			},
+
 			{ type="ext-iter",
 				common_ext_struct,
 			},
 	},
 }
 
+local decl_header_struct =
+{ type="group",
+-- Internal header files.
+{ type="enum-seen",
+{ type="func-seen",
+	--Write the type header file.
+	{ type="file", style="type_hdr", name="GetFilename(basename, spec, options)",
+		{ type="block", name="IncludeGuard(hFile, spec, options)",
+			{ type="write", name="Init(hFile, spec, options)"},
+			{ type="write", name="StdTypedefs(hFile, spec, options)"},
+			{ type="write", name="PassthruTypedefs(hFile, specData, spec, options)"},
+		},
+	},
+	
+	--Write the extension file
+	ext_file_struct,
+	
+	--For each version, write files containing just the core declarations.
+	{ type="version-iter",
+		{ type="filter", name="VersionHasCore(version, specData, spec, options)",
+			{ type="file", style="core_hdr", name="GetFilename(basename, version, spec, options)",
+				{ type="block", name="IncludeGuard(hFile, version, spec, options)",
+					{ type="blank"},
+					{ type="block", name="Extern(hFile, spec, options)",
+						{ type="filter", name="VersionHasCoreEnums(version, specData, spec, options)",
+							{ type="block", name="Enumerators(hFile, spec, options)", optional=true,
+								{ type="enum-iter",
+									{ type="filter", name="CoreEnum(enum)",
+										{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen)", },
+									},
+								},
+							},
+							{ type="blank", cond="enum-iter"},
+						},
+						{ type="block", name="FuncTypedefs(hFile, spec, options)", optional=true, cond="func-iter",
+							{ type="func-iter",
+								{ type="filter", name="CoreFunc(func)",
+									{ type="write", name="FuncTypedef(hFile, func, typemap, spec, options)", },
+								},
+							},
+						},
+						{ type="blank", cond="func-iter"},
+						{ type="func-iter",
+							{ type="filter", name="CoreFunc(func)",
+								{ type="write", name="FuncDecl(hFile, func, typemap, spec, options)", },
+							},
+						},
+						{ type="blank", cond="func-iter"},
+					},
+				},
+			},
+		},
+	},
+	
+	--For each version, write files containing core declarations that were removed.
+	{ type="version-iter",
+		{ type="filter", name="VersionHasRemoved(version, specData, spec, options)",
+			{ type="file", style="core_hdr", name="GetFilenameRem(basename, version, spec, options)",
+				{ type="block", name="IncludeGuardRem(hFile, version, spec, options)",
+					{ type="blank"},
+					{ type="block", name="Extern(hFile, spec, options)",
+						{ type="filter", name="VersionHasCompEnums(version, specData, spec, options)",
+							{ type="block", name="Enumerators(hFile, spec, options)", optional=true,
+								{ type="enum-iter",
+									{ type="filter", name="CompEnum(enum)",
+										{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen)", },
+									},
+								},
+							},
+						},
+						{ type="blank", cond="enum-iter"},
+						{ type="block", name="FuncTypedefs(hFile, spec, options)", optional=true, cond="func-iter",
+							{ type="func-iter",
+								{ type="filter", name="CompFunc(func)",
+									{ type="write", name="FuncTypedef(hFile, func, typemap, spec, options)", },
+								},
+							},
+						},
+						{ type="blank", cond="func-iter"},
+						{ type="func-iter",
+							{ type="filter", name="CompFunc(func)",
+								{ type="write", name="FuncDecl(hFile, func, typemap, spec, options)", },
+							},
+						},
+						{ type="blank", cond="func-iter"},
+					},
+				},
+			},
+		},
+	},
+},
+},
+
+}
+
+
+local include_header_struct =
+{ type="group",
+	--Main header files.
+	{ type="version-iter",
+		{ type="file", style="incl_hdr", name="VersionFilenameCore(basename, version, spec, options)",
+			{ type="block", name="IncludeGuardCore(hFile, version, spec, options)",
+				{ type="blank" },
+				{ type="write", name="IncludeIntType(hFile, spec, options)"},
+				{ type="write", name="IncludeIntExts(hFile, spec, options)"},
+				{ type="blank" },
+				{ type="sub-version-iter",
+					{ type="write", name="IncludeIntVersionCore(hFile, sub_version, specData, spec, options)"},
+					{ type="blank", last=true, },
+				},
+			},
+		},
+	},
+
+	--Compatibility headers.
+	{ type="version-iter",
+		{ type="filter", name="VersionHasCompProfile(version)",
+			{ type="file", style="incl_hdr", name="VersionFilenameComp(basename, version, spec, options)",
+				{ type="block", name="IncludeGuardComp(hFile, version, spec, options)",
+					{ type="blank" },
+					{ type="write", name="IncludeIntType(hFile, spec, options)"},
+					{ type="write", name="IncludeIntExts(hFile, spec, options)"},
+					{ type="blank" },
+					{ type="sub-version-iter",
+						{ type="write", name="IncludeIntVersionCore(hFile, sub_version, specData, spec, options)"},
+						{ type="write", name="IncludeIntVersionComp(hFile, sub_version, specData, spec, options)"},
+						{ type="blank", last=true, },
+					},
+				},
+			},
+		},
+	},
+
+	--Header that includes everything.
+	{ type="file", style="incl_hdr", name="AllFilename(basename, spec, options)",
+		{ type="block", name="IncludeGuardAll(hFile, spec, options)",
+			{ type="blank" },
+			{ type="write", name="IncludeIntType(hFile, spec, options)"},
+			{ type="write", name="IncludeIntExts(hFile, spec, options)"},
+			{ type="blank" },
+			{ type="version-iter",
+				{ type="write", name="IncludeIntVersionCore(hFile, version, specData, spec, options)"},
+				{ type="write", name="IncludeIntVersionComp(hFile, version, specData, spec, options)"},
+				{ type="blank", last=true, },
+			},
+		},
+	},
+}
+
+
 local function CoreLoaderStruct(funcFilter)
 	return
 	{ type="group",
 	}
 end
 
-local source_struct = 
+
+local source_c_struct = 
 { type="group",
 	{ type="write", name="Includes(hFile, spec, options)" },
 	{ type="blank"},
 	{ type="write", name="MainExtraFuncs(hFile, specData, spec, options)", cond="version-iter" },
 }
 
-local decl_header_struct =
+local source_cpp_struct = 
 { type="group",
--- Internal header files.
-{ type="enum-seen",
-{ type="func-seen",
-	--Write the type header file.
-	{ type="file", style="type_hdr", name="GetFilename(basename, spec, options)",
-		{ type="block", name="IncludeGuard(hFile, spec, options)",
-			{ type="write", name="Init(hFile, spec, options)"},
-			{ type="write", name="StdTypedefs(hFile, spec, options)"},
-			{ type="write", name="PassthruTypedefs(hFile, specData, spec, options)"},
+}
+
+local my_struct =
+{
+	{ type="group",
+		decl_header_struct,
+		
+		include_header_struct,
+		
+		--Header to load things.
+		{ type="file", style="load_hdr", name="GetFilename(basename, spec, options)",
+			{ type="block", name="IncludeGuard(hFile, spec, options)",
+				{ type="write", name="LoaderDecl(hFile, spec, options)" },
+			}
+		},
+		
+		--Source file.
+		{ type="file", style="source", name="GetFilename(basename, spec, options)",
+			source_c_struct,
 		},
 	},
 	
-	--Write the extension file
-	ext_file_struct,
-	
-	--For each version, write files containing just the core declarations.
-	{ type="version-iter",
-		{ type="filter", name="VersionHasCore(version, specData, spec, options)",
-			{ type="file", style="core_hdr", name="GetFilename(basename, version, spec, options)",
-				{ type="block", name="IncludeGuard(hFile, version, spec, options)",
-					{ type="blank"},
-					{ type="block", name="Extern(hFile, spec, options)",
-						{ type="enum-iter",
-							{ type="filter", name="CoreEnum(enum)",
-								{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options)", },
-							},
-						},
-						{ type="blank", cond="enum-iter"},
-						{ type="func-iter",
-							{ type="filter", name="CoreFunc(func)",
-								{ type="write", name="FuncTypedef(hFile, func, typemap, spec, options)", },
-							},
-						},
-						{ type="blank", cond="func-iter"},
-						{ type="func-iter",
-							{ type="filter", name="CoreFunc(func)",
-								{ type="write", name="FuncDecl(hFile, func, typemap, spec, options)", },
-							},
-						},
-						{ type="blank", cond="func-iter"},
-					},
-				},
-			},
+	{ type="group", style="cpp",
+		decl_header_struct,
+		
+		include_header_struct,
+		
+		--Header to load things.
+		{ type="file", style="load_hdr", name="GetFilename(basename, spec, options)",
+			{ type="block", name="IncludeGuard(hFile, spec, options)",
+				{ type="write", name="LoaderDecl(hFile, spec, options)" },
+			}
 		},
-	},
-	
-	--For each version, write files containing core declarations that were removed.
-	{ type="version-iter",
-		{ type="filter", name="VersionHasRemoved(version, specData, spec, options)",
-			{ type="file", style="core_hdr", name="GetFilenameRem(basename, version, spec, options)",
-				{ type="block", name="IncludeGuardRem(hFile, version, spec, options)",
-					{ type="blank"},
-					{ type="block", name="Extern(hFile, spec, options)",
-						{ type="enum-iter",
-							{ type="filter", name="CompEnum(enum)",
-								{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options)", },
-							},
-						},
-						{ type="blank", cond="enum-iter"},
-						{ type="func-iter",
-							{ type="filter", name="CompFunc(func)",
-								{ type="write", name="FuncTypedef(hFile, func, typemap, spec, options)", },
-							},
-						},
-						{ type="blank", cond="func-iter"},
-						{ type="func-iter",
-							{ type="filter", name="CompFunc(func)",
-								{ type="write", name="FuncDecl(hFile, func, typemap, spec, options)", },
-							},
-						},
-						{ type="blank", cond="func-iter"},
-					},
-				},
-			},
+		
+		--Source file.
+		{ type="file", style="source", name="GetFilename(basename, spec, options)",
+			source_cpp_struct,
 		},
 	},
-},
-},
-
-}
-
-
-local my_struct =
-{
-	decl_header_struct,
-
-	--Main header files.
-	{ type="version-iter",
-		{ type="file", style="incl_hdr", name="VersionFilenameCore(basename, version, spec, options)",
-			{ type="block", name="IncludeGuardCore(hFile, version, spec, options)",
-				{ type="blank" },
-				{ type="write", name="IncludeIntType(hFile, spec, options)"},
-				{ type="write", name="IncludeIntExts(hFile, spec, options)"},
-				{ type="blank" },
-				{ type="sub-version-iter",
-					{ type="write", name="IncludeIntVersionCore(hFile, sub_version, specData, spec, options)"},
-					{ type="blank", last=true, },
-				},
-			},
-		},
-	},
-
-	--Compatibility headers.
-	{ type="version-iter",
-		{ type="filter", name="VersionHasCompProfile(version)",
-			{ type="file", style="incl_hdr", name="VersionFilenameComp(basename, version, spec, options)",
-				{ type="block", name="IncludeGuardComp(hFile, version, spec, options)",
-					{ type="blank" },
-					{ type="write", name="IncludeIntType(hFile, spec, options)"},
-					{ type="write", name="IncludeIntExts(hFile, spec, options)"},
-					{ type="blank" },
-					{ type="sub-version-iter",
-						{ type="write", name="IncludeIntVersionCore(hFile, sub_version, specData, spec, options)"},
-						{ type="write", name="IncludeIntVersionComp(hFile, sub_version, specData, spec, options)"},
-						{ type="blank", last=true, },
-					},
-				},
-			},
-		},
-	},
-
-	--Header that includes everything.
-	{ type="file", style="incl_hdr", name="AllFilename(basename, spec, options)",
-		{ type="block", name="IncludeGuardAll(hFile, spec, options)",
-			{ type="blank" },
-			{ type="write", name="IncludeIntType(hFile, spec, options)"},
-			{ type="write", name="IncludeIntExts(hFile, spec, options)"},
-			{ type="blank" },
-			{ type="version-iter",
-				{ type="write", name="IncludeIntVersionCore(hFile, version, specData, spec, options)"},
-				{ type="write", name="IncludeIntVersionComp(hFile, version, specData, spec, options)"},
-				{ type="blank", last=true, },
-			},
-		},
-	},
-
-	--Header to load things.
-	{ type="file", style="load_hdr", name="GetFilename(basename, spec, options)",
-		{ type="write", name="LoaderDecl(hFile, spec, options)" },
-	},
-	
-	--Source file.
-	{ type="file", style="source", name="GetFilename(basename, spec, options)",
-		source_struct,
-	},
 }
 
 

modules/Structure.lua

 
 - style: All `name`d functions must be within one of the tables in scope. The `style` command adds an additional scope of the given name. What this means is that the system will check each style within scope for a table with the given name. That table then becomes the most recent style scope that names are looked through. Thus, all names below this node (*including* this node's name) will search through this style and every previous style for their names.
 
+- optional: It is not an error for the `name`d function to be present. The action, and its children, will be processed as normal, ***except*** for `filter` actions. For them, if the function is not present, everything is filtered out; the children will not be processed.
+
 - first: When set, this particular action (and any of its child actions) will only be executed the first time through the most recent iteration loop. Note that this only works for the most recent iteration loop. And it only works within an interation loop, since they are the only ones who execute their children multiple times.
 
 - last: Like first, except for the last time through a block. Usually for inserting blank space.
 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
 	
 			
 			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
 		

modules/StyleGLLoad.lua

 	return dir .. glload.headerDirectory .. glload.GetTypeHeaderBasename(spec, options)
 end
 
-function type_hdr.WriteBlockBeginIncludeGuard(hFile, spec, options)
-	local includeGuard = glload.GetTypeHdrFileIncludeGuard(spec, options)
-	hFile:fmt("#ifndef %s\n", includeGuard)
-	hFile:fmt("#define %s\n", includeGuard)
-end
-
-function type_hdr.WriteBlockEndIncludeGuard(hFile, spec, options)
-	hFile:fmt("#endif /*%s*/\n", glload.GetTypeHdrFileIncludeGuard(spec, options))
-end
+glload.CreateIncludeGuardWriters(type_hdr, "IncludeGuard",
+	function(...) return glload.GetTypeHdrFileIncludeGuard(...) end)
 
 function type_hdr.WriteInit(hFile, spec, options)
 	hFile:rawwrite(spec.GetHeaderInit())
 		glload.GetExtVariableName(extName, spec, options))
 end
 
+function ext_hdr.FilterEnumsPerExtInGroup() return true end
+
 function ext_hdr.WriteEnumerator(hFile, enum, enumTable, spec, options)
 	hFile:fmt("#define %s %s\n",
 		glload.GetEnumeratorName(enum, spec, options),
 	return dir .. glload.headerDirectory .. glload.GetLoaderBasename(spec, options)
 end
 
+glload.CreateIncludeGuardWriters(load_hdr, "IncludeGuard",
+	function(...) return glload.GetInclFileLoaderIncludeGuard(...) end)
+
 function load_hdr.WriteLoaderDecl(hFile, spec, options)
 	hFile:writeblock(glload.GetLoaderHeaderString(spec, options))
 end
 
+
 ----------------------------------------------------------
 -- Source file.
 local source = {}
 	hFile:writeblock(common.GetProcessExtsFromStringFunc("LoadExtByName(%s)"))
 end
 
-local function FindFuncByName(specData, name)
-	for _, func in ipairs(specData.funcData.functions) do
-		if(name == func.name) then
-			return func
-		end
-	end
-end
-
 function source.WriteMainLoader(hFile, specData, spec, options)
 	if(options.version) then
 		hFile:writeblock[[
 	if(options.version) then
 		--Get the current version.
 		--To do that, we need certain functions.
-		local strFunc = FindFuncByName(specData, "GetString")
+		local strFunc = specData.functable["GetString"]
 		
 		hFile:writeblock(glload.GetInMainFuncLoader(hFile, strFunc, spec, options))
 		strFunc = glload.GetFuncPtrName(strFunc, spec, options)
 	else
 		local extListName, needLoad = spec.GetExtStringFuncName()
 		if(needLoad) then
-			extListName = FindFuncByName(specData, extListName)
+			extListName = specData.functable[extListName]
 			
 			hFile:writeblock(glload.GetInMainFuncLoader(hFile, extListName, spec, options))
 
 ]]
 end
 
+----------------------------------------------------------
+-- C++ styling.
+
+local cpp = {}
+
+cpp.type_hdr = util.DeepCopyTable(type_hdr)
+cpp.ext_hdr = util.DeepCopyTable(ext_hdr)
+cpp.core_hdr = util.DeepCopyTable(core_hdr)
+cpp.incl_hdr = util.DeepCopyTable(incl_hdr)
+cpp.load_hdr = util.DeepCopyTable(load_hdr)
+cpp.source = {}
+
+function cpp._init()
+	glload = glload.cpp
+end
+
+function cpp._exit()
+	glload = require "glload_util"
+end
+
+function cpp.ext_hdr.WriteBlockBeginExtern(hFile, spec, options)
+	glload.WriteNamespaceBegin(hFile, spec.FuncNamePrefix())
+end
+
+function cpp.ext_hdr.WriteBlockEndExtern(hFile, spec, options)
+	glload.WriteNamespaceEnd(hFile)
+end
+
+function cpp.ext_hdr.WriteBlockBeginExtVariables(hFile, spec, options)
+	glload.WriteNamespaceBegin(hFile, "exts")
+	hFile:writeblock(glload.LoadTestClassDef())
+	hFile:write "\n"
+end
+
+function cpp.ext_hdr.WriteBlockEndExtVariables(hFile, spec, options)
+	glload.WriteNamespaceEnd(hFile)
+end
+
+function cpp.ext_hdr.FilterEnumsAllAtOnce() return true end
+cpp.ext_hdr.FilterEnumsPerExtInGroup = nil
+
+function cpp.ext_hdr.WriteBlockBeginEnumerators(hFile, spec, options)
+	hFile:write("enum\n")
+	hFile:write "{\n"
+	hFile:inc()
+end
+
+function cpp.ext_hdr.WriteBlockEndEnumerators(hFile, spec, options)
+	hFile:dec()
+	hFile:write "};\n"
+end
+
+function cpp.ext_hdr.WriteEnumerator(hFile, enum, enumTable, spec, options)
+	local enumName = glload.GetCppEnumName(enum)
+	local lenEnum = #enumName
+	local numIndent = 33
+	
+	local numSpaces = numIndent - lenEnum
+	if(numSpaces < 1) then
+		numSpaces = 1
+	end
+
+	hFile:fmt("%s%s= %s,\n",
+		enumName,
+		string.rep(" ", numSpaces),
+		common.ResolveEnumValue(enum, enumTable))
+end
+
+function cpp.ext_hdr.WriteBlockBeginFuncTypedefs(hFile, spec, options)
+	glload.WriteNamespaceBegin(hFile, glload.GetFuncPtrTypedefNamespace())
+end
+
+function cpp.ext_hdr.WriteBlockEndFuncTypedefs(hFile, spec, options)
+	glload.WriteNamespaceEnd(hFile)
+end
+
+function cpp.ext_hdr.WriteFuncDecl(hFile, func, typemap, spec, options)
+	hFile:fmt("extern %s::%s %s;\n",
+		glload.GetFuncPtrTypedefNamespace(),
+		glload.GetFuncTypedefName(func, spec, options),
+		func.name)
+end
+
+cpp.core_hdr.WriteBlockBeginExtern = cpp.ext_hdr.WriteBlockBeginExtern
+cpp.core_hdr.WriteBlockEndExtern = cpp.ext_hdr.WriteBlockEndExtern
+
+cpp.core_hdr.WriteBlockBeginEnumerators = cpp.ext_hdr.WriteBlockBeginEnumerators
+cpp.core_hdr.WriteBlockEndEnumerators = cpp.ext_hdr.WriteBlockEndEnumerators
+
+function cpp.core_hdr.WriteEnumerator(hFile, enum, enumTable, spec, options, enumSeen)
+	if(enumSeen[enum.name]) then
+		hFile:fmt("//%s taken from %s",
+			enum.name,
+			enumSeen[enum.name])
+	else
+		cpp.ext_hdr.WriteEnumerator(hFile, enum, enumTable, spec, options, enumSeen)
+	end
+end
+
+cpp.core_hdr.WriteBlockBeginFuncTypedefs = cpp.ext_hdr.WriteBlockBeginFuncTypedefs
+cpp.core_hdr.WriteBlockEndFuncTypedefs = cpp.ext_hdr.WriteBlockEndFuncTypedefs
+cpp.core_hdr.WriteFuncDecl = cpp.ext_hdr.WriteFuncDecl
+
+
+--------------------------------------------------------------
+-- Source CPP file.
+function cpp.source.GetFilename(basename, spec, options)
+	local basename, dir = util.ParsePath(basename)
+	return dir .. glload.sourceDirectory .. spec.FilePrefix() .. "load.cpp"
+end
+
+
 ------------------------------------------------------
 -- Filters
 
 	incl_hdr = incl_hdr,
 	load_hdr = load_hdr,
 	source = source,
+	cpp = cpp
 }
 
 function my_style.FilterVersionHasRemoved(version, specData, spec, options)
 	return false
 end
 
+function my_style.FilterVersionHasCoreEnums(version, specData, spec, options)
+	for _, enum in ipairs(specData.coredefs[version].enums) do
+		if(not enum.removed and not enum.extensions) then
+			return true
+		end
+	end
+	
+	return false
+end
+
+function my_style.FilterVersionHasCompEnums(version, specData, spec, options)
+	for _, enum in ipairs(specData.coredefs[version].enums) do
+		if(enum.removed and not enum.extensions) then
+			return true
+		end
+	end
+	
+	return false
+end
+
 function my_style.FilterVersionHasCoreFuncs(version, specData, spec, options)
 	local coreExtByVersion = spec.GetCoreExts()
 	if(not coreExtByVersion) then return end

modules/glload_util.lua

 local common = require "CommonStyle"
 
 local data = {}
+data.cpp = {}
 
 data.internalPrefix = "_int_"
 data.headerDirectory = "include/glload/"
 data.includeDirectory = "glload/" --For inclusions from source.
 data.sourceDirectory = "source/"
 
+
+
+function data.CreateIncludeGuardWriters(tbl, name, Func)
+	tbl["WriteBlockBegin" .. name] = function(hFile, ...)
+		local includeGuard = Func(...)
+		hFile:fmt("#ifndef %s\n", includeGuard)
+		hFile:fmt("#define %s\n", includeGuard)
+	end
+	tbl["WriteBlockEnd" .. name] = function(hFile, ...)
+		local includeGuard = Func(...)
+		hFile:fmt("#endif /*%s*/\n", includeGuard)
+	end
+end
+
+
+-----------------------------------------------
+-- Header filenames
 function data.GetLoaderBasename(spec, options)
 	return spec.FilePrefix() .. "load.h"
 end
 	return spec.GetIncludeGuardString() .. "_GEN_ALL_H"
 end
 
+function data.GetInclFileLoaderIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_LOAD_FUNCTIONS_H"
+end
+
 function data.GetBeginExternBlock()
 	return [[
 #ifdef __cplusplus
 end
 
 
+----------------------------------------------------------------------------
+-- CPP-specific
+data.cpp = util.DeepCopyTable(data)
+
+function data.cpp.GetLoaderBasename(spec, options)
+	return spec.FilePrefix() .. "load.hpp"
+end
+
+function data.cpp.GetVersionCoreBasename(version, spec, options)
+	return spec.FilePrefix() .. version:gsub("%.", "_") .. ".hpp"
+end
+
+function data.cpp.GetVersionCompBasename(version, spec, options)
+	return spec.FilePrefix() .. version:gsub("%.", "_") .. "_comp.hpp"
+end
+
+function data.cpp.GetAllBasename(spec, options)
+	return spec.FilePrefix() .. "all.hpp"
+end
+
+function data.cpp.GetTypeHeaderBasename(spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. "type.hpp"
+end
+
+function data.cpp.GetExtsHeaderBasename(spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. "exts.hpp"
+end
+
+function data.cpp.GetCoreHeaderBasename(version, spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. version:gsub("%.", "_") .. ".hpp"
+end
+
+function data.cpp.GetRemHeaderBasename(version, spec, options)
+	return data.internalPrefix .. spec.FilePrefix() .. version:gsub("%.", "_") .. "_rem.hpp"
+end
+
+function data.cpp.GetTypeHdrFileIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_TYPE" .. "_HPP"
+end
+
+function data.cpp.GetExtFileIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_EXTENSIONS" .. "_HPP"
+end
+
+function data.cpp.GetCoreHdrFileIncludeGuard(version, spec, options, removed)
+	if(removed) then
+		return spec.GetIncludeGuardString() .. "_GEN_CORE_REM" .. version:gsub("%.", "_") .. "_HPP"
+	else
+		return spec.GetIncludeGuardString() .. "_GEN_CORE_" .. version:gsub("%.", "_") .. "_HPP"
+	end
+end
+
+function data.cpp.GetInclFileIncludeGuard(version, spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_" .. version:gsub("%.", "_") .. "_HPP"
+end
+
+function data.cpp.GetInclFileCompIncludeGuard(version, spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_" .. version:gsub("%.", "_") .. "COMP_HPP"
+end
+
+function data.cpp.GetInclFileAllIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_ALL_HPP"
+end
+
+function data.cpp.GetInclFileLoaderIncludeGuard(spec, options)
+	return spec.GetIncludeGuardString() .. "_GEN_LOAD_FUNCTIONS_HPP"
+end
+
+function data.cpp.WriteNamespaceBegin(hFile, namespace)
+	hFile:fmt("namespace %s\n", namespace)
+	hFile:write("{\n")
+	hFile:inc()
+end
+
+function data.cpp.WriteNamespaceEnd(hFile)
+	hFile:dec()
+	hFile:write("}\n")
+end
+
+function data.cpp.LoadTestClassDef()
+	return [[
+class LoadTest
+{
+private:
+	//Safe bool idiom. Joy!
+	typedef void (LoadTest::*bool_type)() const;
+	void big_long_name_that_really_doesnt_matter() const {}
+	
+public:
+	operator bool_type() const
+	{
+		return m_isLoaded ? &LoadTest::big_long_name_that_really_doesnt_matter : 0;
+	}
+	
+	int GetNumMissing() const {return m_numMissing;}
+	
+	LoadTest() : m_isLoaded(false), m_numMissing(0) {}
+	LoadTest(bool isLoaded, int numMissing) : m_isLoaded(isLoaded), m_numMissing(numMissing) {}
+private:
+	bool m_isLoaded;
+	int m_numMissing;
+};
+]]
+end
+
+function data.cpp.GetFuncTypedefName(func, spec, options)
+	local temp = "Proc_" .. spec.FuncNamePrefix() .. func.name
+	return temp
+end
+
+function data.cpp.GetFuncPtrTypedefNamespace()
+	return "_detail"
+end
+
+function data.cpp.GetCppEnumName(enum)
+	--Note: some enumerators start with characters C++ forbids as initial
+	--identifiers. If we detect such an enum, prefix it with `_`.
+	local enumName = enum.name
+	if(not enumName:match("^[a-zA-Z_]")) then
+		enumName = "_" .. enumName
+	end
+	
+	--Also, certain identifiers can need it because they conflict.
+	local badIdent = {"TRUE", "FALSE", "NO_ERROR", "WAIT_FAILED"}
+	for _, ident in ipairs(badIdent) do
+		if(enumName == ident) then
+			enumName = enumName .. "_"
+			break
+		end
+	end
+	
+	return enumName
+end
+
+local cpp_hdr_extra_spec =
+{
+	wgl = "",
+	glX = "",
+	gl = [=[
+		/**
+		This function retrieves the major GL version number. Only works after LoadFunctions has been called.
+		**/
+		int GetMajorVersion();
+
+		/**
+		This function retrieves the minor GL version number. Only works after LoadFunctions has been called.
+		**/
+		int GetMinorVersion();
+
+		/**Returns non-zero if the current GL version is greater than or equal to the given version.**/
+		int IsVersionGEQ(int testMajorVersion, int testMinorVersion);
+]=],
+}
+
+local hdr_pattern = 
+[=[
+/**
+\file
+\brief C++ header to include if you want to initialize $<specname>.
+
+**/
+
+
+///\addtogroup module_glload_cppinter
+///@{
+
+///The core namespace for the C++ interface for the OpenGL initialization functions.
+namespace $<funcspec>
+{
+	namespace sys
+	{
+		/**
+		\brief The loading status returned by the loader function.
+
+		**/
+]=]
+.. data.cpp.LoadTestClassDef() ..
+[=[
+
+		/**
+		\brief Loads all of the function pointers available.
+
+$<desc>
+
+		\return A sys::LoadTest object that defines whether the loading was successful.
+		**/
+		LoadTest LoadFunctions($<params>);
+
+$<extra>
+	}
+}
+///@}
+]=]
+
+function data.cpp.GetLoaderHeaderString(spec, options)
+	local ret = hdr_pattern
+	ret = ret:gsub("%$%<extra%>", cpp_hdr_extra_spec[options.spec])
+	ret = ret:gsub("%$%<specname%>", spec.DisplayName())
+	ret = ret:gsub("%$%<prefix%>", spec.DeclPrefix())
+	ret = ret:gsub("%$%<desc%>", hdr_desc[options.spec])
+	ret = ret:gsub("%$%<params%>", spec.GetLoaderParams())
+	ret = ret:gsub("%$%<funcspec%>", spec.FuncNamePrefix())	
+	return ret
+end
+
+
+
+
+
 return data