Added project.language and session validation
This commit is contained in:
parent
cb88b243b8
commit
3621f5fbe9
@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
#include "action/action.h"
|
||||
#include "make.h"
|
||||
#include "make_solution.h"
|
||||
|
||||
|
||||
@ -37,6 +38,12 @@ static SessionProjectCallback ProjectCallbacks[] =
|
||||
*/
|
||||
int gmake_action(Session sess)
|
||||
{
|
||||
/* make sure I can support all of the features used in the session */
|
||||
if (make_validate_session(sess) != OKAY)
|
||||
{
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
stream_writeline(Console, "Generating project files for GNU make...");
|
||||
return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks);
|
||||
}
|
||||
|
@ -7,8 +7,9 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
#include "action/make/make.h"
|
||||
#include "make.h"
|
||||
#include "base/cstr.h"
|
||||
#include "base/error.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -113,3 +114,40 @@ const char* make_get_solution_makefile(Session sess, Solution sln)
|
||||
/* all good */
|
||||
return my_path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make sure all of the features described in the sesson are supported
|
||||
* by the Make-based actions.
|
||||
* \param sess The session to validate.
|
||||
* \returns OKAY if the session can be supported.
|
||||
*/
|
||||
int make_validate_session(Session sess)
|
||||
{
|
||||
int si, sn;
|
||||
assert(sess);
|
||||
|
||||
sn = session_num_solutions(sess);
|
||||
for (si = 0; si < sn; ++si)
|
||||
{
|
||||
int pi, pn;
|
||||
Solution sln = session_get_solution(sess, si);
|
||||
|
||||
pn = solution_num_projects(sln);
|
||||
for (pi = 0; pi < pn; ++pi)
|
||||
{
|
||||
const char* value;
|
||||
Project prj = solution_get_project(sln, pi);
|
||||
|
||||
/* check for a recognized language */
|
||||
value = project_get_language(prj);
|
||||
if (!cstr_eq(value, "c") && !cstr_eq(value, "c++"))
|
||||
{
|
||||
error_set("%s is not currently supported for Make", value);
|
||||
return !OKAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
@ -10,5 +10,6 @@
|
||||
|
||||
const char* make_get_project_makefile(Session sess, Project prj);
|
||||
const char* make_get_solution_makefile(Session sess, Solution sln);
|
||||
int make_validate_session(Session sess);
|
||||
|
||||
#endif
|
||||
|
@ -56,6 +56,10 @@ struct FxMake
|
||||
|
||||
SUITE(action)
|
||||
{
|
||||
/**********************************************************************
|
||||
* Makefile naming tests
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxMake, GetSolutionMakefile_ReturnsMakefile_OnUniqueLocation)
|
||||
{
|
||||
solution_set_location(sln1, "MySolution");
|
||||
@ -90,4 +94,16 @@ SUITE(action)
|
||||
const char* result = make_get_project_makefile(sess, prj1);
|
||||
CHECK_EQUAL("./MyProject/MyProject1.make", result);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Session validation tests
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxMake, MakeValidation_ReturnsNotOkay_OnUnknownLanguage)
|
||||
{
|
||||
project_set_language(prj1, "nonesuch");
|
||||
int result = make_validate_session(sess);
|
||||
CHECK(result != OKAY);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ struct FxAction
|
||||
project_set_base_dir(prj, "/Root");
|
||||
project_set_location(prj, "ProjectFolder");
|
||||
project_set_guid(prj, "AE2461B7-236F-4278-81D3-F0D476F9A4C0");
|
||||
project_set_language(prj, "c++");
|
||||
}
|
||||
|
||||
~FxAction()
|
||||
|
@ -37,4 +37,51 @@ SUITE(action)
|
||||
int result = vs200x_get_target_version(sess);
|
||||
CHECK(result == 2005);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Language GUID tests
|
||||
**********************************************************************/
|
||||
|
||||
TEST(ToolGuid_ReturnsCorrectGUID_OnC)
|
||||
{
|
||||
const char* result = vs200x_tool_guid("c");
|
||||
CHECK_EQUAL("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942", result);
|
||||
}
|
||||
|
||||
TEST(ToolGuid_ReturnsCorrectGUID_OnCpp)
|
||||
{
|
||||
const char* result = vs200x_tool_guid("c++");
|
||||
CHECK_EQUAL("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942", result);
|
||||
}
|
||||
|
||||
TEST(ToolGuid_ReturnsCorrectGUID_OnCSharp)
|
||||
{
|
||||
const char* result = vs200x_tool_guid("c#");
|
||||
CHECK_EQUAL("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC", result);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Language file extensions
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxAction, ProjectExtension_IsVcproj_ForC)
|
||||
{
|
||||
project_set_language(prj, "c");
|
||||
const char* result = vs200x_project_file_extension(prj);
|
||||
CHECK_EQUAL(".vcproj", result);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Session validation
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxAction, Vs200xValidation_ReturnsNotOkay_OnUnknownLanguage)
|
||||
{
|
||||
project_set_language(prj, "nonesuch");
|
||||
int result = vs200x_validate_session(sess);
|
||||
CHECK(result != OKAY);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,9 @@
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
#include "action/action.h"
|
||||
#include "vs200x.h"
|
||||
#include "vs200x_solution.h"
|
||||
#include "vs200x_project.h"
|
||||
|
||||
|
||||
/** The VS2002 solution writing process, for session_enumerate_objects() */
|
||||
@ -26,6 +28,7 @@ static SessionSolutionCallback SolutionCallbacks[] =
|
||||
/** The VS2002 project writing process, for session_enumerate_objects() */
|
||||
static SessionProjectCallback ProjectCallbacks[] =
|
||||
{
|
||||
vs2002_project_create,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -37,6 +40,12 @@ static SessionProjectCallback ProjectCallbacks[] =
|
||||
*/
|
||||
int vs2002_action(Session sess)
|
||||
{
|
||||
/* make sure I can support all of the features used in the session */
|
||||
if (vs200x_validate_session(sess) != OKAY)
|
||||
{
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
stream_writeline(Console, "Generating project files for Visual Studio 2002...");
|
||||
return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks);
|
||||
}
|
||||
|
34
src/action/vs200x/vs2002_project.c
Normal file
34
src/action/vs200x/vs2002_project.c
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* \file vs2002_project.c
|
||||
* \brief Visual Studio 2002 project generation functions.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
#include "vs200x.h"
|
||||
#include "vs200x_project.h"
|
||||
|
||||
|
||||
/**
|
||||
* Create a new output stream for a project, and make it active for subsequent writes.
|
||||
* \param sess The execution session context.
|
||||
* \param prj The current project.
|
||||
* \param strm The currently active stream; set with session_set_active_stream().
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int vs2002_project_create(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
/* create the project file */
|
||||
const char* extension = vs200x_project_file_extension(prj);
|
||||
const char* filename = project_get_filename(prj, NULL, extension);
|
||||
strm = stream_create_file(filename);
|
||||
if (!strm)
|
||||
{
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
/* make the stream active for the functions that come after */
|
||||
session_set_active_stream(sess, strm);
|
||||
return OKAY;
|
||||
}
|
@ -40,6 +40,29 @@ int vs2002_solution_configuration(Session sess, Solution sln, Stream strm)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new output stream for a solution, and make it active for subsequent writes.
|
||||
* \param sess The execution session context.
|
||||
* \param sln The current solution.
|
||||
* \param strm The currently active stream; set with session_set_active_stream().
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int vs2002_solution_create(Session sess, Solution sln, Stream strm)
|
||||
{
|
||||
/* create the solution file */
|
||||
const char* filename = solution_get_filename(sln, NULL, ".sln");
|
||||
strm = stream_create_file(filename);
|
||||
if (!strm)
|
||||
{
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
/* make the stream active for the functions that come after */
|
||||
session_set_active_stream(sess, strm);
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the Visual Studio 2002 project dependencies block.
|
||||
* \param sess The execution session context.
|
||||
@ -79,29 +102,6 @@ int vs2002_solution_extensibility(Session sess, Solution sln, Stream strm)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new output stream for a solution, and make it active for subsequent writes.
|
||||
* \param sess The execution session context.
|
||||
* \param sln The current solution.
|
||||
* \param strm The currently active stream; set with session_set_active_stream().
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int vs2002_solution_create(Session sess, Solution sln, Stream strm)
|
||||
{
|
||||
/* create the solution file */
|
||||
const char* filename = solution_get_filename(sln, NULL, ".sln");
|
||||
strm = stream_create_file(filename);
|
||||
if (!strm)
|
||||
{
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
/* make the stream active for the functions that come after */
|
||||
session_set_active_stream(sess, strm);
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write out the Visual Studio 2002 project configurations block.
|
||||
* \param sess The execution session context.
|
||||
@ -158,7 +158,7 @@ int vs2002_solution_projects(Session sess, Solution sln, Stream strm)
|
||||
const char* prj_name = project_get_name(prj);
|
||||
const char* prj_id = project_get_guid(prj);
|
||||
const char* prj_lang = project_get_language(prj);
|
||||
const char* prj_ext = vs200x_project_extension(prj);
|
||||
const char* prj_ext = vs200x_project_file_extension(prj);
|
||||
const char* prj_file = project_get_filename(prj, prj_name, prj_ext);
|
||||
const char* tool_id = vs200x_tool_guid(prj_lang);
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
#include "action/action.h"
|
||||
#include "vs200x.h"
|
||||
#include "vs200x_solution.h"
|
||||
|
||||
|
||||
@ -36,6 +37,12 @@ static SessionProjectCallback ProjectCallbacks[] =
|
||||
*/
|
||||
int vs2003_action(Session sess)
|
||||
{
|
||||
/* make sure I can support all of the features used in the session */
|
||||
if (vs200x_validate_session(sess) != OKAY)
|
||||
{
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
stream_writeline(Console, "Generating project files for Visual Studio 2003...");
|
||||
return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
#include "action/action.h"
|
||||
#include "vs200x.h"
|
||||
#include "vs200x_solution.h"
|
||||
|
||||
|
||||
@ -36,6 +37,12 @@ static SessionProjectCallback ProjectCallbacks[] =
|
||||
*/
|
||||
int vs2005_action(Session sess)
|
||||
{
|
||||
/* make sure I can support all of the features used in the session */
|
||||
if (vs200x_validate_session(sess) != OKAY)
|
||||
{
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
stream_writeline(Console, "Generating project files for Visual Studio 2005...");
|
||||
return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
#include "action/action.h"
|
||||
#include "vs200x.h"
|
||||
#include "vs200x_solution.h"
|
||||
|
||||
|
||||
@ -36,6 +37,12 @@ static SessionProjectCallback ProjectCallbacks[] =
|
||||
*/
|
||||
int vs2008_action(Session sess)
|
||||
{
|
||||
/* make sure I can support all of the features used in the session */
|
||||
if (vs200x_validate_session(sess) != OKAY)
|
||||
{
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
stream_writeline(Console, "Generating project files for Visual Studio 2008...");
|
||||
return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks);
|
||||
}
|
||||
|
@ -40,6 +40,26 @@ int vs200x_get_target_version(Session sess)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the appropriate file extension for a particular project.
|
||||
* \param prj The project object.
|
||||
* \returns The appropriate project file extension, based on the project settings.
|
||||
*/
|
||||
const char* vs200x_project_file_extension(Project prj)
|
||||
{
|
||||
const char* language = project_get_language(prj);
|
||||
if (cstr_eq(language, "c") || cstr_eq(language, "c++"))
|
||||
{
|
||||
return ".vcproj";
|
||||
}
|
||||
else
|
||||
{
|
||||
error_set("unsupported language '%s'", language);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the Visual Studio GUID for a particular project type.
|
||||
* \param language The programming language used in the project.
|
||||
@ -61,3 +81,40 @@ const char* vs200x_tool_guid(const char* language)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make sure all of the features described in the sesson are supported
|
||||
* by the Visual Studio actions.
|
||||
* \param sess The session to validate.
|
||||
* \returns OKAY if the session can be supported.
|
||||
*/
|
||||
int vs200x_validate_session(Session sess)
|
||||
{
|
||||
int si, sn;
|
||||
assert(sess);
|
||||
|
||||
sn = session_num_solutions(sess);
|
||||
for (si = 0; si < sn; ++si)
|
||||
{
|
||||
int pi, pn;
|
||||
Solution sln = session_get_solution(sess, si);
|
||||
|
||||
pn = solution_num_projects(sln);
|
||||
for (pi = 0; pi < pn; ++pi)
|
||||
{
|
||||
const char* value;
|
||||
Project prj = solution_get_project(sln, pi);
|
||||
|
||||
/* check for a recognized language */
|
||||
value = project_get_language(prj);
|
||||
if (!cstr_eq(value, "c") && !cstr_eq(value, "c++"))
|
||||
{
|
||||
error_set("%s is not currently supported for Visual Studio", value);
|
||||
return !OKAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
@ -9,8 +9,9 @@
|
||||
#include "engine/session.h"
|
||||
|
||||
int vs200x_get_target_version(Session sess);
|
||||
const char* vs200x_project_file_extension(Project prj);
|
||||
const char* vs200x_tool_guid(const char* language);
|
||||
|
||||
int vs200x_validate_session(Session sess);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
/**
|
||||
* \file vs200x_project.c
|
||||
* \brief Visual Studio 200x project generation functions.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "vs200x_project.h"
|
||||
|
||||
|
||||
/**
|
||||
* Returns the correct project file extension for a particular project definition.
|
||||
* \param prj The project to be identified.
|
||||
* \returns The project file extension for the given project.
|
||||
*/
|
||||
const char* vs200x_project_extension(Project prj)
|
||||
{
|
||||
prj = 0;
|
||||
return ".vcproj";
|
||||
}
|
@ -8,6 +8,6 @@
|
||||
|
||||
#include "engine/session.h"
|
||||
|
||||
const char* vs200x_project_extension(Project prj);
|
||||
int vs2002_project_create(Session sess, Project prj, Stream strm);
|
||||
|
||||
#endif
|
||||
|
@ -45,3 +45,19 @@ int cstr_eq(const char* str, const char* expected)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the given C string starts with a particular sequence.
|
||||
* \param str The string to test.
|
||||
* \param expected The sequence for which to look.
|
||||
* \returns True if the string starts with the sequence, false otherwise.
|
||||
*/
|
||||
int cstr_starts_with(const char* str, const char* expected)
|
||||
{
|
||||
if (str != NULL && expected != NULL)
|
||||
{
|
||||
return (strncmp(str, expected, strlen(expected)) == 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -8,5 +8,6 @@
|
||||
|
||||
int cstr_ends_with(const char* str, const char* expected);
|
||||
int cstr_eq(const char* str, const char* expected);
|
||||
int cstr_starts_with(const char* str, const char* expected);
|
||||
|
||||
#endif
|
||||
|
@ -65,4 +65,34 @@ SUITE(cstr)
|
||||
{
|
||||
CHECK(!cstr_eq("something", NULL));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* cstr_starts_with() tests
|
||||
**************************************************************************/
|
||||
|
||||
TEST(CStrStartsWith_ReturnsTrue_OnMatch)
|
||||
{
|
||||
CHECK(cstr_starts_with("Abcdef", "Abc"));
|
||||
}
|
||||
|
||||
TEST(CStrStartsWith_ReturnsFalse_OnMismatch)
|
||||
{
|
||||
CHECK(!cstr_starts_with("Abcdef", "ghi"));
|
||||
}
|
||||
|
||||
TEST(CStrStartsWith_ReturnsFalse_OnLongerNeedle)
|
||||
{
|
||||
CHECK(!cstr_starts_with("Abc", "Abcdef"));
|
||||
}
|
||||
|
||||
TEST(CStrStartsWith_ReturnsFalse_OnNullHaystack)
|
||||
{
|
||||
CHECK(!cstr_starts_with(NULL, "ghi"));
|
||||
}
|
||||
|
||||
TEST(CStrStartsWith_ReturnsFalse_OnNullNeedle)
|
||||
{
|
||||
CHECK(!cstr_starts_with("Abc", NULL));
|
||||
}
|
||||
}
|
||||
|
164
src/engine/accessor.c
Normal file
164
src/engine/accessor.c
Normal file
@ -0,0 +1,164 @@
|
||||
/**
|
||||
* \file accessor.c
|
||||
* \brief A generic getter/setter for project fields.
|
||||
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "internals.h"
|
||||
#include "base/cstr.h"
|
||||
#include "base/error.h"
|
||||
|
||||
|
||||
static int accessor_object_has_field(struct FieldInfo* fields, const char* field_name);
|
||||
static int accessor_register(lua_State* L, struct FieldInfo* fields);
|
||||
static int accessor_register_field(lua_State* L, struct FieldInfo* field);
|
||||
static int accessor_set_string_value(lua_State* L, struct FieldInfo* field);
|
||||
static int fn_accessor(lua_State* L);
|
||||
|
||||
|
||||
/**
|
||||
* Register all of the accessors listed in the project object field information.
|
||||
* \param L The Lua scripting state.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int accessor_register_all(lua_State* L)
|
||||
{
|
||||
int z = OKAY;
|
||||
if (z == OKAY) z = accessor_register(L, SolutionFieldInfo);
|
||||
if (z == OKAY) z = accessor_register(L, ProjectFieldInfo);
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register accessor functions for a set of fields.
|
||||
* \param L The Lua scripting state.
|
||||
* \param fields The list of fields to register.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int accessor_register(lua_State* L, struct FieldInfo* fields)
|
||||
{
|
||||
int i, z = OKAY;
|
||||
|
||||
for (i = 0; z == OKAY && fields[i].name != NULL; ++i)
|
||||
{
|
||||
z = accessor_register_field(L, &fields[i]);
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register a single accessor function.
|
||||
* \param L The Lua scripting state.
|
||||
* \param field The field to register.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int accessor_register_field(lua_State* L, struct FieldInfo* field)
|
||||
{
|
||||
int container_type, z;
|
||||
|
||||
/* has this accessor already been registered? If so, skip it now */
|
||||
lua_getglobal(L, field->name);
|
||||
z = lua_isnil(L, -1);
|
||||
lua_pop(L, 1);
|
||||
if (!z) return OKAY;
|
||||
|
||||
/* figure out what object types this accessor applies to */
|
||||
container_type = 0;
|
||||
if (accessor_object_has_field(SolutionFieldInfo, field->name)) container_type |= SolutionObject;
|
||||
if (accessor_object_has_field(ProjectFieldInfo, field->name)) container_type |= ProjectObject;
|
||||
|
||||
/* register the accessor function */
|
||||
lua_pushnumber(L, container_type);
|
||||
lua_pushlightuserdata(L, field);
|
||||
lua_pushcclosure(L, fn_accessor, 2);
|
||||
lua_setglobal(L, field->name);
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a field list contains a field with a particular name.
|
||||
* \param fields The list of fields to check.
|
||||
* \param field_name The field to look for.
|
||||
* \returns True if the field is contained by the list.
|
||||
*/
|
||||
int accessor_object_has_field(struct FieldInfo* fields, const char* field_name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; fields[i].name != NULL; ++i)
|
||||
{
|
||||
if (cstr_eq(fields[i].name, field_name))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a string field, using the value on the stack.
|
||||
* \param L The Lua state.
|
||||
* \param field The field to set.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int accessor_set_string_value(lua_State* L, struct FieldInfo* field)
|
||||
{
|
||||
/* can't set lists to simple fields */
|
||||
if (lua_istable(L, 1))
|
||||
{
|
||||
luaL_error(L, "the field '%s' does not support lists of values", field->name);
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
/* if a validator function is present, call it */
|
||||
if (field->validator != NULL)
|
||||
{
|
||||
const char* value = luaL_checkstring(L, 1);
|
||||
if (!field->validator(value))
|
||||
{
|
||||
luaL_error(L, "invalid value '%s'", value);
|
||||
return !OKAY;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the field */
|
||||
lua_pushvalue(L, 1);
|
||||
lua_setfield(L, -2, field->name);
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The accessor function; this is what gets called by Lua when an accessor
|
||||
* function is called in a script.
|
||||
* \param L The Lua state.
|
||||
* \returns The current value of the field.
|
||||
*/
|
||||
int fn_accessor(lua_State* L)
|
||||
{
|
||||
struct FieldInfo* field;
|
||||
int container_type;
|
||||
|
||||
/* get the required container object */
|
||||
container_type = lua_tointeger(L, lua_upvalueindex(1));
|
||||
if (!engine_get_active_object(L, container_type, REQUIRED))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get field information */
|
||||
field = (struct FieldInfo*)lua_touserdata(L, lua_upvalueindex(2));
|
||||
|
||||
/* if a value is provided, set the field */
|
||||
if (lua_gettop(L) > 1)
|
||||
{
|
||||
accessor_set_string_value(L, field);
|
||||
}
|
||||
|
||||
/* return the current value of the field */
|
||||
lua_getfield(L, -1, field->name);
|
||||
return 1;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/**
|
||||
* \file fn_guid.c
|
||||
* \brief Specify a project GUID.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "internals.h"
|
||||
#include "base/guid.h"
|
||||
|
||||
|
||||
/**
|
||||
* Specify a project GUID, which is used by the Visual Studio actions to
|
||||
* identify the project in the solution.
|
||||
*/
|
||||
int fn_guid(lua_State* L)
|
||||
{
|
||||
const char* guid = luaL_optstring(L, 1, NULL);
|
||||
|
||||
/* retrieve the project being set */
|
||||
if (!engine_get_active_object(L, ProjectObject, REQUIRED))
|
||||
return 0;
|
||||
|
||||
/* if a value is provided, set it */
|
||||
if (guid != NULL)
|
||||
{
|
||||
if (!guid_is_valid(guid))
|
||||
{
|
||||
luaL_error(L, "invalid GUID");
|
||||
return 0;
|
||||
}
|
||||
lua_pushvalue(L, 1);
|
||||
lua_setfield(L, -2, ProjectFieldInfo[ProjectGuid].name);
|
||||
}
|
||||
|
||||
/* return the current value */
|
||||
lua_getfield(L, -1, ProjectFieldInfo[ProjectGuid].name);
|
||||
return 1;
|
||||
}
|
@ -48,6 +48,10 @@ void engine_configure_project_object(lua_State* L, struct FieldInfo* fiel
|
||||
lua_State* session_get_lua_state(Session sess);
|
||||
|
||||
|
||||
/* Generic project object field getter/setter API */
|
||||
int accessor_register_all(lua_State* L);
|
||||
|
||||
|
||||
/* Project object unloading API. The unload functions "interface" provides an
|
||||
* opportunity to mock the actual implementation for automated testing */
|
||||
struct UnloadFuncs
|
||||
@ -65,11 +69,9 @@ int unload_project(Session sess, lua_State* L, Project prj);
|
||||
int fn_dofile(lua_State* L);
|
||||
int fn_error(lua_State* L);
|
||||
int fn_getcwd(lua_State* L);
|
||||
int fn_guid(lua_State* L);
|
||||
int fn_include(lua_State* L);
|
||||
int fn_project(lua_State* L);
|
||||
int fn_solution(lua_State* L);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
#include "base/array.h"
|
||||
#include "base/cstr.h"
|
||||
#include "base/error.h"
|
||||
#include "internals.h"
|
||||
|
||||
@ -18,7 +19,6 @@
|
||||
/** Functions to add to the global namespace */
|
||||
static const luaL_Reg funcs[] = {
|
||||
{ "dofile", fn_dofile },
|
||||
{ "guid", fn_guid },
|
||||
{ "include", fn_include },
|
||||
{ "project", fn_project },
|
||||
{ "solution", fn_solution },
|
||||
@ -59,6 +59,9 @@ Session session_create()
|
||||
/* install all the standard libraries */
|
||||
luaL_openlibs(L);
|
||||
|
||||
/* register the project object accessor functions */
|
||||
accessor_register_all(L);
|
||||
|
||||
/* register the Premake non-configuration related functions */
|
||||
luaL_register(L, "_G", funcs);
|
||||
luaL_register(L, "os", os_funcs);
|
||||
@ -298,9 +301,17 @@ const char* session_run_file(Session sess, const char* filename)
|
||||
*/
|
||||
const char* session_run_string(Session sess, const char* script)
|
||||
{
|
||||
const char* result;
|
||||
|
||||
assert(sess);
|
||||
assert(script);
|
||||
return session_run(sess->L, script, 0);
|
||||
|
||||
result = session_run(sess->L, script, 0);
|
||||
if (cstr_starts_with(result, "[string "))
|
||||
{
|
||||
result = strstr(result, ":1:") + 4;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -355,3 +366,48 @@ int session_unload(Session sess)
|
||||
result = unload_all(sess, sess->L, &funcs);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make sure that all required objects and values have been defined by the
|
||||
* project script.
|
||||
* \param sess The session to validate.
|
||||
* \returns OKAY if the session is valid.
|
||||
*/
|
||||
int session_validate(Session sess)
|
||||
{
|
||||
int si, sn;
|
||||
|
||||
assert(sess);
|
||||
|
||||
sn = session_num_solutions(sess);
|
||||
for (si = 0; si < sn; ++si)
|
||||
{
|
||||
int pi, pn;
|
||||
Solution sln = session_get_solution(sess, si);
|
||||
|
||||
/* every solution must have at least one project */
|
||||
pn = solution_num_projects(sln);
|
||||
if (pn == 0)
|
||||
{
|
||||
error_set("no projects defined for solution '%s'", solution_get_name(sln));
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
for (pi = 0; pi < pn; ++pi)
|
||||
{
|
||||
const char* value;
|
||||
Project prj = solution_get_project(sln, pi);
|
||||
|
||||
/* every project must have a language defined */
|
||||
value = project_get_language(prj);
|
||||
if (value == NULL)
|
||||
{
|
||||
error_set("no language defined for project '%s'", project_get_name(prj));
|
||||
return !OKAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
@ -68,5 +68,6 @@ const char* session_run_string(Session sess, const char* script);
|
||||
void session_set_action(Session sess, const char* action);
|
||||
void session_set_active_stream(Session sess, Stream strm);
|
||||
int session_unload(Session sess);
|
||||
int session_validate(Session sess);
|
||||
|
||||
#endif
|
||||
|
67
src/engine/tests/accessor_tests.cpp
Normal file
67
src/engine/tests/accessor_tests.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* \file accessor_tests.cpp
|
||||
* \brief Automated tests for the generic value getter/setter function.
|
||||
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "accessor_tests.h"
|
||||
|
||||
|
||||
SUITE(engine)
|
||||
{
|
||||
/**************************************************************************
|
||||
* Initial state tests
|
||||
**************************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_FunctionExists_OnStartup)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"return (location ~= nil)");
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_RaisesError_OnNoActiveObject)
|
||||
{
|
||||
Session sess = session_create();
|
||||
const char* result = session_run_string(sess, "location()");
|
||||
CHECK_EQUAL("no active solution or project", result);
|
||||
session_destroy(sess);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* String field tests
|
||||
**************************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_ReturnsNil_OnEmptyStringValue)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"return (location() == nil)");
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_RaisesError_OnListValueAndStringField)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"location {}");
|
||||
CHECK_EQUAL("the field 'location' does not support lists of values", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_SetsField_OnStringField)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"location 'MyLocation';"
|
||||
"return prj.location" );
|
||||
CHECK_EQUAL("MyLocation", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_GetsField_OnStringField)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"prj.location = 'MyLocation';"
|
||||
"return location()" );
|
||||
CHECK_EQUAL("MyLocation", result);
|
||||
}
|
||||
|
||||
}
|
31
src/engine/tests/accessor_tests.h
Normal file
31
src/engine/tests/accessor_tests.h
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* \file accessor_tests.h
|
||||
* \brief Common fixture for accessor function tests.
|
||||
* \author Copyright (c) 2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "testing/testing.h"
|
||||
extern "C" {
|
||||
#include "engine/session.h"
|
||||
#include "base/error.h"
|
||||
}
|
||||
|
||||
|
||||
struct FxAccessor
|
||||
{
|
||||
Session sess;
|
||||
|
||||
FxAccessor()
|
||||
{
|
||||
sess = session_create();
|
||||
session_run_string(sess,
|
||||
"sln = solution 'MySolution';"
|
||||
"prj = project 'MyProject';");
|
||||
}
|
||||
|
||||
~FxAccessor()
|
||||
{
|
||||
session_destroy(sess);
|
||||
error_clear();
|
||||
}
|
||||
};
|
@ -1,88 +1,37 @@
|
||||
/**
|
||||
* \file fn_guid_tests.cpp
|
||||
* \brief Automated tests for the guid() function.
|
||||
* \author Copyright (c) 2008 Jason Perkins and the Premake project
|
||||
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "testing/testing.h"
|
||||
#include "accessor_tests.h"
|
||||
extern "C" {
|
||||
#include "engine/session.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/error.h"
|
||||
}
|
||||
|
||||
struct FnGuid
|
||||
{
|
||||
Session sess;
|
||||
|
||||
FnGuid()
|
||||
{
|
||||
sess = session_create();
|
||||
}
|
||||
|
||||
~FnGuid()
|
||||
{
|
||||
session_destroy(sess);
|
||||
error_clear();
|
||||
}
|
||||
};
|
||||
|
||||
struct FnGuid2 : FnGuid
|
||||
{
|
||||
FnGuid2()
|
||||
{
|
||||
session_run_string(sess,
|
||||
"solution 'MySolution';"
|
||||
"prj = project 'MyProject';");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
SUITE(engine)
|
||||
{
|
||||
/**************************************************************************
|
||||
* Initial state tests
|
||||
**************************************************************************/
|
||||
|
||||
TEST_FIXTURE(FnGuid, Guid_Exists_OnStartup)
|
||||
TEST_FIXTURE(FxAccessor, Guid_Exists_OnStartup)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"return (guid ~= nil)");
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FnGuid, Guid_RaisesError_OnNoProject)
|
||||
{
|
||||
const char* result = session_run_string(sess, "guid '0C202E43-B9AF-4972-822B-5A42F0BF008C'");
|
||||
CHECK_EQUAL("[string \"guid '0C202E43-B9AF-4972-822B-5A42F0BF008C'\"]:1: no active project", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FnGuid2, Guid_ReturnsDefaultValue_OnNoValueSet)
|
||||
{
|
||||
const char* result = session_run_string(sess, "return guid()");
|
||||
CHECK(result != NULL && guid_is_valid(result));
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FnGuid2, Guid_SetsField)
|
||||
TEST_FIXTURE(FxAccessor, Guid_CanRoundtrip)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"guid '0C202E43-B9AF-4972-822B-5A42F0BF008C';"
|
||||
"return prj.guid");
|
||||
CHECK_EQUAL("0C202E43-B9AF-4972-822B-5A42F0BF008C", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FnGuid2, Guid_ReturnsField_OnNoParams)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"prj.guid = '0C202E43-B9AF-4972-822B-5A42F0BF008C';"
|
||||
"return guid()");
|
||||
CHECK_EQUAL("0C202E43-B9AF-4972-822B-5A42F0BF008C", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FnGuid2, Guid_RaisesError_OnInvalidGuid)
|
||||
TEST_FIXTURE(FxAccessor, Guid_RaisesError_OnInvalidGuid)
|
||||
{
|
||||
const char* result = session_run_string(sess, "guid '0C2XXXX-B9AF-4972-822B-5A42F0BF008C'");
|
||||
CHECK_EQUAL("[string \"guid '0C2XXXX-B9AF-4972-822B-5A42F0BF008C'\"]:1: invalid GUID", result);
|
||||
const char* result = session_run_string(sess,
|
||||
"guid '0C202E43-XXXX-4972-822B-5A42F0BF008C'");
|
||||
CHECK_EQUAL("invalid value '0C202E43-XXXX-4972-822B-5A42F0BF008C'", result);
|
||||
}
|
||||
}
|
||||
|
34
src/engine/tests/fn_language_tests.cpp
Normal file
34
src/engine/tests/fn_language_tests.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* \file fn_language_tests.cpp
|
||||
* \brief Automated tests for the language() function.
|
||||
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "accessor_tests.h"
|
||||
|
||||
|
||||
SUITE(engine)
|
||||
{
|
||||
TEST_FIXTURE(FxAccessor, Language_Exists_OnStartup)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"return (language ~= nil)");
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Language_CanRoundtrip)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"language 'c++';"
|
||||
"return language()");
|
||||
CHECK_EQUAL("c++", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Language_RaisesError_OnInvalidLanguage)
|
||||
{
|
||||
const char* result = session_run_string(sess,
|
||||
"language 'nosuch'");
|
||||
CHECK_EQUAL("invalid value 'nosuch'", result);
|
||||
}
|
||||
}
|
@ -74,7 +74,7 @@ SUITE(engine)
|
||||
TEST_FIXTURE(FnProject, Project_Fails_OnNoActiveSolution)
|
||||
{
|
||||
const char* result = session_run_string(sess, "project('MyProject')");
|
||||
CHECK_EQUAL("[string \"project('MyProject')\"]:1: no active solution", result);
|
||||
CHECK_EQUAL("no active solution", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FnProject2, Project_ReturnsNewObject_OnNewName)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "testing/testing.h"
|
||||
extern "C" {
|
||||
#include "engine/session.h"
|
||||
#include "base/error.h"
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +35,8 @@ static int test_solution_fail(Session sess, Solution sln, Stream strm)
|
||||
struct FxSession
|
||||
{
|
||||
Session sess;
|
||||
Solution sln;
|
||||
Project prj;
|
||||
|
||||
FxSession()
|
||||
{
|
||||
@ -45,14 +48,24 @@ struct FxSession
|
||||
~FxSession()
|
||||
{
|
||||
session_destroy(sess);
|
||||
error_clear();
|
||||
}
|
||||
|
||||
Solution AddSolution()
|
||||
{
|
||||
Solution sln = solution_create();
|
||||
sln = solution_create();
|
||||
session_add_solution(sess, sln);
|
||||
solution_set_name(sln, "MySolution");
|
||||
return sln;
|
||||
}
|
||||
|
||||
Project AddProject()
|
||||
{
|
||||
prj = project_create();
|
||||
solution_add_project(sln, prj);
|
||||
project_set_name(prj, "MyProject");
|
||||
return prj;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -206,5 +219,42 @@ SUITE(session)
|
||||
int result = session_unload(sess);
|
||||
CHECK(result == OKAY);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Session validation tests
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxSession, Validate_ReturnsOkay_OnNoSolutions)
|
||||
{
|
||||
int result = session_validate(sess);
|
||||
CHECK(result == OKAY);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxSession, Validate_ReturnsOkay_OnAllsWell)
|
||||
{
|
||||
AddSolution();
|
||||
AddProject();
|
||||
project_set_language(prj, "c++");
|
||||
int result = session_validate(sess);
|
||||
CHECK(result == OKAY);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxSession, Validate_NotOkay_OnEmptySolution)
|
||||
{
|
||||
AddSolution();
|
||||
int result = session_validate(sess);
|
||||
CHECK(result != OKAY);
|
||||
CHECK_EQUAL("no projects defined for solution 'MySolution'", error_get());
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxSession, Validate_NotOkay_OnNullLanguage)
|
||||
{
|
||||
AddSolution();
|
||||
AddProject();
|
||||
int result = session_validate(sess);
|
||||
CHECK(result != OKAY);
|
||||
CHECK_EQUAL("no language defined for project 'MyProject'", error_get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ struct FxUnloadProject
|
||||
"solution('MySolution');"
|
||||
"prj = project('MyProject');"
|
||||
" guid '0C202E43-B9AF-4972-822B-5A42F0BF008C';"
|
||||
" language 'c++';"
|
||||
"return prj");
|
||||
}
|
||||
|
||||
@ -60,5 +61,12 @@ SUITE(unload)
|
||||
const char* result = project_get_guid(prj);
|
||||
CHECK_EQUAL("0C202E43-B9AF-4972-822B-5A42F0BF008C", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsLanguage)
|
||||
{
|
||||
unload_project(sess, L, prj);
|
||||
const char* result = project_get_language(prj);
|
||||
CHECK_EQUAL("c++", result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,27 +127,22 @@ int unload_solution(Session sess, lua_State* L, Solution sln)
|
||||
int unload_project(Session sess, lua_State* L, Project prj)
|
||||
{
|
||||
const char* value;
|
||||
int i;
|
||||
|
||||
assert(sess);
|
||||
UNUSED(sess);
|
||||
assert(L);
|
||||
assert(prj);
|
||||
|
||||
sess = 0; /* unused */
|
||||
|
||||
lua_getfield(L, -1, "name");
|
||||
for (i = 0; i < NumProjectFields; ++i)
|
||||
{
|
||||
lua_getfield(L, -1, ProjectFieldInfo[i].name);
|
||||
value = lua_tostring(L, -1);
|
||||
project_set_name(prj, value);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "basedir");
|
||||
value = lua_tostring(L, -1);
|
||||
project_set_base_dir(prj, value);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "guid");
|
||||
value = lua_tostring(L, -1);
|
||||
project_set_guid(prj, value);
|
||||
if (value != NULL)
|
||||
{
|
||||
project_set_value(prj, i, value);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
@ -157,22 +157,3 @@ int host_show_help(Session sess)
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make sure that the session contains a valid set of project objects: at least
|
||||
* one solution, each solution contains at least one project, etc.
|
||||
* \param sess The current execution session context.
|
||||
* \returns OKAY if the session is valid.
|
||||
*/
|
||||
int host_validate_session(Session sess)
|
||||
{
|
||||
assert(sess);
|
||||
if (session_num_solutions(sess) == 0)
|
||||
{
|
||||
error_set("no solutions defined");
|
||||
return !OKAY;
|
||||
}
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
@ -31,6 +31,5 @@ int host_run_steps(Session sess, HostExecutionStep* steps);
|
||||
void host_set_argv(const char** argv);
|
||||
int host_show_help(Session sess);
|
||||
int host_tests(void);
|
||||
int host_validate_session(Session sess);
|
||||
|
||||
#endif
|
||||
|
@ -1,63 +0,0 @@
|
||||
/**
|
||||
* \file host_validate_tests.cpp
|
||||
* \brief Automated tests for session validation.
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "testing/testing.h"
|
||||
extern "C" {
|
||||
#include "host/host.h"
|
||||
#include "base/error.h"
|
||||
}
|
||||
|
||||
struct FxHostValidate
|
||||
{
|
||||
Session sess;
|
||||
Solution sln;
|
||||
char buffer[8192];
|
||||
|
||||
FxHostValidate()
|
||||
{
|
||||
sess = session_create();
|
||||
stream_set_buffer(Console, buffer);
|
||||
}
|
||||
|
||||
~FxHostValidate()
|
||||
{
|
||||
session_destroy(sess);
|
||||
error_clear();
|
||||
host_set_argv(NULL);
|
||||
}
|
||||
|
||||
void AddSolution()
|
||||
{
|
||||
sln = solution_create();
|
||||
session_add_solution(sess, sln);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
SUITE(host)
|
||||
{
|
||||
TEST_FIXTURE(FxHostValidate, Validate_ReturnsOkay_OnValidSession)
|
||||
{
|
||||
AddSolution();
|
||||
int result = host_validate_session(sess);
|
||||
CHECK(result == OKAY);
|
||||
}
|
||||
|
||||
|
||||
TEST_FIXTURE(FxHostValidate, Validate_ReturnsNotOkay_OnNoSolutions)
|
||||
{
|
||||
int result = host_validate_session(sess);
|
||||
CHECK(result != OKAY);
|
||||
}
|
||||
|
||||
|
||||
TEST_FIXTURE(FxHostValidate, Validate_SetsError_OnNoSolutions)
|
||||
{
|
||||
host_validate_session(sess);
|
||||
CHECK_EQUAL("no solutions defined", error_get());
|
||||
}
|
||||
}
|
@ -18,8 +18,8 @@ static HostExecutionStep Steps[] =
|
||||
host_parse_argv, /* process the command line arguments */
|
||||
host_run_script, /* run the main script (i.e. premake4.lua) */
|
||||
session_unload, /* unload the objects built by the script into more accessible C data structures */
|
||||
session_validate, /* make sure that all required objects and values have been defined by the script */
|
||||
host_show_help, /* show help and version messages as appropriate; may end processing here */
|
||||
host_validate_session, /* make sure script defined required project objects */
|
||||
host_run_action, /* run the action specified on the command line */
|
||||
NULL /* all done! */
|
||||
};
|
||||
|
@ -17,6 +17,14 @@ enum FieldKind
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Field validation function signature.
|
||||
* \param value The value to validate.
|
||||
* \returns True if the value is considered valid.
|
||||
*/
|
||||
typedef int (*FieldValidator)(const char* value);
|
||||
|
||||
|
||||
/**
|
||||
* Metadata about a project object field.
|
||||
*/
|
||||
@ -24,6 +32,7 @@ struct FieldInfo
|
||||
{
|
||||
const char* name; /**< The name of the field. */
|
||||
enum FieldKind kind; /**< StringField or ListField */
|
||||
FieldValidator validator; /**< The field validation function */
|
||||
};
|
||||
|
||||
|
||||
|
@ -8,17 +8,20 @@
|
||||
#include <stdlib.h>
|
||||
#include "premake.h"
|
||||
#include "project/project.h"
|
||||
#include "base/cstr.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/path.h"
|
||||
#include "base/strings.h"
|
||||
|
||||
|
||||
struct FieldInfo ProjectFieldInfo[] =
|
||||
{
|
||||
{ "basedir", StringField },
|
||||
{ "guid", StringField },
|
||||
{ "location", StringField },
|
||||
{ "name", StringField },
|
||||
{ 0, 0 }
|
||||
{ "basedir", StringField, NULL },
|
||||
{ "guid", StringField, guid_is_valid },
|
||||
{ "language", StringField, project_is_valid_language },
|
||||
{ "location", StringField, NULL },
|
||||
{ "name", StringField, NULL },
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
@ -112,14 +115,13 @@ const char* project_get_guid(Project prj)
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the programming language specified for a project.
|
||||
* \param prj The project to query.
|
||||
* \returns The programming language specified for the project.
|
||||
* Get the programming language used by the project.
|
||||
* \param prj The project object to query.
|
||||
* \returns The language used by the project, or NULL if no language has been set.
|
||||
*/
|
||||
const char* project_get_language(Project prj)
|
||||
{
|
||||
prj = 0;
|
||||
return "c++";
|
||||
return project_get_value(prj, ProjectLanguage);
|
||||
}
|
||||
|
||||
|
||||
@ -158,6 +160,20 @@ const char* project_get_value(Project prj, enum ProjectField field)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the specified language is recognized. Current valid language strings
|
||||
* are 'c', 'c++', and 'c#'.
|
||||
* \param language The language string.
|
||||
* \returns True if the language string is recognized.
|
||||
*/
|
||||
int project_is_valid_language(const char* language)
|
||||
{
|
||||
return (cstr_eq(language, "c") ||
|
||||
cstr_eq(language, "c++") ||
|
||||
cstr_eq(language, "c#"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the base directory of the project.
|
||||
* \param prj The project object to modify.
|
||||
@ -181,6 +197,17 @@ void project_set_guid(Project prj, const char* guid)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the programming language used by a project.
|
||||
* \param prj The project to modify.
|
||||
* \param language The programming language used by the project.
|
||||
*/
|
||||
void project_set_language(Project prj, const char* language)
|
||||
{
|
||||
project_set_value(prj, ProjectLanguage, language);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the output location (the relative path from the base directory to the
|
||||
* target output directory) for this project.
|
||||
|
@ -17,6 +17,7 @@ enum ProjectField
|
||||
{
|
||||
ProjectBaseDirectory,
|
||||
ProjectGuid,
|
||||
ProjectLanguage,
|
||||
ProjectLocation,
|
||||
ProjectName,
|
||||
NumProjectFields
|
||||
@ -37,9 +38,11 @@ const char* project_get_language(Project prj);
|
||||
const char* project_get_location(Project prj);
|
||||
const char* project_get_name(Project prj);
|
||||
const char* project_get_value(Project prj, enum ProjectField field);
|
||||
int project_is_valid_language(const char* language);
|
||||
void project_set_base_dir(Project prj, const char* base_dir);
|
||||
void project_set_location(Project prj, const char* location);
|
||||
void project_set_guid(Project prj, const char* guid);
|
||||
void project_set_language(Project prj, const char* language);
|
||||
void project_set_location(Project prj, const char* location);
|
||||
void project_set_name(Project prj, const char* name);
|
||||
void project_set_value(Project prj, enum ProjectField field, const char* value);
|
||||
int project_tests(void);
|
||||
|
@ -17,10 +17,10 @@
|
||||
|
||||
struct FieldInfo SolutionFieldInfo[] =
|
||||
{
|
||||
{ "basedir", StringField },
|
||||
{ "location", StringField },
|
||||
{ "name", StringField },
|
||||
{ 0, 0 }
|
||||
{ "basedir", StringField, NULL },
|
||||
{ "location", StringField, NULL },
|
||||
{ "name", StringField, NULL },
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
|
@ -85,7 +85,7 @@ SUITE(project)
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* GUID testrs
|
||||
* GUID tests
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxProject, GetGuid_ReturnsNull_OnStartup)
|
||||
@ -102,6 +102,24 @@ SUITE(project)
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Language tests
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxProject, GetLanguage_ReturnsNull_OnStartup)
|
||||
{
|
||||
const char* result = project_get_language(prj);
|
||||
CHECK(result == NULL);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxProject, SetLanguage_CanRoundtrip)
|
||||
{
|
||||
project_set_language(prj, "c++");
|
||||
const char* result = project_get_language(prj);
|
||||
CHECK_EQUAL("c++", result);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Location tests
|
||||
**********************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user