예제 #1
0
/*
   =================
   Com_SkipBracedSection

   The next token should be an open brace.
   Skips until a matching close brace is found.
   Internal brace depths are properly skipped.
   =================
 */
void Com_SkipBracedSection( const char *( *program ) ) {
	const char          *token;
	int depth;

	depth = 0;
	do {
		token = Com_Parse( program );
		if ( token[1] == 0 ) {
			if ( token[0] == '{' ) {
				depth++;
			}
			else if ( token[0] == '}' ) {
				depth--;
			}
		}
	} while ( depth && *program );
}
예제 #2
0
/*
==================
Com_MatchToken
==================
*/
void Com_MatchToken(const char * (*buf_p), const char *match, qboolean warning)
{
	const char  *token;

	token = Com_Parse(buf_p);

	if(strcmp(token, match))
	{
		if(warning)
		{
			Com_ScriptWarning("MatchToken: %s != %s", token, match);
		}
		else
		{
			Com_ScriptError("MatchToken: %s != %s", token, match);
		}
	}
}
예제 #3
0
/**
 * @brief This function parses a list of items that should be set to researchable = true after campaign start
 * @param[in] campaign The campaign data structure
 * @param[in] name Name of the techlist
 * @param[in,out] text Script to parse
 * @param[in] researchable Mark them researchable or not researchable
 * @sa CP_ParseScriptFirst
 */
static void CP_ParseResearchableCampaignStates (const campaign_t *campaign, const char *name, const char **text, qboolean researchable)
{
	const char *errhead = "CP_ParseResearchableCampaignStates: unexpected end of file (equipment ";
	const char *token;
	int i;

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

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

	if (!Q_streq(campaign->researched, name)) {
		Com_DPrintf(DEBUG_CLIENT, "..don't use '%s' as researchable list\n", name);
		return;
	}

	Com_DPrintf(DEBUG_CLIENT, "..campaign researchable list '%s'\n", name);
	do {
		token = Com_EParse(text, errhead, name);
		if (!*text || *token == '}')
			return;

		for (i = 0; i < ccs.numTechnologies; i++) {
			technology_t *tech = RS_GetTechByIDX(i);
			if (Q_streq(token, tech->id)) {
				if (researchable) {
					tech->mailSent = MAILSENT_PROPOSAL;
					RS_MarkOneResearchable(tech);
				} else {
					/** @todo Mark unresearchable */
				}
				Com_DPrintf(DEBUG_CLIENT, "...tech %s\n", tech->id);
				break;
			}
		}

		if (i == ccs.numTechnologies)
			Com_Printf("CP_ParseResearchableCampaignStates: unknown token \"%s\" ignored (tech %s)\n", token, name);

	} while (*text);
}
예제 #4
0
/**
 * @brief This function parses a list of items that should be set to researched = true after campaign start
 */
static void CP_ParseResearchedCampaignItems (const campaign_t *campaign, const char *name, const char **text)
{
	const char *errhead = "CP_ParseResearchedCampaignItems: unexpected end of file (equipment ";
	const char *token;
	int i;

	/* Don't parse if it is not definition for current type of campaign. */
	if (!Q_streq(campaign->researched, name))
		return;

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

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

	Com_DPrintf(DEBUG_CLIENT, "..campaign research list '%s'\n", name);
	do {
		token = Com_EParse(text, errhead, name);
		if (!*text || *token == '}')
			return;

		for (i = 0; i < ccs.numTechnologies; i++) {
			technology_t *tech = RS_GetTechByIDX(i);
			assert(tech);
			if (Q_streq(token, tech->id)) {
				tech->mailSent = MAILSENT_FINISHED;
				tech->markResearched.markOnly[tech->markResearched.numDefinitions] = qtrue;
				tech->markResearched.campaign[tech->markResearched.numDefinitions] = Mem_PoolStrDup(name, cp_campaignPool, 0);
				tech->markResearched.numDefinitions++;
				Com_DPrintf(DEBUG_CLIENT, "...tech %s\n", tech->id);
				break;
			}
		}

		if (i == ccs.numTechnologies)
			Com_Printf("CP_ParseResearchedCampaignItems: unknown token \"%s\" ignored (tech %s)\n", token, name);

	} while (*text);
}
예제 #5
0
/**
 * @brief unittest around default use of parser
 */
TEST_F(ParserTest, Parser)
{
	const char* string = "aa \t\n {\"bbb(bbb bbb)bbb {\"{a}\n/* foooo { } \n { } */\n// fooooo\naaaa";
	const char* cursor = string;
	const char* token;

	token = Com_Parse(&cursor);
	ASSERT_NE(Com_GetType(&cursor), TT_QUOTED_WORD);
	ASSERT_STREQ(token, "aa");

	token = Com_Parse(&cursor);
	ASSERT_NE(Com_GetType(&cursor), TT_QUOTED_WORD);
	ASSERT_STREQ(token, "{");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_QUOTED_WORD);
	ASSERT_STREQ(token, "bbb(bbb bbb)bbb {");

	token = Com_Parse(&cursor);
	ASSERT_NE(Com_GetType(&cursor), TT_QUOTED_WORD);
	ASSERT_STREQ(token, "{");

	token = Com_Parse(&cursor);
	ASSERT_NE(Com_GetType(&cursor), TT_QUOTED_WORD);
	ASSERT_STREQ(token, "a");

	token = Com_Parse(&cursor);
	ASSERT_NE(Com_GetType(&cursor), TT_QUOTED_WORD);
	ASSERT_STREQ(token, "}");

	token = Com_Parse(&cursor);
	ASSERT_NE(Com_GetType(&cursor), TT_QUOTED_WORD);
	ASSERT_STREQ(token, "aaaa");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_EOF);
	ASSERT_STREQ(token, "\0");
}
예제 #6
0
static void G_Say_f (player_t *player, bool arg0, bool team)
{
    char text[256];
    player_t *p;

    if (gi.Cmd_Argc() < 2 && !arg0)
        return;

    if (G_CheckFlood(player))
        return;

    if (!team)
        Com_sprintf(text, sizeof(text), "%s: ", player->pers.netname);
    else
        Com_sprintf(text, sizeof(text), "^B%s (team): ", player->pers.netname);

    if (arg0) {
        Q_strcat(text, gi.Cmd_Argv(0), sizeof(text));
        Q_strcat(text, " ", sizeof(text));
        Q_strcat(text, gi.Cmd_Args(), sizeof(text));
    } else {
        const char *p = gi.Cmd_Args();
        const char *token = Com_Parse(&p);

        Q_strcat(text, token, sizeof(text));
    }

    Q_strcat(text, "\n", sizeof(text));

    if (sv_dedicated->integer)
        gi.DPrintf("%s", text);

    p = NULL;
    while ((p = G_PlayerGetNextActiveHuman(p))) {
        if (team && p->pers.team != player->pers.team)
            continue;
        G_ClientPrintf(p, PRINT_CHAT, "%s", text);
    }
}
예제 #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 = Com_EParse(text, errhead, name);
		if (!*text)
			break;
		if (*token == '}')
			break;

		if (Q_streq(token, "equipment")) {
			linkedList_t **list = &alienCategory->equipment;
			token = Com_EParse(text, errhead, name);
			if (!*text || *token != '{') {
				Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" has equipment with no opening brace\n", name);
				break;
			}
			do {
				token = Com_EParse(text, errhead, name);
				if (!*text || *token == '}')
					break;
				LIST_AddString(list, token);
			} while (*text);
		} else if (Q_streq(token, "category")) {
			token = Com_EParse(text, errhead, name);
			if (!*text || *token != '{') {
				Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" has category with no opening brace\n", name);
				break;
			}
			do {
				token = Com_EParse(text, errhead, name);
				if (!*text || *token == '}')
					break;
				alienCategory->missionCategories[alienCategory->numMissionCategories] = CP_GetAlienMissionTypeByID(token);
				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++;
			} while (*text);
		} else if (Q_streq(token, "team")) {
			alienTeamGroup_t *group;

			token = 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 = 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;

					/* This is an alien team */
					if (group->numAlienTeams >= MAX_TEAMS_PER_MISSION)
						Com_Error(ERR_DROP, "CL_ParseAlienTeam: MAX_TEAMS_PER_MISSION hit");
					teamDef = Com_GetTeamDefinitionByID(token);
					if (teamDef)
						group->alienTeams[group->numAlienTeams++] = teamDef;
				}
			} 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");
}
예제 #8
0
/**
 * @brief Parses one "components" entry in a .ufo file and writes it into the next free entry in xxxxxxxx (components_t).
 * @param[in] name The unique id of a components_t array entry.
 * @param[in] text the whole following text after the "components" definition.
 * @sa CP_ParseScriptFirst
 */
static void CP_ParseComponents (const char *name, const char **text)
{
	components_t *comp;
	const char *errhead = "CP_ParseComponents: unexpected end of file.";
	const char *token;

	/* get body */
	token = Com_Parse(text);
	if (!*text || *token != '{') {
		Com_Printf("CP_ParseComponents: \"%s\" components def without body ignored.\n", name);
		return;
	}
	if (ccs.numComponents >= MAX_ASSEMBLIES) {
		Com_Printf("CP_ParseComponents: too many technology entries. limit is %i.\n", MAX_ASSEMBLIES);
		return;
	}

	/* New components-entry (next free entry in global comp-list) */
	comp = &ccs.components[ccs.numComponents];
	ccs.numComponents++;

	OBJZERO(*comp);

	/* set standard values */
	Q_strncpyz(comp->assemblyId, name, sizeof(comp->assemblyId));
	comp->assemblyItem = INVSH_GetItemByIDSilent(comp->assemblyId);
	if (comp->assemblyItem)
		Com_DPrintf(DEBUG_CLIENT, "CP_ParseComponents: linked item: %s with components: %s\n", name, comp->assemblyId);

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

		/* get values */
		if (Q_streq(token, "item")) {
			/* Defines what items need to be collected for this item to be researchable. */
			if (comp->numItemtypes < MAX_COMP) {
				/* Parse item name */
				token = Com_Parse(text);

				comp->items[comp->numItemtypes] = INVSH_GetItemByID(token);	/* item id -> item pointer */

				/* Parse number of items. */
				token = Com_Parse(text);
				comp->itemAmount[comp->numItemtypes] = atoi(token);
				token = Com_Parse(text);
				/* If itemcount needs to be scaled */
				if (token[0] == '%')
					comp->itemAmount2[comp->numItemtypes] = COMP_ITEMCOUNT_SCALED;
				else
					comp->itemAmount2[comp->numItemtypes] = atoi(token);

				/** @todo Set item links to NONE if needed */
				/* comp->item_idx[comp->numItemtypes] = xxx */

				comp->numItemtypes++;
			} else {
				Com_Printf("CP_ParseComponents: \"%s\" Too many 'items' defined. Limit is %i - ignored.\n", name, MAX_COMP);
			}
		} else if (Q_streq(token, "time")) {
			/* Defines how long disassembly lasts. */
			token = Com_Parse(text);
			comp->time = atoi(token);
		} else {
			Com_Printf("CP_ParseComponents: Error in \"%s\" - unknown token: \"%s\".\n", name, token);
		}
	} while (*text);
}
예제 #9
0
void idInterpolatedPosition::parse(const char * (*text))
{
	const char *token;
	Com_MatchToken(text, "{");

	do
	{
		token = Com_Parse(text);

		if(!token[0])
		{
			break;
		}

		if(!strcmp(token, "}"))
		{
			break;
		}

		// here we may have to jump over brush epairs ( only used in editor )
		do
		{
			// if token is not a brace, it is a key for a key/value pair
			if(!token[0] || !strcmp(token, "(") || !strcmp(token, "}"))
			{
				break;
			}

			Com_UngetToken();
			idStr key = Com_ParseOnLine(text);

			Com_Parse(text);

			if(Q_stricmp(key.c_str(), "startPos") == 0)
			{
				Com_UngetToken();
				Com_Parse1DMatrix(text, 3, startPos);
			}
			else if(Q_stricmp(key.c_str(), "endPos") == 0)
			{
				Com_UngetToken();
				Com_Parse1DMatrix(text, 3, endPos);
			}
			else
			{
				Com_UngetToken();
				idCameraPosition::parseToken(key.c_str(), text);
			}

			token = Com_Parse(text);

		}
		while(1);

		if(!strcmp(token, "}"))
		{
			break;
		}

	}
	while(1);

	Com_UngetToken();
	Com_MatchToken(text, "}");
}
예제 #10
0
int Com_ParseInt(const char **buf_p)
{
	return atoi(Com_Parse(buf_p));
}
예제 #11
0
/**
 * @brief Parse a window
 * @sa CL_ParseClientData
 * @code
 * window windowName {
 * }
 * @endcode
 */
bool UI_ParseWindow (const char* type, const char* name, const char** text)
{
	const char* errhead = "UI_ParseWindow: unexpected end of file (window";
	uiNode_t* window;
	const char* token;
	int i;

	if (!Q_streq(type, "window")) {
		Com_Error(ERR_FATAL, "UI_ParseWindow: '%s %s' is not a window node\n", type, name);
		return false;	/* never reached */
	}

	if (!UI_TokenIsName(name, Com_GetType(text) == TT_QUOTED_WORD)) {
		Com_Printf("UI_ParseWindow: \"%s\" is not a well formed node name ([a-zA-Z_][a-zA-Z0-9_]*)\n", name);
		return false;
	}
	if (UI_TokenIsReserved(name)) {
		Com_Printf("UI_ParseWindow: \"%s\" is a reserved token, we can't call a node with it (node \"%s\")\n", name, name);
		return false;
	}

	/* search for windows with same name */
	for (i = 0; i < ui_global.numWindows; i++)
		if (!strncmp(name, ui_global.windows[i]->name, sizeof(ui_global.windows[i]->name)))
			break;

	if (i < ui_global.numWindows) {
		Com_Printf("UI_ParseWindow: %s \"%s\" with same name found, second ignored\n", type, name);
	}

	if (ui_global.numWindows >= UI_MAX_WINDOWS) {
		Com_Error(ERR_FATAL, "UI_ParseWindow: max windows exceeded (%i) - ignore '%s'\n", UI_MAX_WINDOWS, name);
		return false;	/* never reached */
	}

	/* get window body */
	token = Com_Parse(text);

	/* does this window inherit data from another window? */
	if (Q_streq(token, "extends")) {
		uiNode_t* superWindow;
		token = Com_Parse(text);
		superWindow = UI_GetWindow(token);
		if (superWindow == nullptr)
			Sys_Error("Could not get the super window \"%s\"", token);
		window = UI_CloneNode(superWindow, nullptr, true, name, false);
		token = Com_Parse(text);
	} else {
		window = UI_AllocNode(name, type, false);
		window->root = window;
	}

	UI_InsertWindow(window);

	/* parse it's body */
	bool result = UI_ParseNodeBody(window, text, &token, errhead);
	if (!result) {
		Com_Error(ERR_FATAL, "UI_ParseWindow: window \"%s\" has a bad body\n", window->name);
	}

	UI_Node_Loaded(window);
	return true;
}
예제 #12
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);
}
예제 #13
0
/**
 * @brief Do our own preprocessing to the shader file, before the
 * GLSL implementation calls it's preprocessor.
 *
 * "#if/#endif" pairs, "#unroll", "#endunroll", "#include", "#replace" are handled by our
 * preprocessor, not the GLSL implementation's preprocessor (except "#include" which may
 * also be handled by the implementation's preprocessor).  "#if" operates off
 * of the value of a cvar interpreted as a bool. Note the GLSL implementation
 * preprocessor handles "#ifdef" and "#ifndef", not "#if".
 * @param[in] name The file name of the shader (e.g. "world_fs.glsl").
 * @param[in] inPtr The non-preprocessed shader string.
 * @param[in,out] out The preprocessed shader string, nullptr if we don't want to write to it.
 * @param[in,out] remainingOutChars The number of characters left in the out buffer.
 * @param[in] nested If true, parsing a part of "#if" clause, so "#else" and "#endif" tokens are allowed
 * @param[in] inElse If true, parsing an "#else" clause and shouldn't expect another "#else"
 * @return The number of characters added to the buffer pointed to by out.
 */
static size_t R_PreprocessShaderR (const char* name, const char** inPtr, char* out, long* remainingOutChars, bool nested, bool inElse)
{
	const size_t INITIAL_REMAINING_OUT_CHARS = (size_t)*remainingOutChars;
	/* Keep looping till we reach the end of the shader string, or a parsing error.*/
	while (**inPtr) {
		if ('#' == **inPtr) {
			bool endBlockToken;
			(*inPtr)++;

			endBlockToken = !strncmp(*inPtr, "endif", 5);

			if (!strncmp(*inPtr, "else", 4)) {
				if (inElse) {
					/* Error in shader! Print a message saying our preprocessor failed parsing.*/
					Com_Error(ERR_DROP, "R_PreprocessShaderR: #else without #if: %s", name);
				}
				endBlockToken = true;
			}

			if (endBlockToken) {
				if (!nested) {
					/* Error in shader! Print a message saying our preprocessor failed parsing.*/
					Com_Error(ERR_DROP, "R_PreprocessShaderR: Unmatched #endif/#else: %s", name);
				}
				/* Whoever called us will have to deal with closing the block */
				return (INITIAL_REMAINING_OUT_CHARS - (size_t)*remainingOutChars);
			}

			if (!strncmp((*inPtr), "if ", 3)) {
				/* The line looks like "#if r_postprocess".*/
				(*inPtr) += 3;
				/* Get the corresponding cvar value.*/
				float f = Cvar_GetValue(Com_Parse(inPtr));
				if (f) { /* Condition is true, recursively preprocess #if block, and skip over #else block, if any */
					int size = R_PreprocessShaderR(name, inPtr, out, remainingOutChars, true, false);
					if (out) out += size;

					if (!strncmp((*inPtr), "else", 4)) {/* Preprocess and skip #else block */
						(*inPtr) +=4 ;
						R_PreprocessShaderR(name, inPtr, (char*)0, remainingOutChars, true, true);
					}
				} else {
					/* The cvar was false, don't add to out. Lets look and see if we hit a #else, or #endif.*/
					R_PreprocessShaderR(name, inPtr, (char*)0, remainingOutChars, true, false);
					if (!strncmp((*inPtr), "else", 4)) {
						int size;
						/* All right, we want to add this to out.*/
						(*inPtr) +=4 ;
						size = R_PreprocessShaderR(name, inPtr, out, remainingOutChars, true, true);
						if (out) out += size;
					}
				}
				/* skip #endif, if any (could also get here by unexpected EOF */
				if (!strncmp((*inPtr), "endif", 5))
					(*inPtr) +=5 ;
			} else if (!strncmp((*inPtr), "ifndef", 6) || !strncmp((*inPtr), "ifdef", 5)) { /* leave those for GLSL compiler, but follow #else/#endif nesting */
				int size;
				if (out) {
					if (*remainingOutChars <= 0)
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
					*out++ = '#';
					(*remainingOutChars)--;
				}

				size = R_PreprocessShaderR(name, inPtr, out, remainingOutChars, true, false);
				if (out) out += size;

				if (!strncmp((*inPtr), "else", 4)) {
					if (out) {
						if (*remainingOutChars <= 0)
							Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
						*out++ = '#';
						(*remainingOutChars)--;
					}
					size = R_PreprocessShaderR(name, inPtr, out, remainingOutChars, true, true);
					if (out) out += size;
				}

				if (out) {
					if (*remainingOutChars <= 0)
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
					*out++ = '#';
					(*remainingOutChars)--;
				}

			} else if (!strncmp((*inPtr), "include", 7)) {
				char path[MAX_QPATH];
				byte* buf = (byte*)0;
				const char* bufAsChar = (const char*)0;
				const char** bufAsCharPtr = (const char**)0;
				(*inPtr) += 8;
				Com_sprintf(path, sizeof(path), "shaders/%s", Com_Parse(inPtr));
				if (FS_LoadFile(path, &buf) == -1) {
					Com_Printf("Failed to resolve #include: %s.\n", path);
					continue;
				}
				bufAsChar = (const char*)buf;
				bufAsCharPtr = &bufAsChar;
				if (out) {
					out += R_PreprocessShaderR(name, bufAsCharPtr, out, remainingOutChars, nested, false);
				} else {
					R_PreprocessShaderR(name, bufAsCharPtr, out, remainingOutChars, nested, false);
				}
				FS_FreeFile(buf);
			} else if (!strncmp((*inPtr), "unroll", 6)) {
				/* loop unrolling */
				size_t subLength = 0;
				byte* const buffer = Mem_PoolAllocTypeN(byte, SHADER_BUF_SIZE, vid_imagePool);
				(*inPtr) += 6;
				int z = Cvar_GetValue(Com_Parse(inPtr));
				while (*(*inPtr)) {
					if (!strncmp((*inPtr), "#endunroll", 10)) {
						(*inPtr) += 10;
						break;
					}
					buffer[subLength++] = *(*inPtr)++;
					if (subLength >= SHADER_BUF_SIZE)
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
				}
				if (out) {
					for (int j = 0; j < z; j++) {
						for (int l = 0; l < subLength; l++) {
							if (buffer[l] == '$') {
								byte insertedLen = (j / 10) + 1;
								if (!Com_sprintf(out, (size_t)*remainingOutChars, "%d", j))
									Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
								out += insertedLen;
								(*remainingOutChars) -= insertedLen;
							} else {
								if (*remainingOutChars <= 0)
									Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
								*out++ = buffer[l];
								(*remainingOutChars)--;
							}
						}
					}
				}
				Mem_Free(buffer);
			} else if (!strncmp((*inPtr), "replace", 7)) {
				int r = 0;
				(*inPtr) += 8;
				r = Cvar_GetValue(Com_Parse(inPtr));
				if (out) {
					byte insertedLen = 0;
					if (!Com_sprintf(out, (size_t)*remainingOutChars, "%d", r))
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
					insertedLen = (r / 10) + 1;
					out += insertedLen;
					(*remainingOutChars) -= insertedLen;
				}
			} else {
				/* general case is to copy so long as the buffer has room */
				if (out) {
					if (*remainingOutChars <= 0)
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
					*out++ = '#';
					(*remainingOutChars)--;
				}
			}
		} else {
			/* general case is to copy so long as the buffer has room */
			if (out) {
				if (*remainingOutChars <= 0)
					Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
				*out++ = *(*inPtr);
				(*remainingOutChars)--;
			}
			(*inPtr)++;
		}
	}
	/* Return the number of characters added to the buffer.*/
	return (INITIAL_REMAINING_OUT_CHARS - *remainingOutChars);
}
예제 #14
0
/**
 * @brief Serverbrowser text
 * @sa CL_PingServer
 * @sa CL_PingServers_f
 * @note This function fills the network browser server information with text
 * @sa NET_OOB_Printf
 * @sa CL_ServerInfoCallback
 * @sa SVC_Info
 */
void CL_ParseServerInfoMessage (dbuffer *msg, const char *hostname)
{
	const char *value;
	char str[MAX_INFO_STRING];
	char buf[256];

	cgi->NET_ReadString(msg, str, sizeof(str));

	/* check for server status response message */
	value = Info_ValueForKey(str, "sv_dedicated");
	if (*value) {
		const char *token;
		/* server info cvars and users are seperated via newline */
		const char *users = strstr(str, "\n");
		if (!users) {
			cgi->Com_Printf(S_COLOR_GREEN "%s\n", str);
			return;
		}
		cgi->Com_DPrintf(DEBUG_CLIENT, "%s\n", str); /* status string */

		cgi->Cvar_Set("mn_mappic", "maps/shots/default");
		if (*Info_ValueForKey(str, "sv_needpass") == '1')
			cgi->Cvar_Set("mn_server_need_password", "1");
		else
			cgi->Cvar_Set("mn_server_need_password", "0");

		Com_sprintf(serverInfoText, sizeof(serverInfoText), _("IP\t%s\n\n"), hostname);
		cgi->Cvar_Set("mn_server_ip", hostname);
		value = Info_ValueForKey(str, "sv_mapname");
		assert(value);
		cgi->Cvar_Set("mn_svmapname", value);
		Q_strncpyz(buf, value, sizeof(buf));
		token = buf;
		/* skip random map char */
		if (token[0] == '+')
			token++;

		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Map:\t%s\n"), value);
		if (!cgi->R_ImageExists("pics/maps/shots/%s", token)) {
			/* store it relative to pics/ dir - not relative to game dir */
			cgi->Cvar_Set("mn_mappic", va("maps/shots/%s", token));
		}
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Servername:\t%s\n"), Info_ValueForKey(str, "sv_hostname"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Moralestates:\t%s\n"), _(Info_BoolForKey(str, "sv_enablemorale")));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Gametype:\t%s\n"), Info_ValueForKey(str, "sv_gametype"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Gameversion:\t%s\n"), Info_ValueForKey(str, "ver"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Dedicated server:\t%s\n"), _(Info_BoolForKey(str, "sv_dedicated")));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Operating system:\t%s\n"), Info_ValueForKey(str, "sys_os"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Network protocol:\t%s\n"), Info_ValueForKey(str, "sv_protocol"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Roundtime:\t%s\n"), Info_ValueForKey(str, "sv_roundtimelimit"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Teamplay:\t%s\n"), _(Info_BoolForKey(str, "sv_teamplay")));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Max. players per team:\t%s\n"), Info_ValueForKey(str, "sv_maxplayersperteam"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Max. teams allowed in this map:\t%s\n"), Info_ValueForKey(str, "sv_maxteams"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Max. clients:\t%s\n"), Info_ValueForKey(str, "sv_maxclients"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Max. soldiers per player:\t%s\n"), Info_ValueForKey(str, "sv_maxsoldiersperplayer"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Max. soldiers per team:\t%s\n"), Info_ValueForKey(str, "sv_maxsoldiersperteam"));
		Com_sprintf(serverInfoText + strlen(serverInfoText), sizeof(serverInfoText) - strlen(serverInfoText), _("Password protected:\t%s\n"), _(Info_BoolForKey(str, "sv_needpass")));
		cgi->UI_RegisterText(TEXT_STANDARD, serverInfoText);
		userInfoText[0] = '\0';
		do {
			int team;
			token = Com_Parse(&users);
			if (!users)
				break;
			team = atoi(token);
			token = Com_Parse(&users);
			if (!users)
				break;
			Com_sprintf(userInfoText + strlen(userInfoText), sizeof(userInfoText) - strlen(userInfoText), "%s\t%i\n", token, team);
		} while (1);
		cgi->UI_RegisterText(TEXT_LIST, userInfoText);
		cgi->UI_PushWindow("serverinfo");
	} else
		cgi->Com_Printf(S_COLOR_GREEN "%s", str);
}
예제 #15
0
/**
 * @brief Creates a server's entity / program execution context
 * by parsing textual entity definitions out of an ent file.
 * @sa CM_EntityString
 * @sa SV_SpawnServer
 */
void G_SpawnEntities (const char *mapname, bool day, const char *entities)
{
	int entnum;

	G_FreeTags(TAG_LEVEL);

	OBJZERO(level);
	level.pathingMap = (pathing_t *)G_TagMalloc(sizeof(*level.pathingMap), TAG_LEVEL);

	G_EdictsReset();

	/* initialize reactionFire data */
	G_ReactionFireTargetsInit();

	Q_strncpyz(level.mapname, mapname, sizeof(level.mapname));
	level.day = day;

	G_ResetClientData();

	level.activeTeam = TEAM_NO_ACTIVE;
	level.actualRound = 1;
	level.hurtAliens = sv_hurtaliens->integer;
	ai_waypointList = NULL;

	/* parse ents */
	entnum = 0;
	while (1) {
		edict_t *ent;
		/* parse the opening brace */
		const char *token = Com_Parse(&entities);
		if (!entities)
			break;
		if (token[0] != '{')
			gi.Error("ED_LoadFromFile: found %s when expecting {", token);

		ent = G_Spawn();

		entities = ED_ParseEdict(entities, ent);

		ent->mapNum = entnum++;

		/* Set the position of the entity */
		VecToPos(ent->origin, ent->pos);

		/* Call this entity's specific initializer (sets ent->type) */
		ED_CallSpawn(ent);

		/* if this entity is an bbox (e.g. actor), then center its origin based on its position */
		if (ent->solid == SOLID_BBOX)
			G_EdictCalcOrigin(ent);
	}

	/* spawn ai players, if needed */
	if (level.num_spawnpoints[TEAM_CIVILIAN]) {
		if (AI_CreatePlayer(TEAM_CIVILIAN) == NULL)
			gi.DPrintf("Could not create civilian\n");
	}

	if ((sv_maxclients->integer == 1 || ai_numactors->integer) && level.num_spawnpoints[TEAM_ALIEN]) {
		if (AI_CreatePlayer(TEAM_ALIEN) == NULL)
			gi.DPrintf("Could not create alien\n");
	}

	Com_Printf("Used inventory slots after ai spawn: %i\n", game.i.GetUsedSlots(&game.i));

	G_FindEdictGroups();
}
예제 #16
0
/**
 * @brief unittest around default use of parser
 */
TEST_F(ParserTest, ParserWithFunctionScriptToken)
{
	const char* string = "aa \t\n aa,({\"bbb(bbb bbb)bbb {\"{a}\n/* foooo { } \n { } */\n// fooooo\naaaa)";
	const char* cursor = string;
	const char* token;

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_WORD);
	ASSERT_STREQ(token, "aa");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_WORD);
	ASSERT_STREQ(token, "aa");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_COMMA);
	ASSERT_STREQ(token, ",");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_BEGIN_LIST);
	ASSERT_STREQ(token, "(");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_BEGIN_BLOCK);
	ASSERT_STREQ(token, "{");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_QUOTED_WORD);
	ASSERT_STREQ(token, "bbb(bbb bbb)bbb {");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_BEGIN_BLOCK);
	ASSERT_STREQ(token, "{");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_WORD);
	ASSERT_STREQ(token, "a");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_END_BLOCK);
	ASSERT_STREQ(token, "}");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_WORD);
	ASSERT_STREQ(token, "aaaa");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_END_LIST);
	ASSERT_STREQ(token, ")");

	token = Com_Parse(&cursor);
	ASSERT_EQ(Com_GetType(&cursor), TT_EOF);
	ASSERT_STREQ(token, "\0");
}
예제 #17
0
void idCameraDef::parse(const char * (*text))
{

	const char  *token;

	do
	{
		token = Com_Parse(text);

		if(!token[0])
		{
			break;
		}

		if(!Q_stricmp(token, "}"))
		{
			break;
		}

		if(Q_stricmp(token, "time") == 0)
		{
			baseTime = Com_ParseFloat(text);
		}
		else if(Q_stricmp(token, "camera_fixed") == 0)
		{
			cameraPosition = new idFixedPosition();
			cameraPosition->parse(text);
		}
		else if(Q_stricmp(token, "camera_interpolated") == 0)
		{
			cameraPosition = new idInterpolatedPosition();
			cameraPosition->parse(text);
		}
		else if(Q_stricmp(token, "camera_spline") == 0)
		{
			cameraPosition = new idSplinePosition();
			cameraPosition->parse(text);
		}
		else if(Q_stricmp(token, "target_fixed") == 0)
		{
			idFixedPosition *pos = new idFixedPosition();
			pos->parse(text);
			targetPositions.Append(pos);
		}
		else if(Q_stricmp(token, "target_interpolated") == 0)
		{
			idInterpolatedPosition *pos = new idInterpolatedPosition();
			pos->parse(text);
			targetPositions.Append(pos);
		}
		else if(Q_stricmp(token, "target_spline") == 0)
		{
			idSplinePosition *pos = new idSplinePosition();
			pos->parse(text);
			targetPositions.Append(pos);
		}
		else if(Q_stricmp(token, "fov") == 0)
		{
			fov.parse(text);
		}
		else if(Q_stricmp(token, "event") == 0)
		{
			idCameraEvent *event = new idCameraEvent();
			event->parse(text);
			addEvent(event);
		}


	}
	while(1);

	if(!cameraPosition)
	{
		Com_Printf("no camera position specified\n");
		// prevent a crash later on
		cameraPosition = new idFixedPosition();
	}

	Com_UngetToken();
	Com_MatchToken(text, "}");

}
예제 #18
0
void idSplineList::parse(const char * (*text))
{
	const char *token;

	//Com_MatchToken( text, "{" );
	do
	{
		token = Com_Parse(text);

		if(!token[0])
		{
			break;
		}

		if(!Q_stricmp(token, "}"))
		{
			break;
		}

		do
		{
			// if token is not a brace, it is a key for a key/value pair
			if(!token[0] || !Q_stricmp(token, "(") || !Q_stricmp(token, "}"))
			{
				break;
			}

			Com_UngetToken();
			idStr key = Com_ParseOnLine(text);
			const char *token = Com_Parse(text);

			if(Q_stricmp(key.c_str(), "granularity") == 0)
			{
				granularity = atof(token);
			}
			else if(Q_stricmp(key.c_str(), "name") == 0)
			{
				name = token;
			}

			token = Com_Parse(text);

		}
		while(1);

		if(!Q_stricmp(token, "}"))
		{
			break;
		}

		Com_UngetToken();
		// read the control point
		idVec3 point;
		Com_Parse1DMatrix(text, 3, point);
		addPoint(point.x, point.y, point.z);
	}
	while(1);

	//Com_UngetToken();
	//Com_MatchToken( text, "}" );
	dirty = true;
}
예제 #19
0
파일: sdl_input.c 프로젝트: otty/cake3
/*
===============
IN_IsConsoleKey

TODO: If the SDL_Scancode situation improves, use it instead of
      both of these methods
===============
*/
static qboolean IN_IsConsoleKey( keyNum_t key, int character )
{
	typedef struct consoleKey_s
	{
		enum
		{
			QUAKE_KEY,
			CHARACTER
		} type;

		union
		{
			keyNum_t        key;
			int 			character;
		} u;
	} consoleKey_t;

	static consoleKey_t consoleKeys[MAX_CONSOLE_KEYS];
	static int      numConsoleKeys = 0;
	int             i;

	// Only parse the variable when it changes
	if(cl_consoleKeys->modified)
	{
		char           *text_p, *token;

		cl_consoleKeys->modified = qfalse;
		text_p = cl_consoleKeys->string;
		numConsoleKeys = 0;

		while(numConsoleKeys < MAX_CONSOLE_KEYS)
		{
			consoleKey_t   *c = &consoleKeys[numConsoleKeys];
			int             charCode = 0;

			token = Com_Parse(&text_p);
			if(!token[0])
				break;

			if(strlen(token) == 4)
				charCode = Com_HexStrToInt(token);

			if(charCode > 0)
			{
				c->type = CHARACTER;
				c->u.character = charCode;
			}
			else
			{
				c->type = QUAKE_KEY;
				c->u.key = Key_StringToKeynum(token);

				// 0 isn't a key
				if(c->u.key <= 0)
					continue;
			}

			numConsoleKeys++;
		}
	}

	// If the character is the same as the key, prefer the character
	if(key == character)
		key = 0;

	for(i = 0; i < numConsoleKeys; i++)
	{
		consoleKey_t   *c = &consoleKeys[i];

		switch (c->type)
		{
			case QUAKE_KEY:
				if(key && c->u.key == key)
					return qtrue;
				break;

			case CHARACTER:
				if(c->u.character == character)
					return qtrue;
				break;
		}
	}

	return qfalse;
}
예제 #20
0
/**
 * @brief Read a value from the stream and init an action with it
 * @return An initialized action else nullptr
 */
static uiAction_t *UI_ParseValueExpression (const char **text)
{
	const char* token;
	uiAction_t *expression = UI_AllocStaticAction();

	token = Com_Parse(text);
	if (*text == nullptr) {
		Com_Printf("UI_ParseTerminalExpression: Token expected\n");
		return nullptr;
	}

	/* it is a const string (or an injection tag for compatibility) */
	if (Com_GetType(text) == TT_QUOTED_WORD || token[0] == '<') {
		expression->d.terminal.d1.constString = UI_AllocStaticString(token, 0);
		if (UI_IsInjectedString(token))
			expression->type = EA_VALUE_STRING_WITHINJECTION;
		else
			expression->type = EA_VALUE_STRING;
		return expression;
	}

	/* it is a param */
	if (!Q_strncasecmp(token, "param", 5)) {
		if (!Q_strcasecmp(token, "paramcount")) {
			expression->type = EA_VALUE_PARAMCOUNT;
			return expression;
		} else if (token[5] >= '1' && token[5] <= '9') {
			int i;
			if (sscanf(token + 5, "%i", &i) == 1) {
				/* token range 1-9 already avoid 0 */
				assert(i != 0);
				/** @todo when it is possible, we must check range of param id */
				expression->type = EA_VALUE_PARAM;
				expression->d.terminal.d1.integer = i;
				return expression;
			}
		}
	}

	/* it is a cvarname */
	if (char const* const cvarName = Q_strstart(token, "*cvar:")) {
		expression->d.terminal.d1.constString = UI_AllocStaticString(cvarName, 0);
		if (UI_IsInjectedString(cvarName))
			expression->type = EA_VALUE_CVARNAME_WITHINJECTION;
		else
			expression->type = EA_VALUE_CVARNAME;
		return expression;
	}

	/* it is a node property or it is a OLD syntax node property */
	/** @todo We MUST remove the OLD code as fast as possible */
	if (char const* path = Q_strstart(token, "*")) {
		const char *propertyName;
#if 0	/* it looks useless, an unused cache */
		const value_t *property;
#endif

		char const* const relativeToNode = Q_strstart(path, "node:");
		if (relativeToNode)
			path = relativeToNode;

		if (UI_IsInjectedString(path))
			expression->type = EA_VALUE_PATHPROPERTY_WITHINJECTION;
		else
			expression->type = EA_VALUE_PATHPROPERTY;
		if (!relativeToNode) {
			Com_Printf("UI_ParseExpression: Old syntax, please prefix '%s' with \"*node:root.\" \n", token);
			path = va("root.%s", path);
		}
		expression->d.terminal.d1.constString = UI_AllocStaticString(path, 0);

		/* get property name */
		propertyName = strchr(path, '@');
		if (propertyName == nullptr) {
			if (expression->type == EA_VALUE_PATHPROPERTY_WITHINJECTION)
				expression->type = EA_VALUE_PATHNODE_WITHINJECTION;
			else
				expression->type = EA_VALUE_PATHNODE;
			return expression;
		}
		propertyName++;

		return expression;
	}

	/* unsigned and signed number */
	if ((token[0] >= '0' && token[0] <= '9')
		|| (token[0] == '-' && token[1] >= '0' && token[1] <= '9')) {
		/** @todo use a better check - e.g. Com_ParseValue with V_INT or V_FLOAT */
		float f = atof(token);
		expression->d.terminal.d1.number = f;
		expression->type = EA_VALUE_FLOAT;
		return expression;
	}

	/* boolean */
	if (Q_streq(token, "true")) {
		expression->d.terminal.d1.number = 1.0;
		expression->type = EA_VALUE_FLOAT;
		return expression;
	}
	if (Q_streq(token, "false")) {
		expression->d.terminal.d1.number = 0.0;
		expression->type = EA_VALUE_FLOAT;
		return expression;
	}

	Com_Error(ERR_FATAL, "UI_ParseValueExpression: Token \"%s\" unknown. String must use quotes, cvar and nodes must use prefix.\n", token);
}
예제 #21
0
파일: cl_spawn.c 프로젝트: chrisglass/ufoai
/**
 * @brief Parse the map entity string and spawns those entities that are client-side only
 * @sa G_SendEdictsAndBrushModels
 * @sa CL_AddBrushModel
 */
void CL_SpawnParseEntitystring (void)
{
	const char *es = cl.mapData->mapEntityString;
	int entnum = 0, maxLevel;

	if (cl.mapMaxLevel > 0 && cl.mapMaxLevel < PATHFINDING_HEIGHT)
		maxLevel = cl.mapMaxLevel;
	else
		maxLevel = PATHFINDING_HEIGHT;

	/* vid restart? */
	if (cl.numMapParticles || cl.numLMs)
		return;

	OBJZERO(sun);

	/* parse ents */
	while (1) {
		localEntityParse_t entData;
		/* parse the opening brace */
		const char *entityToken = Com_Parse(&es);
		/* memorize the start */
		if (!es)
			break;

		if (entityToken[0] != '{')
			Com_Error(ERR_DROP, "V_ParseEntitystring: found %s when expecting {", entityToken);

		/* initialize */
		OBJZERO(entData);
		VectorSet(entData.scale, 1, 1, 1);
		entData.volume = SND_VOLUME_DEFAULT;
		entData.maxLevel = maxLevel;
		entData.entStringPos = es;
		entData.entnum = entnum;
		entData.maxMultiplayerTeams = TEAM_MAX_HUMAN;
		entData.attenuation = SOUND_ATTN_IDLE;

		/* go through all the dictionary pairs */
		while (1) {
			const value_t *v;
			/* parse key */
			entityToken = Com_Parse(&es);
			if (entityToken[0] == '}')
				break;
			if (!es)
				Com_Error(ERR_DROP, "V_ParseEntitystring: EOF without closing brace");

			for (v = localEntityValues; v->string; v++)
				if (Q_streq(entityToken, v->string)) {
					/* found a definition */
					entityToken = Com_Parse(&es);
					if (!es)
						Com_Error(ERR_DROP, "V_ParseEntitystring: EOF without closing brace");
					Com_EParseValue(&entData, entityToken, v->type, v->ofs, v->size);
					break;
				}
		}
		CL_SpawnCall(&entData);

		entnum++;
	}

	/* add the appropriate directional source to the list of active light sources*/
	R_AddLightsource(&sun);

	/* after we have parsed all the entities we can resolve the target, targetname
	 * connections for the misc_model entities */
	LM_Think();
}
예제 #22
0
uiAction_t *UI_ParseExpression (const char **text)
{
	const char* token;

	token = Com_Parse(text);
	if (*text == nullptr)
		return nullptr;

	if (Q_streq(token, "(")) {
		uiAction_t *expression;
		uiAction_t *e;

		e = UI_ParseExpression(text);

		token = Com_Parse(text);
		if (*text == nullptr)
			return nullptr;

		/* unary operator or unneed "( ... )" */
		if (Q_streq(token, ")"))
			return e;

		/* then its an operator */
		expression = UI_AllocStaticAction();
		expression->d.nonTerminal.left = e;
		expression->type = UI_GetActionTokenType(token, EA_BINARYOPERATOR);
		if (expression->type == EA_nullptr) {
			Com_Printf("UI_ParseExpression: Invalid 'expression' statement. Unknown '%s' operator\n", token);
			return nullptr;
		}

		e = UI_ParseExpression(text);
		expression->d.nonTerminal.right = e;

		token = Com_Parse(text);
		if (*text == nullptr)
			return nullptr;
		if (!Q_streq(token, ")")) {
			Com_Printf("UI_ParseExpression: Token ')' expected\n");
			return nullptr;
		}

		return expression;
	} else {
		const int type = UI_GetActionTokenType(token, EA_UNARYOPERATOR);
		if (type == EA_nullptr) {
			Com_UnParseLastToken();
			return UI_ParseValueExpression(text);
		} else {
			uiAction_t *expression = UI_AllocStaticAction();
			uiAction_t *e;

			e = UI_ParseExpression(text);
			expression->type = type;
			expression->d.nonTerminal.left = e;

			if (expression->type == EA_OPERATOR_EXISTS) {
				switch (e->type) {
				case EA_VALUE_CVARNAME:
				case EA_VALUE_CVARNAME_WITHINJECTION:
				case EA_VALUE_PATHNODE:
				case EA_VALUE_PATHNODE_WITHINJECTION:
					break;
				default:
					Com_Printf("UI_ParseExpression: Cvar or Node path expected, but type %d found\n", e->type);
					return nullptr;
				}
			}
			return expression;
		}
	}
}
예제 #23
0
파일: cp_rank.cpp 프로젝트: cigo/ufoai
/**
 * @brief Parse medals and ranks defined in the medals.ufo file.
 * @sa CL_ParseScriptFirst
 */
void CL_ParseRanks (const char* name, const char** text)
{
	rank_t* rank;
	const char* errhead = "CL_ParseRanks: unexpected end of file (medal/rank ";
	const char* token;

	/* get name list body body */
	token = Com_Parse(text);

	if (!*text || *token != '{') {
		Com_Printf("CL_ParseRanks: rank/medal \"%s\" without body ignored\n", name);
		return;
	}

	for (int i = 0; i < ccs.numRanks; i++) {
		if (Q_streq(name, ccs.ranks[i].name)) {
			Com_Printf("CL_ParseRanks: Rank with same name '%s' already loaded.\n", name);
			return;
		}
	}
	/* parse ranks */
	if (ccs.numRanks >= MAX_RANKS) {
		Com_Printf("CL_ParseRanks: Too many rank descriptions, '%s' ignored.\n", name);
		ccs.numRanks = MAX_RANKS;
		return;
	}

	rank = &ccs.ranks[ccs.numRanks++];
	OBJZERO(*rank);
	rank->id = Mem_PoolStrDup(name, cp_campaignPool, 0);
	rank->level = -1;

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

		if (Com_ParseBlockToken(name, text, rank, rankValues, cp_campaignPool, token)) {
			continue;
		} else if (Q_streq(token, "type")) {
			/* employeeType_t */
			token = cgi->Com_EParse(text, errhead, name);
			if (!*text)
				return;
			/* error check is performed in E_GetEmployeeType function */
			rank->type = E_GetEmployeeType(token);
		} else
			Com_Printf("CL_ParseRanks: unknown token \"%s\" ignored (medal/rank %s)\n", token, name);
	} while (*text);

	if (rank->image == nullptr || !strlen(rank->image))
		cgi->Com_Error(ERR_DROP, "CL_ParseRanks: image is missing for rank %s", rank->id);

	if (rank->name == nullptr || !strlen(rank->name))
		cgi->Com_Error(ERR_DROP, "CL_ParseRanks: name is missing for rank %s", rank->id);

	if (rank->shortname == nullptr || !strlen(rank->shortname))
		rank->shortname = rank->name;

	if (rank->level == -1)
		cgi->Com_Error(ERR_DROP, "CL_ParseRanks: level is missing for rank %s", rank->id);
}
예제 #24
0
void idCameraEvent::parse(const char * (*text))
{
	const char *token;
	Com_MatchToken(text, "{");

	do
	{
		token = Com_Parse(text);

		if(!token[0])
		{
			break;
		}

		if(!strcmp(token, "}"))
		{
			break;
		}

		// here we may have to jump over brush epairs ( only used in editor )
		do
		{
			// if token is not a brace, it is a key for a key/value pair
			if(!token[0] || !strcmp(token, "(") || !strcmp(token, "}"))
			{
				break;
			}

			Com_UngetToken();
			idStr key = Com_ParseOnLine(text);
			const char *token = Com_Parse(text);

			if(Q_stricmp(key.c_str(), "type") == 0)
			{
				type = static_cast<idCameraEvent::eventType>(atoi(token));
			}
			else if(Q_stricmp(key.c_str(), "param") == 0)
			{
				paramStr = token;
			}
			else if(Q_stricmp(key.c_str(), "time") == 0)
			{
				time = atoi(token);
			}

			token = Com_Parse(text);

		}
		while(1);

		if(!strcmp(token, "}"))
		{
			break;
		}

	}
	while(1);

	Com_UngetToken();
	Com_MatchToken(text, "}");
}
예제 #25
0
/**
 * @brief parses the models.ufo and all files where UI models (menu_model) are defined
 * @sa CL_ParseClientData
 */
bool UI_ParseUIModel (const char* name, const char** text)
{
	const char* errhead = "UI_ParseUIModel: unexpected end of file (names ";

	/* search for a UI models with same name */
	for (int i = 0; i < ui_global.numModels; i++)
		if (Q_streq(ui_global.models[i].id, name)) {
			Com_Printf("UI_ParseUIModel: menu_model \"%s\" with same name found, second ignored\n", name);
			return false;
		}

	if (ui_global.numModels >= UI_MAX_MODELS) {
		Com_Printf("UI_ParseUIModel: Max UI models reached\n");
		return false;
	}

	/* initialize the model */
	uiModel_t* model = &ui_global.models[ui_global.numModels];
	OBJZERO(*model);

	Vector4Set(model->color, 1, 1, 1, 1);

	model->id = Mem_PoolStrDup(name, ui_sysPool, 0);
	Com_DPrintf(DEBUG_CLIENT, "Found UI model %s (%i)\n", model->id, ui_global.numModels);

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

	if (!*text || token[0] != '{') {
		Com_Printf("UI_ParseUIModel: Model \"%s\" without body ignored\n", model->id);
		return false;
	}

	ui_global.numModels++;

	do {
		const value_t* v = nullptr;
		/* get the name type */
		token = Com_EParse(text, errhead, name);
		if (!*text)
			return false;
		if (token[0] == '}')
			break;

		v = UI_FindPropertyByName(uiModelProperties, token);
		if (!v) {
			Com_Printf("UI_ParseUIModel: unknown token \"%s\" ignored (UI model %s)\n", token, name);
			return false;
		}

		if (v->type == V_NULL) {
			if (Q_streq(v->string, "need")) {
				token = Com_EParse(text, errhead, name);
				if (!*text)
					return false;
				if (model->next != nullptr)
					Sys_Error("UI_ParseUIModel: second 'need' token found in model %s", name);
				model->next = UI_GetUIModel(token);
				 if (!model->next)
					Com_Printf("Could not find UI model %s", token);
			}
		} else {
			token = Com_EParse(text, errhead, name);
			if (!*text)
				return false;
			switch (v->type) {
			case V_HUNK_STRING:
				Mem_PoolStrDupTo(token, &Com_GetValue<char*>(model, v), ui_sysPool, 0);
				break;
			default:
				Com_EParseValue(model, token, v->type, v->ofs, v->size);
				break;
			}
		}
	} while (*text);

	return true;
}
예제 #26
0
/**
 * @brief Compute the next token
 * @return Type of the next token
 */
Com_TokenType_t Com_NextToken(const char **data_p)
{
	Com_Parse(data_p);
	return type;
}
예제 #27
0
float Com_ParseFloat(const char **buf_p)
{
	return (float)atof(Com_Parse(buf_p));
}
예제 #28
0
/**
 * @sa CL_ParseClientData
 */
static void CP_ParseCampaign (const char *name, const char **text)
{
	const char *errhead = "CP_ParseCampaign: unexpected end of file (campaign ";
	campaign_t *cp;
	const char *token;
	int i;
	salary_t *s;

	/* search for campaigns with same name */
	for (i = 0; i < ccs.numCampaigns; i++)
		if (Q_streq(name, ccs.campaigns[i].id))
			break;

	if (i < ccs.numCampaigns) {
		Com_Printf("CP_ParseCampaign: campaign def \"%s\" with same name found, second ignored\n", name);
		return;
	}

	if (ccs.numCampaigns >= MAX_CAMPAIGNS) {
		Com_Printf("CP_ParseCampaign: Max campaigns reached (%i)\n", MAX_CAMPAIGNS);
		return;
	}

	/* initialize the campaign */
	cp = &ccs.campaigns[ccs.numCampaigns++];
	OBJZERO(*cp);

	cp->idx = ccs.numCampaigns - 1;
	Q_strncpyz(cp->id, name, sizeof(cp->id));

	/* some default values */
	cp->team = TEAM_PHALANX;
	Q_strncpyz(cp->researched, "researched_human", sizeof(cp->researched));

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

	if (!*text || *token != '{') {
		Com_Printf("CP_ParseCampaign: campaign def \"%s\" without body ignored\n", name);
		ccs.numCampaigns--;
		return;
	}

	/* some default values */
	s = &cp->salaries;
	s->base[EMPL_SOLDIER] = 3000;
	s->rankBonus[EMPL_SOLDIER] = 500;
	s->base[EMPL_WORKER] = 3000;
	s->rankBonus[EMPL_WORKER] = 500;
	s->base[EMPL_SCIENTIST] = 3000;
	s->rankBonus[EMPL_SCIENTIST] = 500;
	s->base[EMPL_PILOT] = 3000;
	s->rankBonus[EMPL_PILOT] = 500;
	s->aircraftFactor = 1;
	s->aircraftDivisor = 25;
	s->baseUpkeep = 20000;
	s->adminInitial = 1000;
	s->admin[EMPL_SOLDIER] = 75;
	s->admin[EMPL_WORKER] = 75;
	s->admin[EMPL_SCIENTIST] = 75;
	s->admin[EMPL_PILOT] = 75;
	s->debtInterest = 0.005;

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

		/* check for some standard values */
		if (Com_ParseBlockToken(name, text, cp, campaign_vals, NULL, token)) {
			continue;
		} else if (Q_streq(token, "salary")) {
			CP_ParseSalary(token, text, s);
		} else if (Q_streq(token, "events")) {
			token = Com_EParse(text, errhead, name);
			if (!*text)
				return;
			cp->events = CP_GetEventsByID(token);
		} else {
			Com_Printf("CP_ParseCampaign: unknown token \"%s\" ignored (campaign %s)\n", token, name);
			Com_EParse(text, errhead, name);
		}
	} while (*text);

	if (cp->difficulty < -4)
		cp->difficulty = -4;
	else if (cp->difficulty > 4)
		cp->difficulty = 4;
}
예제 #29
0
/**
 * @brief Copies an entry from the building description file into the list of building types.
 * @note Parses one "building" entry in the basemanagement.ufo file and writes
 * it into the next free entry in bmBuildings[0], which is the list of buildings
 * in the first base (building_t).
 * @param[in] name Unique script id of a building. This is parsed from "building xxx" -> id=xxx.
 * @param[in] text the whole following text that is part of the "building" item definition in .ufo.
 * @param[in] link Bool value that decides whether to link the tech pointer in or not
 * @sa CL_ParseScriptFirst (link is false here)
 * @sa CL_ParseScriptSecond (link it true here)
 */
void B_ParseBuildings (const char *name, const char **text, bool link)
{
	building_t *building;
	technology_t *techLink;
	const char *errhead = "B_ParseBuildings: unexpected end of file (names ";
	const char *token;

	/* get id list body */
	token = Com_Parse(text);
	if (!*text || *token != '{') {
		Com_Printf("B_ParseBuildings: building \"%s\" without body ignored\n", name);
		return;
	}

	if (ccs.numBuildingTemplates >= MAX_BUILDINGS)
		cgi->Com_Error(ERR_DROP, "B_ParseBuildings: too many buildings");

	if (!link) {
		int i;
		for (i = 0; i < ccs.numBuildingTemplates; i++) {
			if (Q_streq(ccs.buildingTemplates[i].id, name)) {
				Com_Printf("B_ParseBuildings: Second building with same name found (%s) - second ignored\n", name);
				return;
			}
		}

		/* new entry */
		building = &ccs.buildingTemplates[ccs.numBuildingTemplates];
		OBJZERO(*building);
		building->id = Mem_PoolStrDup(name, cp_campaignPool, 0);

		Com_DPrintf(DEBUG_CLIENT, "...found building %s\n", building->id);

		/* set standard values */
		building->tpl = building;	/* Self-link just in case ... this way we can check if it is a template or not. */
		building->idx = -1;			/* No entry in buildings list (yet). */
		building->base = NULL;
		building->buildingType = MAX_BUILDING_TYPE;
		building->dependsBuilding = NULL;
		building->maxCount = -1;	/* Default: no limit */
		building->size[0] = 1;
		building->size[1] = 1;

		ccs.numBuildingTemplates++;
		do {
			/* get the name type */
			token = cgi->Com_EParse(text, errhead, name);
			if (!*text)
				break;
			if (*token == '}')
				break;

			/* get values */
			if (Q_streq(token, "type")) {
				token = cgi->Com_EParse(text, errhead, name);
				if (!*text)
					return;

				building->buildingType = B_GetBuildingTypeByBuildingID(token);
				if (building->buildingType >= MAX_BUILDING_TYPE)
					Com_Printf("didn't find buildingType '%s'\n", token);
			} else {
				/* no linking yet */
				if (Q_streq(token, "depends")) {
					cgi->Com_EParse(text, errhead, name);
					if (!*text)
						return;
				} else {
					if (!Com_ParseBlockToken(name, text, building, valid_building_vars, cp_campaignPool, token))
						Com_Printf("B_ParseBuildings: unknown token \"%s\" ignored (building %s)\n", token, name);
				}
			}
		} while (*text);
		if (building->size[0] < 1 || building->size[1] < 1 || building->size[0] >= BASE_SIZE || building->size[1] >= BASE_SIZE) {
			Com_Printf("B_ParseBuildings: Invalid size for building %s (%i, %i)\n", building->id, (int)building->size[0], (int)building->size[1]);
			ccs.numBuildingTemplates--;
		}
	} else {
		building = B_GetBuildingTemplate(name);
		if (!building)
			cgi->Com_Error(ERR_DROP, "B_ParseBuildings: Could not find building with id %s\n", name);

		techLink = RS_GetTechByProvided(name);
		if (techLink)
			building->tech = techLink;

		do {
			/* get the name type */
			token = cgi->Com_EParse(text, errhead, name);
			if (!*text)
				break;
			if (*token == '}')
				break;
			/* get values */
			if (Q_streq(token, "depends")) {
				const building_t *dependsBuilding = B_GetBuildingTemplate(cgi->Com_EParse(text, errhead, name));
				if (!dependsBuilding)
					cgi->Com_Error(ERR_DROP, "Could not find building depend of %s\n", building->id);
				building->dependsBuilding = dependsBuilding;
				if (!*text)
					return;
			}
		} while (*text);
	}
}
예제 #30
0
void idCameraFOV::parse(const char * (*text))
{
	const char *token;
	Com_MatchToken(text, "{");

	do
	{
		token = Com_Parse(text);

		if(!token[0])
		{
			break;
		}

		if(!strcmp(token, "}"))
		{
			break;
		}

		// here we may have to jump over brush epairs ( only used in editor )
		do
		{
			// if token is not a brace, it is a key for a key/value pair
			if(!token[0] || !strcmp(token, "(") || !strcmp(token, "}"))
			{
				break;
			}

			Com_UngetToken();
			idStr key = Com_ParseOnLine(text);
			const char *token = Com_Parse(text);

			if(Q_stricmp(key.c_str(), "fov") == 0)
			{
				fov = atof(token);
			}
			else if(Q_stricmp(key.c_str(), "startFOV") == 0)
			{
				startFOV = atof(token);
			}
			else if(Q_stricmp(key.c_str(), "endFOV") == 0)
			{
				endFOV = atof(token);
			}
			else if(Q_stricmp(key.c_str(), "time") == 0)
			{
				time = atoi(token);
			}

			token = Com_Parse(text);

		}
		while(1);

		if(!strcmp(token, "}"))
		{
			break;
		}

	}
	while(1);

	Com_UngetToken();
	Com_MatchToken(text, "}");
}