- Response file improvements:

* Fixed: Trying to use a response file would result in infinite looping until memory was
    exhausted.
  * Fixed: Response files were read after coalescing file parameters, which would lead to
    non-coalesced parameters if the original command line and response file both had them.
  * You can now use more than one response file.
  * Response files can include other response files.

SVN r2334 (trunk)
This commit is contained in:
Randy Heit 2010-05-25 02:30:05 +00:00
parent adcf26d2b5
commit 61d2a808d7
5 changed files with 84 additions and 39 deletions

View File

@ -1753,12 +1753,15 @@ void D_DoomMain (void)
#endif
#endif
// Check response files before coalescing file parameters.
M_FindResponseFile ();
// Combine different file parameters with their pre-switch bits.
Args->CollectFiles("-deh", ".deh");
Args->CollectFiles("-bex", ".bex");
Args->CollectFiles("-exec", ".cfg");
Args->CollectFiles("-playdemo", ".lmp");
Args->CollectFiles("-file", NULL); // anythnig left goes after -file
Args->CollectFiles("-file", NULL); // anything left goes after -file
PClass::StaticInit ();
atterm (C_DeinitConsole);
@ -1769,7 +1772,6 @@ void D_DoomMain (void)
rngseed = I_MakeRNGSeed();
FRandom::StaticClearRandom ();
M_FindResponseFile ();
Printf ("M_LoadDefaults: Load system defaults.\n");
M_LoadDefaults (); // load before initing other systems

View File

@ -302,6 +302,19 @@ void DArgs::AppendArgs(int argc, const FString *argv)
}
}
//===========================================================================
//
// DArgs :: RemoveArg
//
// Removes a single argument from argv.
//
//===========================================================================
void DArgs::RemoveArg(int argindex)
{
Argv.Delete(argindex);
}
//===========================================================================
//
// DArgs :: CollectFiles

View File

@ -53,6 +53,7 @@ public:
void AppendArg(FString arg);
void AppendArgs(int argc, const FString *argv);
void RemoveArg(int argindex);
void SetArgs(int argc, char **argv);
void CollectFiles(const char *param, const char *extension);
DArgs *GatherFiles(const char *param) const;

View File

@ -150,40 +150,54 @@ int M_ReadFile (char const *name, BYTE **buffer)
void M_FindResponseFile (void)
{
int i;
const int limit = 100; // avoid infinite recursion
int added_stuff = 0;
int i = 1;
for (i = 1; i < Args->NumArgs(); i++)
while (i < Args->NumArgs())
{
if (Args->GetArg(i)[0] == '@')
if (Args->GetArg(i)[0] != '@')
{
i++;
}
else
{
char **argv;
char *file;
int argc;
char *file = NULL;
int argc = 0;
FILE *handle;
int size;
long argsize;
int k;
int index;
// READ THE RESPONSE FILE INTO MEMORY
handle = fopen (Args->GetArg(i) + 1,"rb");
if (!handle)
{ // [RH] Make this a warning, not an error.
Printf ("No such response file (%s)!", Args->GetArg(i) + 1);
continue;
// Any more response files after the limit will be removed from the
// command line.
if (added_stuff < limit)
{
// READ THE RESPONSE FILE INTO MEMORY
handle = fopen (Args->GetArg(i) + 1,"rb");
if (!handle)
{ // [RH] Make this a warning, not an error.
Printf ("No such response file (%s)!\n", Args->GetArg(i) + 1);
}
else
{
Printf ("Found response file %s!\n", Args->GetArg(i) + 1);
fseek (handle, 0, SEEK_END);
size = ftell (handle);
fseek (handle, 0, SEEK_SET);
file = new char[size+1];
fread (file, size, 1, handle);
file[size] = 0;
fclose (handle);
argsize = ParseCommandLine (file, &argc, NULL);
}
}
else
{
Printf ("Ignored response file %s.\n", Args->GetArg(i) + 1);
}
Printf ("Found response file %s!\n", Args->GetArg(i) + 1);
fseek (handle, 0, SEEK_END);
size = ftell (handle);
fseek (handle, 0, SEEK_SET);
file = new char[size+1];
fread (file, size, 1, handle);
file[size] = 0;
fclose (handle);
argsize = ParseCommandLine (file, &argc, NULL);
argc = Args->NumArgs() - 1;
if (argc != 0)
{
@ -199,27 +213,39 @@ void M_FindResponseFile (void)
newargs->AppendArg(Args->GetArg(index));
// Copy parameters from response file.
for (index = 0; index < argc; ++i)
for (index = 0; index < argc; ++index)
newargs->AppendArg(argv[index]);
// Copy parameters after response file.
for (index = i + 1, i = newargs->NumArgs(); index < Args->NumArgs(); ++index)
for (index = i + 1; index < Args->NumArgs(); ++index)
newargs->AppendArg(Args->GetArg(index));
// Use the new argument vector as the global Args object.
Args = newargs;
if (++added_stuff == limit)
{
Printf("Response file limit of %d hit.\n", limit);
}
}
else
{
// Remove the response file from the Args object
Args->RemoveArg(i);
}
if (file != NULL)
{
delete[] file;
}
delete[] file;
// DISPLAY ARGS
Printf ("%d command-line args:\n", Args->NumArgs ());
for (k = 1; k < Args->NumArgs (); k++)
Printf ("%s\n", Args->GetArg (k));
break;
}
}
if (added_stuff > 0)
{
// DISPLAY ARGS
Printf ("Added %d response file%s, now have %d command-line args:\n",
added_stuff, added_stuff > 1 ? "s" : "", Args->NumArgs ());
for (int k = 1; k < Args->NumArgs (); k++)
Printf ("%s\n", Args->GetArg (k));
}
}
// ParseCommandLine

View File

@ -159,10 +159,13 @@ public:
void Delete (unsigned int index, int deletecount)
{
if (index + deletecount > Count) deletecount = Count - index;
if (index + deletecount > Count)
{
deletecount = Count - index;
}
if (deletecount > 0)
{
for(int i = 0; i < deletecount; i++)
for (int i = 0; i < deletecount; i++)
{
Array[index + i].~T();
}