Beispiel #1
0
/**
 * @brief unittest to check well formed empty list
 */
TEST_F(ParserTest, ParserListOkEmpty)
{
	const char* string = " (  \n ) ()";
	const char* cursor = string;
	linkedList_t* list;

	ASSERT_TRUE(Com_ParseList(&cursor, &list)) << "List parsing failed";

	ASSERT_EQ(LIST_Count(list), 0);

	ASSERT_TRUE(Com_ParseList(&cursor, &list)) << "List parsing failed";

	ASSERT_EQ(LIST_Count(list), 0);
}
Beispiel #2
0
/**
 * @brief unittest to check wrong list which contains another sublist
 */
TEST_F(ParserTest, ParserListKoNewList)
{
	const char* string = " (  aaa \n bbb \t ccc \n \n ( ";
	const char* cursor = string;
	linkedList_t* list;

	ASSERT_FALSE(Com_ParseList(&cursor, &list)) << "List parsing succeed, which is wrong";
}
Beispiel #3
0
/**
 * @brief Parses music definitions for different situations
 * @note We have lists for geoscape, battlescape, main and aircombat
 */
void M_ParseMusic (const char* name, const char** text)
{
	int i;

	if (Q_streq(name, "geoscape"))
		i = MUSIC_GEOSCAPE;
	else if (Q_streq(name, "battlescape"))
		i = MUSIC_BATTLESCAPE;
	else if (Q_streq(name, "aircombat"))
		i = MUSIC_AIRCOMBAT;
	else if (Q_streq(name, "main"))
		i = MUSIC_MAIN;
	else {
		Com_Printf("M_ParseMusic: Invalid music id '%s'!\n", name);
		linkedList_t* list;
		Com_ParseList(text, &list);
		LIST_Delete(&list);
		return;
	}

	/* get it's body */
	linkedList_t* list;
	if (!Com_ParseList(text, &list)) {
		Com_Error(ERR_DROP, "M_ParseMusic: error while reading music \"%s\"", name);
	}

	for (linkedList_t* element = list; element != nullptr; element = element->next) {
		if (musicArrayLength[i] >= MUSIC_MAX_ENTRIES) {
			Com_Printf("M_ParseMusic: Too many music entries for category: '%s'!\n", name);
			break;
		}
		musicArrays[i][musicArrayLength[i]] = Mem_PoolStrDup((char*)element->data, cl_genericPool, 0);
		musicArrayLength[i]++;
	}

	LIST_Delete(&list);
}
Beispiel #4
0
/**
 * @brief unittest to check well formed list
 */
TEST_F(ParserTest, ParserListOk)
{
	const char* string = " (  aaa \n \"bbb\" \t ccc \n \n ) ";
	const char* cursor = string;
	linkedList_t* list;

	ASSERT_TRUE(Com_ParseList(&cursor, &list)) << "List parsing failed";

	ASSERT_EQ(LIST_Count(list), 3);

	ASSERT_STREQ(static_cast<const char*>(list->data), "aaa");
	ASSERT_STREQ(static_cast<const char*>(list->next->data), "bbb");
	ASSERT_STREQ(static_cast<const char*>(list->next->next->data), "ccc");

	LIST_Delete(&list);
}
Beispiel #5
0
/**
 * @brief Reads the sequence values from given text-pointer
 * @sa CL_ParseClientData
 */
void CL_ParseSequence (const char *name, const char **text)
{
	const char *errhead = "CL_ParseSequence: unexpected end of file (sequence ";
	sequence_t *sp;
	const char *token;
	int i;

	/* search for sequences with same name */
	for (i = 0; i < numSequences; i++)
		if (Q_streq(name, sequences[i].name))
			break;

	if (i < numSequences) {
		Com_Printf("CL_ParseSequence: sequence def \"%s\" with same name found, second ignored\n", name);
		return;
	}

	/* initialize the sequence */
	if (numSequences >= MAX_SEQUENCES)
		Com_Error(ERR_FATAL, "Too many sequences");

	sp = &sequences[numSequences++];
	OBJZERO(*sp);
	Q_strncpyz(sp->name, name, sizeof(sp->name));
	sp->start = numSeqCmds;

	/* get it's body */
	token = Com_Parse(text);

	if (!*text || *token != '{') {
		Com_Printf("CL_ParseSequence: sequence def \"%s\" without body ignored\n", name);
		numSequences--;
		return;
	}

	do {
		token = Com_EParse(text, errhead, name);
		if (!*text)
			break;
		if (*token == '}')
			break;

		/* check for commands */
		int i = CL_FindSequenceCommand(token);
		if (i != -1) {
			int maxLength = MAX_DATA_LENGTH;
			char *data;
			seqCmd_t *sc;

			/* found a command */
			token = Com_EParse(text, errhead, name);
			if (!*text)
				return;

			if (numSeqCmds >= MAX_SEQCMDS)
				Com_Error(ERR_FATAL, "Too many sequence commands for %s", name);

			/* init seqCmd */
			if (seqCmds == NULL)
				seqCmds = Mem_PoolAllocTypeN(seqCmd_t, MAX_SEQCMDS, cl_genericPool);
			sc = &seqCmds[numSeqCmds++];
			OBJZERO(*sc);
			sc->handler = seqCmdFunc[i];
			sp->length++;

			/* copy name */
			Q_strncpyz(sc->name, token, sizeof(sc->name));

			/* read data */
			token = Com_EParse(text, errhead, name);
			if (!*text)
				return;
			if (*token == '{') {
				// TODO depth is useless IMHO (bayo)
				int depth = 1;
				data = &sc->data[0];
				while (depth) {
					if (maxLength <= 0) {
						Com_Printf("Too much data for sequence %s", sc->name);
						break;
					}
					token = Com_EParse(text, errhead, name);
					if (!*text)
						return;

					if (*token == '{')
						depth++;
					else if (*token == '}')
						depth--;
					if (depth) {
						Q_strncpyz(data, token, maxLength);
						data += strlen(token) + 1;
						maxLength -= (strlen(token) + 1);
					}
				}
			} else if (*token == '(') {
				linkedList_t *list;
				Com_UnParseLastToken();
				if (!Com_ParseList(text, &list)) {
					Com_Error(ERR_DROP, "CL_ParseSequence: error while reading list (sequence \"%s\")", name);
				}
				data = &sc->data[0];
				for (linkedList_t *element = list; element != NULL; element = element->next) {
					if (maxLength <= 0) {
						Com_Printf("Too much data for sequence %s", sc->name);
						break;
					}
					const char* v = (char*)element->data;
					Q_strncpyz(data, v, maxLength);
					data += strlen(v) + 1;
					maxLength -= (strlen(v) + 1);
				}
				LIST_Delete(&list);
			} else {
				Com_UnParseLastToken();
			}
		} else {
			Com_Printf("CL_ParseSequence: unknown command \"%s\" ignored (sequence %s)\n", token, name);
			Com_EParse(text, errhead, name);
		}
	} while (*text);
}
Beispiel #6
0
/**
 * @brief Parse all language definitions from the script files
 */
void CL_ParseLanguages (const char* name, const char** text)
{
	const char* errhead = "CL_ParseLanguages: unexpected end of file (language ";
	const char* token;

	if (!*text) {
		Com_Printf("CL_ParseLanguages: language without body ignored (%s)\n", name);
		return;
	}

	token = Com_EParse(text, errhead, name);
	if (!*text || *token != '{') {
		Com_Printf("CL_ParseLanguages: language without body ignored (%s)\n", name);
		return;
	}

	language_t* const language = Mem_PoolAllocType(language_t, cl_genericPool);
	language->localeID = Mem_PoolStrDup(name, cl_genericPool, 0);
	language->localeString = "";
	language->nativeString = "";
	language->localeMapping = nullptr;

	do {
		/* get the name type */
		token = Com_EParse(text, errhead, name);
		if (!*text || *token == '}')
			break;
		/* inner locale id definition */
		if (Q_streq(token, "code")) {
			linkedList_t* list;
			if (!Com_ParseList(text, &list)) {
				Com_Error(ERR_DROP, "CL_ParseLanguages: error while reading language codes \"%s\"", name);
			}
			for (linkedList_t* element = list; element != nullptr; element = element->next) {
				localeMapping_t* const mapping = Mem_PoolAllocType(localeMapping_t, cl_genericPool);
				mapping->localeMapping = Mem_PoolStrDup((char*)element->data, cl_genericPool, 0);
				/* link it in */
				mapping->next = language->localeMapping;
				language->localeMapping = mapping;
			}
			LIST_Delete(&list);
		} else if (Q_streq(token, "name")) {
			token = Com_EParse(text, errhead, name);
			if (!*text || *token == '}')
				Com_Error(ERR_FATAL, "CL_ParseLanguages: Name expected for language \"%s\".\n", name);
			if (*token != '_') {
				Com_Printf("CL_ParseLanguages: language: '%s' - not marked translatable (%s)\n", name, token);
			}
			language->localeString = Mem_PoolStrDup(token, cl_genericPool, 0);
		} else if (Q_streq(token, "native")) {
			token = Com_EParse(text, errhead, name);
			if (!*text || *token == '}')
				Com_Error(ERR_FATAL, "CL_ParseLanguages: Native expected for language \"%s\".\n", name);
			language->nativeString = Mem_PoolStrDup(token, cl_genericPool, 0);
		}
	} while (*text);

	language->next = languageList;
	languageList = language;
	languageCount++;
}
Beispiel #7
0
/**
 * @sa CL_ParseScriptFirst
 */
static void CP_ParseAlienTeam (const char *name, const char **text)
{
	const char *errhead = "CP_ParseAlienTeam: unexpected end of file (alienteam ";
	const char *token;
	int i;
	alienTeamCategory_t *alienCategory;

	/* get it's body */
	token = Com_Parse(text);

	if (!*text || *token != '{') {
		Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" without body ignored\n", name);
		return;
	}

	if (ccs.numAlienCategories >= ALIENCATEGORY_MAX) {
		Com_Printf("CP_ParseAlienTeam: maximum number of alien team category reached (%i)\n", ALIENCATEGORY_MAX);
		return;
	}

	/* search for category with same name */
	for (i = 0; i < ccs.numAlienCategories; i++)
		if (Q_streq(name, ccs.alienCategories[i].id))
			break;
	if (i < ccs.numAlienCategories) {
		Com_Printf("CP_ParseAlienTeam: alien category def \"%s\" with same name found, second ignored\n", name);
		return;
	}

	alienCategory = &ccs.alienCategories[ccs.numAlienCategories++];
	Q_strncpyz(alienCategory->id, name, sizeof(alienCategory->id));

	do {
		token = cgi->Com_EParse(text, errhead, name);
		if (!*text)
			break;
		if (*token == '}')
			break;

		if (Q_streq(token, "equipment")) {
			linkedList_t **list = &alienCategory->equipment;
			if (!Com_ParseList(text, list)) {
				cgi->Com_Error(ERR_DROP, "CL_ParseAlienTeam: \"%s\" Error while parsing equipment list", name);
			}
		} else if (Q_streq(token, "category")) {
			linkedList_t *list;
			if (!Com_ParseList(text, &list)) {
				cgi->Com_Error(ERR_DROP, "CL_ParseAlienTeam: \"%s\" Error while parsing category list", name);
			}
			for (linkedList_t *element = list; element != NULL; element = element->next) {
				alienCategory->missionCategories[alienCategory->numMissionCategories] = CP_GetAlienMissionTypeByID((char*)element->data);
				if (alienCategory->missionCategories[alienCategory->numMissionCategories] == INTERESTCATEGORY_NONE)
					Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" is used with no mission category. It won't be used in game.\n", name);
				alienCategory->numMissionCategories++;
			}
			LIST_Delete(&list);
		} else if (Q_streq(token, "teaminterest")) {
			alienTeamGroup_t *group;

			token = cgi->Com_EParse(text, errhead, name);
			if (!*text || *token != '{') {
				Com_Printf("CP_ParseAlienTeam: alien team \"%s\" has team with no opening brace\n", name);
				break;
			}

			if (alienCategory->numAlienTeamGroups >= MAX_ALIEN_GROUP_PER_CATEGORY) {
				Com_Printf("CP_ParseAlienTeam: maximum number of alien team reached (%i) in category \"%s\"\n", MAX_ALIEN_GROUP_PER_CATEGORY, name);
				break;
			}

			group = &alienCategory->alienTeamGroups[alienCategory->numAlienTeamGroups];
			group->idx = alienCategory->numAlienTeamGroups;
			group->categoryIdx = alienCategory - ccs.alienCategories;
			alienCategory->numAlienTeamGroups++;

			do {
				token = cgi->Com_EParse(text, errhead, name);

				if (!Com_ParseBlockToken(name, text, group, alien_group_vals, cp_campaignPool, token)) {
					const teamDef_t *teamDef;
					if (!*text || *token == '}')
						break;

					if (Q_streq(token, "team")) {
						linkedList_t *list;
						if (!Com_ParseList(text, &list)) {
							cgi->Com_Error(ERR_DROP, "CL_ParseAlienTeam: \"%s\" Error while parsing team list", name);
						}
						for (linkedList_t *element = list; element != NULL; element = element->next) {
							if (group->numAlienTeams >= MAX_TEAMS_PER_MISSION)
								cgi->Com_Error(ERR_DROP, "CL_ParseAlienTeam: MAX_TEAMS_PER_MISSION hit");
							teamDef = cgi->Com_GetTeamDefinitionByID((char*)element->data);
							if (teamDef)
								group->alienTeams[group->numAlienTeams++] = teamDef;
						}
						LIST_Delete(&list);
					} else {
						cgi->Com_Error(ERR_DROP, "CL_ParseAlienTeam: Unknown token \"%s\"\n", token);
					}
				}
			} while (*text);
		} else {
			Com_Printf("CP_ParseAlienTeam: unknown token \"%s\" ignored (category %s)\n", token, name);
			continue;
		}
	} while (*text);

	if (LIST_IsEmpty(alienCategory->equipment))
		Sys_Error("alien category equipment list is empty");
}