G
Geoff
I found this code in a Quake 2 project. Would you call this a case of
premature optimization or a case of single-returnitis in the face of a
necessarily multi-return function. I am referring to the multiple
gotos in the function designed to bypass a single line of code.
void TeamplaySpawnEntities (char *mapname, char *entities, char
*spawnpoint)
{
FILE *f;
char szFile[MAX_QPATH];
int nEntSize, nRead;
char *pszCustomEnt;
// If teamplay is off, do the normal thing.
if (!ctf->value)
{
SpawnEntities (mapname, entities, spawnpoint);
return;
}
// Create the pathname to the entity file.
Com_sprintf (szFile, sizeof (szFile), "%s/ent/%s.ent",
gamedir->string, mapname);
// Try to open it.
f = fopen (szFile, "rb");
if (!f)
{
// No custom entity file, so just use the default.
SpawnEntities (mapname, entities, spawnpoint);
return;
}
// Get the size of the file.
if (fseek (f, 0, SEEK_END) != 0)
{
gi.dprintf ("TeamplaySpawnEntities(): fseek %s\n", szFile);
goto errClose;
}
nEntSize = ftell (f);
if (nEntSize < 0)
{
gi.dprintf ("TeamplaySpawnEntities(): ftell %s (%d)\n",
szFile, nEntSize);
goto errClose;
}
if (fseek (f, 0, SEEK_SET) != 0)
{
gi.dprintf ("TeamplaySpawnEntities(): fseek %s\n", szFile);
goto errClose;
}
// Create a buffer and read the custom entity file.
pszCustomEnt = malloc (nEntSize + 1);
if (!pszCustomEnt)
{
gi.dprintf ("TeamplaySpawnEntities(): malloc\n");
goto errClose;
}
nRead = fread (pszCustomEnt, 1, nEntSize, f);
if (nRead != nEntSize)
{
gi.dprintf ("TeamplaySpawnEntities(): fread %s (%d/%d)\n",
szFile, nRead, nEntSize);
goto errFree;
}
// Null-terminate the string.
pszCustomEnt[nEntSize] = '\0';
// Now spawn *these* entities!
SpawnEntities (mapname, pszCustomEnt, spawnpoint);
// Clean up.
errFree:
free (pszCustomEnt);
errClose:
fclose (f);
}
premature optimization or a case of single-returnitis in the face of a
necessarily multi-return function. I am referring to the multiple
gotos in the function designed to bypass a single line of code.
void TeamplaySpawnEntities (char *mapname, char *entities, char
*spawnpoint)
{
FILE *f;
char szFile[MAX_QPATH];
int nEntSize, nRead;
char *pszCustomEnt;
// If teamplay is off, do the normal thing.
if (!ctf->value)
{
SpawnEntities (mapname, entities, spawnpoint);
return;
}
// Create the pathname to the entity file.
Com_sprintf (szFile, sizeof (szFile), "%s/ent/%s.ent",
gamedir->string, mapname);
// Try to open it.
f = fopen (szFile, "rb");
if (!f)
{
// No custom entity file, so just use the default.
SpawnEntities (mapname, entities, spawnpoint);
return;
}
// Get the size of the file.
if (fseek (f, 0, SEEK_END) != 0)
{
gi.dprintf ("TeamplaySpawnEntities(): fseek %s\n", szFile);
goto errClose;
}
nEntSize = ftell (f);
if (nEntSize < 0)
{
gi.dprintf ("TeamplaySpawnEntities(): ftell %s (%d)\n",
szFile, nEntSize);
goto errClose;
}
if (fseek (f, 0, SEEK_SET) != 0)
{
gi.dprintf ("TeamplaySpawnEntities(): fseek %s\n", szFile);
goto errClose;
}
// Create a buffer and read the custom entity file.
pszCustomEnt = malloc (nEntSize + 1);
if (!pszCustomEnt)
{
gi.dprintf ("TeamplaySpawnEntities(): malloc\n");
goto errClose;
}
nRead = fread (pszCustomEnt, 1, nEntSize, f);
if (nRead != nEntSize)
{
gi.dprintf ("TeamplaySpawnEntities(): fread %s (%d/%d)\n",
szFile, nRead, nEntSize);
goto errFree;
}
// Null-terminate the string.
pszCustomEnt[nEntSize] = '\0';
// Now spawn *these* entities!
SpawnEntities (mapname, pszCustomEnt, spawnpoint);
// Clean up.
errFree:
free (pszCustomEnt);
errClose:
fclose (f);
}