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) void array_set(Array arr, int index, void* item)
{ {
assert(arr); assert(arr);
assert(item);
assert(index >= 0 && index < arr->size); assert(index >= 0 && index < arr->size);
arr->contents[index] = item; arr->contents[index] = item;
} }

View File

@ -57,7 +57,10 @@ void strings_destroy(Strings strs)
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
{ {
String item = (String)array_item(strs->contents, i); String item = (String)array_item(strs->contents, i);
string_destroy(item); if (item != NULL)
{
string_destroy(item);
}
} }
array_destroy(strs->contents); array_destroy(strs->contents);
free(strs); free(strs);
@ -71,7 +74,7 @@ void strings_destroy(Strings strs)
*/ */
void strings_add(Strings strs, const char* item) 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); 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) const char* strings_item(Strings strs, int index)
{ {
String item = (String)array_item(strs->contents, 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) void strings_set(Strings strs, int index, const char* item)
{ {
String str = (String)array_item(strs->contents, index); 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); 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(fields);
assert(index >= 0 && index < fields->count); assert(index >= 0 && index < fields->count);
assert(value);
values = fields->values[index]; values = fields->values[index];
if (strings_size(values) == 0) if (strings_size(values) == 0 && value != NULL)
{ {
strings_add(values, value); strings_add(values, value);
} }

View File

@ -22,12 +22,23 @@ FieldInfo ProjectFieldInfo[] =
{ "basedir", StringField, NULL }, { "basedir", StringField, NULL },
{ "files", FilesField, NULL }, { "files", FilesField, NULL },
{ "guid", StringField, guid_is_valid }, { "guid", StringField, guid_is_valid },
{ "language", StringField, NULL }, { "kind", StringField, project_is_valid_kind },
{ "language", StringField, project_is_valid_language },
{ "location", StringField, NULL }, { "location", StringField, NULL },
{ "name", StringField, NULL }, { "name", StringField, NULL },
{ 0, 0, NULL } { 0, 0, NULL }
}; };
static const char* ValidKinds[] =
{
"Console", NULL
};
static const char* ValidLanguages[] =
{
"C++", NULL
};
DEFINE_CLASS(Project) 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. * Get the programming language used by the project.
*/ */
const char* project_get_language(Project prj) const char* project_get_language(Project prj)
{ {
const char* result = project_get_value(prj, ProjectLanguage); const char* lang = project_get_value(prj, ProjectLanguage);
if (result == NULL && prj->solution != NULL) 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 * Returns true if the project kind matches the parameter.
* are 'c', 'c++', and 'c#'. */
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) int project_is_valid_language(const char* language)
{ {
return (cstr_eq(language, "c") || const char** i;
cstr_eq(language, "c++") || for (i = ValidLanguages; (*i) != NULL; ++i)
cstr_eq(language, "c#")); {
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. * Set the programming language used by a project.
*/ */

View File

@ -27,6 +27,7 @@ enum ProjectField
ProjectBaseDir, ProjectBaseDir,
ProjectFiles, ProjectFiles,
ProjectGuid, ProjectGuid,
ProjectKind,
ProjectLanguage, ProjectLanguage,
ProjectLocation, ProjectLocation,
ProjectName, 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); const char* project_get_filename_relative(Project prj, const char* basename, const char* ext);
Strings project_get_files(Project prj); Strings project_get_files(Project prj);
const char* project_get_guid(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_language(Project prj);
const char* project_get_location(Project prj); const char* project_get_location(Project prj);
const char* project_get_name(Project prj); const char* project_get_name(Project prj);
const char* project_get_outfile(Project prj); const char* project_get_outfile(Project prj);
Session project_get_session(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, 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); int project_is_valid_language(const char* language);
void project_set_base_dir(Project prj, const char* base_dir); void project_set_base_dir(Project prj, const char* base_dir);
void project_set_config(Project prj, const char* cfg_name); void project_set_config(Project prj, const char* cfg_name);
void project_set_guid(Project prj, const char* guid); 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_language(Project prj, const char* language);
void project_set_location(Project prj, const char* location); void project_set_location(Project prj, const char* location);
void project_set_name(Project prj, const char* name); 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); Project prj = solution_get_project(sln, pi);
const char* prj_name = project_get_name(prj); const char* prj_name = project_get_name(prj);
const char* prj_kind = project_get_kind(prj);
const char* prj_lang = project_get_language(prj); const char* prj_lang = project_get_language(prj);
/* every project must have a language defined */ /* every project must have these fields defined */
if (prj_lang == NULL) 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; return !OKAY;
} }
/* action must support the language */
for (i = 0; features->languages[i] != NULL; ++i) 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; break;
} }
if (features->languages[i] == NULL) 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; return !OKAY;
} }
} }

View File

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

View File

@ -19,6 +19,7 @@ FieldInfo SolutionFieldInfo[] =
{ {
{ "basedir", StringField, NULL }, { "basedir", StringField, NULL },
{ "configurations", ListField, NULL }, { "configurations", ListField, NULL },
{ "kind", StringField, project_is_valid_kind },
{ "language", StringField, project_is_valid_language }, { "language", StringField, project_is_valid_language },
{ "location", StringField, NULL }, { "location", StringField, NULL },
{ "name", 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. * 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. * Set the global programming language for the solution.
*/ */

View File

@ -27,6 +27,7 @@ enum SolutionField
{ {
SolutionBaseDir, SolutionBaseDir,
SolutionConfigurations, SolutionConfigurations,
SolutionKind,
SolutionLanguage, SolutionLanguage,
SolutionLocation, SolutionLocation,
SolutionName, SolutionName,
@ -47,6 +48,7 @@ const char* solution_get_config(Solution sln, int index);
Strings solution_get_configs(Solution sln); Strings solution_get_configs(Solution sln);
Fields solution_get_fields(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_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_language(Solution sln);
const char* solution_get_location(Solution sln); const char* solution_get_location(Solution sln);
const char* solution_get_name(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_configs(Solution sln);
int solution_num_projects(Solution sln); int solution_num_projects(Solution sln);
void solution_set_base_dir(Solution sln, const char* base_dir); 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_language(Solution sln, const char* language);
void solution_set_location(Solution sln, const char* location); void solution_set_location(Solution sln, const char* location);
void solution_set_name(Solution sln, const char* name); 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 * Language tests
**********************************************************************/ **********************************************************************/

View File

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

View File

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