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

View File

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

View File

@ -150,29 +150,38 @@ int M_ReadFile (char const *name, BYTE **buffer)
void M_FindResponseFile (void) 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 **argv;
char *file; char *file = NULL;
int argc; int argc = 0;
FILE *handle; FILE *handle;
int size; int size;
long argsize; long argsize;
int k;
int index; int index;
// Any more response files after the limit will be removed from the
// command line.
if (added_stuff < limit)
{
// READ THE RESPONSE FILE INTO MEMORY // READ THE RESPONSE FILE INTO MEMORY
handle = fopen (Args->GetArg(i) + 1,"rb"); handle = fopen (Args->GetArg(i) + 1,"rb");
if (!handle) if (!handle)
{ // [RH] Make this a warning, not an error. { // [RH] Make this a warning, not an error.
Printf ("No such response file (%s)!", Args->GetArg(i) + 1); Printf ("No such response file (%s)!\n", Args->GetArg(i) + 1);
continue;
} }
else
{
Printf ("Found response file %s!\n", Args->GetArg(i) + 1); Printf ("Found response file %s!\n", Args->GetArg(i) + 1);
fseek (handle, 0, SEEK_END); fseek (handle, 0, SEEK_END);
size = ftell (handle); size = ftell (handle);
@ -183,7 +192,12 @@ void M_FindResponseFile (void)
fclose (handle); fclose (handle);
argsize = ParseCommandLine (file, &argc, NULL); argsize = ParseCommandLine (file, &argc, NULL);
argc = Args->NumArgs() - 1; }
}
else
{
Printf ("Ignored response file %s.\n", Args->GetArg(i) + 1);
}
if (argc != 0) if (argc != 0)
{ {
@ -199,27 +213,39 @@ void M_FindResponseFile (void)
newargs->AppendArg(Args->GetArg(index)); newargs->AppendArg(Args->GetArg(index));
// Copy parameters from response file. // Copy parameters from response file.
for (index = 0; index < argc; ++i) for (index = 0; index < argc; ++index)
newargs->AppendArg(argv[index]); newargs->AppendArg(argv[index]);
// Copy parameters after response file. // 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)); newargs->AppendArg(Args->GetArg(index));
// Use the new argument vector as the global Args object. // Use the new argument vector as the global Args object.
Args = newargs; 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 // ParseCommandLine

View File

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