From e5004f482e1e5ff6c17e6b9252a0ff1381ce90db Mon Sep 17 00:00:00 2001 From: havoc Date: Thu, 21 Nov 2002 18:26:48 +0000 Subject: [PATCH] implemented PR_GetString and PR_SetString from QWSV source, these work around the map change crash bugs in gcc 2.95.3 git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2644 d7cf8633-e32d-0410-b094-e92efae38249 --- host_cmd.c | 10 +++++----- makefile | 2 +- pr_cmds.c | 18 +++++++++--------- pr_edict.c | 42 +++++++++++++++++++++--------------------- pr_exec.c | 38 ++++++++++++++++++++++++++++++++++++-- pr_execprogram.h | 6 +++--- progs.h | 7 +++++-- sv_main.c | 16 ++++++++-------- sv_phys.c | 4 ++-- 9 files changed, 90 insertions(+), 53 deletions(-) diff --git a/host_cmd.c b/host_cmd.c index bd209df6..25d861c2 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -664,7 +664,7 @@ void Host_Name_f (void) if (strcmp(host_client->name, newName) != 0) Con_Printf ("%s renamed to %s\n", host_client->name, newName); strcpy (host_client->name, newName); - host_client->edict->v->netname = host_client->name - pr_strings; + host_client->edict->v->netname = PR_SetString(host_client->name); // send notification to all clients @@ -943,11 +943,11 @@ void Host_Pause_f (void) if (sv.paused) { - SV_BroadcastPrintf ("%s paused the game\n", pr_strings + sv_player->v->netname); + SV_BroadcastPrintf ("%s paused the game\n", PR_GetString(sv_player->v->netname)); } else { - SV_BroadcastPrintf ("%s unpaused the game\n",pr_strings + sv_player->v->netname); + SV_BroadcastPrintf ("%s unpaused the game\n", PR_GetString(sv_player->v->netname)); } // send notification to all clients @@ -1038,7 +1038,7 @@ void Host_Spawn_f (void) memset (ent->v, 0, progs->entityfields * 4); ent->v->colormap = NUM_FOR_EDICT(ent); ent->v->team = (host_client->colors & 15) + 1; - ent->v->netname = host_client->name - pr_strings; + ent->v->netname = PR_SetString(host_client->name); if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_pmodel))) val->_float = host_client->pmodel; @@ -1403,7 +1403,7 @@ edict_t *FindViewthing (void) for (i=0 ; iv->classname, "viewthing") ) + if (!strcmp (PR_GetString(e->v->classname), "viewthing")) return e; } Con_Printf ("No viewthing on map\n"); diff --git a/makefile b/makefile index c1385307..e3215234 100644 --- a/makefile +++ b/makefile @@ -1,7 +1,7 @@ ##### Variables that you may want to modify ##### #choose the compiler you want to use -CC=gcc-cvs +CC=gcc #recommended for: anyone not using ALSA 0.5 OBJ_SND=snd_oss.o snd_dma.o snd_mix.o snd_mem.o diff --git a/pr_cmds.c b/pr_cmds.c index 304773cc..6984e28e 100644 --- a/pr_cmds.c +++ b/pr_cmds.c @@ -145,7 +145,7 @@ void PF_error (void) edict_t *ed; s = PF_VarString(0); - Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s); + Con_Printf ("======SERVER ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name), s); ed = PROG_TO_EDICT(pr_global_struct->self); ED_Print (ed); @@ -168,7 +168,7 @@ void PF_objerror (void) edict_t *ed; s = PF_VarString(0); - Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s); + Con_Printf ("======OBJECT ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name), s); ed = PROG_TO_EDICT(pr_global_struct->self); ED_Print (ed); ED_Free (ed); @@ -253,7 +253,7 @@ void PF_setsize (void) { edict_t *e; float *min, *max; - + e = G_EDICT(OFS_PARM0); min = G_VECTOR(OFS_PARM1); max = G_VECTOR(OFS_PARM2); @@ -287,7 +287,7 @@ void PF_setmodel (void) Host_Error ("no precache: %s\n", m); - e->v->model = m - pr_strings; + e->v->model = PR_SetString(*check); e->v->modelindex = i; mod = sv.models[ (int)e->v->modelindex]; @@ -517,7 +517,7 @@ void PF_random (void) float num; num = (rand ()&0x7fff) / ((float)0x7fff); - + G_FLOAT(OFS_RETURN) = num; } @@ -1045,7 +1045,7 @@ void PF_ftos (void) s = PR_GetTempString(); // LordHavoc: ftos improvement sprintf (s, "%g", v); - G_INT(OFS_RETURN) = s - pr_strings; + G_INT(OFS_RETURN) = PR_SetString(s); } void PF_fabs (void) @@ -1060,7 +1060,7 @@ void PF_vtos (void) char *s; s = PR_GetTempString(); sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]); - G_INT(OFS_RETURN) = s - pr_strings; + G_INT(OFS_RETURN) = PR_SetString(s); } void PF_etos (void) @@ -1068,7 +1068,7 @@ void PF_etos (void) char *s; s = PR_GetTempString(); sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0)); - G_INT(OFS_RETURN) = s - pr_strings; + G_INT(OFS_RETURN) = PR_SetString(s); } void PF_Spawn (void) @@ -2559,7 +2559,7 @@ void PF_getsurfacetexture(void) G_INT(OFS_RETURN) = 0; if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1)))) return; - G_INT(OFS_RETURN) = surf->texinfo->texture->name - pr_strings; + G_INT(OFS_RETURN) = PR_SetString(surf->texinfo->texture->name); } //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438; void PF_getsurfacenearpoint(void) diff --git a/pr_edict.c b/pr_edict.c index 396d8106..ac1f7835 100644 --- a/pr_edict.c +++ b/pr_edict.c @@ -306,7 +306,7 @@ ddef_t *ED_FindField (const char *name) for (i=0 ; inumfielddefs ; i++) { def = &pr_fielddefs[i]; - if (!strcmp(pr_strings + def->s_name,name) ) + if (!strcmp(PR_GetString(def->s_name), name)) return def; } return NULL; @@ -325,7 +325,7 @@ ddef_t *ED_FindGlobal (const char *name) for (i=0 ; inumglobaldefs ; i++) { def = &pr_globaldefs[i]; - if (!strcmp(pr_strings + def->s_name,name) ) + if (!strcmp(PR_GetString(def->s_name), name)) return def; } return NULL; @@ -345,7 +345,7 @@ dfunction_t *ED_FindFunction (const char *name) for (i=0 ; inumfunctions ; i++) { func = &pr_functions[i]; - if (!strcmp(pr_strings + func->s_name,name) ) + if (!strcmp(PR_GetString(func->s_name), name)) return func; } return NULL; @@ -372,7 +372,7 @@ char *PR_ValueString (etype_t type, eval_t *val) switch (type) { case ev_string: - sprintf (line, "%s", pr_strings + val->string); + sprintf (line, "%s", PR_GetString(val->string)); break; case ev_entity: n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)); @@ -383,11 +383,11 @@ char *PR_ValueString (etype_t type, eval_t *val) break; case ev_function: f = pr_functions + val->function; - sprintf (line, "%s()", pr_strings + f->s_name); + sprintf (line, "%s()", PR_GetString(f->s_name)); break; case ev_field: def = ED_FieldAtOfs ( val->_int ); - sprintf (line, ".%s", pr_strings + def->s_name); + sprintf (line, ".%s", PR_GetString(def->s_name)); break; case ev_void: sprintf (line, "void"); @@ -432,22 +432,22 @@ char *PR_UglyValueString (etype_t type, eval_t *val) switch (type) { case ev_string: - sprintf (line, "%s", pr_strings + val->string); + sprintf (line, "%s", PR_GetString(val->string)); break; case ev_entity: sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict))); break; case ev_function: f = pr_functions + val->function; - sprintf (line, "%s", pr_strings + f->s_name); + sprintf (line, "%s", PR_GetString(f->s_name)); break; case ev_field: def = ED_FieldAtOfs ( val->_int ); // LordHavoc: parse the string a bit to turn special characters // (like newline, specifically) into escape codes, // this fixes saving games from various mods - //sprintf (line, "%s", pr_strings + def->s_name); - s = pr_strings + def->s_name; + //sprintf (line, "%s", PR_GetString(def->s_name)); + s = PR_GetString(def->s_name); for (i = 0;i < 4095 && *s;) { if (*s == '\n') @@ -506,7 +506,7 @@ char *PR_GlobalString (int ofs) else { s = PR_ValueString (def->type, val); - sprintf (line,"%i(%s)%s", ofs, pr_strings + def->s_name, s); + sprintf (line,"%i(%s)%s", ofs, PR_GetString(def->s_name), s); } i = strlen(line); @@ -527,7 +527,7 @@ char *PR_GlobalStringNoContents (int ofs) if (!def) sprintf (line,"%i(?)", ofs); else - sprintf (line,"%i(%s)", ofs, pr_strings + def->s_name); + sprintf (line,"%i(%s)", ofs, PR_GetString(def->s_name)); i = strlen(line); for ( ; i<20 ; i++) @@ -568,7 +568,7 @@ void ED_Print (edict_t *ed) for (i=1 ; inumfielddefs ; i++) { d = &pr_fielddefs[i]; - name = pr_strings + d->s_name; + name = PR_GetString(d->s_name); if (name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars @@ -641,7 +641,7 @@ void ED_Write (QFile *f, edict_t *ed) for (i=1 ; inumfielddefs ; i++) { d = &pr_fielddefs[i]; - name = pr_strings + d->s_name; + name = PR_GetString(d->s_name); if (name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars @@ -772,7 +772,7 @@ void ED_WriteGlobals (QFile *f) if (type != ev_string && type != ev_float && type != ev_entity) continue; - name = pr_strings + def->s_name; + name = PR_GetString(def->s_name); Qprintf (f,"\"%s\" ", name); Qprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs])); } @@ -875,7 +875,7 @@ qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s) switch (key->type & ~DEF_SAVEGLOBAL) { case ev_string: - *(string_t *)d = ED_NewString (s) - pr_strings; + *(string_t *)d = PR_SetString(ED_NewString(s)); break; case ev_float: @@ -1094,7 +1094,7 @@ void ED_LoadFromFile (const char *data) } // look for the spawn function - func = ED_FindFunction ( pr_strings + ent->v->classname ); + func = ED_FindFunction (PR_GetString(ent->v->classname)); if (!func) { @@ -1259,7 +1259,7 @@ void PR_LoadProgs (void) { pr_fielddefs[progs->numfielddefs].type = dpfields[i].type; pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields; - pr_fielddefs[progs->numfielddefs].s_name = dpfields[i].string - pr_strings; + pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string); if (pr_fielddefs[progs->numfielddefs].type == ev_vector) progs->entityfields += 3; else @@ -1401,7 +1401,7 @@ void PR_Fields_f (void) for (i = 1;i < progs->numfielddefs;i++) { d = &pr_fielddefs[i]; - name = pr_strings + d->s_name; + name = PR_GetString(d->s_name); if (name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars v = (int *)((char *)ed->v + d->ofs*4); @@ -1422,7 +1422,7 @@ void PR_Fields_f (void) for (i = 0;i < progs->numfielddefs;i++) { d = &pr_fielddefs[i]; - name = pr_strings + d->s_name; + name = PR_GetString(d->s_name); if (name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars switch(d->type & ~DEF_SAVEGLOBAL) @@ -1493,7 +1493,7 @@ void PR_Globals_f (void) return; } for (i = 0;i < progs->numglobaldefs;i++) - Con_Printf("%s\n", (pr_strings + pr_globaldefs[i].s_name)); + Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name)); Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4); } diff --git a/pr_exec.c b/pr_exec.c index 5681213f..05e366d2 100644 --- a/pr_exec.c +++ b/pr_exec.c @@ -197,7 +197,7 @@ void PR_StackTrace (void) if (!f) Con_Printf ("\n"); else - Con_Printf ("%12s : %s : statement %i\n", pr_strings + f->s_file, pr_strings + f->s_name, pr_stack[i].s - f->first_statement); + Con_Printf ("%12s : %s : statement %i\n", PR_GetString(f->s_file), PR_GetString(f->s_name), pr_stack[i].s - f->first_statement); } } @@ -232,7 +232,7 @@ void PR_Profile_f (void) if (best) { if (num < 10) - Con_Printf ("%7i %s\n", best->profile, pr_strings+best->s_name); + Con_Printf ("%7i %s\n", best->profile, PR_GetString(best->s_name)); num++; best->profile = 0; } @@ -348,11 +348,14 @@ int PR_LeaveFunction (void) return pr_stack[pr_depth].s; } +void PR_ReInitStrings (void); void PR_Execute_ProgsLoaded(void) { // dump the stack pr_depth = 0; localstack_used = 0; + // reset the string table + PR_ReInitStrings(); } /* @@ -424,3 +427,34 @@ chooseexecprogram: } } +// LordHavoc: grabbed these from QWSV, works around a gcc 2.95.3 compiler bug +#define MAX_PRSTR 1024 +static char *pr_strtbl[MAX_PRSTR]; +static int num_prstr; + +char *PR_GetString (int num) +{ + return num >= 0 ? pr_strings + num : pr_strtbl[-num]; +} + +int PR_SetString (char *s) +{ + if (s >= pr_strings) + return (int) (s - pr_strings); + else + { + int i; + for (i = 0; i <= num_prstr; i++) + if (pr_strtbl[i] == s) + return -i; + if (num_prstr >= (MAX_PRSTR - 1)) + Host_Error ("PR_Setstring: ran out of string table slots"); + pr_strtbl[++num_prstr] = s; + return -num_prstr; + } +} + +void PR_ReInitStrings (void) +{ + num_prstr = 0; +} diff --git a/pr_execprogram.h b/pr_execprogram.h index be8468bc..33dc3e0a 100644 --- a/pr_execprogram.h +++ b/pr_execprogram.h @@ -82,7 +82,7 @@ OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2]; break; case OP_NOT_S: - OPC->_float = !OPA->string || !pr_strings[OPA->string]; + OPC->_float = !OPA->string || !*PR_GetString(OPA->string); break; case OP_NOT_FNC: OPC->_float = !OPA->function; @@ -97,7 +97,7 @@ OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]); break; case OP_EQ_S: - OPC->_float = !strcmp(pr_strings+OPA->string,pr_strings+OPB->string); + OPC->_float = !strcmp(PR_GetString(OPA->string),PR_GetString(OPB->string)); break; case OP_EQ_E: OPC->_float = OPA->_int == OPB->_int; @@ -112,7 +112,7 @@ OPC->_float = (OPA->vector[0] != OPB->vector[0]) || (OPA->vector[1] != OPB->vector[1]) || (OPA->vector[2] != OPB->vector[2]); break; case OP_NE_S: - OPC->_float = strcmp(pr_strings+OPA->string,pr_strings+OPB->string); + OPC->_float = strcmp(PR_GetString(OPA->string),PR_GetString(OPB->string)); break; case OP_NE_E: OPC->_float = OPA->_int != OPB->_int; diff --git a/progs.h b/progs.h index 96b50128..f08a73fc 100644 --- a/progs.h +++ b/progs.h @@ -155,14 +155,14 @@ edict_t *PROG_TO_EDICT(int n); #define G_EDICT(o) (PROG_TO_EDICT(*(int *)&pr_globals[o])) #define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o)) #define G_VECTOR(o) (&pr_globals[o]) -#define G_STRING(o) (pr_strings + *(string_t *)&pr_globals[o]) +#define G_STRING(o) (PR_GetString(*(string_t *)&pr_globals[o])) //#define G_FUNCTION(o) (*(func_t *)&pr_globals[o]) // FIXME: make these go away? #define E_FLOAT(e,o) (((float*)e->v)[o]) //#define E_INT(e,o) (((int*)e->v)[o]) //#define E_VECTOR(e,o) (&((float*)e->v)[o]) -#define E_STRING(e,o) (pr_strings + *(string_t *)&((float*)e->v)[o]) +#define E_STRING(e,o) (PR_GetString(*(string_t *)&((float*)e->v)[o])) extern int type_size[8]; @@ -183,5 +183,8 @@ void PR_Execute_ProgsLoaded(void); void ED_PrintEdicts (void); void ED_PrintNum (int ent); +char *PR_GetString (int num); +int PR_SetString (char *s); + #endif diff --git a/sv_main.c b/sv_main.c index cd283f9e..74530b39 100644 --- a/sv_main.c +++ b/sv_main.c @@ -260,7 +260,7 @@ void SV_SendServerinfo (client_t *client) else MSG_WriteByte (&client->message, GAME_COOP); - sprintf (message, pr_strings+sv.edicts->v->message); + sprintf (message, PR_GetString(sv.edicts->v->message)); MSG_WriteString (&client->message,message); @@ -586,7 +586,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg) if (val->_float != 0) bits |= U_GLOWTRAIL; - if (ent->v->modelindex >= 0 && ent->v->modelindex < MAX_MODELS && pr_strings[ent->v->model]) + if (ent->v->modelindex >= 0 && ent->v->modelindex < MAX_MODELS && *PR_GetString(ent->v->model)) { model = sv.models[(int)ent->v->modelindex]; Mod_CheckLoaded(model); @@ -970,7 +970,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg) } modelindex = 0; - if (ent->v->modelindex >= 0 && ent->v->modelindex < MAX_MODELS && pr_strings[ent->v->model]) + if (ent->v->modelindex >= 0 && ent->v->modelindex < MAX_MODELS && *PR_GetString(ent->v->model)) { modelindex = ent->v->modelindex; model = sv.models[(int)ent->v->modelindex]; @@ -1346,7 +1346,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) if (bits & SU_ARMOR) MSG_WriteByte (msg, ent->v->armorvalue); if (bits & SU_WEAPON) - MSG_WriteByte (msg, SV_ModelIndex(pr_strings+ent->v->weaponmodel)); + MSG_WriteByte (msg, SV_ModelIndex(PR_GetString(ent->v->weaponmodel))); MSG_WriteShort (msg, ent->v->health); MSG_WriteByte (msg, ent->v->currentammo); @@ -1820,9 +1820,9 @@ void SV_SpawnServer (const char *server) // SV_ClearWorld (); - sv.sound_precache[0] = pr_strings; + sv.sound_precache[0] = ""; - sv.model_precache[0] = pr_strings; + sv.model_precache[0] = ""; sv.model_precache[1] = sv.modelname; for (i = 1;i < sv.worldmodel->numsubmodels;i++) { @@ -1836,7 +1836,7 @@ void SV_SpawnServer (const char *server) ent = EDICT_NUM(0); memset (ent->v, 0, progs->entityfields * 4); ent->free = false; - ent->v->model = sv.worldmodel->name - pr_strings; + ent->v->model = PR_SetString(sv.modelname); ent->v->modelindex = 1; // world model ent->v->solid = SOLID_BSP; ent->v->movetype = MOVETYPE_PUSH; @@ -1846,7 +1846,7 @@ void SV_SpawnServer (const char *server) else pr_global_struct->deathmatch = deathmatch.integer; - pr_global_struct->mapname = sv.name - pr_strings; + pr_global_struct->mapname = PR_SetString(sv.name); // serverflags are for cross level information (sigils) pr_global_struct->serverflags = svs.serverflags; diff --git a/sv_phys.c b/sv_phys.c index 2bb5b439..44daad48 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -103,12 +103,12 @@ void SV_CheckVelocity (edict_t *ent) { if (IS_NAN(ent->v->velocity[i])) { - Con_Printf ("Got a NaN velocity on %s\n", pr_strings + ent->v->classname); + Con_Printf ("Got a NaN velocity on %s\n", PR_GetString(ent->v->classname)); ent->v->velocity[i] = 0; } if (IS_NAN(ent->v->origin[i])) { - Con_Printf ("Got a NaN origin on %s\n", pr_strings + ent->v->classname); + Con_Printf ("Got a NaN origin on %s\n", PR_GetString(ent->v->classname)); ent->v->origin[i] = 0; } } -- 2.39.2