Bug fixes and refactorings (r382:387)

This commit is contained in:
starkos 2008-05-21 21:03:46 +00:00
parent 8377b2e217
commit d5a4def451
22 changed files with 211 additions and 126 deletions

View File

@ -12,6 +12,13 @@
#include "make_project.h"
/** The project features supported by this action */
static SessionFeatures Features =
{
{ "c", "c++", NULL },
};
/** The GNU make solution writing process, for session_enumerate_objects() */
static SessionSolutionCallback SolutionCallbacks[] =
{
@ -70,7 +77,7 @@ static SessionProjectCallback ConfigCallbacks[] =
int gmake_action(Session sess)
{
/* make sure I can support all of the features used in the session */
if (make_validate_session(sess) != OKAY)
if (session_validate(sess, &Features) != OKAY)
{
return !OKAY;
}

View File

@ -128,40 +128,3 @@ 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;
}

View File

@ -11,6 +11,5 @@
const char* make_get_obj_filename(const char* filename);
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

View File

@ -140,9 +140,9 @@ int make_project_config_outdir(Session sess, Project prj, Stream strm)
*/
int make_project_config_outfile(Session sess, Project prj, Stream strm)
{
const char* outfile = project_get_outfile(prj);
UNUSED(sess);
UNUSED(prj);
return stream_writeline(strm, " OUTFILE := $(OUTDIR)/MyApp");
return stream_writeline(strm, " OUTFILE := $(OUTDIR)/%s", outfile);
}

View File

@ -8,6 +8,7 @@
#include "action/tests/action_tests.h"
extern "C" {
#include "action/make/make_project.h"
#include "platform/platform.h"
}
SUITE(action)
@ -88,9 +89,10 @@ SUITE(action)
TEST_FIXTURE(FxAction, MakeProject_Config_OutFile)
{
platform_set(MacOSX);
make_project_config_outfile(sess, prj, strm);
CHECK_EQUAL(
" OUTFILE := $(OUTDIR)/MyApp\n",
" OUTFILE := $(OUTDIR)/MyProject\n",
buffer);
}

View File

@ -95,16 +95,4 @@ 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);
}
}

View File

@ -46,16 +46,4 @@ SUITE(action)
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);
}
}

View File

@ -12,6 +12,13 @@
#include "vs200x_project.h"
/** The project features supported by this action */
static SessionFeatures Features =
{
{ "c", "c++", NULL },
};
/** The VS2002 solution writing process, for session_enumerate_objects() */
static SessionSolutionCallback SolutionCallbacks[] =
{
@ -67,7 +74,7 @@ static SessionProjectCallback ConfigCallbacks[] =
int vs2002_action(Session sess)
{
/* make sure I can support all of the features used in the session */
if (vs200x_validate_session(sess) != OKAY)
if (session_validate(sess, &Features) != OKAY)
{
return !OKAY;
}

View File

@ -12,6 +12,13 @@
#include "vs200x_project.h"
/** The project features supported by this action */
static SessionFeatures Features =
{
{ "c", "c++", NULL },
};
/** The VS2003 solution writing process, for session_enumerate_objects() */
static SessionSolutionCallback SolutionCallbacks[] =
{
@ -67,7 +74,7 @@ static SessionProjectCallback ConfigCallbacks[] =
int vs2003_action(Session sess)
{
/* make sure I can support all of the features used in the session */
if (vs200x_validate_session(sess) != OKAY)
if (session_validate(sess, &Features) != OKAY)
{
return !OKAY;
}

View File

@ -12,6 +12,13 @@
#include "vs200x_project.h"
/** The project features supported by this action */
static SessionFeatures Features =
{
{ "c", "c++", NULL },
};
/** The VS2005 solution writing process, for session_enumerate_objects() */
static SessionSolutionCallback SolutionCallbacks[] =
{
@ -74,7 +81,7 @@ static SessionProjectCallback ConfigCallbacks[] =
int vs2005_action(Session sess)
{
/* make sure I can support all of the features used in the session */
if (vs200x_validate_session(sess) != OKAY)
if (session_validate(sess, &Features) != OKAY)
{
return !OKAY;
}

View File

@ -12,6 +12,13 @@
#include "vs200x_project.h"
/** The project features supported by this action */
static SessionFeatures Features =
{
{ "c", "c++", NULL },
};
/** The VS2008 solution writing process, for session_enumerate_objects() */
static SessionSolutionCallback SolutionCallbacks[] =
{
@ -73,7 +80,7 @@ static SessionProjectCallback ConfigCallbacks[] =
int vs2008_action(Session sess)
{
/* make sure I can support all of the features used in the session */
if (vs200x_validate_session(sess) != OKAY)
if (session_validate(sess, &Features) != OKAY)
{
return !OKAY;
}

View File

@ -161,40 +161,3 @@ const char* vs200x_true(Session sess)
int version = vs200x_get_target_version(sess);
return (version < 2005) ? "TRUE" : "true";
}
/**
* 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;
}

View File

@ -15,7 +15,6 @@ int vs200x_get_target_version(Session sess);
const char* vs200x_project_file_extension(Project prj);
const char* vs200x_tool_guid(const char* language);
const char* vs200x_true(Session sess);
int vs200x_validate_session(Session sess);
#endif

34
src/platform/platform.c Normal file
View File

@ -0,0 +1,34 @@
/**
* \file platform.c
* \brief Platform abstraction API.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include "premake.h"
#include "platform.h"
static enum Platform CurrentPlatform = Unknown;
enum Platform platform_get()
{
if (CurrentPlatform == Unknown)
{
#if defined(PLATFORM_BSD)
CurrentPlatform = BSD;
#elif defined(PLATFORM_LINUX)
CurrentPlatform = Linux;
#elif defined(PLATFORM_MACOSX)
CurrentPlatform = MacOSX;
#else
CurrentPlatform = Windows;
#endif
}
return CurrentPlatform;
}
void platform_set(enum Platform id)
{
CurrentPlatform = id;
}

View File

@ -7,16 +7,29 @@
#define PREMAKE_PLATFORM_H
/* Determine the current OS. I'm not sure how to reliably detect Windows
* but since it is the most common I use it as the default */
/**
* The currently support platforms. If you add to this list be sure to
* also update the platform detection logic below, and the platform
* identifier initialization in platform.c.
*/
enum Platform
{
Unknown,
BSD,
Linux,
MacOSX,
Windows
};
#if defined(__linux__)
#define PLATFORM_LINUX 1
#define PLATFORM_LINUX (1)
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define PLATFORM_BSD 1
#define PLATFORM_BSD (1)
#elif defined(__APPLE__) && defined(__MACH__)
#define PLATFORM_MACOSX 1
#define PLATFORM_MACOSX (1)
#else
#define PLATFORM_WINDOWS 1
#define PLATFORM_WINDOWS (1)
#endif
@ -51,4 +64,18 @@ int platform_dir_get_current(char* buffer, int size);
int platform_dir_set_current(const char* path);
/**
* Retrieve the current platform identifier.
*/
enum Platform platform_get(void);
/**
* Set the platform identification string, forcing a platform-specific
* behavior regardless of the actual current platform.
* \param id One of the platform identifiers.
*/
void platform_set(enum Platform id);
#endif

View File

@ -18,7 +18,6 @@ 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_run_action, /* run the action specified on the command line */
NULL /* all done! */

View File

@ -6,12 +6,15 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "premake.h"
#include "project/project.h"
#include "base/buffers.h"
#include "base/cstr.h"
#include "base/guid.h"
#include "base/path.h"
#include "base/strings.h"
#include "platform/platform.h"
struct FieldInfo ProjectFieldInfo[] =
@ -172,6 +175,24 @@ const char* project_get_name(Project prj)
}
/**
* Retrieve the output filename for this project, taking into account platform-specific
* naming conventions. For instance, for a project named "MyProject" this function would
* return "MyProject.exe" on Windows. No path information is included, use the function
* project_get_outdir() for that.
*/
const char* project_get_outfile(Project prj)
{
char* buffer = buffers_next();
strcpy(buffer, project_get_name(prj));
if (platform_get() == Windows)
{
strcat(buffer, ".exe");
}
return buffer;
}
/**
* Retrieve a string (single value) fields from a project, using the field indices.
* \param prj The project object to query.

View File

@ -40,6 +40,7 @@ const char* project_get_guid(Project prj);
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_outfile(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);

View File

@ -8,6 +8,7 @@
#include "testing/testing.h"
extern "C" {
#include "project/project.h"
#include "platform/platform.h"
}
@ -176,6 +177,28 @@ SUITE(project)
const char* filename = project_get_filename(prj, NULL, ".xyz");
CHECK_EQUAL("/BaseDir/Location/MyProject.xyz", filename);
}
/**********************************************************************
* Output file tests
**********************************************************************/
TEST_FIXTURE(FxProject, GetOutFile_ReturnsProjectName_OnNoTargetAndNotWindows)
{
platform_set(MacOSX);
project_set_name(prj, "MyProject");
const char* result = project_get_outfile(prj);
CHECK_EQUAL("MyProject", result);
}
TEST_FIXTURE(FxProject, GetOutFile_AddsExe_OnNoTargetAndWindows)
{
platform_set(Windows);
project_set_name(prj, "MyProject");
const char* result = project_get_outfile(prj);
CHECK_EQUAL("MyProject.exe", result);
}
}

View File

@ -305,14 +305,16 @@ int session_unload(Session sess)
/**
* Make sure that all required objects and values have been defined by the
* project script.
* \param sess The session to validate.
* \param sess The session to validate.
* \param features The features (language, kind, etc.) supported by the current action.
* \returns OKAY if the session is valid.
*/
int session_validate(Session sess)
int session_validate(Session sess, SessionFeatures* features)
{
int si, sn;
assert(sess);
assert(features);
sn = session_num_solutions(sess);
for (si = 0; si < sn; ++si)
@ -330,14 +332,29 @@ int session_validate(Session sess)
for (pi = 0; pi < pn; ++pi)
{
const char* value;
int i;
Project prj = solution_get_project(sln, pi);
const char* prj_name = project_get_name(prj);
const char* prj_lang = project_get_language(prj);
/* every project must have a language defined */
value = project_get_language(prj);
if (value == NULL)
if (prj_lang == NULL)
{
error_set("no language defined for project '%s'", project_get_name(prj));
error_set("no language defined for project '%s'", prj_name);
return !OKAY;
}
/* action must support the language */
for (i = 0; features->languages[i] != NULL; ++i)
{
if (cstr_eq(prj_lang, features->languages[i]))
break;
}
if (features->languages[i] == NULL)
{
error_set("%s language projects are not supported by this action", prj_lang);
return !OKAY;
}
}

View File

@ -64,6 +64,17 @@ typedef struct struct_SessionAction
} SessionAction;
/**
* Describe the features (languages, project kinds, etc.) supported by an action. Used by
* session_validate() to ensure that action handler functions only get called with data
* that they can handle.
*/
typedef struct struct_SessionFeatures
{
const char* languages[64];
} SessionFeatures;
Session session_create(void);
void session_destroy(Session sess);
void session_add_solution(Session sess, Solution sln);
@ -79,7 +90,7 @@ void session_set_action(Session sess, const char* action);
void session_set_active_stream(Session sess, Stream strm);
int session_tests(void);
int session_unload(Session sess);
int session_validate(Session sess);
int session_validate(Session sess, SessionFeatures* features);
#endif
/** @} */

View File

@ -36,6 +36,11 @@ int session_tests()
#define FAIL_SLN_PARAM (1)
#define FAIL_PRJ_PARAM (2)
static SessionFeatures features = {
{ "c", "c++", NULL },
};
static int num_solution_calls;
static int num_project_calls;
static int num_config_calls;
@ -349,7 +354,7 @@ SUITE(session)
TEST_FIXTURE(FxSession, Validate_ReturnsOkay_OnNoSolutions)
{
int result = session_validate(sess);
int result = session_validate(sess, &features);
CHECK(result == OKAY);
}
@ -358,14 +363,14 @@ SUITE(session)
AddSolution();
AddProject();
project_set_language(prj, "c++");
int result = session_validate(sess);
int result = session_validate(sess, &features);
CHECK(result == OKAY);
}
TEST_FIXTURE(FxSession, Validate_NotOkay_OnEmptySolution)
{
AddSolution();
int result = session_validate(sess);
int result = session_validate(sess, &features);
CHECK(result != OKAY);
CHECK_EQUAL("no projects defined for solution 'MySolution'", error_get());
}
@ -374,9 +379,19 @@ SUITE(session)
{
AddSolution();
AddProject();
int result = session_validate(sess);
int result = session_validate(sess, &features);
CHECK(result != OKAY);
CHECK_EQUAL("no language defined for project 'MyProject'", error_get());
}
TEST_FIXTURE(FxSession, Validate_NotOkay_OnUnsupportedLanguage)
{
AddSolution();
AddProject();
project_set_language(prj, "nonesuch");
int result = session_validate(sess, &features);
CHECK(result != OKAY);
CHECK_EQUAL("nonesuch language projects are not supported by this action", error_get());
}
}