Added Symbols, Optimize, OptimizeSize, and OptimizeSpeed build flags, refactorings (r488:497)

This commit is contained in:
starkos 2008-08-20 20:02:42 +00:00
parent 25d5b3aac7
commit 2dbd283813
22 changed files with 435 additions and 59 deletions

View File

@ -48,8 +48,32 @@ int make_project_config_conditional(Project prj, Stream strm)
*/
int make_project_config_cflags(Project prj, Stream strm)
{
UNUSED(prj);
return stream_writeline(strm, " CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)");
int z = OKAY;
z |= stream_write(strm, " CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)");
/* debugging symbols */
if (project_has_flag(prj, "Symbols"))
{
z |= stream_write(strm, " -g");
}
/* optimizations */
if (project_has_flag(prj, "Optimize"))
{
z |= stream_write(strm, " -O2");
}
else if (project_has_flag(prj, "OptimizeSize"))
{
z |= stream_write(strm, " -Os");
}
else if (project_has_flag(prj, "OptimizeSpeed"))
{
z |= stream_write(strm, " -O3");
}
z |= stream_writeline(strm, "");
return z;
}

View File

@ -27,7 +27,7 @@ SUITE(action)
TEST_FIXTURE(FxAction, MakeCppFlags_WithDefines)
{
char* defines[] = { "DEFINE0", "DEFINE1", NULL};
const char* defines[] = { "DEFINE0", "DEFINE1", NULL};
SetConfigField(prj, BlockDefines, defines);
make_project_config_cppflags(prj, strm);
CHECK_EQUAL(
@ -48,6 +48,46 @@ SUITE(action)
buffer);
}
TEST_FIXTURE(FxAction, MakeProject_Config_WithSymbols)
{
const char* flags[] = { "Symbols", NULL };
SetConfigField(prj, BlockFlags, flags);
make_project_config_cflags(prj, strm);
CHECK_EQUAL(
" CFLAGS += $(CPPFLAGS) $(ARCHFLAGS) -g\n",
buffer);
}
TEST_FIXTURE(FxAction, MakeProject_Config_WithOptimize)
{
const char* flags[] = { "Optimize", NULL };
SetConfigField(prj, BlockFlags, flags);
make_project_config_cflags(prj, strm);
CHECK_EQUAL(
" CFLAGS += $(CPPFLAGS) $(ARCHFLAGS) -O2\n",
buffer);
}
TEST_FIXTURE(FxAction, MakeProject_Config_WithOptimizeSize)
{
const char* flags[] = { "OptimizeSize", NULL };
SetConfigField(prj, BlockFlags, flags);
make_project_config_cflags(prj, strm);
CHECK_EQUAL(
" CFLAGS += $(CPPFLAGS) $(ARCHFLAGS) -Os\n",
buffer);
}
TEST_FIXTURE(FxAction, MakeProject_Config_WithOptimizeSpeed)
{
const char* flags[] = { "OptimizeSpeed", NULL };
SetConfigField(prj, BlockFlags, flags);
make_project_config_cflags(prj, strm);
CHECK_EQUAL(
" CFLAGS += $(CPPFLAGS) $(ARCHFLAGS) -O3\n",
buffer);
}
/**********************************************************************
* CXXFLAGS tests

View File

@ -56,7 +56,7 @@ SUITE(action)
TEST_FIXTURE(FxAction, MakeProject_Objects_ConvertsFileExtension)
{
char* files[] = { "Hello.cpp", "Good Bye.cpp", NULL };
const char* files[] = { "Hello.cpp", "Good Bye.cpp", NULL };
SetField(prj, ProjectFiles, files);
make_project_objects(prj, strm);
CHECK_EQUAL(
@ -160,7 +160,7 @@ SUITE(action)
TEST_FIXTURE(FxAction, MakeProject_SourceRules)
{
char* files[] = { "Good Bye.cpp", NULL };
const char* files[] = { "Good Bye.cpp", NULL };
SetField(prj, ProjectFiles, files);
make_project_source_rules(prj, strm);
CHECK_EQUAL(

View File

@ -50,10 +50,10 @@ struct FxAction
}
void SetField(Project prj, enum ProjectField index, char** values)
void SetField(Project prj, ProjectField index, const char** values)
{
Strings strs = strings_create();
for (char** value = values; (*value) != NULL; ++value)
for (const char** value = values; (*value) != NULL; ++value)
{
strings_add(strs, *value);
}
@ -61,10 +61,10 @@ struct FxAction
project_set_values(prj, index, strs);
}
void SetConfigField(Project prj, enum BlockField index, char** values)
void SetConfigField(Project prj, BlockField index, const char** values)
{
Strings strs = strings_create();
for (char** value = values; (*value) != NULL; ++value)
for (const char** value = values; (*value) != NULL; ++value)
{
strings_add(strs, *value);
}

View File

@ -32,7 +32,7 @@ SUITE(action)
"\t\t\t\tUsePrecompiledHeader=\"2\"\n"
"\t\t\t\tWarningLevel=\"3\"\n"
"\t\t\t\tDetect64BitPortabilityProblems=\"TRUE\"\n"
"\t\t\t\tDebugInformationFormat=\"4\"/>\n",
"\t\t\t\tDebugInformationFormat=\"0\"/>\n",
buffer);
}
@ -50,7 +50,7 @@ SUITE(action)
"\t\t\t\tUsePrecompiledHeader=\"0\"\n"
"\t\t\t\tWarningLevel=\"3\"\n"
"\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n"
"\t\t\t\tDebugInformationFormat=\"4\"\n"
"\t\t\t\tDebugInformationFormat=\"0\"\n"
"\t\t\t/>\n",
buffer);
}
@ -68,13 +68,12 @@ SUITE(action)
"\t\t\t\tRuntimeLibrary=\"3\"\n"
"\t\t\t\tUsePrecompiledHeader=\"0\"\n"
"\t\t\t\tWarningLevel=\"3\"\n"
"\t\t\t\tDebugInformationFormat=\"4\"\n"
"\t\t\t\tDebugInformationFormat=\"0\"\n"
"\t\t\t/>\n",
buffer);
}
/**********************************************************************
* Defines tests
**********************************************************************/
@ -82,7 +81,7 @@ SUITE(action)
TEST_FIXTURE(FxAction, VCCLCompilerTool_WithDefines)
{
env_set_action("vs2002");
char* defines[] = { "DEFINE0", "DEFINE1", NULL };
const char* defines[] = { "DEFINE0", "DEFINE1", NULL };
SetConfigField(prj, BlockDefines, defines);
vs200x_project_vc_cl_compiler_tool(prj, strm);
CHECK_EQUAL(
@ -97,7 +96,7 @@ SUITE(action)
"\t\t\t\tUsePrecompiledHeader=\"2\"\n"
"\t\t\t\tWarningLevel=\"3\"\n"
"\t\t\t\tDetect64BitPortabilityProblems=\"TRUE\"\n"
"\t\t\t\tDebugInformationFormat=\"4\"/>\n",
"\t\t\t\tDebugInformationFormat=\"0\"/>\n",
buffer);
}
}

View File

@ -46,6 +46,91 @@ SUITE(action)
}
/*************************************************************************
* Debug information tests
*************************************************************************/
TEST_FIXTURE(FxAction, VsDebugFormat_Is0_OnNoSymbols)
{
env_set_action("vs2002");
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"0\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is4_OnSymbols)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"4\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndManaged)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "Managed", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndOptimize)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "Optimize", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndOptimizeSize)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "OptimizeSize", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndOptimizeSpeed)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "OptimizeSpeed", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndNoEditAndContinue)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "NoEditAndContinue", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VCDebugInfo_IsOff_WithNoSymbols)
{
env_set_action("vs2002");
vs200x_config_generate_debug_information(prj, strm);
CHECK_EQUAL("\n\t\t\t\tGenerateDebugInformation=\"FALSE\"", buffer);
}
TEST_FIXTURE(FxAction, VCDebugInfo_IsOn_WithSymbols)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_generate_debug_information(prj, strm);
CHECK_EQUAL(
"\n\t\t\t\tGenerateDebugInformation=\"TRUE\""
"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/My Project.pdb\"",
buffer);
}
/*************************************************************************
* Defines tests
*************************************************************************/
@ -53,16 +138,55 @@ SUITE(action)
TEST_FIXTURE(FxAction, VsDefines_Empty_OnNoSymbols)
{
env_set_action("vs2002");
vs200x_config_defines(strm, prj);
vs200x_config_defines(prj, strm);
CHECK_EQUAL("", buffer);
}
TEST_FIXTURE(FxAction, VsDefines_SemiSplitList)
{
env_set_action("vs2002");
char* values[] = { "DEFINE0", "DEFINE1", "DEFINE2", NULL };
const char* values[] = { "DEFINE0", "DEFINE1", "DEFINE2", NULL };
SetConfigField(prj, BlockDefines, values);
vs200x_config_defines(strm, prj);
vs200x_config_defines(prj, strm);
CHECK_EQUAL("\n\t\t\t\tPreprocessorDefinitions=\"DEFINE0;DEFINE1;DEFINE2\"", buffer);
}
/*************************************************************************
* Optimization tests
*************************************************************************/
TEST_FIXTURE(FxAction, VsOptimization_Is0_OnNoOptimization)
{
env_set_action("vs2002");
vs200x_config_optimization(prj, strm);
CHECK_EQUAL("\n\t\t\t\tOptimization=\"0\"", buffer);
}
TEST_FIXTURE(FxAction, VsOptimization_Is1_OnOptimizeSize)
{
env_set_action("vs2002");
const char* flags[] = { "OptimizeSize", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_optimization(prj, strm);
CHECK_EQUAL("\n\t\t\t\tOptimization=\"1\"", buffer);
}
TEST_FIXTURE(FxAction, VsOptimization_Is2_OnOptimizeSpeed)
{
env_set_action("vs2002");
const char* flags[] = { "OptimizeSpeed", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_optimization(prj, strm);
CHECK_EQUAL("\n\t\t\t\tOptimization=\"2\"", buffer);
}
TEST_FIXTURE(FxAction, VsOptimization_Is2_OnOptimize)
{
env_set_action("vs2002");
const char* flags[] = { "Optimize", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_optimization(prj, strm);
CHECK_EQUAL("\n\t\t\t\tOptimization=\"3\"", buffer);
}
}

View File

@ -25,7 +25,7 @@ SUITE(action)
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCLinkerTool\"\n"
"\t\t\t\tLinkIncremental=\"2\"\n"
"\t\t\t\tGenerateDebugInformation=\"TRUE\"\n"
"\t\t\t\tGenerateDebugInformation=\"FALSE\"\n"
"\t\t\t\tSubSystem=\"1\"\n"
"\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"\n"
"\t\t\t\tTargetMachine=\"1\"/>\n",
@ -40,7 +40,7 @@ SUITE(action)
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCLinkerTool\"\n"
"\t\t\t\tLinkIncremental=\"2\"\n"
"\t\t\t\tGenerateDebugInformation=\"TRUE\"\n"
"\t\t\t\tGenerateDebugInformation=\"FALSE\"\n"
"\t\t\t\tSubSystem=\"1\"\n"
"\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"\n"
"\t\t\t\tTargetMachine=\"1\"/>\n",
@ -55,7 +55,7 @@ SUITE(action)
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCLinkerTool\"\n"
"\t\t\t\tLinkIncremental=\"2\"\n"
"\t\t\t\tGenerateDebugInformation=\"true\"\n"
"\t\t\t\tGenerateDebugInformation=\"false\"\n"
"\t\t\t\tSubSystem=\"1\"\n"
"\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"\n"
"\t\t\t\tTargetMachine=\"1\"\n"
@ -71,7 +71,7 @@ SUITE(action)
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCLinkerTool\"\n"
"\t\t\t\tLinkIncremental=\"2\"\n"
"\t\t\t\tGenerateDebugInformation=\"true\"\n"
"\t\t\t\tGenerateDebugInformation=\"false\"\n"
"\t\t\t\tSubSystem=\"1\"\n"
"\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"\n"
"\t\t\t\tTargetMachine=\"1\"\n"

View File

@ -404,7 +404,7 @@ SUITE(action)
TEST_FIXTURE(FxAction, Vs200x_Files_OnSingleCppFile)
{
env_set_action("vs2002");
char* values[] = { "Hello.cpp", 0 };
const char* values[] = { "Hello.cpp", 0 };
SetField(prj, ProjectFiles, values);
vs200x_project_files(prj, strm);
CHECK_EQUAL(
@ -419,7 +419,7 @@ SUITE(action)
TEST_FIXTURE(FxAction, Vs200x_Files_OnUpperDirectory)
{
env_set_action("vs2002");
char* values[] = { "../../Hello.cpp", 0 };
const char* values[] = { "../../Hello.cpp", 0 };
SetField(prj, ProjectFiles, values);
vs200x_project_files(prj, strm);
CHECK_EQUAL(
@ -434,7 +434,7 @@ SUITE(action)
TEST_FIXTURE(FxAction, Vs200x_Files_OnGroupedCppFile)
{
env_set_action("vs2002");
char* values[] = { "Src/Hello.cpp", 0 };
const char* values[] = { "Src/Hello.cpp", 0 };
SetField(prj, ProjectFiles, values);
vs200x_project_files(prj, strm);
CHECK_EQUAL(

View File

@ -15,11 +15,35 @@ int vs200x_config_character_set(Stream strm)
}
int vs200x_config_debug_information_format(Project prj, Stream strm)
{
const char* value;
if (!project_has_flag(prj, "Symbols"))
{
value = "0";
}
else if (project_has_flag(prj, "Managed") ||
project_has_flag(prj, "Optimize") ||
project_has_flag(prj, "OptimizeSize") ||
project_has_flag(prj, "OptimizeSpeed") ||
project_has_flag(prj, "NoEditAndContinue"))
{
value = "3";
}
else
{
value = "4";
}
return vs200x_attribute(strm, 4, "DebugInformationFormat", value);
}
/**
* Write out the list of preprocessor symbols as defined by the configuration.
* This entry is only written if there are values to write.
*/
int vs200x_config_defines(Stream strm, Project prj)
int vs200x_config_defines(Project prj, Stream strm)
{
Strings values = project_get_config_values(prj, BlockDefines);
if (strings_size(values) > 0)
@ -41,6 +65,45 @@ int vs200x_config_detect_64bit_portability(Stream strm)
}
int vs200x_config_generate_debug_information(Project prj, Stream strm)
{
int z = OKAY;
if (project_has_flag(prj, "Symbols"))
{
z |= vs200x_attribute(strm, 4, "GenerateDebugInformation", vs200x_true());
z |= vs200x_attribute(strm, 4, "ProgramDatabaseFile", "$(OutDir)/%s.pdb", project_get_name(prj));
}
else
{
z |= vs200x_attribute(strm, 4, "GenerateDebugInformation", vs200x_false());
}
return z;
}
int vs200x_config_optimization(Project prj, Stream strm)
{
const char* value;
if (project_has_flag(prj, "Optimize"))
{
value = "3";
}
else if (project_has_flag(prj, "OptimizeSize"))
{
value= "1";
}
else if (project_has_flag(prj, "OptimizeSpeed"))
{
value = "2";
}
else
{
value = "0";
}
return vs200x_attribute(strm, 4, "Optimization", value);
}
int vs200x_config_runtime_type_info(Stream strm)
{
if (vs200x_get_target_version() < 2005)

View File

@ -7,8 +7,11 @@
#define PREMAKE_VS200X_CONFIG_H
int vs200x_config_character_set(Stream strm);
int vs200x_config_defines(Stream strm, Project prj);
int vs200x_config_debug_information_format(Project prj, Stream strm);
int vs200x_config_defines(Project prj, Stream strm);
int vs200x_config_detect_64bit_portability(Stream strm);
int vs200x_config_generate_debug_information(Project prj, Stream strm);
int vs200x_config_optimization(Project prj, Stream strm);
int vs200x_config_runtime_type_info(Stream strm);
int vs200x_config_use_precompiled_header(Stream strm);

View File

@ -322,8 +322,8 @@ int vs200x_project_vc_cl_compiler_tool(Project prj, Stream strm)
int z = OKAY;
z |= stream_write(strm, "\t\t\t<Tool");
z |= vs200x_attribute(strm, 4, "Name", "VCCLCompilerTool");
z |= vs200x_attribute(strm, 4, "Optimization", "0");
z |= vs200x_config_defines(strm, prj);
z |= vs200x_config_optimization(prj, strm);
z |= vs200x_config_defines(prj, strm);
z |= vs200x_attribute(strm, 4, "MinimalRebuild", vs200x_true());
z |= vs200x_attribute(strm, 4, "BasicRuntimeChecks", "3");
z |= vs200x_attribute(strm, 4, "RuntimeLibrary", "3");
@ -331,7 +331,7 @@ int vs200x_project_vc_cl_compiler_tool(Project prj, Stream strm)
z |= vs200x_config_use_precompiled_header(strm);
z |= vs200x_attribute(strm, 4, "WarningLevel", "3");
z |= vs200x_config_detect_64bit_portability(strm);
z |= vs200x_attribute(strm, 4, "DebugInformationFormat", "4");
z |= vs200x_config_debug_information_format(prj, strm);
z |= vs200x_element_end(strm, 3, "/>");
return z;
}
@ -361,11 +361,10 @@ int vs200x_project_vc_fx_cop_tool(Project prj, Stream strm)
int vs200x_project_vc_linker_tool(Project prj, Stream strm)
{
int z = OKAY;
UNUSED(prj);
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());
z |= vs200x_config_generate_debug_information(prj, strm);
z |= vs200x_attribute(strm, 4, "SubSystem", "1");
z |= vs200x_attribute(strm, 4, "EntryPointSymbol", "mainCRTStartup");
z |= vs200x_attribute(strm, 4, "TargetMachine", "1");

View File

@ -8,6 +8,7 @@
#include "premake.h"
#include "strings.h"
#include "base/array.h"
#include "base/cstr.h"
#include "base/string.h"
@ -96,6 +97,23 @@ void strings_append(Strings dest, Strings src)
}
/**
* Returns true if the collection contains the specified value.
*/
int strings_contains(Strings strs, const char* item)
{
int i, n;
n = strings_size(strs);
for (i = 0; i < n; ++i)
{
const char* str = strings_item(strs, i);
if (cstr_eqi(str, item))
return 1;
}
return 0;
}
/**
* Retrieve an C string item from an array of strings.
* \param strs The string array to query.

View File

@ -21,6 +21,7 @@ void strings_destroy(Strings strs);
void strings_add(Strings strs, const char* item);
void strings_append(Strings dest, Strings src);
int strings_contains(Strings strs, const char* item);
const char* strings_item(Strings strs, int index);
void strings_set(Strings strs, int index, const char* item);
int strings_size(Strings strs);

View File

@ -15,12 +15,25 @@
FieldInfo BlockFieldInfo[] =
{
{ "defines", ListField, NULL },
{ "flags", ListField, block_is_valid_flag },
{ "objdir", PathField, NULL },
{ "terms", ListField, NULL },
{ 0, 0, NULL }
};
static const char* ValidFlags[] =
{
"Managed",
"NoEditAndContinue",
"Optimize",
"OptimizeSize",
"OptimizeSpeed",
"Symbols",
NULL
};
DEFINE_CLASS(Block)
{
Fields fields;
@ -94,17 +107,33 @@ Fields block_get_fields(Block blk)
/**
* Retrieve a list of values associated with a block.
*/
Strings block_get_values(Block blk, enum BlockField which)
Strings block_get_values(Block blk, BlockField which)
{
assert(blk);
return fields_get_values(blk->fields, which);
}
/**
* Returns true if the specified language is recognized. See the ValidLanguages at
* the top of this file for a list of valid values.
*/
int block_is_valid_flag(const char* flag)
{
const char** i;
for (i = ValidFlags; (*i) != NULL; ++i)
{
if (cstr_eqi((*i), flag))
return 1;
}
return 0;
}
/**
* Set a value list field on the block.
*/
void block_set_values(Block blk, enum BlockField which, Strings strs)
void block_set_values(Block blk, BlockField which, Strings strs)
{
assert(blk);
fields_set_values(blk->fields, which, strs);

View File

@ -17,13 +17,14 @@
* Configuration block field index.
* \note If you modify this list, you must also update BlockFieldInfo[].
*/
enum BlockField
typedef enum enum_BlockField
{
BlockDefines,
BlockFlags,
BlockObjDir,
BlockTerms,
NumBlockFields
};
} BlockField;
extern FieldInfo BlockFieldInfo[];
@ -35,8 +36,9 @@ void block_destroy(Block blk);
int block_applies_to(Block blk, const char* cfg_name);
Fields block_get_fields(Block blk);
Strings block_get_values(Block blk, enum BlockField which);
void block_set_values(Block blk, enum BlockField which, Strings strs);
Strings block_get_values(Block blk, BlockField which);
int block_is_valid_flag(const char* flag);
void block_set_values(Block blk, BlockField which, Strings strs);
#endif

View File

@ -116,7 +116,7 @@ Blocks project_get_blocks(Project prj)
/**
* Scans a list of blocks and appends any values found to the provided list.
*/
static void project_get_values_from_blocks(Project prj, Strings values, Blocks blks, enum BlockField field)
static void project_get_values_from_blocks(Project prj, Strings values, Blocks blks, BlockField field)
{
int i, n = blocks_size(blks);
for (i = 0; i < n; ++i)
@ -148,7 +148,7 @@ const char* project_get_config(Project prj)
/**
* Retrieve a list value from the project configuration, respecting the current filter set.
*/
Strings project_get_config_values(Project prj, enum BlockField field)
Strings project_get_config_values(Project prj, BlockField field)
{
Strings values;
@ -339,13 +339,23 @@ Solution project_get_solution(Project prj)
/**
* Retrieve a string (single value) fields from a project, using the field indices.
*/
const char* project_get_value(Project prj, enum ProjectField field)
const char* project_get_value(Project prj, ProjectField field)
{
assert(prj);
return fields_get_value(prj->fields, field);
}
/**
* Returns true if the project flags contain the specified flag.
*/
int project_has_flag(Project prj, const char* flag)
{
Strings flags = project_get_config_values(prj, BlockFlags);
return strings_contains(flags, flag);
}
/**
* Returns true if the project kind matches the parameter.
*/
@ -479,7 +489,7 @@ void project_set_solution(Project prj, Solution sln)
/**
* Set a string (single value) field on a project, using the field indices.
*/
void project_set_value(Project prj, enum ProjectField field, const char* value)
void project_set_value(Project prj, ProjectField field, const char* value)
{
assert(prj);
fields_set_value(prj->fields, field, value);
@ -490,7 +500,7 @@ void project_set_value(Project prj, enum ProjectField field, const char* 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.
*/
void project_set_values(Project prj, enum ProjectField field, Strings values)
void project_set_values(Project prj, ProjectField field, Strings values)
{
assert(prj);
fields_set_values(prj->fields, field, values);

View File

@ -22,7 +22,7 @@ DECLARE_CLASS(Project)
* Project field index.
* \note If you modify this list, you must also update ProjectFieldInfo[].
*/
enum ProjectField
typedef enum enum_ProjectField
{
ProjectBaseDir,
ProjectFiles,
@ -32,7 +32,7 @@ enum ProjectField
ProjectLocation,
ProjectName,
NumProjectFields
};
} ProjectField;
extern FieldInfo ProjectFieldInfo[];
@ -43,7 +43,7 @@ void project_destroy(Project prj);
const char* project_get_base_dir(Project prj);
Blocks project_get_blocks(Project prj);
const char* project_get_config(Project prj);
Strings project_get_config_values(Project prj, enum BlockField field);
Strings project_get_config_values(Project prj, BlockField field);
Fields project_get_fields(Project prj);
const char* project_get_filename(Project prj, const char* basename, const char* ext);
const char* project_get_filename_relative(Project prj, const char* basename, const char* ext);
@ -55,7 +55,8 @@ const char* project_get_location(Project prj);
const char* project_get_name(Project prj);
const char* project_get_outfile(Project prj);
Session project_get_session(Project prj);
const char* project_get_value(Project prj, enum ProjectField field);
const char* project_get_value(Project prj, ProjectField field);
int project_has_flag(Project prj, const char* flag);
int project_is_kind(Project prj, const char* kind);
int project_is_language(Project prj, const char* language);
int project_is_valid_kind(const char* kind);
@ -67,8 +68,8 @@ void project_set_kind(Project prj, const char* kind);
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);
void project_set_value(Project prj, ProjectField field, const char* value);
void project_set_values(Project prj, ProjectField field, Strings values);
#endif

View File

@ -232,7 +232,7 @@ Session solution_get_session(Solution sln)
/**
* Retrieve a string (single value) fields from a solution, using the field indices.
*/
const char* solution_get_value(Solution sln, enum SolutionField field)
const char* solution_get_value(Solution sln, SolutionField field)
{
assert(sln);
return fields_get_value(sln->fields, field);
@ -320,7 +320,7 @@ void solution_set_session(Solution sln, Session sess)
/**
* Set a string (single value) field on a solution, using the field indices.
*/
void solution_set_value(Solution sln, enum SolutionField field, const char* value)
void solution_set_value(Solution sln, SolutionField field, const char* value)
{
assert(sln);
fields_set_value(sln->fields, field, value);

View File

@ -23,7 +23,7 @@ DECLARE_CLASS(Solution)
* Solution field index.
* \note If you modify this list, you must also update SolutionFieldInfo[].
*/
enum SolutionField
typedef enum enum_SolutionField
{
SolutionBaseDir,
SolutionConfigurations,
@ -32,7 +32,7 @@ enum SolutionField
SolutionLocation,
SolutionName,
NumSolutionFields
};
} SolutionField;
extern FieldInfo SolutionFieldInfo[];
@ -54,7 +54,7 @@ const char* solution_get_location(Solution sln);
const char* solution_get_name(Solution sln);
Project solution_get_project(Solution sln, int index);
Session solution_get_session(Solution sln);
const char* solution_get_value(Solution sln, enum SolutionField field);
const char* solution_get_value(Solution sln, SolutionField field);
int solution_num_configs(Solution sln);
int solution_num_projects(Solution sln);
void solution_set_base_dir(Solution sln, const char* base_dir);
@ -62,7 +62,7 @@ void solution_set_kind(Solution sln, const char* kind);
void solution_set_language(Solution sln, const char* language);
void solution_set_location(Solution sln, const char* location);
void solution_set_name(Solution sln, const char* name);
void solution_set_value(Solution sln, enum SolutionField field, const char* value);
void solution_set_value(Solution sln, SolutionField field, const char* value);
#endif

View File

@ -13,7 +13,7 @@
static int fn_accessor_object_has_field(FieldInfo* fields, const char* field_name);
static int fn_accessor_register(lua_State* L, FieldInfo* fields);
static int fn_accessor_register_field(lua_State* L, FieldInfo* field);
static void fn_accessor_append_value(lua_State* L, FieldInfo* field, int tbl, int idx);
static int fn_accessor_append_value(lua_State* L, FieldInfo* field, int tbl, int idx);
/**
@ -173,15 +173,17 @@ int fn_accessor_set_string_value(lua_State* L, FieldInfo* field)
*/
int fn_accessor_set_list_value(lua_State* L, FieldInfo* field)
{
int z;
/* get the current value of the field */
lua_getfield(L, -1, field->name);
/* move the values into the field */
fn_accessor_append_value(L, field, lua_gettop(L), 1);
z = fn_accessor_append_value(L, field, lua_gettop(L), 1);
/* remove the field value from the stack */
lua_pop(L, 1);
return OKAY;
return z;
}
@ -194,7 +196,7 @@ int fn_accessor_set_list_value(lua_State* L, FieldInfo* field)
* \param tbl The table to contain the values.
* \param idx The value to add to the table.
*/
static void fn_accessor_append_value(lua_State* L, FieldInfo* field, int tbl, int idx)
static int fn_accessor_append_value(lua_State* L, FieldInfo* field, int tbl, int idx)
{
int i, n;
@ -223,9 +225,22 @@ static void fn_accessor_append_value(lua_State* L, FieldInfo* field, int tbl, in
}
else
{
/* if a validator function is present, call it */
if (field->validator != NULL)
{
const char* value = lua_tostring(L, idx);
if (!field->validator(value))
{
luaL_error(L, "invalid value '%s'", value);
return !OKAY;
}
}
lua_pushvalue(L, idx);
n = luaL_getn(L, tbl);
lua_rawseti(L, tbl, n + 1);
}
}
return OKAY;
}

View File

@ -121,6 +121,12 @@ SUITE(script)
CHECK(result == NULL);
}
TEST_FIXTURE(FxAccessor, Accessor_RaisesError_OnBadListData)
{
const char* result = script_run_string(script, "flags { 'none' }");
CHECK_EQUAL("invalid value 'none'", result);
}
/**************************************************************************
* Files field tests

View File

@ -0,0 +1,42 @@
/**
* \file fn_flags_tests.cpp
* \brief Automated tests for the flags() function.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*/
#include "premake.h"
#include "script_tests.h"
SUITE(script)
{
TEST_FIXTURE(FxAccessor, Flags_Exists_OnStartup)
{
const char* result = script_run_string(script,
"return (flags ~= nil)");
CHECK_EQUAL("true", result);
}
TEST_FIXTURE(FxAccessor, Flags_Error_OnNoActiveObject)
{
Script script = script_create();
const char* result = script_run_string(script, "flags {'Symbols'}");
CHECK_EQUAL("no active configuration block", result);
script_destroy(script);
}
TEST_FIXTURE(FxAccessor, Flags_CanRoundtrip)
{
const char* result = script_run_string(script,
"flags {'Symbols'};"
"return flags()[1]");
CHECK_EQUAL("Symbols", result);
}
TEST_FIXTURE(FxAccessor, Flags_RaisesError_OnInvalidValue)
{
const char* result = script_run_string(script,
"flags 'nosuch'");
CHECK_EQUAL("invalid value 'nosuch'", result);
}
}