Initial implementation of files() with Visual Studio support (r359:369)
This commit is contained in:
parent
e238e847b1
commit
b3bb81cfd0
@ -4,9 +4,11 @@
|
||||
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
#include "action/action.h"
|
||||
|
||||
#include "base/buffers.h"
|
||||
#include "base/cstr.h"
|
||||
|
||||
SessionAction Actions[] =
|
||||
{
|
||||
@ -17,3 +19,97 @@ SessionAction Actions[] =
|
||||
{ "vs2008", "Microsoft Visual Studio 2008 (includes Express editions)", vs2008_action },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static int action_source_tree_do(Session sess, Project prj, Stream strm, ActionSourceCallback handler, const char* group);
|
||||
|
||||
|
||||
/**
|
||||
* Walk a list of source files and pass them off, in nesting order, to
|
||||
* the specified callback. Handles the grouping of related files info
|
||||
* groups (by directory currently).
|
||||
* \param sess The current execution session context.
|
||||
* \param prj The project containing the files to enumerate.
|
||||
* \param strm The active output stream.
|
||||
* \param handler The per-file handler function.
|
||||
* \returns OKAY on success.
|
||||
*/
|
||||
int action_source_tree(Session sess, Project prj, Stream strm, ActionSourceCallback handler)
|
||||
{
|
||||
return action_source_tree_do(sess, prj, strm, handler, "");
|
||||
}
|
||||
|
||||
|
||||
static int action_source_tree_do(Session sess, Project prj, Stream strm, ActionSourceCallback handler, const char* group)
|
||||
{
|
||||
int i, n, group_len;
|
||||
Strings files;
|
||||
char* buffer = buffers_next();
|
||||
|
||||
/* open an enclosing group */
|
||||
group_len = strlen(group);
|
||||
strcpy(buffer, group);
|
||||
if (cstr_ends_with(buffer, "/")) /* Trim off trailing path separator */
|
||||
{
|
||||
buffer[strlen(buffer)-1] = '\0';
|
||||
}
|
||||
handler(sess, prj, strm, buffer, GroupStart);
|
||||
|
||||
/* scan all files in this group and process any subdirectories (subgroups) */
|
||||
files = project_get_files(prj);
|
||||
n = strings_size(files);
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
const char* filename = strings_item(files, i);
|
||||
|
||||
/* is this file in the group that I am currently processing? */
|
||||
if (cstr_starts_with(filename, group))
|
||||
{
|
||||
/* see if this file contains an additional directory level (a new group) */
|
||||
const char* ptr = strchr(filename + group_len, '/');
|
||||
if (ptr)
|
||||
{
|
||||
int j;
|
||||
|
||||
/* pull out the name of this new group */
|
||||
size_t len = ptr - filename + 1;
|
||||
strncpy(buffer, filename, len);
|
||||
buffer[len] = '\0';
|
||||
|
||||
/* have I processed this subdirectory already? See if it appears earlier in the list */
|
||||
for (j = 0; j < i; ++j)
|
||||
{
|
||||
if (cstr_starts_with(strings_item(files, j), buffer))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == j)
|
||||
{
|
||||
/* a new group, process it now */
|
||||
if (action_source_tree_do(sess, prj, strm, handler, buffer) != OKAY)
|
||||
return !OKAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now process all files that belong to this current group (and not a subgroup) */
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
const char* filename = strings_item(files, i);
|
||||
if (!strchr(filename + group_len, '/'))
|
||||
{
|
||||
if (handler(sess, prj, strm, filename, SourceFile) != OKAY)
|
||||
return !OKAY;
|
||||
}
|
||||
}
|
||||
|
||||
/* close the group */
|
||||
strcpy(buffer, group);
|
||||
if (cstr_ends_with(buffer, "/")) /* Trim off trailing path separator */
|
||||
{
|
||||
buffer[strlen(buffer)-1] = '\0';
|
||||
}
|
||||
handler(sess, prj, strm, buffer, GroupEnd);
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,31 @@
|
||||
|
||||
#include "session/session.h"
|
||||
|
||||
|
||||
/**
|
||||
* State values for the source tree enumeration functions.
|
||||
*/
|
||||
enum ActionSourceState
|
||||
{
|
||||
GroupStart,
|
||||
GroupEnd,
|
||||
SourceFile
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Per-file callback signature for action_source_tree.
|
||||
* \param sess The current execution state context.
|
||||
* \param prj The current project; contains the file being enumerated.
|
||||
* \param strm The active output stream; for writing the file markup.
|
||||
* \param filename The name of the file to process.
|
||||
* \param state One of the ActionSourceStates, enabling file grouping.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
typedef int (*ActionSourceCallback)(Session sess, Project prj, Stream strm, const char* filename, int state);
|
||||
|
||||
|
||||
/* the list of built-in Premake actions */
|
||||
extern SessionAction Actions[];
|
||||
|
||||
int gmake_action(Session sess);
|
||||
@ -16,4 +41,9 @@ int vs2003_action(Session sess);
|
||||
int vs2005_action(Session sess);
|
||||
int vs2008_action(Session sess);
|
||||
|
||||
|
||||
/* support functions */
|
||||
int action_source_tree(Session sess, Project prj, Stream strm, ActionSourceCallback handler);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -48,4 +48,16 @@ struct FxAction
|
||||
stream_destroy(strm);
|
||||
session_destroy(sess);
|
||||
}
|
||||
|
||||
|
||||
void SetField(Project prj, enum ProjectField index, char** values)
|
||||
{
|
||||
Strings strs = strings_create();
|
||||
for (char** value = values; (*value) != NULL; ++value)
|
||||
{
|
||||
strings_add(strs, *value);
|
||||
}
|
||||
|
||||
project_set_values(prj, index, strs);
|
||||
}
|
||||
};
|
||||
|
@ -23,7 +23,7 @@ SUITE(action)
|
||||
{
|
||||
TEST_FIXTURE(Fx2002Config, CharacterSet_Default)
|
||||
{
|
||||
vs200x_config_character_set(sess);
|
||||
vs200x_config_character_set(sess, strm);
|
||||
CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ SUITE(action)
|
||||
{
|
||||
TEST_FIXTURE(Fx2003Config, CharacterSet_Default)
|
||||
{
|
||||
vs200x_config_character_set(sess);
|
||||
vs200x_config_character_set(sess, strm);
|
||||
CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ SUITE(action)
|
||||
{
|
||||
TEST_FIXTURE(Fx2005Config, CharacterSet_Default)
|
||||
{
|
||||
vs200x_config_character_set(sess);
|
||||
vs200x_config_character_set(sess, strm);
|
||||
CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ SUITE(action)
|
||||
{
|
||||
TEST_FIXTURE(Fx2008Config, CharacterSet_Default)
|
||||
{
|
||||
vs200x_config_character_set(sess);
|
||||
vs200x_config_character_set(sess, strm);
|
||||
CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer);
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ SUITE(action)
|
||||
* Files section tests
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxVsProject, Vs200x_Files)
|
||||
TEST_FIXTURE(FxVsProject, Vs200x_Files_OnNoFiles)
|
||||
{
|
||||
vs200x_project_files(sess, prj, strm);
|
||||
CHECK_EQUAL(
|
||||
@ -231,6 +231,52 @@ SUITE(action)
|
||||
buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxVsProject, Vs200x_Files_OnSingleCppFile)
|
||||
{
|
||||
char* values[] = { "Hello.cpp", 0 };
|
||||
SetField(prj, ProjectFiles, values);
|
||||
vs200x_project_files(sess, prj, strm);
|
||||
CHECK_EQUAL(
|
||||
"\t<Files>\n"
|
||||
"\t\t<File\n"
|
||||
"\t\t\tRelativePath=\".\\Hello.cpp\">\n"
|
||||
"\t\t</File>\n"
|
||||
"\t</Files>\n",
|
||||
buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxVsProject, Vs200x_Files_OnUpperDirectory)
|
||||
{
|
||||
char* values[] = { "../../Hello.cpp", 0 };
|
||||
SetField(prj, ProjectFiles, values);
|
||||
vs200x_project_files(sess, prj, strm);
|
||||
CHECK_EQUAL(
|
||||
"\t<Files>\n"
|
||||
"\t\t<File\n"
|
||||
"\t\t\tRelativePath=\"..\\..\\Hello.cpp\">\n"
|
||||
"\t\t</File>\n"
|
||||
"\t</Files>\n",
|
||||
buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxVsProject, Vs200x_Files_OnGroupedCppFile)
|
||||
{
|
||||
char* values[] = { "Src/Hello.cpp", 0 };
|
||||
SetField(prj, ProjectFiles, values);
|
||||
vs200x_project_files(sess, prj, strm);
|
||||
CHECK_EQUAL(
|
||||
"\t<Files>\n"
|
||||
"\t\t<Filter\n"
|
||||
"\t\t\tName=\"Src\"\n"
|
||||
"\t\t\tFilter=\"\">\n"
|
||||
"\t\t\t<File\n"
|
||||
"\t\t\t\tRelativePath=\".\\Src\\Hello.cpp\">\n"
|
||||
"\t\t\t</File>\n"
|
||||
"\t\t</Filter>\n"
|
||||
"\t</Files>\n",
|
||||
buffer);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Globals section tests
|
||||
@ -245,5 +291,4 @@ SUITE(action)
|
||||
"</VisualStudioProject>\n",
|
||||
buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,43 +13,6 @@ extern "C" {
|
||||
|
||||
SUITE(action)
|
||||
{
|
||||
/**********************************************************************
|
||||
* Element tests
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxAction, Element_OnLevel0)
|
||||
{
|
||||
session_set_action(sess, "vs2002");
|
||||
vs200x_element(sess, 0, "VisualStudioProject");
|
||||
CHECK_EQUAL("<VisualStudioProject>\n", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, Element_OnLevel1)
|
||||
{
|
||||
session_set_action(sess, "vs2002");
|
||||
vs200x_element(sess, 1, "VisualStudioProject");
|
||||
CHECK_EQUAL("\t<VisualStudioProject>\n", buffer);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Element start tests
|
||||
**********************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxAction, ElementStart_OnLevel0)
|
||||
{
|
||||
session_set_action(sess, "vs2002");
|
||||
vs200x_element_start(sess, 0, "VisualStudioProject");
|
||||
CHECK_EQUAL("<VisualStudioProject", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, ElementStart_OnLevel1)
|
||||
{
|
||||
session_set_action(sess, "vs2002");
|
||||
vs200x_element_start(sess, 1, "VisualStudioProject");
|
||||
CHECK_EQUAL("\t<VisualStudioProject", buffer);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Element end tests
|
||||
**********************************************************************/
|
||||
@ -57,56 +20,56 @@ SUITE(action)
|
||||
TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2002)
|
||||
{
|
||||
session_set_action(sess, "vs2002");
|
||||
vs200x_element_end(sess, 0, "/>");
|
||||
vs200x_element_end(sess, strm, 0, "/>");
|
||||
CHECK_EQUAL("/>\n", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2003)
|
||||
{
|
||||
session_set_action(sess, "vs2003");
|
||||
vs200x_element_end(sess, 0, "/>");
|
||||
vs200x_element_end(sess, strm, 0, "/>");
|
||||
CHECK_EQUAL("/>\n", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2005)
|
||||
{
|
||||
session_set_action(sess, "vs2005");
|
||||
vs200x_element_end(sess, 0, "/>");
|
||||
vs200x_element_end(sess, strm, 0, "/>");
|
||||
CHECK_EQUAL("\n/>\n", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2008)
|
||||
{
|
||||
session_set_action(sess, "vs2008");
|
||||
vs200x_element_end(sess, 0, "/>");
|
||||
vs200x_element_end(sess, strm, 0, "/>");
|
||||
CHECK_EQUAL("\n/>\n", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2002)
|
||||
{
|
||||
session_set_action(sess, "vs2002");
|
||||
vs200x_element_end(sess, 0, ">");
|
||||
vs200x_element_end(sess, strm, 0, ">");
|
||||
CHECK_EQUAL(">\n", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2003)
|
||||
{
|
||||
session_set_action(sess, "vs2003");
|
||||
vs200x_element_end(sess, 0, ">");
|
||||
vs200x_element_end(sess, strm, 0, ">");
|
||||
CHECK_EQUAL(">\n", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2005)
|
||||
{
|
||||
session_set_action(sess, "vs2005");
|
||||
vs200x_element_end(sess, 0, ">");
|
||||
vs200x_element_end(sess, strm, 0, ">");
|
||||
CHECK_EQUAL("\n\t>\n", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2008)
|
||||
{
|
||||
session_set_action(sess, "vs2008");
|
||||
vs200x_element_end(sess, 0, ">");
|
||||
vs200x_element_end(sess, strm, 0, ">");
|
||||
CHECK_EQUAL("\n\t>\n", buffer);
|
||||
}
|
||||
|
||||
@ -118,42 +81,14 @@ SUITE(action)
|
||||
TEST_FIXTURE(FxAction, Attribute_OnLevel0)
|
||||
{
|
||||
session_set_action(sess, "vs2002");
|
||||
vs200x_attribute(sess, 0, "ProjectType", "Visual C++");
|
||||
CHECK_EQUAL("\n\tProjectType=\"Visual C++\"", buffer);
|
||||
vs200x_attribute(strm, 0, "ProjectType", "Visual C++");
|
||||
CHECK_EQUAL("\nProjectType=\"Visual C++\"", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, Attribute_OnLevel1)
|
||||
TEST_FIXTURE(FxAction, Attribute_OnLevel3)
|
||||
{
|
||||
session_set_action(sess, "vs2002");
|
||||
vs200x_attribute(sess, 1, "ProjectType", "Visual C++");
|
||||
CHECK_EQUAL("\n\t\tProjectType=\"Visual C++\"", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, Attribute_BooleanValue_OnVs2002)
|
||||
{
|
||||
session_set_action(sess, "vs2002");
|
||||
vs200x_attribute(sess, 0, "RuntimeTypeInfo", "true");
|
||||
CHECK_EQUAL("\n\tRuntimeTypeInfo=\"TRUE\"", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, Attribute_BooleanValue_OnVs2003)
|
||||
{
|
||||
session_set_action(sess, "vs2003");
|
||||
vs200x_attribute(sess, 0, "RuntimeTypeInfo", "true");
|
||||
CHECK_EQUAL("\n\tRuntimeTypeInfo=\"TRUE\"", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, Attribute_BooleanValue_OnVs2005)
|
||||
{
|
||||
session_set_action(sess, "vs2005");
|
||||
vs200x_attribute(sess, 0, "RuntimeTypeInfo", "true");
|
||||
CHECK_EQUAL("\n\tRuntimeTypeInfo=\"true\"", buffer);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAction, Attribute_BooleanValue_OnVs2008)
|
||||
{
|
||||
session_set_action(sess, "vs2008");
|
||||
vs200x_attribute(sess, 0, "RuntimeTypeInfo", "true");
|
||||
CHECK_EQUAL("\n\tRuntimeTypeInfo=\"true\"", buffer);
|
||||
vs200x_attribute(strm, 3, "ProjectType", "Visual C++");
|
||||
CHECK_EQUAL("\n\t\t\tProjectType=\"Visual C++\"", buffer);
|
||||
}
|
||||
}
|
||||
|
@ -14,33 +14,20 @@
|
||||
|
||||
/**
|
||||
* Write an XML attribute, adjusting for the differing Visual Studio formats.
|
||||
* \param sess The current execution session.
|
||||
* \param level The XML element nesting level.
|
||||
* \param strm The output stream, the attribute will be written here.
|
||||
* \param indent_size How far to indent (with tabs) the attribute.
|
||||
* \param name The attribute name.
|
||||
* \param value The attribute value.
|
||||
* \param value The attribute value; may contain printf-style formatting codes.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int vs200x_attribute(Session sess, int level, const char* name, const char* value, ...)
|
||||
int vs200x_attribute(Stream strm, int indent_size, const char* name, const char* value, ...)
|
||||
{
|
||||
int z;
|
||||
va_list args;
|
||||
Stream strm = session_get_active_stream(sess);
|
||||
|
||||
if (vs200x_get_target_version(sess) < 2005)
|
||||
{
|
||||
if (cstr_eq(value, "true"))
|
||||
{
|
||||
value = "TRUE";
|
||||
}
|
||||
else if (cstr_eq(value, "false"))
|
||||
{
|
||||
value = "FALSE";
|
||||
}
|
||||
}
|
||||
int z = OKAY;
|
||||
|
||||
va_start(args, value);
|
||||
z = stream_writeline(strm, "");
|
||||
z |= stream_write_n(strm, "\t", level + 1);
|
||||
z |= stream_writeline(strm, "");
|
||||
z |= stream_write_n(strm, "\t", indent_size);
|
||||
z |= stream_write(strm, "%s=\"", name);
|
||||
z |= stream_vprintf(strm, value, args);
|
||||
z |= stream_write(strm, "\"");
|
||||
@ -49,34 +36,17 @@ int vs200x_attribute(Session sess, int level, const char* name, const char* valu
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write out an element tag.
|
||||
* \param sess The current execution session.
|
||||
* \param level The XML element nesting level.
|
||||
* \param name The element name.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int vs200x_element(Session sess, int level, const char* name)
|
||||
{
|
||||
int z;
|
||||
Stream strm = session_get_active_stream(sess);
|
||||
z = stream_write_n(strm, "\t", level);
|
||||
z |= stream_writeline(strm, "<%s>", name);
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write the ending part of an XML tag, adjust for the differing Visual Studio formats.
|
||||
* \param sess The current execution session.
|
||||
* \param strm The output stream.
|
||||
* \param level The XML element nesting level.
|
||||
* \param markup The end tag markup.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int vs200x_element_end(Session sess, int level, const char* markup)
|
||||
int vs200x_element_end(Session sess, Stream strm, int level, const char* markup)
|
||||
{
|
||||
int z;
|
||||
Stream strm = session_get_active_stream(sess);
|
||||
int version = vs200x_get_target_version(sess);
|
||||
if (version >= 2005)
|
||||
{
|
||||
@ -97,19 +67,13 @@ int vs200x_element_end(Session sess, int level, const char* markup)
|
||||
|
||||
|
||||
/**
|
||||
* Write out the starting part of an XML element tag: "<MyElement".
|
||||
* \param sess The current execution session.
|
||||
* \param level The XML element nesting level.
|
||||
* \param name The element name.
|
||||
* \returns OKAY if successful.
|
||||
* Return the Visual Studio version appropriate version of the string for a false
|
||||
* value. Before 2005 this was "FALSE", after it is "false".
|
||||
*/
|
||||
int vs200x_element_start(Session sess, int level, const char* name)
|
||||
const char* vs200x_false(Session sess)
|
||||
{
|
||||
int z;
|
||||
Stream strm = session_get_active_stream(sess);
|
||||
z = stream_write_n(strm, "\t", level);
|
||||
z |= stream_write(strm, "<%s", name);
|
||||
return z;
|
||||
int version = vs200x_get_target_version(sess);
|
||||
return (version < 2005) ? "FALSE" : "false";
|
||||
}
|
||||
|
||||
|
||||
@ -188,6 +152,17 @@ const char* vs200x_tool_guid(const char* language)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the Visual Studio version appropriate version of the string for a true
|
||||
* value. Before 2005 this was "TRUE", after it is "true".
|
||||
*/
|
||||
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.
|
||||
|
@ -8,13 +8,13 @@
|
||||
|
||||
#include "session/session.h"
|
||||
|
||||
int vs200x_attribute(Session sess, int level, const char* name, const char* value, ...);
|
||||
int vs200x_element(Session sess, int level, const char* name);
|
||||
int vs200x_element_end(Session sess, int level, const char* markup);
|
||||
int vs200x_element_start(Session sess, int level, const char* name);
|
||||
int vs200x_attribute(Stream strm, int indent_size, const char* name, const char* value, ...);
|
||||
int vs200x_element_end(Session sess, Stream strm, int level, const char* markup);
|
||||
const char* vs200x_false(Session sess);
|
||||
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
|
||||
|
@ -9,40 +9,40 @@
|
||||
#include "vs200x_config.h"
|
||||
|
||||
|
||||
int vs200x_config_character_set(Session sess)
|
||||
int vs200x_config_character_set(Session sess, Stream strm)
|
||||
{
|
||||
int version = vs200x_get_target_version(sess);
|
||||
return vs200x_attribute(sess, 2, "CharacterSet", version > 2003 ? "1" : "2");
|
||||
return vs200x_attribute(strm, 3, "CharacterSet", version > 2003 ? "1" : "2");
|
||||
}
|
||||
|
||||
|
||||
int vs200x_config_detect_64bit_portability(Session sess, Project prj)
|
||||
int vs200x_config_detect_64bit_portability(Session sess, Stream strm, Project prj)
|
||||
{
|
||||
int version = vs200x_get_target_version(sess);
|
||||
UNUSED(prj);
|
||||
if (version < 2008)
|
||||
{
|
||||
return vs200x_attribute(sess, 3, "Detect64BitPortabilityProblems", "true");
|
||||
return vs200x_attribute(strm, 4, "Detect64BitPortabilityProblems", vs200x_true(sess));
|
||||
}
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
int vs200x_config_runtime_type_info(Session sess, Project prj)
|
||||
int vs200x_config_runtime_type_info(Session sess, Stream strm, Project prj)
|
||||
{
|
||||
int version = vs200x_get_target_version(sess);
|
||||
UNUSED(prj);
|
||||
if (version < 2005)
|
||||
{
|
||||
return vs200x_attribute(sess, 3, "RuntimeTypeInfo", "true");
|
||||
return vs200x_attribute(strm, 4, "RuntimeTypeInfo", vs200x_true(sess));
|
||||
}
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
int vs200x_config_use_precompiled_header(Session sess, Project prj)
|
||||
int vs200x_config_use_precompiled_header(Session sess, Stream strm, Project prj)
|
||||
{
|
||||
int version = vs200x_get_target_version(sess);
|
||||
UNUSED(prj);
|
||||
return vs200x_attribute(sess, 3, "UsePrecompiledHeader", (version > 2003) ? "0" : "2");
|
||||
return vs200x_attribute(strm, 4, "UsePrecompiledHeader", (version > 2003) ? "0" : "2");
|
||||
}
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
#include "session/session.h"
|
||||
|
||||
int vs200x_config_character_set(Session sess);
|
||||
int vs200x_config_detect_64bit_portability(Session sess, Project prj);
|
||||
int vs200x_config_runtime_type_info(Session sess, Project prj);
|
||||
int vs200x_config_use_precompiled_header(Session sess, Project prj);
|
||||
int vs200x_config_character_set(Session sess, Stream strm);
|
||||
int vs200x_config_detect_64bit_portability(Session sess, Stream strm, Project prj);
|
||||
int vs200x_config_runtime_type_info(Session sess, Stream strm, Project prj);
|
||||
int vs200x_config_use_precompiled_header(Session sess, Stream strm, Project prj);
|
||||
|
||||
#endif
|
||||
|
@ -5,10 +5,14 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "premake.h"
|
||||
#include "action/action.h"
|
||||
#include "vs200x.h"
|
||||
#include "vs200x_project.h"
|
||||
#include "vs200x_config.h"
|
||||
#include "base/cstr.h"
|
||||
#include "base/path.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -16,16 +20,15 @@
|
||||
*/
|
||||
int vs200x_project_config_element(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
int z;
|
||||
int z = OKAY;
|
||||
const char* cfg_name = project_get_configuration_filter(prj);
|
||||
UNUSED(strm);
|
||||
z = vs200x_element_start(sess, 2, "Configuration");
|
||||
z |= vs200x_attribute(sess, 2, "Name", "%s|Win32", cfg_name);
|
||||
z |= vs200x_attribute(sess, 2, "OutputDirectory", "$(SolutionDir)$(ConfigurationName)");
|
||||
z |= vs200x_attribute(sess, 2, "IntermediateDirectory", "$(ConfigurationName)");
|
||||
z |= vs200x_attribute(sess, 2, "ConfigurationType", "1");
|
||||
z |= vs200x_config_character_set(sess);
|
||||
z |= vs200x_element_end(sess, 2, ">");
|
||||
z |= stream_write(strm, "\t\t<Configuration");
|
||||
z |= vs200x_attribute(strm, 3, "Name", "%s|Win32", cfg_name);
|
||||
z |= vs200x_attribute(strm, 3, "OutputDirectory", "$(SolutionDir)$(ConfigurationName)");
|
||||
z |= vs200x_attribute(strm, 3, "IntermediateDirectory", "$(ConfigurationName)");
|
||||
z |= vs200x_attribute(strm, 3, "ConfigurationType", "1");
|
||||
z |= vs200x_config_character_set(sess, strm);
|
||||
z |= vs200x_element_end(sess, strm, 2, ">");
|
||||
return z;
|
||||
}
|
||||
|
||||
@ -35,9 +38,9 @@ int vs200x_project_config_element(Session sess, Project prj, Stream strm)
|
||||
*/
|
||||
int vs200x_project_config_end(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
UNUSED(sess);
|
||||
UNUSED(prj);
|
||||
UNUSED(strm);
|
||||
return vs200x_element(sess, 2, "/Configuration");
|
||||
return stream_writeline(strm, "\t\t</Configuration>");
|
||||
}
|
||||
|
||||
|
||||
@ -71,8 +74,6 @@ int vs200x_project_element(Session sess, Project prj, Stream strm)
|
||||
const char* prj_name = project_get_name(prj);
|
||||
const char* prj_guid = project_get_guid(prj);
|
||||
|
||||
UNUSED(strm);
|
||||
|
||||
version = vs200x_get_target_version(sess);
|
||||
switch (version)
|
||||
{
|
||||
@ -86,21 +87,21 @@ int vs200x_project_element(Session sess, Project prj, Stream strm)
|
||||
prj_ver = "9.00"; break;
|
||||
}
|
||||
|
||||
z = vs200x_element_start(sess, 0, "VisualStudioProject");
|
||||
z |= vs200x_attribute(sess, 0, "ProjectType", "Visual C++");
|
||||
z |= vs200x_attribute(sess, 0, "Version", prj_ver);
|
||||
z |= vs200x_attribute(sess, 0, "Name", prj_name);
|
||||
z |= vs200x_attribute(sess, 0, "ProjectGUID", "{%s}", prj_guid);
|
||||
z = stream_write(strm, "<VisualStudioProject");
|
||||
z |= vs200x_attribute(strm, 1, "ProjectType", "Visual C++");
|
||||
z |= vs200x_attribute(strm, 1, "Version", prj_ver);
|
||||
z |= vs200x_attribute(strm, 1, "Name", prj_name);
|
||||
z |= vs200x_attribute(strm, 1, "ProjectGUID", "{%s}", prj_guid);
|
||||
if (version > 2003)
|
||||
{
|
||||
z |= vs200x_attribute(sess, 0, "RootNamespace", prj_name);
|
||||
z |= vs200x_attribute(strm, 1, "RootNamespace", prj_name);
|
||||
}
|
||||
z |= vs200x_attribute(sess, 0, "Keyword", "Win32Proj");
|
||||
z |= vs200x_attribute(strm, 1, "Keyword", "Win32Proj");
|
||||
if (version > 2005)
|
||||
{
|
||||
z |= vs200x_attribute(sess, 0, "TargetFrameworkVersion", "196613");
|
||||
z |= vs200x_attribute(strm, 1, "TargetFrameworkVersion", "196613");
|
||||
}
|
||||
z |= vs200x_element_end(sess, 0, ">");
|
||||
z |= vs200x_element_end(sess, strm, 0, ">");
|
||||
return z;
|
||||
}
|
||||
|
||||
@ -117,16 +118,89 @@ int vs200x_project_encoding(Session sess, Project prj, Stream strm)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write an individual file entry to the project file; callback for action_source_tree().
|
||||
* \param sess The current execution session context.
|
||||
* \param prj The current project; contains the file being enumerated.
|
||||
* \param strm The active output stream; for writing the file markup.
|
||||
* \param filename The name of the file to process.
|
||||
* \param state One of the ActionSourceStates, enabling file grouping.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int vs200x_project_file(Session sess, Project prj, Stream strm, const char* filename, int state)
|
||||
{
|
||||
const char* name;
|
||||
const char* ptr;
|
||||
int depth, z = OKAY;
|
||||
|
||||
/* figure out the grouping depth, skipping over any leading dot directories */
|
||||
depth = 2;
|
||||
|
||||
ptr = filename;
|
||||
while (cstr_starts_with(ptr, "../"))
|
||||
{
|
||||
ptr += 3;
|
||||
}
|
||||
|
||||
ptr = strchr(ptr, '/');
|
||||
while (ptr != NULL)
|
||||
{
|
||||
depth++;
|
||||
ptr = strchr(ptr + 1, '/');
|
||||
}
|
||||
|
||||
/* group name is just the last bit of the path */
|
||||
name = path_filename(filename);
|
||||
|
||||
/* use the Windows path separator */
|
||||
filename = path_translate(filename, "\\");
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case GroupStart:
|
||||
if (strlen(filename) > 0 && !cstr_eq(name, ".."))
|
||||
{
|
||||
z |= stream_write_n(strm, "\t", depth);
|
||||
z |= stream_write(strm, "<Filter");
|
||||
z |= vs200x_attribute(strm, depth + 1, "Name", name);
|
||||
z |= vs200x_attribute(strm, depth + 1, "Filter", "");
|
||||
z |= vs200x_element_end(sess, strm, depth, ">");
|
||||
}
|
||||
break;
|
||||
|
||||
case GroupEnd:
|
||||
if (strlen(filename) > 0 && !cstr_eq(name, ".."))
|
||||
{
|
||||
z |= stream_write_n(strm, "\t", depth);
|
||||
z |= stream_writeline(strm, "</Filter>");
|
||||
}
|
||||
break;
|
||||
|
||||
case SourceFile:
|
||||
z |= stream_write_n(strm, "\t", depth);
|
||||
z |= stream_write(strm, "<File");
|
||||
ptr = (filename[0] == '.') ? "" : ".\\";
|
||||
z |= vs200x_attribute(strm, depth + 1, "RelativePath", "%s%s", ptr, filename);
|
||||
z |= vs200x_element_end(sess, strm, depth, ">");
|
||||
z |= stream_write_n(strm, "\t", depth);
|
||||
z |= stream_writeline(strm, "</File>");
|
||||
break;
|
||||
}
|
||||
|
||||
UNUSED(prj);
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write out the [Files] element.
|
||||
*/
|
||||
int vs200x_project_files(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
int z;
|
||||
UNUSED(prj);
|
||||
UNUSED(strm);
|
||||
z = vs200x_element(sess, 1, "Files");
|
||||
z |= vs200x_element(sess, 1, "/Files");
|
||||
int z = OKAY;
|
||||
z |= stream_writeline(strm, "\t<Files>");
|
||||
z |= action_source_tree(sess, prj, strm, vs200x_project_file);
|
||||
z |= stream_writeline(strm, "\t</Files>");
|
||||
return z;
|
||||
}
|
||||
|
||||
@ -136,12 +210,12 @@ int vs200x_project_files(Session sess, Project prj, Stream strm)
|
||||
*/
|
||||
int vs200x_project_globals(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
int z;
|
||||
int z = OKAY;
|
||||
UNUSED(sess);
|
||||
UNUSED(prj);
|
||||
UNUSED(strm);
|
||||
z = vs200x_element(sess, 1, "Globals");
|
||||
z |= vs200x_element(sess, 1, "/Globals");
|
||||
z |= vs200x_element(sess, 0, "/VisualStudioProject");
|
||||
z |= stream_writeline(strm, "\t<Globals>");
|
||||
z |= stream_writeline(strm, "\t</Globals>");
|
||||
z |= stream_writeline(strm, "</VisualStudioProject>");
|
||||
return z;
|
||||
}
|
||||
|
||||
@ -151,14 +225,13 @@ int vs200x_project_globals(Session sess, Project prj, Stream strm)
|
||||
*/
|
||||
int vs200x_project_platforms(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
int z;
|
||||
int z = OKAY;
|
||||
UNUSED(prj);
|
||||
UNUSED(strm);
|
||||
z = vs200x_element(sess, 1, "Platforms");
|
||||
z |= vs200x_element_start(sess, 2, "Platform");
|
||||
z |= vs200x_attribute(sess, 2, "Name", "Win32");
|
||||
z |= vs200x_element_end(sess, 2, "/>");
|
||||
z |= vs200x_element(sess, 1, "/Platforms");
|
||||
z |= stream_writeline(strm, "\t<Platforms>");
|
||||
z |= stream_write(strm, "\t\t<Platform");
|
||||
z |= vs200x_attribute(strm, 3, "Name", "Win32");
|
||||
z |= vs200x_element_end(sess, strm, 2, "/>");
|
||||
z |= stream_writeline(strm, "\t</Platforms>");
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
@ -170,12 +243,11 @@ int vs200x_project_references(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
int z;
|
||||
UNUSED(prj);
|
||||
UNUSED(strm);
|
||||
z = vs200x_element(sess, 1, "/Configurations");
|
||||
z = stream_writeline(strm, "\t</Configurations>");
|
||||
if (vs200x_get_target_version(sess) > 2002)
|
||||
{
|
||||
z |= vs200x_element(sess, 1, "References");
|
||||
z |= vs200x_element(sess, 1, "/References");
|
||||
z |= stream_writeline(strm, "\t<References>");
|
||||
z |= stream_writeline(strm, "\t</References>");
|
||||
}
|
||||
return z;
|
||||
}
|
||||
@ -188,15 +260,14 @@ int vs200x_project_tool_files(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
int version, z = OKAY;
|
||||
UNUSED(prj);
|
||||
UNUSED(strm);
|
||||
|
||||
version = vs200x_get_target_version(sess);
|
||||
if (version > 2003)
|
||||
{
|
||||
z |= vs200x_element(sess, 1, "ToolFiles");
|
||||
z |= vs200x_element(sess, 1, "/ToolFiles");
|
||||
z |= stream_writeline(strm, "\t<ToolFiles>");
|
||||
z |= stream_writeline(strm, "\t</ToolFiles>");
|
||||
}
|
||||
z |= vs200x_element(sess, 1, "Configurations");
|
||||
z |= stream_writeline(strm, "\t<Configurations>");
|
||||
return z;
|
||||
}
|
||||
|
||||
@ -208,10 +279,9 @@ static int vs200x_project_vc_empty_tool(Session sess, Project prj, Stream strm,
|
||||
{
|
||||
int z;
|
||||
UNUSED(prj);
|
||||
UNUSED(strm);
|
||||
z = vs200x_element_start(sess, 3, "Tool");
|
||||
z |= vs200x_attribute(sess, 3, "Name", name);
|
||||
z |= vs200x_element_end(sess, 3, "/>");
|
||||
z = stream_write(strm, "\t\t\t<Tool");
|
||||
z |= vs200x_attribute(strm, 4, "Name", name);
|
||||
z |= vs200x_element_end(sess, strm, 3, "/>");
|
||||
return z;
|
||||
}
|
||||
|
||||
@ -250,20 +320,19 @@ int vs200x_project_vc_cl_compiler_tool(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
int version, z;
|
||||
UNUSED(prj);
|
||||
UNUSED(strm);
|
||||
version = vs200x_get_target_version(sess);
|
||||
z = vs200x_element_start(sess, 3, "Tool");
|
||||
z |= vs200x_attribute(sess, 3, "Name", "VCCLCompilerTool");
|
||||
z |= vs200x_attribute(sess, 3, "Optimization", "0");
|
||||
z |= vs200x_attribute(sess, 3, "MinimalRebuild", "true");
|
||||
z |= vs200x_attribute(sess, 3, "BasicRuntimeChecks", "3");
|
||||
z |= vs200x_attribute(sess, 3, "RuntimeLibrary", "3");
|
||||
z |= vs200x_config_runtime_type_info(sess, prj);
|
||||
z |= vs200x_config_use_precompiled_header(sess, prj);
|
||||
z |= vs200x_attribute(sess, 3, "WarningLevel", "3");
|
||||
z |= vs200x_config_detect_64bit_portability(sess, prj);
|
||||
z |= vs200x_attribute(sess, 3, "DebugInformationFormat", "4");
|
||||
z |= vs200x_element_end(sess, 3, "/>");
|
||||
z = stream_write(strm, "\t\t\t<Tool");
|
||||
z |= vs200x_attribute(strm, 4, "Name", "VCCLCompilerTool");
|
||||
z |= vs200x_attribute(strm, 4, "Optimization", "0");
|
||||
z |= vs200x_attribute(strm, 4, "MinimalRebuild", vs200x_true(sess));
|
||||
z |= vs200x_attribute(strm, 4, "BasicRuntimeChecks", "3");
|
||||
z |= vs200x_attribute(strm, 4, "RuntimeLibrary", "3");
|
||||
z |= vs200x_config_runtime_type_info(sess, strm, prj);
|
||||
z |= vs200x_config_use_precompiled_header(sess, strm, prj);
|
||||
z |= vs200x_attribute(strm, 4, "WarningLevel", "3");
|
||||
z |= vs200x_config_detect_64bit_portability(sess, strm, prj);
|
||||
z |= vs200x_attribute(strm, 4, "DebugInformationFormat", "4");
|
||||
z |= vs200x_element_end(sess, strm, 3, "/>");
|
||||
return z;
|
||||
}
|
||||
|
||||
@ -293,15 +362,14 @@ int vs200x_project_vc_linker_tool(Session sess, Project prj, Stream strm)
|
||||
{
|
||||
int z;
|
||||
UNUSED(prj);
|
||||
UNUSED(strm);
|
||||
z = vs200x_element_start(sess, 3, "Tool");
|
||||
z |= vs200x_attribute(sess, 3, "Name", "VCLinkerTool");
|
||||
z |= vs200x_attribute(sess, 3, "LinkIncremental", "2");
|
||||
z |= vs200x_attribute(sess, 3, "GenerateDebugInformation", "true");
|
||||
z |= vs200x_attribute(sess, 3, "SubSystem", "1");
|
||||
z |= vs200x_attribute(sess, 3, "EntryPointSymbol", "mainCRTStartup");
|
||||
z |= vs200x_attribute(sess, 3, "TargetMachine", "1");
|
||||
z |= vs200x_element_end(sess, 3, "/>");
|
||||
z = stream_write(strm, "\t\t\t<Tool");
|
||||
z |= vs200x_attribute(strm, 4, "Name", "VCLinkerTool");
|
||||
z |= vs200x_attribute(strm, 4, "LinkIncremental", "2");
|
||||
z |= vs200x_attribute(strm, 4, "GenerateDebugInformation", vs200x_true(sess));
|
||||
z |= vs200x_attribute(strm, 4, "SubSystem", "1");
|
||||
z |= vs200x_attribute(strm, 4, "EntryPointSymbol", "mainCRTStartup");
|
||||
z |= vs200x_attribute(strm, 4, "TargetMachine", "1");
|
||||
z |= vs200x_element_end(sess, strm, 3, "/>");
|
||||
return z;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ int vs200x_project_config_end(Session sess, Project prj, Stream strm);
|
||||
int vs200x_project_create(Session sess, Project prj, Stream strm);
|
||||
int vs200x_project_element(Session sess, Project prj, Stream strm);
|
||||
int vs200x_project_encoding(Session sess, Project prj, Stream strm);
|
||||
int vs200x_project_file(Session sess, Project prj, Stream strm, const char* filename, int state);
|
||||
int vs200x_project_files(Session sess, Project prj, Stream strm);
|
||||
int vs200x_project_globals(Session sess, Project prj, Stream strm);
|
||||
int vs200x_project_platforms(Session sess, Project prj, Stream strm);
|
||||
|
@ -75,7 +75,6 @@ void fields_destroy(Fields fields)
|
||||
const char* fields_get_value(Fields fields, int index)
|
||||
{
|
||||
Strings values;
|
||||
|
||||
assert(fields);
|
||||
assert(index >= 0 && index < fields->count);
|
||||
|
||||
@ -91,6 +90,20 @@ const char* fields_get_value(Fields fields, int index)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the list of values for a field.
|
||||
* \param fields The collection of fields.
|
||||
* \index index The index of fields to query.
|
||||
* \returns The list of values stored in the field.
|
||||
*/
|
||||
Strings fields_get_values(Fields fields, int index)
|
||||
{
|
||||
assert(fields);
|
||||
assert(index >= 0 && index < fields->count);
|
||||
return fields->values[index];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of a string (single value) field.
|
||||
* \param fields The collection of fields.
|
||||
@ -115,3 +128,25 @@ void fields_set_value(Fields fields, int index, const char* value)
|
||||
strings_set(values, 0, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the list of values associated with a field. The field will subsequently
|
||||
* "own" the list, and take responsibility to destroying it with the field set.
|
||||
* \param fields The collection of fields.
|
||||
* \param index The index of the field to set.
|
||||
* \param values The list of new values for the field.
|
||||
*/
|
||||
void fields_set_values(Fields fields, int index, Strings values)
|
||||
{
|
||||
assert(fields);
|
||||
assert(index >= 0 && index < fields->count);
|
||||
assert(values);
|
||||
|
||||
if (fields->values[index] != NULL)
|
||||
{
|
||||
strings_destroy(fields->values[index]);
|
||||
}
|
||||
|
||||
fields->values[index] = values;
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
#if !defined(PREMAKE_FIELDS_H)
|
||||
#define PREMAKE_FIELDS_H
|
||||
|
||||
#include "base/strings.h"
|
||||
|
||||
|
||||
/**
|
||||
* Field types.
|
||||
@ -43,6 +45,8 @@ Fields fields_create(struct FieldInfo* info);
|
||||
void fields_destroy(Fields fields);
|
||||
|
||||
const char* fields_get_value(Fields fields, int index);
|
||||
Strings fields_get_values(Fields fields, int index);
|
||||
void fields_set_value(Fields fields, int index, const char* value);
|
||||
void fields_set_values(Fields fields, int index, Strings values);
|
||||
|
||||
#endif
|
||||
|
@ -17,6 +17,7 @@
|
||||
struct FieldInfo ProjectFieldInfo[] =
|
||||
{
|
||||
{ "basedir", StringField, NULL },
|
||||
{ "files", ListField, NULL },
|
||||
{ "guid", StringField, guid_is_valid },
|
||||
{ "language", StringField, project_is_valid_language },
|
||||
{ "location", StringField, NULL },
|
||||
@ -118,13 +119,22 @@ const char* project_get_filename(Project prj, const char* basename, const char*
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the list of source files associated with a project.
|
||||
*/
|
||||
Strings project_get_files(Project prj)
|
||||
{
|
||||
assert(prj);
|
||||
return fields_get_values(prj->fields, ProjectFiles);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the GUID associated with a project.
|
||||
* \param prj The project to query.
|
||||
* \returns The GUID associated with the project, or NULL if the GUID has not been set.
|
||||
*/
|
||||
const char* project_get_guid(Project prj)
|
||||
{
|
||||
assert(prj);
|
||||
return project_get_value(prj, ProjectGuid);
|
||||
}
|
||||
|
||||
@ -270,3 +280,17 @@ void project_set_value(Project prj, enum ProjectField field, const char* value)
|
||||
assert(prj);
|
||||
fields_set_value(prj->fields, field, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the list of values associated with a field. The field will subsequently
|
||||
* "own" the list, and take responsibility to destroying it with the field set.
|
||||
* \param prj The project object.
|
||||
* \param index The index of the field to set.
|
||||
* \param values The list of new values for the field.
|
||||
*/
|
||||
void project_set_values(Project prj, enum ProjectField field, Strings values)
|
||||
{
|
||||
assert(prj);
|
||||
fields_set_values(prj->fields, field, values);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
enum ProjectField
|
||||
{
|
||||
ProjectBaseDirectory,
|
||||
ProjectFiles,
|
||||
ProjectGuid,
|
||||
ProjectLanguage,
|
||||
ProjectLocation,
|
||||
@ -34,6 +35,7 @@ void project_destroy(Project prj);
|
||||
const char* project_get_base_dir(Project prj);
|
||||
const char* project_get_configuration_filter(Project prj);
|
||||
const char* project_get_filename(Project prj, const char* basename, const char* ext);
|
||||
Strings project_get_files(Project prj);
|
||||
const char* project_get_guid(Project prj);
|
||||
const char* project_get_language(Project prj);
|
||||
const char* project_get_location(Project prj);
|
||||
@ -47,6 +49,7 @@ 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);
|
||||
void project_set_values(Project prj, enum ProjectField field, Strings values);
|
||||
int project_tests(void);
|
||||
|
||||
#endif
|
||||
|
@ -54,4 +54,11 @@ SUITE(fields)
|
||||
const char* result = fields_get_value(fields, TestStringValue);
|
||||
CHECK_EQUAL("String Value", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxFields, SetValues_CanRoundtrip)
|
||||
{
|
||||
Strings values = strings_create();
|
||||
fields_set_values(fields, TestListValue, values);
|
||||
CHECK(values == fields_get_values(fields, TestListValue));
|
||||
}
|
||||
}
|
||||
|
@ -10,11 +10,13 @@
|
||||
#include "base/error.h"
|
||||
|
||||
|
||||
static int fn_accessor(lua_State* L);
|
||||
static int fn_accessor_object_has_field(struct FieldInfo* fields, const char* field_name);
|
||||
static int fn_accessor_register(lua_State* L, struct FieldInfo* fields);
|
||||
static int fn_accessor_register_field(lua_State* L, struct FieldInfo* field);
|
||||
static int fn_accessor_set_string_value(lua_State* L, struct FieldInfo* field);
|
||||
static int fn_accessor(lua_State* L);
|
||||
static int fn_accessor_set_list_value(lua_State* L, struct FieldInfo* field);
|
||||
static void fn_accessor_append_values(lua_State* L, int destIndex, int srcIndex);
|
||||
|
||||
|
||||
/**
|
||||
@ -119,7 +121,14 @@ static int fn_accessor(lua_State* L)
|
||||
/* if a value is provided, set the field */
|
||||
if (lua_gettop(L) > 1)
|
||||
{
|
||||
fn_accessor_set_string_value(L, field);
|
||||
if (field->kind == StringField)
|
||||
{
|
||||
fn_accessor_set_string_value(L, field);
|
||||
}
|
||||
else
|
||||
{
|
||||
fn_accessor_set_list_value(L, field);
|
||||
}
|
||||
}
|
||||
|
||||
/* return the current value of the field */
|
||||
@ -129,7 +138,7 @@ static int fn_accessor(lua_State* L)
|
||||
|
||||
|
||||
/**
|
||||
* Sets a string field to the value on the top of the Lua stack.
|
||||
* Sets a string field to the value on the bottom of the Lua stack.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
static int fn_accessor_set_string_value(lua_State* L, struct FieldInfo* field)
|
||||
@ -157,3 +166,56 @@ static int fn_accessor_set_string_value(lua_State* L, struct FieldInfo* field)
|
||||
lua_setfield(L, -2, field->name);
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends the value or list at the bottom of the Lua stack to the specified list field.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
static int fn_accessor_set_list_value(lua_State* L, struct FieldInfo* field)
|
||||
{
|
||||
/* get the current value of the field */
|
||||
lua_getfield(L, -1, field->name);
|
||||
|
||||
/* if the value passed in is a table, append all of its contents to the current
|
||||
* field value. If the value passed in is a single string, add it at the end */
|
||||
if (lua_istable(L, 1))
|
||||
{
|
||||
fn_accessor_append_values(L, lua_gettop(L), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushvalue(L, 1);
|
||||
lua_rawseti(L, -2, luaL_getn(L, -2) + 1);
|
||||
}
|
||||
|
||||
/* remove the field value from the stack */
|
||||
lua_pop(L, 1);
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy values from one table to the end of another table.
|
||||
* \param destIndex The absolute stack index of the destination table.
|
||||
* \param srcIndex The absolute stack index of the source table.
|
||||
*/
|
||||
static void fn_accessor_append_values(lua_State* L, int destIndex, int srcIndex)
|
||||
{
|
||||
int i;
|
||||
int src_n = luaL_getn(L, srcIndex);
|
||||
int dst_n = luaL_getn(L, destIndex);
|
||||
for (i = 1; i <= src_n; ++i)
|
||||
{
|
||||
lua_rawgeti(L, srcIndex, i);
|
||||
if (lua_istable(L, -1))
|
||||
{
|
||||
fn_accessor_append_values(L, destIndex, lua_gettop(L));
|
||||
dst_n = luaL_getn(L, destIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_rawseti(L, destIndex, ++dst_n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,11 @@
|
||||
#include "base/string.h"
|
||||
|
||||
|
||||
/**
|
||||
* Replacement implementation for Lua's dofile() function; manages Premake specific
|
||||
* features like the _FILE variable, and makes sure the directory containing the
|
||||
* running script is kept current.
|
||||
*/
|
||||
int fn_dofile(lua_State* L)
|
||||
{
|
||||
const char *filename;
|
||||
|
@ -9,6 +9,10 @@
|
||||
#include "base/error.h"
|
||||
|
||||
|
||||
/**
|
||||
* Handler for errors reported out the script; copies the error message to
|
||||
* Premake's global error state.
|
||||
*/
|
||||
int fn_error(lua_State* L)
|
||||
{
|
||||
const char* message = lua_tostring(L, 1);
|
||||
|
@ -8,6 +8,10 @@
|
||||
#include "script_internal.h"
|
||||
#include "base/dir.h"
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of os.getcwd(): returns the current working directory.
|
||||
*/
|
||||
int fn_getcwd(lua_State* L)
|
||||
{
|
||||
const char* cwd = dir_get_current();
|
||||
|
@ -242,7 +242,8 @@ void script_set_action(Script script, const char* action)
|
||||
/**
|
||||
* Copy project information out of the scripting environment and into C objects that
|
||||
* can be more easily manipulated by the action code.
|
||||
* \param slns An array to hold the list of unloaded solutions.
|
||||
* \param script The project scripting engine instance.
|
||||
* \param slns An array to hold the list of unloaded solutions.
|
||||
* \returns OKAY if successful.
|
||||
*/
|
||||
int script_unload(Script script, Array slns)
|
||||
|
@ -64,4 +64,57 @@ SUITE(script)
|
||||
CHECK_EQUAL("MyLocation", result);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* List field tests
|
||||
**************************************************************************/
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_ReturnsEmptyTable_OnEmptyListValue)
|
||||
{
|
||||
const char* result = script_run_string(script,
|
||||
"return (#files() == 0)");
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_Appends_OnStringValue)
|
||||
{
|
||||
const char* result = script_run_string(script,
|
||||
"files { 'Hello.c' };"
|
||||
"return (prj.files[1] == 'Hello.c')" );
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_Appends_OnListValue)
|
||||
{
|
||||
const char* result = script_run_string(script,
|
||||
"files { 'Hello.c', 'Goodbye.c' };"
|
||||
"return (prj.files[1] == 'Hello.c' and prj.files[2] == 'Goodbye.c')" );
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_Appends_OnTwoCalls)
|
||||
{
|
||||
const char* result = script_run_string(script,
|
||||
"files { 'Hello.c' };"
|
||||
"files { 'Goodbye.c' };"
|
||||
"return (prj.files[1] == 'Hello.c' and prj.files[2] == 'Goodbye.c')" );
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_ReturnsList_OnNoArgs)
|
||||
{
|
||||
const char* result = script_run_string(script,
|
||||
"files { 'Hello.c', 'Goodbye.c' };"
|
||||
"lst = files();"
|
||||
"return (lst[1] == 'Hello.c' and lst[2] == 'Goodbye.c')" );
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
|
||||
TEST_FIXTURE(FxAccessor, Accessor_FlattensTables_OnNestedLists)
|
||||
{
|
||||
const char* result = script_run_string(script,
|
||||
"files { {'Hello.c'}, {'Goodbye.c'} };"
|
||||
"return (prj.files[1] == 'Hello.c' and prj.files[2] == 'Goodbye.c')" );
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
}
|
||||
|
19
src/script/tests/fn_files_tests.cpp
Normal file
19
src/script/tests/fn_files_tests.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* \file fn_files_tests.cpp
|
||||
* \brief Automated tests for the files() function.
|
||||
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
|
||||
*/
|
||||
|
||||
#include "premake.h"
|
||||
#include "script_tests.h"
|
||||
|
||||
|
||||
SUITE(script)
|
||||
{
|
||||
TEST_FIXTURE(FxAccessor, Files_Exists_OnStartup)
|
||||
{
|
||||
const char* result = script_run_string(script,
|
||||
"return (files ~= nil)");
|
||||
CHECK_EQUAL("true", result);
|
||||
}
|
||||
}
|
@ -2,6 +2,14 @@
|
||||
* \file session.h
|
||||
* \brief Context for a program execution session.
|
||||
* \author Copyright (c) 2008 Jason Perkins and the Premake project
|
||||
*
|
||||
* \defgroup session Session
|
||||
*
|
||||
* Premake is essentially a long chain of sequential actions; the Session object
|
||||
* tracks the application state through this chain, and provides the context
|
||||
* necessary for actions to do their work. It's a glorified global, essentially.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#if !defined(PREMAKE_SESSION_H)
|
||||
#define PREMAKE_SESSION_H
|
||||
@ -74,3 +82,5 @@ int session_unload(Session sess);
|
||||
int session_validate(Session sess);
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user