]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_edict.c
ent_create: Fix potential memory leaks. Misc improvements
[xonotic/darkplaces.git] / prvm_edict.c
index 5e4111b791a9f329654edd7751b4d9190fa46bf3..92004b0ae37104c4a7b29556b7f131d671f082dc 100644 (file)
@@ -205,7 +205,7 @@ void PRVM_ED_ClearEdict(prvm_prog_t *prog, prvm_edict_t *e)
 {
        memset(e->fields.fp, 0, prog->entityfields * sizeof(prvm_vec_t));
        e->priv.required->free = false;
-       e->priv.required->freetime = realtime;
+       e->priv.required->freetime = host.realtime;
        if(e->priv.required->allocation_origin)
                Mem_Free((char *)e->priv.required->allocation_origin);
        e->priv.required->allocation_origin = PRVM_AllocationOrigin(prog);
@@ -237,13 +237,13 @@ qboolean PRVM_ED_CanAlloc(prvm_prog_t *prog, prvm_edict_t *e)
 {
        if(!e->priv.required->free)
                return false;
-       if(prvm_reuseedicts_always_allow == realtime)
+       if(prvm_reuseedicts_always_allow == host.realtime)
                return true;
-       if(realtime <= e->priv.required->freetime + 0.1 && prvm_reuseedicts_neverinsameframe.integer)
+       if(host.realtime <= e->priv.required->freetime + 0.1 && prvm_reuseedicts_neverinsameframe.integer)
                return false; // never allow reuse in same frame (causes networking trouble)
        if(e->priv.required->freetime < prog->starttime + prvm_reuseedicts_startuptime.value)
                return true;
-       if(realtime > e->priv.required->freetime + 1)
+       if(host.realtime > e->priv.required->freetime + 1)
                return true;
        return false; // entity slot still blocked because the entity was freed less than one second ago
 }
@@ -309,7 +309,7 @@ void PRVM_ED_Free(prvm_prog_t *prog, prvm_edict_t *ed)
        prog->free_edict(prog, ed);
 
        ed->priv.required->free = true;
-       ed->priv.required->freetime = realtime;
+       ed->priv.required->freetime = host.realtime;
        if(ed->priv.required->allocation_origin)
        {
                Mem_Free((char *)ed->priv.required->allocation_origin);
@@ -395,6 +395,16 @@ ddef_t *PRVM_ED_FindGlobal (prvm_prog_t *prog, const char *name)
        return NULL;
 }
 
+/*
+============
+PRVM_ED_FindGlobalEval
+============
+*/
+prvm_eval_t *PRVM_ED_FindGlobalEval(prvm_prog_t *prog, const char *name)
+{
+       ddef_t *def = PRVM_ED_FindGlobal(prog, name);
+       return def ? (prvm_eval_t *) &prog->globals.fp[def->ofs] : NULL;
+}
 
 /*
 ============
@@ -450,14 +460,14 @@ static char *PRVM_ValueString (prvm_prog_t *prog, etype_t type, prvm_eval_t *val
                        dpsnprintf (line, linelength, "%s()", PRVM_GetString(prog, f->s_name));
                }
                else
-                       dpsnprintf (line, linelength, "function%lli() (invalid!)", val->function);
+                       dpsnprintf (line, linelength, "function %" PRVM_PRIi "() (invalid!)", val->function);
                break;
        case ev_field:
                def = PRVM_ED_FieldAtOfs ( prog, val->_int );
                if (def != NULL)
                        dpsnprintf (line, linelength, ".%s", PRVM_GetString(prog, def->s_name));
                else
-                       dpsnprintf (line, linelength, "field%lli (invalid!)", val->_int );
+                       dpsnprintf (line, linelength, "field %" PRVM_PRIi " (invalid!)", val->_int );
                break;
        case ev_void:
                dpsnprintf (line, linelength, "void");
@@ -544,14 +554,14 @@ char *PRVM_UglyValueString (prvm_prog_t *prog, etype_t type, prvm_eval_t *val, c
                        strlcpy (line, PRVM_GetString (prog, f->s_name), linelength);
                }
                else
-                       dpsnprintf (line, linelength, "bad function %lli (invalid!)", val->function);
+                       dpsnprintf (line, linelength, "bad function %" PRVM_PRIi " (invalid!)", val->function);
                break;
        case ev_field:
                def = PRVM_ED_FieldAtOfs ( prog, val->_int );
                if (def != NULL)
                        dpsnprintf (line, linelength, ".%s", PRVM_GetString(prog, def->s_name));
                else
-                       dpsnprintf (line, linelength, "field%lli (invalid!)", val->_int );
+                       dpsnprintf (line, linelength, "field %" PRVM_PRIi "(invalid!)", val->_int );
                break;
        case ev_void:
                dpsnprintf (line, linelength, "void");
@@ -715,7 +725,6 @@ PRVM_ED_Write
 For savegames
 =============
 */
-extern cvar_t developer_entityparsing;
 void PRVM_ED_Write (prvm_prog_t *prog, qfile_t *f, prvm_edict_t *ed)
 {
        ddef_t  *d;
@@ -1244,7 +1253,7 @@ static void PRVM_ED_EdictSet_f(cmd_state_t *cmd)
        ed = PRVM_EDICT_NUM(atoi(Cmd_Argv(cmd, 2)));
 
        if((key = PRVM_ED_FindField(prog, Cmd_Argv(cmd, 3))) == 0)
-               Con_Printf("Key %s not found !\n", Cmd_Argv(cmd, 3));
+               Con_Printf("Key %s not found!\n", Cmd_Argv(cmd, 3));
        else
                PRVM_ED_ParseEpair(prog, ed, key, Cmd_Argv(cmd, 4), true);
 }
@@ -1343,12 +1352,118 @@ const char *PRVM_ED_ParseEdict (prvm_prog_t *prog, const char *data, prvm_edict_
 
        if (!init) {
                ent->priv.required->free = true;
-               ent->priv.required->freetime = realtime;
+               ent->priv.required->freetime = host.realtime;
        }
 
        return data;
 }
 
+void PRVM_ED_CallPrespawnFunction(prvm_prog_t *prog, prvm_edict_t *ent)
+{
+       if (PRVM_serverfunction(SV_OnEntityPreSpawnFunction))
+       {
+               // self = ent
+               PRVM_serverglobalfloat(time) = sv.time;
+               PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+               prog->ExecuteProgram(prog, PRVM_serverfunction(SV_OnEntityPreSpawnFunction), "QC function SV_OnEntityPreSpawnFunction is missing");
+       }
+}
+
+qboolean PRVM_ED_CallSpawnFunction(prvm_prog_t *prog, prvm_edict_t *ent, const char *data, const char *start)
+{
+       const char *funcname;
+       mfunction_t *func;
+       prvm_eval_t *fulldata = NULL;
+       char vabuf[1024];
+
+//
+// immediately call spawn function, but only if there is a self global and a classname
+//
+       if (!ent->priv.required->free)
+       {
+               if (!PRVM_alledictstring(ent, classname))
+               {
+                       Con_Print("No classname for:\n");
+                       PRVM_ED_Print(prog, ent, NULL);
+                       PRVM_ED_Free (prog, ent);
+                       return false;
+               }
+               /*
+                * This is required for FTE compatibility (FreeCS).
+                * It copies the key/value pairs themselves into a
+                * global for QC to parse on its own.
+                */
+               else if (data && start)
+               {
+                       if((fulldata = PRVM_ED_FindGlobalEval(prog, "__fullspawndata")))
+                       {
+                               const char *in;
+                               char *spawndata;
+                               fulldata->string = PRVM_AllocString(prog, data - start + 1, &spawndata);
+                               for(in = start; in < data; )
+                               {
+                                       char c = *in++;
+                                       if(c == '\n')
+                                               *spawndata++ = '\t';
+                                       else
+                                               *spawndata++ = c;
+                               }
+                               *spawndata = 0;
+                       }
+               }
+
+               // look for the spawn function
+               funcname = PRVM_GetString(prog, PRVM_alledictstring(ent, classname));
+               func = PRVM_ED_FindFunction (prog, va(vabuf, sizeof(vabuf), "spawnfunc_%s", funcname));
+               if(!func)
+                       if(!PRVM_allglobalfloat(require_spawnfunc_prefix))
+                               func = PRVM_ED_FindFunction (prog, funcname);
+
+               if (!func)
+               {
+                       // check for OnEntityNoSpawnFunction
+                       if (PRVM_serverfunction(SV_OnEntityNoSpawnFunction))
+                       {
+                               // self = ent
+                               PRVM_serverglobalfloat(time) = sv.time;
+                               PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+                               prog->ExecuteProgram(prog, PRVM_serverfunction(SV_OnEntityNoSpawnFunction), "QC function SV_OnEntityNoSpawnFunction is missing");
+                       }
+                       else
+                       {
+                               
+                               Con_DPrint("No spawn function for:\n");
+                               if (developer.integer > 0) // don't confuse non-developers with errors  
+                                       PRVM_ED_Print(prog, ent, NULL);
+
+                               PRVM_ED_Free (prog, ent);
+                               return false; // not included in "inhibited" count
+                       }
+               }
+               else
+               {
+                       // self = ent
+                       PRVM_serverglobalfloat(time) = sv.time;
+                       PRVM_allglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+                       prog->ExecuteProgram(prog, func - prog->functions, "");
+               }
+               return true;
+       }
+       PRVM_ED_Free(prog, ent);
+       return false;
+}
+
+void PRVM_ED_CallPostspawnFunction (prvm_prog_t *prog, prvm_edict_t *ent)
+{
+       if(!ent->priv.required->free)
+       if (PRVM_serverfunction(SV_OnEntityPostSpawnFunction))
+       {
+               // self = ent
+               PRVM_serverglobalfloat(time) = sv.time;
+               PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+               prog->ExecuteProgram(prog, PRVM_serverfunction(SV_OnEntityPostSpawnFunction), "QC function SV_OnEntityPostSpawnFunction is missing");
+       }
+}
 
 /*
 ================
@@ -1368,22 +1483,22 @@ to call PRVM_ED_CallSpawnFunctions () to let the objects initialize themselves.
 void PRVM_ED_LoadFromFile (prvm_prog_t *prog, const char *data)
 {
        prvm_edict_t *ent;
+       const char *start;
        int parsed, inhibited, spawned, died;
-       const char *funcname;
-       mfunction_t *func;
-       char vabuf[1024];
 
        parsed = 0;
        inhibited = 0;
        spawned = 0;
        died = 0;
 
-       prvm_reuseedicts_always_allow = realtime;
+       prvm_reuseedicts_always_allow = host.realtime;
 
-// parse ents
+       // parse ents
        while (1)
        {
-// parse the opening brace
+               start = data;
+
+               // parse the opening brace
                if (!COM_ParseToken_Simple(&data, false, false, true))
                        break;
                if (com_token[0] != '{')
@@ -1413,13 +1528,7 @@ void PRVM_ED_LoadFromFile (prvm_prog_t *prog, const char *data)
                        continue;
                }
 
-               if (PRVM_serverfunction(SV_OnEntityPreSpawnFunction))
-               {
-                       // self = ent
-                       PRVM_serverglobalfloat(time) = sv.time;
-                       PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-                       prog->ExecuteProgram(prog, PRVM_serverfunction(SV_OnEntityPreSpawnFunction), "QC function SV_OnEntityPreSpawnFunction is missing");
-               }
+               PRVM_ED_CallPrespawnFunction(prog, ent);
 
                if(ent->priv.required->free)
                {
@@ -1427,64 +1536,10 @@ void PRVM_ED_LoadFromFile (prvm_prog_t *prog, const char *data)
                        continue;
                }
 
-//
-// immediately call spawn function, but only if there is a self global and a classname
-//
-               if(!ent->priv.required->free)
-               {
-                       if (!PRVM_alledictstring(ent, classname))
-                       {
-                               Con_Print("No classname for:\n");
-                               PRVM_ED_Print(prog, ent, NULL);
-                               PRVM_ED_Free (prog, ent);
-                               continue;
-                       }
-
-                       // look for the spawn function
-                       funcname = PRVM_GetString(prog, PRVM_alledictstring(ent, classname));
-                       func = PRVM_ED_FindFunction (prog, va(vabuf, sizeof(vabuf), "spawnfunc_%s", funcname));
-                       if(!func)
-                               if(!PRVM_allglobalfloat(require_spawnfunc_prefix))
-                                       func = PRVM_ED_FindFunction (prog, funcname);
-
-                       if (!func)
-                       {
-                               // check for OnEntityNoSpawnFunction
-                               if (PRVM_serverfunction(SV_OnEntityNoSpawnFunction))
-                               {
-                                       // self = ent
-                                       PRVM_serverglobalfloat(time) = sv.time;
-                                       PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-                                       prog->ExecuteProgram(prog, PRVM_serverfunction(SV_OnEntityNoSpawnFunction), "QC function SV_OnEntityNoSpawnFunction is missing");
-                               }
-                               else
-                               {
-                                       if (developer.integer > 0) // don't confuse non-developers with errors
-                                       {
-                                               Con_Print("No spawn function for:\n");
-                                               PRVM_ED_Print(prog, ent, NULL);
-                                       }
-                                       PRVM_ED_Free (prog, ent);
-                                       continue; // not included in "inhibited" count
-                               }
-                       }
-                       else
-                       {
-                               // self = ent
-                               PRVM_serverglobalfloat(time) = sv.time;
-                               PRVM_allglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-                               prog->ExecuteProgram(prog, func - prog->functions, "");
-                       }
-               }
-
-               if(!ent->priv.required->free)
-               if (PRVM_serverfunction(SV_OnEntityPostSpawnFunction))
-               {
-                       // self = ent
-                       PRVM_serverglobalfloat(time) = sv.time;
-                       PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
-                       prog->ExecuteProgram(prog, PRVM_serverfunction(SV_OnEntityPostSpawnFunction), "QC function SV_OnEntityPostSpawnFunction is missing");
-               }
+               if(!PRVM_ED_CallSpawnFunction(prog, ent, data, start))
+                       continue;
+               
+               PRVM_ED_CallPostspawnFunction(prog, ent);
 
                spawned++;
                if (ent->priv.required->free)
@@ -1859,6 +1914,9 @@ void PRVM_Prog_Reset(prvm_prog_t *prog)
 {
        if (prog->loaded)
        {
+               if(prog->tempstringsbuf.cursize)
+                       Mem_Free(prog->tempstringsbuf.data);
+               prog->tempstringsbuf.cursize = 0;
                PRVM_LeakTest(prog);
                prog->reset_cmd(prog);
                Mem_FreePool(&prog->progs_mempool);
@@ -1977,9 +2035,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
        // TODO bounds check header fields (e.g. numstatements), they must never go behind end of file
 
        prog->profiletime = Sys_DirtyTime();
-       prog->starttime = realtime;
-
-       Con_DPrintf("%s programs occupy %iK.\n", prog->name, (int)(filesize/1024));
+       prog->starttime = host.realtime;
 
        requiredglobalspace = 0;
        for (i = 0;i < numrequiredglobals;i++)
@@ -2392,7 +2448,9 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                        if(!cvar)
                        {
                                const char *value;
-                               char buf[64];
+                               char buf[128];
+                               int prec[3];
+                               float f;
                                Con_DPrintf("PRVM_LoadProgs: no cvar for autocvar global %s in %s, creating...\n", name, prog->name);
                                switch(prog->globaldefs[i].type & ~DEF_SAVEGLOBAL)
                                {
@@ -2400,11 +2458,33 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char * filename, unsigned char * da
                                                if((float)((int)(val->_float)) == val->_float)
                                                        dpsnprintf(buf, sizeof(buf), "%i", (int)(val->_float));
                                                else
-                                                       dpsnprintf(buf, sizeof(buf), "%.9g", val->_float);
+                                               {
+                                                       // ftos_slow
+                                                       f = val->_float;
+                                                       for (int precision = 7; precision <= 9; ++precision) {
+                                                               dpsnprintf(buf, sizeof(buf), "%.*g", precision, f);
+                                                               if ((float)atof(buf) == f) {
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
                                                value = buf;
                                                break;
                                        case ev_vector:
-                                               dpsnprintf(buf, sizeof(buf), "%.9g %.9g %.9g", val->vector[0], val->vector[1], val->vector[2]); value = buf;
+                                               for (i = 0; i < 3; ++i)
+                                               {
+                                                       prec[i] = 9;
+                                                       f = val->vector[i];
+                                                       for (int precision = 7; precision <= 9; ++precision) {
+                                                               dpsnprintf(buf, sizeof(buf), "%.*g", precision, f);
+                                                               if ((float)atof(buf) == f) {
+                                                                       prec[i] = precision;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                               dpsnprintf(buf, sizeof(buf), "%.*g %.*g %.*g", prec[0], val->vector[0], prec[1], val->vector[1], prec[2], val->vector[2]);
+                                               value = buf;
                                                break;
                                        case ev_string:
                                                value = PRVM_GetString(prog, val->string);
@@ -2481,9 +2561,11 @@ fail:
        // init mempools
        PRVM_MEM_Alloc(prog);
 
+       Con_Printf("%s: program loaded (crc %i, size %iK)\n", prog->name, prog->filecrc, (int)(filesize/1024));
+
        // Inittime is at least the time when this function finished. However,
        // later events may bump it.
-       prog->inittime = realtime;
+       prog->inittime = host.realtime;
 }
 
 
@@ -2720,7 +2802,7 @@ void PRVM_Breakpoint(prvm_prog_t *prog, int stack_index, const char *text)
        Con_Printf("PRVM_Breakpoint: %s\n", text);
        PRVM_PrintState(prog, stack_index);
        if (prvm_breakpointdump.integer)
-               Host_Savegame_to(prog, va(vabuf, sizeof(vabuf), "breakpoint-%s.dmp", prog->name));
+               SV_Savegame_to(prog, va(vabuf, sizeof(vabuf), "breakpoint-%s.dmp", prog->name));
 }
 
 void PRVM_Watchpoint(prvm_prog_t *prog, int stack_index, const char *text, etype_t type, prvm_eval_t *o, prvm_eval_t *n)
@@ -2914,47 +2996,26 @@ PRVM_Init
 */
 void PRVM_Init (void)
 {
-       Cmd_AddCommand(&cmd_client, "prvm_edict", PRVM_ED_PrintEdict_f, "print all data about an entity number in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "prvm_edicts", PRVM_ED_PrintEdicts_f, "prints all data about all entities in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "prvm_edictcount", PRVM_ED_Count_f, "prints number of active entities in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "prvm_profile", PRVM_Profile_f, "prints execution statistics about the most used QuakeC functions in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "prvm_childprofile", PRVM_ChildProfile_f, "prints execution statistics about the most used QuakeC functions in the selected VM (server, client, menu), sorted by time taken in function with child calls");
-       Cmd_AddCommand(&cmd_client, "prvm_callprofile", PRVM_CallProfile_f, "prints execution statistics about the most time consuming QuakeC calls from the engine in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "prvm_fields", PRVM_Fields_f, "prints usage statistics on properties (how many entities have non-zero values) in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "prvm_globals", PRVM_Globals_f, "prints all global variables in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "prvm_global", PRVM_Global_f, "prints value of a specified global variable in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "prvm_globalset", PRVM_GlobalSet_f, "sets value of a specified global variable in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "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(&cmd_client, "prvm_edictget", PRVM_ED_EdictGet_f, "retrieves the value of a specified property of a specified entity in the selected VM (server, client menu) into a cvar or to the console");
-       Cmd_AddCommand(&cmd_client, "prvm_globalget", PRVM_ED_GlobalGet_f, "retrieves the value of a specified global variable in the selected VM (server, client menu) into a cvar or to the console");
-       Cmd_AddCommand(&cmd_client, "prvm_printfunction", PRVM_PrintFunction_f, "prints a disassembly (QuakeC instructions) of the specified function in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_client, "cl_cmd", PRVM_GameCommand_Client_f, "calls the client QC function GameCommand with the supplied string as argument");
-       Cmd_AddCommand(&cmd_client, "menu_cmd", PRVM_GameCommand_Menu_f, "calls the menu QC function GameCommand with the supplied string as argument");
-       Cmd_AddCommand(&cmd_client, "sv_cmd", PRVM_GameCommand_Server_f, "calls the server QC function GameCommand with the supplied string as argument");
-       Cmd_AddCommand(&cmd_client, "prvm_breakpoint", PRVM_Breakpoint_f, "marks a statement or function as breakpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear breakpoint");
-       Cmd_AddCommand(&cmd_client, "prvm_globalwatchpoint", PRVM_GlobalWatchpoint_f, "marks a global as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint");
-       Cmd_AddCommand(&cmd_client, "prvm_edictwatchpoint", PRVM_EdictWatchpoint_f, "marks an entity field as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint");
-
-       Cmd_AddCommand(&cmd_server, "prvm_edict", PRVM_ED_PrintEdict_f, "print all data about an entity number in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "prvm_edicts", PRVM_ED_PrintEdicts_f, "prints all data about all entities in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "prvm_edictcount", PRVM_ED_Count_f, "prints number of active entities in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "prvm_profile", PRVM_Profile_f, "prints execution statistics about the most used QuakeC functions in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "prvm_childprofile", PRVM_ChildProfile_f, "prints execution statistics about the most used QuakeC functions in the selected VM (server, client, menu), sorted by time taken in function with child calls");
-       Cmd_AddCommand(&cmd_server, "prvm_callprofile", PRVM_CallProfile_f, "prints execution statistics about the most time consuming QuakeC calls from the engine in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "prvm_fields", PRVM_Fields_f, "prints usage statistics on properties (how many entities have non-zero values) in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "prvm_globals", PRVM_Globals_f, "prints all global variables in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "prvm_global", PRVM_Global_f, "prints value of a specified global variable in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "prvm_globalset", PRVM_GlobalSet_f, "sets value of a specified global variable in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "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(&cmd_server, "prvm_edictget", PRVM_ED_EdictGet_f, "retrieves the value of a specified property of a specified entity in the selected VM (server, client menu) into a cvar or to the console");
-       Cmd_AddCommand(&cmd_server, "prvm_globalget", PRVM_ED_GlobalGet_f, "retrieves the value of a specified global variable in the selected VM (server, client menu) into a cvar or to the console");
-       Cmd_AddCommand(&cmd_server, "prvm_printfunction", PRVM_PrintFunction_f, "prints a disassembly (QuakeC instructions) of the specified function in the selected VM (server, client, menu)");
-       Cmd_AddCommand(&cmd_server, "cl_cmd", PRVM_GameCommand_Client_f, "calls the client QC function GameCommand with the supplied string as argument");
-       Cmd_AddCommand(&cmd_server, "menu_cmd", PRVM_GameCommand_Menu_f, "calls the menu QC function GameCommand with the supplied string as argument");
-       Cmd_AddCommand(&cmd_server, "sv_cmd", PRVM_GameCommand_Server_f, "calls the server QC function GameCommand with the supplied string as argument");
-       Cmd_AddCommand(&cmd_server, "prvm_breakpoint", PRVM_Breakpoint_f, "marks a statement or function as breakpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear breakpoint");
-       Cmd_AddCommand(&cmd_server, "prvm_globalwatchpoint", PRVM_GlobalWatchpoint_f, "marks a global as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint");
-       Cmd_AddCommand(&cmd_server, "prvm_edictwatchpoint", PRVM_EdictWatchpoint_f, "marks an entity field as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint");
+       Cmd_AddCommand(CMD_SHARED, "prvm_edict", PRVM_ED_PrintEdict_f, "print all data about an entity number in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "prvm_edicts", PRVM_ED_PrintEdicts_f, "prints all data about all entities in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "prvm_edictcount", PRVM_ED_Count_f, "prints number of active entities in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "prvm_profile", PRVM_Profile_f, "prints execution statistics about the most used QuakeC functions in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "prvm_childprofile", PRVM_ChildProfile_f, "prints execution statistics about the most used QuakeC functions in the selected VM (server, client, menu), sorted by time taken in function with child calls");
+       Cmd_AddCommand(CMD_SHARED, "prvm_callprofile", PRVM_CallProfile_f, "prints execution statistics about the most time consuming QuakeC calls from the engine in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "prvm_fields", PRVM_Fields_f, "prints usage statistics on properties (how many entities have non-zero values) in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "prvm_globals", PRVM_Globals_f, "prints all global variables in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "prvm_global", PRVM_Global_f, "prints value of a specified global variable in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "prvm_globalset", PRVM_GlobalSet_f, "sets value of a specified global variable in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "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(CMD_SHARED, "prvm_edictget", PRVM_ED_EdictGet_f, "retrieves the value of a specified property of a specified entity in the selected VM (server, client menu) into a cvar or to the console");
+       Cmd_AddCommand(CMD_SHARED, "prvm_globalget", PRVM_ED_GlobalGet_f, "retrieves the value of a specified global variable in the selected VM (server, client menu) into a cvar or to the console");
+       Cmd_AddCommand(CMD_SHARED, "prvm_printfunction", PRVM_PrintFunction_f, "prints a disassembly (QuakeC instructions) of the specified function in the selected VM (server, client, menu)");
+       Cmd_AddCommand(CMD_SHARED, "cl_cmd", PRVM_GameCommand_Client_f, "calls the client QC function GameCommand with the supplied string as argument");
+       Cmd_AddCommand(CMD_SHARED, "menu_cmd", PRVM_GameCommand_Menu_f, "calls the menu QC function GameCommand with the supplied string as argument");
+       Cmd_AddCommand(CMD_SHARED, "sv_cmd", PRVM_GameCommand_Server_f, "calls the server QC function GameCommand with the supplied string as argument");
+       Cmd_AddCommand(CMD_SHARED, "prvm_breakpoint", PRVM_Breakpoint_f, "marks a statement or function as breakpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear breakpoint");
+       Cmd_AddCommand(CMD_SHARED, "prvm_globalwatchpoint", PRVM_GlobalWatchpoint_f, "marks a global as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint");
+       Cmd_AddCommand(CMD_SHARED, "prvm_edictwatchpoint", PRVM_EdictWatchpoint_f, "marks an entity field as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint");
 
        Cvar_RegisterVariable (&prvm_language);
        Cvar_RegisterVariable (&prvm_traceqc);
@@ -3126,7 +3187,7 @@ int PRVM_SetEngineString(prvm_prog_t *prog, const char *s)
                        return PRVM_KNOWNSTRINGBASE + i;
        // new unknown engine string
        if (developer_insane.integer)
-               Con_DPrintf("new engine string %p = \"%s\"\n", s, s);
+               Con_DPrintf("new engine string %p = \"%s\"\n", (void *)s, s);
        for (i = prog->firstfreeknownstring;i < prog->numknownstrings;i++)
                if (!prog->knownstrings[i])
                        break;