X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=prvm_edict.c;h=5f75aa7b9b37c36f3e42277f64db5968f3bf9241;hb=16538d1c3734ca88fe949234e4dc7d37d3e584fe;hp=150d72c1a0bf5a287b4e415154da253aaf0598d8;hpb=bc53279d95750fd59892fdae5d0d7865286f3175;p=xonotic%2Fdarkplaces.git diff --git a/prvm_edict.c b/prvm_edict.c index 150d72c1..5f75aa7b 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -35,6 +35,8 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s); cvar_t prvm_boundscheck = {0, "prvm_boundscheck", "1", "enables detection of out of bounds memory access in the QuakeC code being run (in other words, prevents really exceedingly bad QuakeC code from doing nasty things to your computer)"}; // LordHavoc: prints every opcode as it executes - warning: this is significant spew cvar_t prvm_traceqc = {0, "prvm_traceqc", "0", "prints every QuakeC statement as it is executed (only for really thorough debugging!)"}; +// LordHavoc: counts usage of each QuakeC statement +cvar_t prvm_statementprofiling = {0, "prvm_statementprofiling", "0", "counts how many times each QuakeC statement has been executed, these counts are displayed in prvm_printfunction output (if enabled)"}; //============================================================================ // mempool handling @@ -124,6 +126,16 @@ int PRVM_ED_FindFieldOffset(const char *field) return d->ofs*4; } +ddef_t* PRVM_ED_FindGlobal(const char *name); +int PRVM_ED_FindGlobalOffset(const char *global) +{ + ddef_t *d; + d = PRVM_ED_FindGlobal(global); + if (!d) + return 0; + return d->ofs*4; +} + qboolean PRVM_ProgLoaded(int prognr) { if(prognr < 0 || prognr >= PRVM_MAXPROGS) @@ -410,7 +422,7 @@ char *PRVM_ValueString (etype_t type, prvm_eval_t *val) sprintf (line, "pointer"); break; default: - sprintf (line, "bad type %i", type); + sprintf (line, "bad type %i", (int) type); break; } @@ -499,7 +511,7 @@ padded to 20 field width char *PRVM_GlobalString (int ofs) { char *s; - size_t i; + //size_t i; ddef_t *def; void *val; static char line[128]; @@ -507,37 +519,37 @@ char *PRVM_GlobalString (int ofs) val = (void *)&prog->globals.generic[ofs]; def = PRVM_ED_GlobalAtOfs(ofs); if (!def) - sprintf (line,"%i(?)", ofs); + sprintf (line,"GLOBAL%i", ofs); else { s = PRVM_ValueString ((etype_t)def->type, (prvm_eval_t *)val); - sprintf (line,"%i(%s)%s", ofs, PRVM_GetString(def->s_name), s); + sprintf (line,"%s (=%s)", PRVM_GetString(def->s_name), s); } - i = strlen(line); - for ( ; i<20 ; i++) - strcat (line," "); - strcat (line," "); + //i = strlen(line); + //for ( ; i<20 ; i++) + // strcat (line," "); + //strcat (line," "); return line; } char *PRVM_GlobalStringNoContents (int ofs) { - size_t i; + //size_t i; ddef_t *def; static char line[128]; def = PRVM_ED_GlobalAtOfs(ofs); if (!def) - sprintf (line,"%i(?)", ofs); + sprintf (line,"GLOBAL%i", ofs); else - sprintf (line,"%i(%s)", ofs, PRVM_GetString(def->s_name)); + sprintf (line,"%s", PRVM_GetString(def->s_name)); - i = strlen(line); - for ( ; i<20 ; i++) - strcat (line," "); - strcat (line," "); + //i = strlen(line); + //for ( ; i<20 ; i++) + // strcat (line," "); + //strcat (line," "); return line; } @@ -595,10 +607,10 @@ void PRVM_ED_Print(prvm_edict_t *ed) tempstring2[sizeof(tempstring2)-1] = 0; name = tempstring2; } - strcat(tempstring, name); + strlcat(tempstring, name, sizeof(tempstring)); for (l = strlen(name);l < 14;l++) - strcat(tempstring, " "); - strcat(tempstring, " "); + strlcat(tempstring, " ", sizeof(tempstring)); + strlcat(tempstring, " ", sizeof(tempstring)); name = PRVM_ValueString((etype_t)d->type, (prvm_eval_t *)v); if (strlen(name) > sizeof(tempstring2)-4) @@ -608,8 +620,8 @@ void PRVM_ED_Print(prvm_edict_t *ed) tempstring2[sizeof(tempstring2)-1] = 0; name = tempstring2; } - strcat(tempstring, name); - strcat(tempstring, "\n"); + strlcat(tempstring, name, sizeof(tempstring)); + strlcat(tempstring, "\n", sizeof(tempstring)); if (strlen(tempstring) >= sizeof(tempstring)/2) { Con_Print(tempstring); @@ -831,15 +843,15 @@ void PRVM_ED_ParseGlobals (const char *data) while (1) { // parse key - if (!COM_ParseToken(&data, false)) + if (!COM_ParseTokenConsole(&data)) PRVM_ERROR ("PRVM_ED_ParseGlobals: EOF without closing brace"); if (com_token[0] == '}') break; - strcpy (keyname, com_token); + strlcpy (keyname, com_token, sizeof(keyname)); // parse value - if (!COM_ParseToken(&data, false)) + if (!COM_ParseTokenConsole(&data)) PRVM_ERROR ("PRVM_ED_ParseGlobals: EOF without closing brace"); if (com_token[0] == '}') @@ -1024,7 +1036,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) while (1) { // parse key - if (!COM_ParseToken(&data, false)) + if (!COM_ParseTokenConsole(&data)) PRVM_ERROR ("PRVM_ED_ParseEdict: EOF without closing brace"); if (developer_entityparsing.integer) Con_Printf("Key: \"%s\"", com_token); @@ -1035,7 +1047,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) // and allow them to be turned into vectors. (FIXME...) if (!strcmp(com_token, "angle")) { - strcpy (com_token, "angles"); + strlcpy (com_token, "angles", sizeof(com_token)); anglehack = true; } else @@ -1043,9 +1055,9 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) // FIXME: change light to _light to get rid of this hack if (!strcmp(com_token, "light")) - strcpy (com_token, "light_lev"); // hack for single light def + strlcpy (com_token, "light_lev", sizeof(com_token)); // hack for single light def - strcpy (keyname, com_token); + strlcpy (keyname, com_token, sizeof(keyname)); // another hack to fix keynames with trailing spaces n = strlen(keyname); @@ -1056,7 +1068,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) } // parse value - if (!COM_ParseToken(&data, false)) + if (!COM_ParseTokenConsole(&data)) PRVM_ERROR ("PRVM_ED_ParseEdict: EOF without closing brace"); if (developer_entityparsing.integer) Con_Printf(" \"%s\"\n", com_token); @@ -1085,7 +1097,7 @@ const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent) if (anglehack) { char temp[32]; - strcpy (temp, com_token); + strlcpy (temp, com_token, sizeof(temp)); sprintf (com_token, "0 %s 0", temp); } @@ -1131,7 +1143,7 @@ void PRVM_ED_LoadFromFile (const char *data) while (1) { // parse the opening brace - if (!COM_ParseToken(&data, false)) + if (!COM_ParseTokenConsole(&data)) break; if (com_token[0] != '{') PRVM_ERROR ("PRVM_ED_LoadFromFile: %s: found %s when expecting {", PRVM_NAME, com_token); @@ -1259,7 +1271,8 @@ void PRVM_LoadLNO( const char *progname ) { SafeWrite (h, statement_linenums, numstatements*sizeof(int)); */ if( (unsigned) filesize < (6 + prog->progs->numstatements) * sizeof( int ) ) { - return; + Mem_Free(lno); + return; } header = (unsigned int *) lno; @@ -1297,7 +1310,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required if (prog->progs == NULL || filesize < (fs_offset_t)sizeof(dprograms_t)) PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME); - Con_DPrintf("%s programs occupy %iK.\n", PRVM_NAME, filesize/1024); + Con_DPrintf("%s programs occupy %iK.\n", PRVM_NAME, (int)(filesize/1024)); prog->filecrc = CRC_Block((unsigned char *)prog->progs, filesize); @@ -1336,6 +1349,8 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required prog->statements = (dstatement_t *)((unsigned char *)prog->progs + prog->progs->ofs_statements); + prog->statement_profile = (double *)Mem_Alloc(prog->progs_mempool, prog->progs->numstatements * sizeof(*prog->statement_profile)); + // moved edict_size calculation down below field adding code //pr_global_struct = (globalvars_t *)((unsigned char *)progs + progs->ofs_globals); @@ -1499,7 +1514,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME); break; default: - Con_DPrintf("PRVM_LoadProgs: unknown opcode %d at statement %d in %s", st->op, i, PRVM_NAME); + Con_DPrintf("PRVM_LoadProgs: unknown opcode %d at statement %d in %s\n", st->op, i, PRVM_NAME); break; } } @@ -1601,32 +1616,32 @@ void PRVM_Fields_f (void) switch(d->type & ~DEF_SAVEGLOBAL) { case ev_string: - strcat(tempstring, "string "); + strlcat(tempstring, "string ", sizeof(tempstring)); break; case ev_entity: - strcat(tempstring, "entity "); + strlcat(tempstring, "entity ", sizeof(tempstring)); break; case ev_function: - strcat(tempstring, "function "); + strlcat(tempstring, "function ", sizeof(tempstring)); break; case ev_field: - strcat(tempstring, "field "); + strlcat(tempstring, "field ", sizeof(tempstring)); break; case ev_void: - strcat(tempstring, "void "); + strlcat(tempstring, "void ", sizeof(tempstring)); break; case ev_float: - strcat(tempstring, "float "); + strlcat(tempstring, "float ", sizeof(tempstring)); break; case ev_vector: - strcat(tempstring, "vector "); + strlcat(tempstring, "vector ", sizeof(tempstring)); break; case ev_pointer: - strcat(tempstring, "pointer "); + strlcat(tempstring, "pointer ", sizeof(tempstring)); break; default: sprintf (tempstring2, "bad type %i ", d->type & ~DEF_SAVEGLOBAL); - strcat(tempstring, tempstring2); + strlcat(tempstring, tempstring2, sizeof(tempstring)); break; } if (strlen(name) > sizeof(tempstring2)-4) @@ -1636,12 +1651,12 @@ void PRVM_Fields_f (void) tempstring2[sizeof(tempstring2)-1] = 0; name = tempstring2; } - strcat(tempstring, name); + strlcat(tempstring, name, sizeof(tempstring)); for (j = (int)strlen(name);j < 25;j++) - strcat(tempstring, " "); + strlcat(tempstring, " ", sizeof(tempstring)); sprintf(tempstring2, "%5d", counts[i]); - strcat(tempstring, tempstring2); - strcat(tempstring, "\n"); + strlcat(tempstring, tempstring2, sizeof(tempstring)); + strlcat(tempstring, "\n", sizeof(tempstring)); if (strlen(tempstring) >= sizeof(tempstring)/2) { Con_Print(tempstring); @@ -1753,9 +1768,11 @@ void PRVM_Init (void) Cmd_AddCommand ("prvm_global", PRVM_Global_f, "prints value of a specified global variable in the selected VM (server, client, menu)"); Cmd_AddCommand ("prvm_globalset", PRVM_GlobalSet_f, "sets value of a specified global variable in the selected VM (server, client, menu)"); Cmd_AddCommand ("prvm_edictset", PRVM_ED_EdictSet_f, "changes value of a specified property of a specified entity in the selected VM (server, client, menu)"); + Cmd_AddCommand ("prvm_printfunction", PRVM_PrintFunction_f, "prints a disassembly (QuakeC instructions) of the specified function in the selected VM (server, client, menu)"); // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others)) Cvar_RegisterVariable (&prvm_boundscheck); Cvar_RegisterVariable (&prvm_traceqc); + Cvar_RegisterVariable (&prvm_statementprofiling); //VM_Cmd_Init(); } @@ -1882,7 +1899,7 @@ int PRVM_SetEngineString(const char *s) if (prog->knownstrings[i] == s) return -1 - i; // new unknown engine string - if (developer.integer >= 3) + if (developer.integer >= 100) Con_Printf("new engine string %p\n", s); for (i = prog->firstfreeknownstring;i < prog->numknownstrings;i++) if (!prog->knownstrings[i])