Commits

Jason McKesson  committed 7cfe2d3

GLEE-style finished, but untested.

  • Participants
  • Parent commits b908364

Comments (0)

Files changed (6)

File docs/Structure_Reference.xml

                                 inherited</emphasis>. This parameter is not given to any child
                             actions; only the action this value is set on will have access to this
                             value.</para>
+                        <para>The value must be a string. However, to allow the string to use
+                            various names defined by the system, the string can have special codes
+                            in it. Any use of <quote>%</quote> in the string will denote the
+                            beginning of a special name. Thus, you shouldn't do things like this:
+                                    <quote><literal>some%string</literal>,</quote> this will make
+                            the system think that <literal>%string</literal> is a special name. If
+                            you use <quote>%</quote> by itself, with a space or non-identifier
+                            characters after it, then it will remain a % sign. So
+                                    <quote><literal>some% string</literal></quote> is fine, as is
+                                    <quote><literal>some%-string</literal></quote>.</para>
+                        <para>The special names are just context variable names, only a limited
+                            subset of them. Of the standard context variables, the only ones you can
+                            use are those which are naturally strings (like
+                                <literal>version</literal> and <literal>extName</literal>) or those
+                            which are reasonably convertible to strings (<literal>enum</literal>
+                            would return it's basic string name, with no prefixing).</para>
+                        <para>The main purpose of this is to be able to print messages easily, like
+                            comments that say that extension X's declarations begin here.</para>
+                        <para>User-defined context variables can also be used, but they must be
+                            either strings or tables. If they are tables, then they either must have
+                            a <literal>__tostring</literal> metamethod, or they must have a member
+                            function called <literal>_ValueResolve</literal> function. This function
+                            only takes the table as a parameter.</para>
                     </glossdef>
                 </glossentry>
                 <glossentry>

File modules/CommonStyle.lua

 end
 common.ResolveEnumValue = ResolveEnumValue
 
+function common.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
+
+function common.GetNameLengthPadding(name, length)
+	local numSpaces = length - #name
+	if(numSpaces < 1) then
+		numSpaces = 1
+	end
+	
+	return string.rep(" ", numSpaces)
+end
+
 --Gets the return type for a function.
 function common.GetFuncReturnType(func, typemap)
 	return typemap[func["return"]] or func["return"]
 end
 
+function common.DoesFuncReturnSomething(func, typemap)
+	local returnType = typemap[func["return"]] or func["return"]
+	return (returnType == "void") or (returnType == "GLvoid")
+end
+
 local bIsKindPtr ={
 	value = false,
 	array = true,
 	return table.concat(paramList, ", ");
 end
 
+--Get the list of parameter names, as a string ready to be put into ().
+function common.GetFuncParamCallList(func, typemap)
+	local paramList = {}
+	for i, param in ipairs(func.params) do
+		paramList[#paramList + 1] = param.name
+	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
 
+function common.WriteNamespaceBegin(hFile, namespace)
+	hFile:fmt("namespace %s\n", namespace)
+	hFile:write("{\n")
+	hFile:inc()
+end
+
+function common.WriteNamespaceEnd(hFile)
+	hFile:dec()
+	hFile:write("}\n")
+end
+
+
 common.DeepCopyTable = DeepCopyTable
 
 local my_struct =

File modules/StructGleeCpp.lua

+
+local struct = require "Structure"
+
+
+local ext_variables = 
+{ type="group",
+	{ type="write", name="LargeHeader(hFile, value, options)", value="Extension Variables", },
+	{ type="block", name="ExtVariables(hFile, spec, options)",
+		{ type="ext-iter",
+			{ type="write", name="ExtVariable(hFile, extName, spec, options)", },
+		},
+	},
+}
+
+local func_variables =
+{ type="group",
+{ type="func-seen",
+	{ type="ext-iter",
+		{type="func-iter",
+			{ type="write", name="SmallHeader(hFile, value, options)", value="Extension: %extName", first=true},
+			{ type="write", name="Function(hFile, func, typemap, spec, options, funcSeen)", },
+			{ type="blank", last=true },
+		},
+	},
+	{ type="version-iter",
+		{ type="core-ext-cull-iter",
+			{type="func-iter",
+				{ type="write", name="SmallHeader(hFile, value, options)", value="Extension: %extName", first=true},
+				{ type="write", name="Function(hFile, func, typemap, spec, options, funcSeen)", },
+				{ type="blank", last=true },
+			},
+		},
+		{type="func-iter",
+			{ type="write", name="SmallHeader(hFile, value, options)", value="Extension: %version", first=true},
+			{ type="write", name="Function(hFile, func, typemap, spec, options, funcSeen)", },
+			{ type="blank", last=true },
+		},
+	},
+},
+}
+
+local sys_functions =
+{ type="block", name="System(hFile, spec, options)",
+	{type="write", name="SetupFunction(hFile, specData, spec, options)", },
+	{type="blank", cond="version-iter" },
+	{type="write", name="VersionFunctions(hFile, specData, spec, options)", cond="version-iter"},
+}
+
+
+local my_struct =
+{
+	{ type="file", style="hdr", name="GetFilename(basename, spec, options)",
+		{ type="block", name="IncludeGuard",
+			{ type="blank"},
+			{ type="write", name="Guards(hFile, spec, options)",},
+			{ type="blank"},
+			{ type="write", name="Typedefs(hFile, specData, spec, options)",},
+			{ type="blank"},
+			
+			{ type="block", name="MainNamespace(hFile, spec, options)",
+				ext_variables,
+				{ type="blank"},
+				{ type="block", name="Enumerators(hFile, spec, options)",
+					{ type="enum-seen",
+						{ type="ext-iter",
+							{type="enum-iter",
+								{ type="write", name="SmallHeader(hFile, value, options)", value="Extension: %extName", first=true},
+								{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen)", },
+								{ type="blank", last=true },
+							},
+						},
+						{ type="version-iter",
+							{ type="core-ext-cull-iter",
+								{type="enum-iter",
+									{ type="write", name="SmallHeader(hFile, value, options)", value="Core Extension: %extName", first=true},
+									{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen)", },
+									{ type="blank", last=true },
+								},
+							},
+							{type="enum-iter",
+								{ type="write", name="SmallHeader(hFile, value, options)", value="Version: %version", first=true},
+								{ type="write", name="Enumerator(hFile, enum, enumTable, spec, options, enumSeen)", },
+								{ type="blank", last=true },
+							},
+						},
+					},
+				},
+				{ type="blank"},
+				func_variables,
+				sys_functions,
+			},
+		},
+	},
+	
+	{ type="file", style="src", name="GetFilename(basename, spec, options)",
+		{ type="write", name="Includes(hFile, basename, spec, options)", },
+		{ type="blank"},
+		{ type="write", name="LoaderFunc(hFile, spec, options)", },
+		{ type="blank"},
+		{ type="block", name="MainNamespace(hFile, spec, options)",
+			{ type="group", style="typedefs",
+				func_variables,
+			},
+			{ type="group", style="defs",
+				func_variables,
+			},
+			{ type="blank"},
+			{ type="group", style="switch",
+				func_variables,
+			},
+			{ type="blank"},
+			{ type="block", name="Struct(hFile, spec, options)", style="init",
+				func_variables,
+			},
+			sys_functions,
+		},
+	},
+}
+
+my_struct = struct.BuildStructure(my_struct)
+return my_struct

File modules/Structure.lua

 	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.")
 	end
 	
 	if(self.value) then
-		context.value = self.value
+		context.value = self:Assert(ResolveValue(context, self.value))
 	end
 	
 	local paramList = {}
 	return unpack(rets)
 end
 
-function action:Assert(test, text)
+function action:Assert(...)
+	local test, text = ...
 	if(not test) then
 		local msg = ": " .. text
 		if(self.name) then
 		end
 		assert(test, msg)
 	end
+	
+	return ...
 end
 
 --Iterates over the list, setting the second element returned from the iterator
 	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)

File modules/StyleGleeCpp.lua

+local util = require "util"
+local struct = require "StructGleeCpp"
+local common = require "CommonStyle"
+
+--------------------------------------
+-- Common functions.
+local function GetIncludeGuard(spec, options)
+	local temp = 
+		options.prefix .. spec.GetIncludeGuardString() .. "_GLEE_STYLE_HPP"
+	return temp:upper()
+end
+
+local function GetFuncPtrName(func, spec, options)
+	return func.name
+end
+
+local function GetFuncPtrTypedefName(func, spec, options)
+	return "PFN" .. GetFuncPtrName(func, spec, options):upper() .. "PROC"
+end
+
+local function WriteFuncPtrTypedefStmt(hFile, func, typemap, spec, options)
+	hFile:fmt("typedef %s (%s *%s)(%s);\n",
+		common.GetFuncReturnType(func, typemap),
+		spec.GetCodegenPtrType(),
+		GetFuncPtrTypedefName(func, spec, options),
+		common.GetFuncParamList(func, typemap))
+end
+
+local function GetFuncPtrDefDirect(func, typemap, spec, options)
+	return string.format("%s (%s *%s)(%s)",
+		common.GetFuncReturnType(func, typemap),
+		spec.GetCodegenPtrType(),
+		GetFuncPtrName(func, spec, options),
+		common.GetFuncParamList(func, typemap, true))
+end
+
+local function GetFuncPtrDefTypedef(func, typemap, spec, options)
+	return string.format("%s %s",
+		GetFuncPtrTypedefName(func, spec, options),
+		GetFuncPtrName(func, spec, options))
+end
+
+--------------------------------------
+-- All style functions.
+local my_style = {}
+
+function my_style.WriteLargeHeader(hFile, value, options)
+	local len = #value
+	hFile:write("///", string.rep("/", len), "///\n")
+	hFile:write("// ", value, "\n")
+end
+
+function my_style.WriteSmallHeader(hFile, value, options)
+	hFile:write("// ", value, "\n")
+end
+
+function my_style.WriteBlockBeginMainNamespace(hFile, spec, options)
+	if(#options.prefix > 0) then
+		common.WriteNamespaceBegin(hFile, options.prefix)
+	end
+	
+	common.WriteNamespaceBegin(hFile, spec.FuncNamePrefix())
+end
+
+function my_style.WriteBlockEndMainNamespace(hFile, spec, options)
+	common.WriteNamespaceEnd(hFile, spec.FuncNamePrefix())
+	
+	if(#options.prefix > 0) then
+		common.WriteNamespaceEnd(hFile, options.prefix)
+	end
+end
+
+function my_style.WriteBlockBeginExtVariables(hFile, spec, options)
+	common.WriteNamespaceBegin(hFile, "exts")
+end
+
+function my_style.WriteBlockEndExtVariables(hFile, spec, options)
+	common.WriteNamespaceEnd(hFile, "exts")
+end
+
+function my_style.WriteBlockBeginSystem(hFile, spec, options)
+	common.WriteNamespaceBegin(hFile, "sys")
+end
+
+function my_style.WriteBlockEndSystem(hFile, spec, options)
+	common.WriteNamespaceEnd(hFile, "sys")
+end
+
+
+---------------------------------------------
+-- Header functions.
+local hdr = {}
+my_style.hdr = hdr
+
+function hdr.GetFilename(basename, spec, options)
+	return basename .. ".hpp"
+end
+
+function hdr.WriteBlockBeginIncludeGuard(hFile, spec, options)
+	local guard = GetIncludeGuard(spec, options)
+	hFile:fmt("#ifndef %s\n", guard)
+	hFile:fmt("#define %s\n", guard)
+end
+
+function hdr.WriteBlockEndIncludeGuard(hFile, spec, options)
+	hFile:fmt("#endif //%s\n", GetIncludeGuard(spec, options))
+end
+
+function hdr.WriteGuards(hFile, spec, options)
+	hFile:rawwrite(spec.GetHeaderInit())
+end
+
+function hdr.WriteTypedefs(hFile, specData, spec, options)
+	local defArray = common.GetStdTypedefs()
+	
+	--Use include-guards for the typedefs, since they're common among
+	--headers in this style.
+	hFile:write("#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS\n")
+	hFile:write("#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS\n")
+	hFile:write("\n")
+	hFile:inc()
+	
+	for _, def in ipairs(defArray) do
+		hFile:write(def)
+	end
+	
+	hFile:dec()
+	hFile:write("\n")
+	hFile:write("#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/\n")
+	hFile:write("\n")
+
+	common.WritePassthruData(hFile, specData.funcData.passthru)
+end
+
+function hdr.WriteExtVariable(hFile, extName, spec, options)
+	hFile:fmt("extern bool %s;\n", extName)
+end
+
+function hdr.WriteBlockBeginEnumerators(hFile, spec, options)
+	hFile:writeblock("enum\n{\n")
+	hFile:inc()
+end
+
+function hdr.WriteBlockEndEnumerators(hFile, spec, options)
+	hFile:dec()
+	hFile:write("}\n")
+end
+
+function hdr.WriteEnumerator(hFile, enum, enumTable, spec, options, enumSeen)
+	if(enumSeen[enum.name]) then
+		hFile:fmt("//%s seen in %s\n", enum.name, enumSeen[enum.name])
+	else
+		local name = common.GetCppEnumName(enum)
+		hFile:fmt("%s%s= %s,\n",
+			name,
+			common.GetNameLengthPadding(name, 33),
+			common.ResolveEnumValue(enum, enumTable))
+	end
+end
+
+function hdr.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	if(funcSeen[func.name]) then return end
+	
+	hFile:write(GetFuncPtrDefDirect(func, typemap, spec, options), "\n")
+end
+
+function hdr.WriteSetupFunction(hFile, specData, spec, options)
+	hFile:fmt("void CheckExtensions(%s);\n", spec.GetLoaderParams())
+end
+
+function hdr.WriteVersionFunctions(hFile, specData, spec, options)
+end
+
+
+----------------------------------------
+-- Source file.
+local src = {}
+my_style.src = src
+
+function src.GetFilename(basename, spec, options)
+	return basename .. ".cpp"
+end
+
+function src.WriteIncludes(hFile, basename, spec, options)
+	hFile:writeblock([[
+#include <algorithm>
+#include <string.h>
+]])
+
+	local base = util.ParsePath(hdr.GetFilename(basename, spec, options))
+	hFile:fmt('#include "%s"\n', base)
+
+end
+
+function src.WriteLoaderFunc(hFile, spec, options)
+	hFile:writeblock(spec.GetLoaderFunc())
+end
+
+function src.WriteSetupFunction(hFile, specData, spec, options)
+	common.WriteNamespaceBegin(hFile, "")
+	hFile:writeblock[[
+struct MapEntry
+{
+	const char *extName;
+	bool *extVariable;
+};
+
+struct MapCompare
+{
+	MapCompare(const char *test_) : test(test_) {}
+	bool operator()(const MapEntry &other) { return strcmp(test, other.extName) == 0; }
+	const char *test;
+};
+
+struct ClearEntry
+{
+  void operator()(MapEntry &entry) { *(entry.extVariable) = false;}
+};
+
+]]
+	hFile:write("MapEntry g_mappingTable[] =\n")
+	hFile:write "{\n"
+	hFile:inc()
+	for _, extName in ipairs(options.extensions) do
+		hFile:fmt('{"%s%s", &exts::%s},\n',
+			spec.ExtNamePrefix(),
+			extName,
+			extName)
+	end
+	hFile:dec()
+	hFile:write "};\n"
+	
+	hFile:write "\n"
+	hFile:fmtblock([[
+void LoadExtByName(const char *extensionName)
+{
+	std::vector<MapEntry>::iterator entry = std::find_if(&g_mappingTable[0], &g_mappingTable[%i], MapCompare(extensionName));
+	
+	if(entry != table.end())
+		(*entry->extVariable) = true;
+}
+]], #options.extensions)
+
+	hFile:write "\n"
+	
+	local indexed = spec.GetIndexedExtStringFunc(options);
+	if(indexed) then
+		indexed[1] = specData.functable[indexed[1]]
+		indexed[3] = specData.functable[indexed[3]]
+		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([[
+void ProcExtsFromExtList()
+{
+	GLint iLoop;
+	GLint iNumExtensions = 0;
+	]] .. indexed[1].name
+	.. [[(]] .. indexed[2].name
+	.. [[, &iNumExtensions);
+
+	for(iLoop = 0; iLoop < iNumExtensions; iLoop++)
+	{
+		const char *strExtensionName = (const char *)]] ..
+		indexed[3].name ..
+		[[(]] .. indexed[4].name .. [[, iLoop);
+		LoadExtByName(strExtensionName);
+	}
+}
+]])
+	else
+		hFile:writeblock(
+			common.GetProcessExtsFromStringFunc("LoadExtByName(%s)"))
+	end
+
+	common.WriteNamespaceEnd(hFile, "")
+	
+	hFile:fmt("void CheckExtensions(%s)\n", spec.GetLoaderParams())
+	hFile:write "{\n"
+	hFile:inc()
+	hFile:fmt("std::for_each(&g_mappingTable[0], &g_mappingTable[%i], ClearEntry());\n", #options.extensions)
+	hFile:write "\n"
+	if(indexed) then
+		hFile:write("ProcExtsFromExtList();\n")
+	else
+		hFile:fmt("ProcExtsFromExtString((const char *)%s(%s));\n",
+			spec.GetExtStringFuncName(),
+			spec.GetExtStringParamList(
+				function (name) return spec.FuncNamePrefix() .. "::" .. name end))
+	end
+	hFile:dec()
+	hFile:write "}\n"
+end
+
+function src.WriteVersionFunctions(hFile, specData, spec, options)
+end
+
+local typedefs = {}
+src.typedefs = typedefs
+
+function typedefs.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	WriteFuncPtrTypedefStmt(hFile, func, typemap, spec, options)
+end
+
+local defs = {}
+src.defs = defs
+
+function defs.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	hFile:write(GetFuncPtrDefTypedef(func, typemap, spec, options), "\n")
+end
+
+local switch = {}
+src.switch = switch
+
+function switch.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	hFile:fmt("static %s %s Switch_%s(%s);\n",
+		spec.GetCodegenPtrType(),
+		common.GetFuncReturnType(func, typemap),
+		func.name,
+		common.GetFuncParamList(func, typemap, true))
+	hFile:write "{\n"
+	hFile:inc()
+	hFile:fmt('%s = (%s)%s("%s");\n',
+		GetFuncPtrName(func, spec, options),
+		GetFuncPtrTypedefName(func, spec, options),
+		spec.GetPtrLoaderFuncName(),
+		func.name)
+		
+	if(common.DoesFuncReturnSomething(func, typemap)) then
+		hFile:fmt('%s(%s);\n',
+			GetFuncPtrName(func, spec, options),
+			common.GetFuncParamCallList(func, typemap))
+	else
+		hFile:fmt('return %s(%s);\n',
+			GetFuncPtrName(func, spec, options),
+			common.GetFuncParamCallList(func, typemap))
+	end
+	hFile:dec()
+	hFile:write "}\n\n"
+end
+
+local init = {}
+src.init = init
+
+function init.WriteBlockBeginStruct(hFile, spec, options)
+	common.WriteNamespaceBegin(hFile, "")
+	hFile:write("struct InitializeVariables\n")
+	hFile:write "{\n"
+	hFile:inc()
+
+	hFile:write("InitializeVariables()\n")
+	hFile:write "{\n"
+	hFile:inc()
+end
+
+function init.WriteBlockEndStruct(hFile, spec, options)
+	hFile:dec()
+	hFile:write "}\n"
+	hFile:dec()
+	hFile:write "};\n\n"
+	hFile:write("InitializeVariables g_initVariables;\n")
+end
+
+function init.WriteFunction(hFile, func, typemap, spec, options, funcSeen)
+	hFile:fmt("%s = Switch_%s;\n", func.name, func.name)
+end
+
+
+local function Create()
+	return common.DeepCopyTable(my_style), struct
+end
+
+return { Create = Create }
+

File modules/Styles.lua

 	pointer_c = require("StylePointerC"),
 	pointer_cpp = require("StylePointerCPP"),
 	glload = require("StyleGLLoad"),
+	glee_cpp = require("StyleGleeCpp"),
 }
 
 local default_style = "pointer_c"