/* ================= 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 ); }
/* ================== 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); } } }
/** * @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); }
/** * @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); }
/** * @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"); }
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); } }
/** * @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"); }
/** * @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); }
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, "}"); }
int Com_ParseInt(const char **buf_p) { return atoi(Com_Parse(buf_p)); }
/** * @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; }
/** * @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); }
/** * @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); }
/** * @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); }
/** * @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(); }
/** * @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"); }
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, "}"); }
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; }
/* =============== 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; }
/** * @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); }
/** * @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(); }
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; } } }
/** * @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); }
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, "}"); }
/** * @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; }
/** * @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; }
float Com_ParseFloat(const char **buf_p) { return (float)atof(Com_Parse(buf_p)); }
/** * @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; }
/** * @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); } }
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, "}"); }