Commits

Jason McKesson committed 7748c22

System for generating test data semi-automatically and for generating projects.

Comments (0)

Files changed (6)

+
+
+local tests =
+{
+	[[lua $<dir>LoadGen.lua -spec=gl -version=3.3 -profile=core -style=pointer_cpp -stdext=extfiles/gl_ubiquitous.txt $<dir>test/pointer_cpp/test]],
+}
+
+local platTests =
+{
+	wgl =
+	{
+		[[lua $<dir>LoadGen.lua -spec=wgl -style=pointer_cpp -stdext=extfiles/wgl_common.txt $<dir>test/pointer_cpp/test]],
+	},
+	
+	glX =
+	{
+	},
+}
+
+local glXTests = {}
+
+local baseDir = arg[0]:match("^(.*[\\/])")
+baseDir = baseDir or "./"
+
+local function ExecTests(testList)
+	for _, test in ipairs(testList) do
+		test = test:gsub("%$<dir>", baseDir)
+		print(test)
+		os.execute(test)
+	end
+end
+
+if(arg[1]) then
+	assert(platTests[arg[1]], "Invalid platform " .. arg[1])
+end
+
+ExecTests(tests)
+if(arg[1]) then
+	ExecTests(platTests[arg[1]])
+end
+
 --Get the location of our modules relative to here.
 local baseDir = arg[0]:match("^(.*[\\/])")
 baseDir = baseDir or "./"
-assert(baseDir, arg[0] .. " No directory")
 
 --Fixup the package path to be relative to this directory.
 package.path = baseDir .. "modules/?.lua;" .. package.path

modules/Structure.lua

 
 - name: The name of a function to call, or part of a name. This can also include a parenthesized list of parameters. The parameter names much match those in the above list of parameters, and those parameters must be available in this particular scope (different actions create different scopes. If a particular parameter is not available in a context, a runtime error will occur.
 
-- style: This represents a scoping for the style for all children of this action. It will access the main style using the given string, and it expects a table of functions. All names within this action will be expected to be in that style; if they are not, they'll check the previous style, on down until the first style. These can be nested, but note that the fetching of the table is always done in the *main* style, not the "current" style.
+- 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.
 
 - 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.
 
 	name = name or self.name
 	self:Assert(name, "Unknown function name.")
 	local style = context:FindStyleForFunc(name)
-	self:Assert(style, "The style does not have a function " .. name)
+	
+	if(not style) then
+		if(self.optional) then
+			return
+		else
+			self:Assert(nil, "The style does not have a function " .. name)
+		end
+	end
 	
 	local paramList = {}
 	for _, param in ipairs(self.params) do
 end
 
 function action:Assert(test, text)
-	assert(test, self._actionType .. ": " .. 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
 end
 
 --Iterates over the list, setting the second element returned from the iterator
 	end
 	
 	act.newStyle = data.style
+	act.optional = data.optional
 
 	--Make child actions recursively.
 	for _, child in ipairs(data) do
 		end
 		
 		function context:PushStyle(newStyleName)
-			assert(context._styles[1][newStyleName], "There is no style named " .. newStyleName)
-			table.insert(context._styles, context._styles[1][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]
 		end
 		

test/pointer_cpp/test.cpp

+#include <string>
+#include <exception>
+#include <stdexcept>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gl_test.hpp"
+#include "wgl_test.hpp"
+#include <GL/freeglut.h>
+
+GLuint positionBufferObject;
+GLuint program;
+GLuint vao;
+
+GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
+{
+	GLuint shader = gl::CreateShader(eShaderType);
+	const char *strFileData = shaderText.c_str();
+	gl::ShaderSource(shader, 1, &strFileData, NULL);
+
+	gl::CompileShader(shader);
+
+	GLint status;
+	gl::GetShaderiv(shader, gl::COMPILE_STATUS, &status);
+	if (status == gl::FALSE_)
+	{
+		GLint infoLogLength;
+		gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		gl::GetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
+
+		const char *strShaderType = NULL;
+		switch(eShaderType)
+		{
+		case gl::VERTEX_SHADER: strShaderType = "vertex"; break;
+//		case gl::GEOMETRY_SHADER: strShaderType = "geometry"; break;
+		case gl::FRAGMENT_SHADER: strShaderType = "fragment"; break;
+		}
+
+		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
+		delete[] strInfoLog;
+
+		throw std::runtime_error("Compile failure in shader.");
+	}
+
+	return shader;
+}
+
+
+void init()
+{
+	gl::GenVertexArrays(1, &vao);
+	gl::BindVertexArray(vao);
+
+	const float vertexPositions[] = {
+		0.75f, 0.75f, 0.0f, 1.0f,
+		0.75f, -0.75f, 0.0f, 1.0f,
+		-0.75f, -0.75f, 0.0f, 1.0f,
+	};
+
+	gl::GenBuffers(1, &positionBufferObject);
+	gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
+	gl::BufferData(gl::ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, gl::STATIC_DRAW);
+	gl::BindBuffer(gl::ARRAY_BUFFER, 0);
+
+	const std::string vertexShader(
+		"#version 330\n"
+		"layout(location = 0) in vec4 position;\n"
+		"void main()\n"
+		"{\n"
+		"   gl_Position = position;\n"
+		"}\n"
+		);
+
+	const std::string fragmentShader(
+		"#version 330\n"
+		"out vec4 outputColor;\n"
+		"void main()\n"
+		"{\n"
+		"   outputColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
+		"}\n"
+		);
+
+	GLuint vertShader = BuildShader(gl::VERTEX_SHADER, vertexShader);
+	GLuint fragShader = BuildShader(gl::FRAGMENT_SHADER, fragmentShader);
+
+	program = gl::CreateProgram();
+	gl::AttachShader(program, vertShader);
+	gl::AttachShader(program, fragShader);	
+	gl::LinkProgram(program);
+
+	GLint status;
+	gl::GetProgramiv (program, gl::LINK_STATUS, &status);
+	if (status == gl::FALSE_)
+	{
+		GLint infoLogLength;
+		gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &infoLogLength);
+
+		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
+		gl::GetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
+		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
+		delete[] strInfoLog;
+
+		throw std::runtime_error("Shader could not be linked.");
+	}
+}
+
+//Called to update the display.
+//You should call glutSwapBuffers after all of your rendering to display what you rendered.
+//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
+void display()
+{
+	gl::ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+	gl::Clear(gl::COLOR_BUFFER_BIT);
+
+	gl::UseProgram(program);
+
+	gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
+	gl::EnableVertexAttribArray(0);
+	gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE_, 0, 0);
+
+	gl::DrawArrays(gl::TRIANGLES, 0, 3);
+
+	gl::DisableVertexAttribArray(0);
+	gl::UseProgram(0);
+
+	glutSwapBuffers();
+}
+
+//Called whenever the window is resized. The new window size is given, in pixels.
+//This is an opportunity to call gl::Viewport or gl::Scissor to keep up with the change in size.
+void reshape (int w, int h)
+{
+	gl::Viewport(0, 0, (GLsizei) w, (GLsizei) h);
+}
+
+//Called whenever a key on the keyboard was pressed.
+//The key is given by the ''key'' parameter, which is in ASCII.
+//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to 
+//exit the program.
+void keyboard(unsigned char key, int x, int y)
+{
+	switch (key)
+	{
+	case 27:
+		glutLeaveMainLoop();
+		break;
+	}
+}
+
+
+int main(int argc, char** argv)
+{
+	glutInit(&argc, argv);
+
+	int width = 500;
+	int height = 500;
+	unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
+
+	glutInitDisplayMode(displayMode);
+	glutInitContextVersion (3, 3);
+	glutInitContextProfile(GLUT_CORE_PROFILE);
+	glutInitWindowSize (width, height); 
+	glutInitWindowPosition (300, 200);
+	glutCreateWindow (argv[0]);
+
+	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
+
+	gl::exts::LoadTest didLoad = gl::sys::LoadFunctions();
+	if(!didLoad)
+		printf("OpenGL: %i\n", didLoad.GetNumMissing());
+	else
+		printf("OpenGL Loaded!\n");
+
+	init();
+
+	HDC hdc = wglGetCurrentDC();
+	wgl::exts::LoadTest load = wgl::sys::LoadFunctions(hdc);
+	if(!load)
+		printf("WGL: %i\n", load.GetNumMissing());
+	else
+		printf("WGL Loaded!\n");
+
+	glutDisplayFunc(display); 
+	glutReshapeFunc(reshape);
+	glutKeyboardFunc(keyboard);
+	glutMainLoop();
+	return 0;
+}

test/premake4.lua

 
 dofile "glsdk/links.lua"
 
-solution "loadtest"
+solution "test"
 	configurations {"Debug", "Release"}
 	defines {"_CRT_SECURE_NO_WARNINGS", "_SCL_SECURE_NO_WARNINGS"}
 
+local testDirs = {"pointer_cpp"}
+
+local oldDir = os.getcwd()
+for _, testDir in ipairs(testDirs) do
+	os.chdir(path.getabsolute(testDir))
 	
-project("loadtest")
-	kind "ConsoleApp"
-	language "c++"
-	objdir("obj")
-	files {"*.cpp"}
-	files {"*.c"}
-	files {"*.hpp"}
-	files {"*.h"}
+	project(testDir .. "_test")
+		kind "ConsoleApp"
+		language "c++"
+		objdir("obj")
+		files {"**.cpp"}
+		files {"**.c"}
+		files {"**.hpp"}
+		files {"**.h"}
+		
+		UseLibs {"freeglut"}
+		
+		configuration "windows"
+			links {"glu32", "opengl32", "gdi32", "winmm", "user32"}
+			
+		configuration "linux"
+			links {"GL", "GLU", "Xrandr", "X11"}
+			
+		configuration "Debug"
+			targetsuffix "D"
+			defines "_DEBUG"
+			flags "Symbols"
+
+		configuration "Release"
+			defines "NDEBUG"
+			flags {"OptimizeSpeed", "NoFramePointer", "ExtraWarnings", "NoEditAndContinue"};
 	
-	files {"glload/*.cpp"}
-	files {"glload/*.c"}
-	files {"glload/*.hpp"}
-	files {"glload/*.h"}
-
-	UseLibs {"freeglut"}
-	
-	configuration "windows"
-		links {"glu32", "opengl32", "gdi32", "winmm", "user32"}
-		
-	configuration "linux"
-		links {"GL", "GLU", "Xrandr", "X11"}
-		
-	configuration "Debug"
-		targetsuffix "D"
-		defines "_DEBUG"
-		flags "Symbols"
-
-	configuration "Release"
-		defines "NDEBUG"
-		flags {"OptimizeSpeed", "NoFramePointer", "ExtraWarnings", "NoEditAndContinue"};
+	os.chdir(testDir)
+end

test/test.cpp

-#include <string>
-#include <exception>
-#include <stdexcept>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "gl_test.hpp"
-#include "wgl_test.hpp"
-#include <GL/freeglut.h>
-
-GLuint positionBufferObject;
-GLuint program;
-GLuint vao;
-
-GLuint BuildShader(GLenum eShaderType, const std::string &shaderText)
-{
-	GLuint shader = gl::CreateShader(eShaderType);
-	const char *strFileData = shaderText.c_str();
-	gl::ShaderSource(shader, 1, &strFileData, NULL);
-
-	gl::CompileShader(shader);
-
-	GLint status;
-	gl::GetShaderiv(shader, gl::COMPILE_STATUS, &status);
-	if (status == gl::FALSE_)
-	{
-		GLint infoLogLength;
-		gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &infoLogLength);
-
-		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
-		gl::GetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
-
-		const char *strShaderType = NULL;
-		switch(eShaderType)
-		{
-		case gl::VERTEX_SHADER: strShaderType = "vertex"; break;
-//		case gl::GEOMETRY_SHADER: strShaderType = "geometry"; break;
-		case gl::FRAGMENT_SHADER: strShaderType = "fragment"; break;
-		}
-
-		fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
-		delete[] strInfoLog;
-
-		throw std::runtime_error("Compile failure in shader.");
-	}
-
-	return shader;
-}
-
-
-void init()
-{
-	gl::GenVertexArrays(1, &vao);
-	gl::BindVertexArray(vao);
-
-	const float vertexPositions[] = {
-		0.75f, 0.75f, 0.0f, 1.0f,
-		0.75f, -0.75f, 0.0f, 1.0f,
-		-0.75f, -0.75f, 0.0f, 1.0f,
-	};
-
-	gl::GenBuffers(1, &positionBufferObject);
-	gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
-	gl::BufferData(gl::ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, gl::STATIC_DRAW);
-	gl::BindBuffer(gl::ARRAY_BUFFER, 0);
-
-	const std::string vertexShader(
-		"#version 330\n"
-		"layout(location = 0) in vec4 position;\n"
-		"void main()\n"
-		"{\n"
-		"   gl_Position = position;\n"
-		"}\n"
-		);
-
-	const std::string fragmentShader(
-		"#version 330\n"
-		"out vec4 outputColor;\n"
-		"void main()\n"
-		"{\n"
-		"   outputColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
-		"}\n"
-		);
-
-	GLuint vertShader = BuildShader(gl::VERTEX_SHADER, vertexShader);
-	GLuint fragShader = BuildShader(gl::FRAGMENT_SHADER, fragmentShader);
-
-	program = gl::CreateProgram();
-	gl::AttachShader(program, vertShader);
-	gl::AttachShader(program, fragShader);	
-	gl::LinkProgram(program);
-
-	GLint status;
-	gl::GetProgramiv (program, gl::LINK_STATUS, &status);
-	if (status == gl::FALSE_)
-	{
-		GLint infoLogLength;
-		gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &infoLogLength);
-
-		GLchar *strInfoLog = new GLchar[infoLogLength + 1];
-		gl::GetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
-		fprintf(stderr, "Linker failure: %s\n", strInfoLog);
-		delete[] strInfoLog;
-
-		throw std::runtime_error("Shader could not be linked.");
-	}
-}
-
-//Called to update the display.
-//You should call glutSwapBuffers after all of your rendering to display what you rendered.
-//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
-void display()
-{
-	gl::ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
-	gl::Clear(gl::COLOR_BUFFER_BIT);
-
-	gl::UseProgram(program);
-
-	gl::BindBuffer(gl::ARRAY_BUFFER, positionBufferObject);
-	gl::EnableVertexAttribArray(0);
-	gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE_, 0, 0);
-
-	gl::DrawArrays(gl::TRIANGLES, 0, 3);
-
-	gl::DisableVertexAttribArray(0);
-	gl::UseProgram(0);
-
-	glutSwapBuffers();
-}
-
-//Called whenever the window is resized. The new window size is given, in pixels.
-//This is an opportunity to call gl::Viewport or gl::Scissor to keep up with the change in size.
-void reshape (int w, int h)
-{
-	gl::Viewport(0, 0, (GLsizei) w, (GLsizei) h);
-}
-
-//Called whenever a key on the keyboard was pressed.
-//The key is given by the ''key'' parameter, which is in ASCII.
-//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to 
-//exit the program.
-void keyboard(unsigned char key, int x, int y)
-{
-	switch (key)
-	{
-	case 27:
-		glutLeaveMainLoop();
-		break;
-	}
-}
-
-
-int main(int argc, char** argv)
-{
-	glutInit(&argc, argv);
-
-	int width = 500;
-	int height = 500;
-	unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
-
-	glutInitDisplayMode(displayMode);
-	glutInitContextVersion (3, 3);
-	glutInitContextProfile(GLUT_CORE_PROFILE);
-	glutInitWindowSize (width, height); 
-	glutInitWindowPosition (300, 200);
-	glutCreateWindow (argv[0]);
-
-	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
-
-	gl::exts::LoadTest didLoad = gl::sys::LoadFunctions();
-	if(!didLoad)
-		printf("OpenGL: %i\n", didLoad.GetNumMissing());
-	else
-		printf("OpenGL Loaded!\n");
-
-	init();
-
-	HDC hdc = wglGetCurrentDC();
-	wgl::exts::LoadTest load = wgl::sys::LoadFunctions(hdc);
-	if(!load)
-		printf("WGL: %i\n", load.GetNumMissing());
-	else
-		printf("WGL Loaded!\n");
-
-	glutDisplayFunc(display); 
-	glutReshapeFunc(reshape);
-	glutKeyboardFunc(keyboard);
-	glutMainLoop();
-	return 0;
-}