diff --git a/src/d_main.cpp b/src/d_main.cpp index 828545387e..f755409834 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -129,7 +129,7 @@ void D_CheckNetGame (); void D_ProcessEvents (); void G_BuildTiccmd (ticcmd_t* cmd); void D_DoAdvanceDemo (); -void D_AddWildFile (const char *pattern); +void D_AddWildFile (TArray &wadfiles, const char *pattern); // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- @@ -1478,27 +1478,22 @@ static const char *BaseFileSearch (const char *file, const char *ext, bool lookf // //========================================================================== -bool ConsiderPatches (const char *arg, const char *ext) +bool ConsiderPatches (const char *arg) { - bool noDef = false; - DArgs *files = Args->GatherFiles (arg, ext, false); + int i, argc; + FString *args; + const char *f; - if (files->NumArgs() > 0) + argc = Args->CheckParmList(arg, &args); + for (i = 0; i < argc; ++i) { - int i; - const char *f; - - for (i = 0; i < files->NumArgs(); ++i) + if ( (f = BaseFileSearch(args[i], ".deh")) || + (f = BaseFileSearch(args[i], ".bex")) ) { - if ( (f = BaseFileSearch (files->GetArg (i), ".deh")) ) - D_LoadDehFile(f); - else if ( (f = BaseFileSearch (files->GetArg (i), ".bex")) ) - D_LoadDehFile(f); + D_LoadDehFile(f); } - noDef = true; } - files->Destroy(); - return noDef; + return argc > 0; } //========================================================================== @@ -1591,40 +1586,18 @@ void D_MultiExec (DArgs *list, bool usePullin) static void GetCmdLineFiles(TArray &wadfiles) { - DArgs *files = Args->GatherFiles ("-file", ".wad", true); - DArgs *files1 = Args->GatherFiles (NULL, ".zip", false); - DArgs *files2 = Args->GatherFiles (NULL, ".pk3", false); - DArgs *files3 = Args->GatherFiles (NULL, ".txt", false); - if (files->NumArgs() > 0 || files1->NumArgs() > 0 || files2->NumArgs() > 0 || files3->NumArgs() > 0) - { - // Check for -file in shareware - if (gameinfo.flags & GI_SHAREWARE) - { - I_FatalError ("You cannot -file with the shareware version. Register!"); - } + FString *args; + int i, argc; - // the files gathered are wadfile/lump names - for (int i = 0; i < files->NumArgs(); i++) - { - D_AddWildFile (wadfiles, files->GetArg (i)); - } - for (int i = 0; i < files1->NumArgs(); i++) - { - D_AddWildFile (wadfiles, files1->GetArg (i)); - } - for (int i = 0; i < files2->NumArgs(); i++) - { - D_AddWildFile (wadfiles, files2->GetArg (i)); - } - for (int i = 0; i < files3->NumArgs(); i++) - { - D_AddWildFile (wadfiles, files3->GetArg (i)); - } + argc = Args->CheckParmList("-file", &args); + if ((gameinfo.flags & GI_SHAREWARE) && argc > 0) + { + I_FatalError ("You cannot -file with the shareware version. Register!"); + } + for (i = 0; i < argc; ++i) + { + D_AddWildFile(wadfiles, args[i]); } - files->Destroy(); - files1->Destroy(); - files2->Destroy(); - files3->Destroy(); } static void CopyFiles(TArray &to, TArray &from) @@ -1757,6 +1730,8 @@ void D_DoomMain (void) const char *wad; DArgs *execFiles; TArray pwads; + FString *args; + int argcount; // Set the FPU precision to 53 significant bits. This is the default // for Visual C++, but not for GCC, so some slight math variances @@ -1775,6 +1750,13 @@ void D_DoomMain (void) #endif #endif + // 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 + PClass::StaticInit (); atterm (C_DeinitConsole); @@ -1859,12 +1841,10 @@ void D_DoomMain (void) execFiles = new DArgs; GameConfig->AddAutoexec (execFiles, GameNames[gameinfo.gametype]); D_MultiExec (execFiles, true); - execFiles->Destroy(); // Run .cfg files at the start of the command line. - execFiles = Args->GatherFiles (NULL, ".cfg", false); + execFiles = Args->GatherFiles ("-exec"); D_MultiExec (execFiles, true); - execFiles->Destroy(); C_ExecCmdLineParams (); // [RH] do all +set commands on the command line @@ -1999,10 +1979,10 @@ void D_DoomMain (void) #endif // turbo option // [RH] (now a cvar) + v = Args->CheckValue("-turbo"); + if (v != NULL) { - double amt; - const char *value = Args->CheckValue("-turbo"); - amt = value != NULL ? atof(value) : 100; + double amt = atof(v); Printf ("turbo scale: %.0f%%\n", amt); turbo = (float)amt; } @@ -2082,7 +2062,7 @@ void D_DoomMain (void) // If there are none, try adding any in the config file. // Note that the command line overrides defaults from the config. - if ((ConsiderPatches("-deh", ".deh") | ConsiderPatches("-bex", ".bex")) == 0 && + if ((ConsiderPatches("-deh") | ConsiderPatches("-bex")) == 0 && gameinfo.gametype == GAME_Doom && GameConfig->SetSection ("Doom.DefaultDehacked")) { const char *key; @@ -2120,10 +2100,10 @@ void D_DoomMain (void) } //Added by MC: - DArgs *bots = Args->GatherFiles("-bots", "", false); - for (p = 0; p < bots->NumArgs(); ++p) + argcount = Args->CheckParmList("-bots", &args); + for (p = 0; p < argcount; ++p) { - bglobal.getspawned.Push(bots->GetArg(p)); + bglobal.getspawned.Push(args[p]); } bglobal.spawn_tries = 0; bglobal.wanted_botnum = bglobal.getspawned.Size(); @@ -2173,14 +2153,13 @@ void D_DoomMain (void) V_Init2(); - DArgs *files = Args->GatherFiles ("-playdemo", ".lmp", false); - if (files->NumArgs() > 0) + v = Args->CheckValue("-playdemo"); + if (v != NULL) { singledemo = true; // quit after one demo - G_DeferedPlayDemo (files->GetArg (0)); + G_DeferedPlayDemo (v); D_DoomLoop (); // never returns } - files->Destroy(); v = Args->CheckValue ("-timedemo"); if (v) diff --git a/src/m_argv.cpp b/src/m_argv.cpp index b45315eeb5..5dbdc4d3de 100644 --- a/src/m_argv.cpp +++ b/src/m_argv.cpp @@ -70,6 +70,19 @@ DArgs::DArgs(int argc, char **argv) SetArgs(argc, argv); } +//=========================================================================== +// +// DArgs String Argv Constructor +// +//=========================================================================== + +DArgs::DArgs(int argc, FString *argv) +{ + AppendArgs(argc, argv); +} + + + //=========================================================================== // // DArgs Copy Operator @@ -129,6 +142,41 @@ int DArgs::CheckParm(const char *check, int start) const return 0; } +//=========================================================================== +// +// DArgs :: CheckParmList +// +// Returns the number of arguments after the parameter (if found) and also +// returns a pointer to the first argument. +// +//=========================================================================== + +int DArgs::CheckParmList(const char *check, FString **strings, int start) const +{ + unsigned int i, parmat = CheckParm(check, start); + + if (parmat == 0) + { + if (strings != NULL) + { + *strings = NULL; + } + return 0; + } + for (i = ++parmat; i < Argv.Size(); ++i) + { + if (Argv[i][0] == '-' || Argv[i][1] == '+') + { + break; + } + } + if (strings != NULL) + { + *strings = &Argv[parmat]; + } + return i - parmat; +} + //=========================================================================== // // DArgs :: CheckValue @@ -167,15 +215,17 @@ FString DArgs::TakeValue(const char *check) int i = CheckParm(check); FString out; - if (i > 0 && i < (int)Argv.Size() - 1 && - Argv[i+1][0] != '+' && Argv[i+1][0] != '-') + if (i > 0 && i < (int)Argv.Size()) { - out = Argv[i+1]; - Argv.Delete(i, 2); // Delete the parm and its value. - } - else - { - Argv.Delete(i); // Just delete the parm, since it has no value. + if (i < (int)Argv.Size() - 1 && Argv[i+1][0] != '+' && Argv[i+1][0] != '-') + { + out = Argv[i+1]; + Argv.Delete(i, 2); // Delete the parm and its value. + } + else + { + Argv.Delete(i); // Just delete the parm, since it has no value. + } } return out; } @@ -234,53 +284,102 @@ void DArgs::AppendArg(FString arg) //=========================================================================== // -// DArgs :: GatherFiles +// DArgs :: AppendArgs +// +// Adds an array of FStrings to argv. // //=========================================================================== -DArgs *DArgs::GatherFiles (const char *param, const char *extension, bool acceptNoExt) const +void DArgs::AppendArgs(int argc, const FString *argv) { + if (argv != NULL && argc > 0) + { + Argv.Grow(argc); + for (int i = 0; i < argc; ++i) + { + Argv.Push(argv[i]); + } + } +} + +//=========================================================================== +// +// DArgs :: CollectFiles +// +// Takes all arguments after any instance of -param and any arguments before +// all switches that end in .extension and combines them into a single +// -switch block at the end of the arguments. If extension is NULL, then +// every parameter before the first switch is added after this -param. +// +//=========================================================================== + +void DArgs::CollectFiles(const char *param, const char *extension) +{ + TArray work; DArgs *out = new DArgs; unsigned int i; - size_t extlen = strlen (extension); + size_t extlen = extension == NULL ? 0 : strlen(extension); - if (extlen > 0) + // Step 1: Find suitable arguments before the first switch. + i = 1; + while (i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+') { - for (i = 1; i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+'; i++) - { + bool useit; + + if (extlen > 0) + { // Argument's extension must match. size_t len = Argv[i].Len(); - if (len >= extlen && stricmp(&Argv[i][0] + len - extlen, extension) == 0) - { - out->AppendArg(Argv[i]); - } - else if (acceptNoExt) - { - const char *src = &Argv[i][0] + len - 1; - - while (src != Argv[i] && *src != '/' - #ifdef _WIN32 - && *src != '\\' - #endif - ) - { - if (*src == '.') - goto morefor; // it has an extension - src--; - } - out->AppendArg(Argv[i]); -morefor: - ; - } + useit = (len >= extlen && stricmp(&Argv[i][len - extlen], extension) == 0); } - } - if (param != NULL) - { - i = 1; - while (0 != (i = CheckParm (param, i))) + else + { // Anything will do so long as it's before the first switch. + useit = true; + } + if (useit) { - for (++i; i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+'; ++i) - out->Argv.Push(Argv[i]); + work.Push(Argv[i]); + Argv.Delete(i); + } + else + { + i++; } } - return out; + + // Step 2: Find each occurence of -param and add its arguments to work. + while ((i = CheckParm(param, i)) > 0) + { + Argv.Delete(i); + while (i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+') + { + work.Push(Argv[i]); + Argv.Delete(i); + } + } + + // Step 3: Add work back to Argv, as long as it's non-empty. + if (work.Size() > 0) + { + Argv.Push(param); + AppendArgs(work.Size(), &work[0]); + } +} + +//=========================================================================== +// +// DArgs :: GatherFiles +// +// Returns all the arguments after the first instance of -param. If you want +// to combine more than one or get switchless stuff included, you need to +// call CollectFiles first. +// +//=========================================================================== + +DArgs *DArgs::GatherFiles(const char *param) const +{ + FString *files; + int filecount; + + filecount = CheckParmList(param, &files); + return new DArgs(filecount, files); } diff --git a/src/m_argv.h b/src/m_argv.h index 83f86a517f..b2a432edb2 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -47,17 +47,19 @@ public: DArgs(); DArgs(const DArgs &args); DArgs(int argc, char **argv); + DArgs(int argc, FString *argv); DArgs &operator=(const DArgs &other); void AppendArg(FString arg); + void AppendArgs(int argc, const FString *argv); void SetArgs(int argc, char **argv); - DArgs *GatherFiles(const char *param, const char *extension, bool acceptNoExt) const; + void CollectFiles(const char *param, const char *extension); + DArgs *GatherFiles(const char *param) const; void SetArg(int argnum, const char *arg); - // Returns the position of the given parameter - // in the arg list (0 if not found). - int CheckParm(const char *check, int start=1) const; + int CheckParm(const char *check, int start=1) const; // Returns the position of the given parameter in the arg list (0 if not found). + int CheckParmList(const char *check, FString **strings, int start=1) const; const char *CheckValue(const char *check) const; const char *GetArg(int arg) const; FString *GetArgList(int arg) const;