Added kind()

This commit is contained in:
starkos 2008-08-15 02:36:04 +00:00
parent 95c23ec10b
commit 25d5b3aac7
13 changed files with 222 additions and 28 deletions

View File

@ -103,7 +103,6 @@ void* array_item(Array arr, int index)
void array_set(Array arr, int index, void* item)
{
assert(arr);
assert(item);
assert(index >= 0 && index < arr->size);
arr->contents[index] = item;
}

View File

@ -57,7 +57,10 @@ void strings_destroy(Strings strs)
for (i = 0; i < n; ++i)
{
String item = (String)array_item(strs->contents, i);
string_destroy(item);
if (item != NULL)
{
string_destroy(item);
}
}
array_destroy(strs->contents);
free(strs);
@ -71,7 +74,7 @@ void strings_destroy(Strings strs)
*/
void strings_add(Strings strs, const char* item)
{
String str = string_create(item);
String str = (item != NULL) ? string_create(item) : NULL;
array_add(strs->contents, (void*)str);
}
@ -102,7 +105,7 @@ void strings_append(Strings dest, Strings src)
const char* strings_item(Strings strs, int index)
{
String item = (String)array_item(strs->contents, index);
return string_cstr(item);
return (item != NULL) ? string_cstr(item) : NULL;
}
@ -115,9 +118,12 @@ const char* strings_item(Strings strs, int index)
void strings_set(Strings strs, int index, const char* item)
{
String str = (String)array_item(strs->contents, index);
string_destroy(str);
if (str != NULL)
{
string_destroy(str);
}
str = string_create(item);
str = (item != NULL) ? string_create(item) : NULL;
array_set(strs->contents, index, (void*)str);
}

View File

@ -131,10 +131,9 @@ void fields_set_value(Fields fields, int index, const char* value)
assert(fields);
assert(index >= 0 && index < fields->count);
assert(value);
values = fields->values[index];
if (strings_size(values) == 0)
if (strings_size(values) == 0 && value != NULL)
{
strings_add(values, value);
}

View File

@ -22,12 +22,23 @@ FieldInfo ProjectFieldInfo[] =
{ "basedir", StringField, NULL },
{ "files", FilesField, NULL },
{ "guid", StringField, guid_is_valid },
{ "language", StringField, NULL },
{ "kind", StringField, project_is_valid_kind },
{ "language", StringField, project_is_valid_language },
{ "location", StringField, NULL },
{ "name", StringField, NULL },
{ 0, 0, NULL }
};
static const char* ValidKinds[] =
{
"Console", NULL
};
static const char* ValidLanguages[] =
{
"C++", NULL
};
DEFINE_CLASS(Project)
{
@ -241,17 +252,31 @@ const char* project_get_guid(Project prj)
}
/**
* Get the project kind: console, windowed, etc.
*/
const char* project_get_kind(Project prj)
{
const char* kind = project_get_value(prj, ProjectKind);
if (kind == NULL && prj->solution != NULL)
{
kind = solution_get_kind(prj->solution);
}
return kind;
}
/**
* Get the programming language used by the project.
*/
const char* project_get_language(Project prj)
{
const char* result = project_get_value(prj, ProjectLanguage);
if (result == NULL && prj->solution != NULL)
const char* lang = project_get_value(prj, ProjectLanguage);
if (lang == NULL && prj->solution != NULL)
{
result = solution_get_language(prj->solution);
lang = solution_get_language(prj->solution);
}
return result;
return lang;
}
@ -322,14 +347,54 @@ const char* project_get_value(Project prj, enum ProjectField field)
/**
* Returns true if the specified language is recognized. Current valid language strings
* are 'c', 'c++', and 'c#'.
* Returns true if the project kind matches the parameter.
*/
int project_is_kind(Project prj, const char* kind)
{
assert(prj);
return cstr_eqi(project_get_kind(prj), kind);
}
/**
* Returns true if the project language matches the parameter.
*/
int project_is_language(Project prj, const char* language)
{
assert(prj);
return cstr_eqi(project_get_language(prj), language);
}
/**
* Returns true if the specified language is recognized. See the ValidLanguages at
* the top of this file for a list of valid values.
*/
int project_is_valid_kind(const char* kind)
{
const char** i;
for (i = ValidKinds; (*i) != NULL; ++i)
{
if (cstr_eqi((*i), kind))
return 1;
}
return 0;
}
/**
* Returns true if the specified language is recognized. See the ValidLanguages at
* the top of this file for a list of valid values.
*/
int project_is_valid_language(const char* language)
{
return (cstr_eq(language, "c") ||
cstr_eq(language, "c++") ||
cstr_eq(language, "c#"));
const char** i;
for (i = ValidLanguages; (*i) != NULL; ++i)
{
if (cstr_eqi((*i), language))
return 1;
}
return 0;
}
@ -364,6 +429,15 @@ void project_set_guid(Project prj, const char* guid)
}
/**
* Set the project kind: console, windowed, etc.
*/
void project_set_kind(Project prj, const char* kind)
{
project_set_value(prj, ProjectKind, kind);
}
/**
* Set the programming language used by a project.
*/

View File

@ -27,6 +27,7 @@ enum ProjectField
ProjectBaseDir,
ProjectFiles,
ProjectGuid,
ProjectKind,
ProjectLanguage,
ProjectLocation,
ProjectName,
@ -48,16 +49,21 @@ const char* project_get_filename(Project prj, const char* basename, const char*
const char* project_get_filename_relative(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_kind(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);
Session project_get_session(Project prj);
const char* project_get_value(Project prj, enum ProjectField field);
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);
int project_is_valid_language(const char* language);
void project_set_base_dir(Project prj, const char* base_dir);
void project_set_config(Project prj, const char* cfg_name);
void project_set_guid(Project prj, const char* guid);
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);

View File

@ -254,25 +254,44 @@ int session_validate(Session sess, SessionFeatures* features)
Project prj = solution_get_project(sln, pi);
const char* prj_name = project_get_name(prj);
const char* prj_kind = project_get_kind(prj);
const char* prj_lang = project_get_language(prj);
/* every project must have a language defined */
if (prj_lang == NULL)
/* every project must have these fields defined */
if (prj_kind == NULL)
{
error_set("no language defined for project '%s'", prj_name);
error_set("project '%s' needs a kind", prj_name);
return !OKAY;
}
if (prj_lang == NULL)
{
error_set("project '%s' needs a language", prj_name);
return !OKAY;
}
/* check actual project values against the list of supported values */
for (i = 0; features->kinds[i] != NULL; ++i)
{
if (cstr_eqi(prj_kind, features->kinds[i]))
break;
}
if (features->kinds[i] == NULL)
{
error_set("%s projects are not supported by this action", prj_kind);
return !OKAY;
}
/* action must support the language */
for (i = 0; features->languages[i] != NULL; ++i)
{
if (cstr_eq(prj_lang, features->languages[i]))
if (cstr_eqi(prj_lang, features->languages[i]))
break;
}
if (features->languages[i] == NULL)
{
error_set("%s language projects are not supported by this action", prj_lang);
error_set("%s projects are not supported by this action", prj_lang);
return !OKAY;
}
}

View File

@ -51,6 +51,7 @@ typedef int (*SessionProjectCallback)(Project prj, Stream strm);
*/
typedef struct struct_SessionFeatures
{
const char* kinds[32];
const char* languages[64];
} SessionFeatures;

View File

@ -19,6 +19,7 @@ FieldInfo SolutionFieldInfo[] =
{
{ "basedir", StringField, NULL },
{ "configurations", ListField, NULL },
{ "kind", StringField, project_is_valid_kind },
{ "language", StringField, project_is_valid_language },
{ "location", StringField, NULL },
{ "name", StringField, NULL },
@ -167,6 +168,15 @@ const char* solution_get_filename(Solution sln, const char* basename, const char
}
/**
* Get the solution-wide project kind.
*/
const char* solution_get_kind(Solution sln)
{
return solution_get_value(sln, SolutionKind);
}
/**
* Get the programming language set globally for the solution.
*/
@ -260,6 +270,15 @@ void solution_set_base_dir(Solution sln, const char* base_dir)
}
/**
* Set the solution-wide project kind.
*/
void solution_set_kind(Solution sln, const char* kind)
{
solution_set_value(sln, SolutionKind, kind);
}
/**
* Set the global programming language for the solution.
*/

View File

@ -27,6 +27,7 @@ enum SolutionField
{
SolutionBaseDir,
SolutionConfigurations,
SolutionKind,
SolutionLanguage,
SolutionLocation,
SolutionName,
@ -47,6 +48,7 @@ const char* solution_get_config(Solution sln, int index);
Strings solution_get_configs(Solution sln);
Fields solution_get_fields(Solution sln);
const char* solution_get_filename(Solution sln, const char* basename, const char* ext);
const char* solution_get_kind(Solution sln);
const char* solution_get_language(Solution sln);
const char* solution_get_location(Solution sln);
const char* solution_get_name(Solution sln);
@ -56,6 +58,7 @@ const char* solution_get_value(Solution sln, enum 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);
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);

View File

@ -64,6 +64,19 @@ SUITE(project)
/**********************************************************************
* Kind tests
**********************************************************************/
TEST_FIXTURE(FxProject, GetKind_ReturnsSolutionKind_OnNoProjectKind)
{
project_set_solution(prj, sln);
solution_set_kind(sln, "console");
const char* result = project_get_kind(prj);
CHECK_EQUAL("console", result);
}
/**********************************************************************
* Language tests
**********************************************************************/

View File

@ -22,6 +22,7 @@ extern "C" {
#define FAIL_PRJ_PARAM (2)
static SessionFeatures features = {
{ "console", NULL },
{ "c", "c++", NULL },
};
@ -101,6 +102,8 @@ struct FxSession
prj = project_create();
solution_add_project(sln, prj);
project_set_name(prj, "MyProject");
project_set_kind(prj, "Console");
project_set_language(prj, "C++");
return prj;
}
};
@ -295,13 +298,34 @@ SUITE(session)
CHECK_EQUAL("no projects defined for solution 'MySolution'", error_get());
}
TEST_FIXTURE(FxSession, Validate_NotOkay_OnNullKind)
{
AddSolution();
AddProject();
project_set_kind(prj, NULL);
int result = session_validate(sess, &features);
CHECK(result != OKAY);
CHECK_EQUAL("project 'MyProject' needs a kind", error_get());
}
TEST_FIXTURE(FxSession, Validate_NotOkay_OnUnsupportedKind)
{
AddSolution();
AddProject();
project_set_kind(prj, "nonesuch");
int result = session_validate(sess, &features);
CHECK(result != OKAY);
CHECK_EQUAL("nonesuch projects are not supported by this action", error_get());
}
TEST_FIXTURE(FxSession, Validate_NotOkay_OnNullLanguage)
{
AddSolution();
AddProject();
project_set_language(prj, NULL);
int result = session_validate(sess, &features);
CHECK(result != OKAY);
CHECK_EQUAL("no language defined for project 'MyProject'", error_get());
CHECK_EQUAL("project 'MyProject' needs a language", error_get());
}
TEST_FIXTURE(FxSession, Validate_NotOkay_OnUnsupportedLanguage)
@ -311,7 +335,7 @@ SUITE(session)
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());
CHECK_EQUAL("nonesuch projects are not supported by this action", error_get());
}
}

View File

@ -99,6 +99,29 @@ SUITE(script)
}
/**************************************************************************
* Data validation tests
**************************************************************************/
TEST_FIXTURE(FxAccessor, Accessor_Succeeds_OnGoodData)
{
const char* result = script_run_string(script, "language 'c++'");
CHECK(result == NULL);
}
TEST_FIXTURE(FxAccessor, Accessor_RaisesError_OnBadData)
{
const char* result = script_run_string(script, "language 'none'");
CHECK_EQUAL("invalid value 'none'", result);
}
TEST_FIXTURE(FxAccessor, Accessor_Succeeds_OnDifferingCase)
{
const char* result = script_run_string(script, "language 'C++'");
CHECK(result == NULL);
}
/**************************************************************************
* Files field tests
**************************************************************************/

View File

@ -30,7 +30,8 @@ struct FxUnloadProject
"prj = project('MyProject');"
" prj.basedir = '/basedir';"
" guid '0C202E43-B9AF-4972-822B-5A42F0BF008C';"
" language 'c++';"
" language 'C++';"
" kind 'Console';"
" files { 'Hello.cpp', 'Goodbye.cpp' };"
"return prj");
}
@ -89,11 +90,18 @@ SUITE(unload)
CHECK_EQUAL("0C202E43-B9AF-4972-822B-5A42F0BF008C", result);
}
TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsKind)
{
unload_project(L, prj);
const char* result = project_get_kind(prj);
CHECK_EQUAL("Console", result);
}
TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsLanguage)
{
unload_project(L, prj);
const char* result = project_get_language(prj);
CHECK_EQUAL("c++", result);
CHECK_EQUAL("C++", result);
}
TEST_FIXTURE(FxUnloadProject, UnloadProject_SetsLocation_OnUnsetLocation)