From 5da2885d880d94924c667c074baed557a1a90fd7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 2 Mar 2010 04:51:16 +0000 Subject: [PATCH] - Changed DArgs to use a TArray of FStrings instead of doing its own string vector management in preparation for doing GatherFiles the "right" way. SVN r2183 (trunk) --- src/c_dispatch.cpp | 26 ++++ src/c_dispatch.h | 1 + src/d_main.cpp | 33 +++-- src/g_game.cpp | 10 +- src/g_game.h | 6 +- src/gameconfigfile.cpp | 5 +- src/i_net.cpp | 23 ++-- src/m_argv.cpp | 278 +++++++++++++++++++++++++++-------------- src/m_argv.h | 38 +++--- src/m_misc.cpp | 28 +++-- src/r_things.cpp | 2 +- src/v_video.cpp | 2 +- src/win32/i_system.cpp | 2 +- 13 files changed, 284 insertions(+), 170 deletions(-) diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 5ebe450b64..2fbafd2a95 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -1035,6 +1035,32 @@ FString BuildString (int argc, char **argv) } } +FString BuildString (int argc, FString *argv) +{ + if (argc == 1) + { + return *argv; + } + else + { + FString buf; + int arg; + + for (arg = 0; arg < argc; arg++) + { + if (strchr (argv[arg], ' ')) + { + buf << '"' << argv[arg] << "\" "; + } + else + { + buf << argv[arg] << ' '; + } + } + return buf; + } +} + //=========================================================================== // // SubstituteAliasParams diff --git a/src/c_dispatch.h b/src/c_dispatch.h index cde53996a9..fb76f1aee0 100644 --- a/src/c_dispatch.h +++ b/src/c_dispatch.h @@ -59,6 +59,7 @@ void C_SetAlias (const char *name, const char *cmd); // build a single string out of multiple strings FString BuildString (int argc, char **argv); +FString BuildString (int argc, FString *argv); // Class that can parse command lines class FCommandLine diff --git a/src/d_main.cpp b/src/d_main.cpp index 534f30afe5..828545387e 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1753,7 +1753,7 @@ static FString CheckGameInfo(TArray & pwads) void D_DoomMain (void) { int p, flags; - char *v; + const char *v; const char *wad; DArgs *execFiles; TArray pwads; @@ -1965,21 +1965,23 @@ void D_DoomMain (void) autostart = true; } - // [RH] Hack to handle +map - p = Args->CheckParm ("+map"); - if (p && p < Args->NumArgs()-1) + // [RH] Hack to handle +map. The standard console command line handler + // won't be able to handle it, so we take it out of the command line and set + // it up like -warp. + FString mapvalue = Args->TakeValue("+map"); + if (mapvalue.IsNotEmpty()) { - if (!P_CheckMapData(Args->GetArg (p+1))) + if (!P_CheckMapData(mapvalue)) { - Printf ("Can't find map %s\n", Args->GetArg (p+1)); + Printf ("Can't find map %s\n", mapvalue.GetChars()); } else { - startmap = Args->GetArg (p + 1); - Args->GetArg (p)[0] = '-'; + startmap = mapvalue; autostart = true; } } + if (devparm) { Printf ("%s", GStrings("D_DEVSTR")); @@ -1998,16 +2000,11 @@ void D_DoomMain (void) // turbo option // [RH] (now a cvar) { - UCVarValue value; - static char one_hundred[] = "100"; - - value.String = Args->CheckValue ("-turbo"); - if (value.String == NULL) - value.String = one_hundred; - else - Printf ("turbo scale: %s%%\n", value.String); - - turbo.SetGenericRepDefault (value, CVAR_String); + double amt; + const char *value = Args->CheckValue("-turbo"); + amt = value != NULL ? atof(value) : 100; + Printf ("turbo scale: %.0f%%\n", amt); + turbo = (float)amt; } v = Args->CheckValue ("-timer"); diff --git a/src/g_game.cpp b/src/g_game.cpp index dc576c2fcf..e9a4d4f1ef 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2189,18 +2189,14 @@ void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf) // // G_RecordDemo // -void G_RecordDemo (char* name) +void G_RecordDemo (const char* name) { - char *v; - usergame = false; strcpy (demoname, name); FixPathSeperator (demoname); DefaultExtension (demoname, ".lmp"); - v = Args->CheckValue ("-maxdemo"); maxdemosize = 0x20000; demobuffer = (BYTE *)M_Malloc (maxdemosize); - demorecording = true; } @@ -2285,7 +2281,7 @@ void G_BeginRecording (const char *startmap) FString defdemoname; -void G_DeferedPlayDemo (char *name) +void G_DeferedPlayDemo (const char *name) { defdemoname = name; gameaction = ga_playdemo; @@ -2513,7 +2509,7 @@ void G_DoPlayDemo (void) // // G_TimeDemo // -void G_TimeDemo (char* name) +void G_TimeDemo (const char* name) { nodrawers = !!Args->CheckParm ("-nodraw"); noblit = !!Args->CheckParm ("-noblit"); diff --git a/src/g_game.h b/src/g_game.h index 72afcd3c56..56f16081be 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -32,7 +32,7 @@ struct PNGHandle; // void G_DeathMatchSpawnPlayer (int playernum); -void G_DeferedPlayDemo (char* demo); +void G_DeferedPlayDemo (const char* demo); // Can be called by the startup code or M_Responder, // calls P_SetupLevel or W_EnterWorld. @@ -44,12 +44,12 @@ void G_DoLoadGame (void); void G_SaveGame (const char *filename, const char *description); // Only called by startup code. -void G_RecordDemo (char* name); +void G_RecordDemo (const char* name); void G_BeginRecording (const char *startmap); void G_PlayDemo (char* name); -void G_TimeDemo (char* name); +void G_TimeDemo (const char* name); bool G_CheckDemoStatus (void); void G_WorldDone (void); diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index e9f90a23d5..936d4e7f75 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -536,13 +536,14 @@ void FGameConfigFile::ArchiveGlobalData () FString FGameConfigFile::GetConfigPath (bool tryProg) { - char *pathval; + const char *pathval; FString path; pathval = Args->CheckValue ("-config"); if (pathval != NULL) + { return FString(pathval); - + } #ifdef _WIN32 path = NULL; HRESULT hr; diff --git a/src/i_net.cpp b/src/i_net.cpp index 3ff86f7ece..633c75d1a2 100644 --- a/src/i_net.cpp +++ b/src/i_net.cpp @@ -338,20 +338,21 @@ void PreSend (const void *buffer, int bufferlen, const sockaddr_in *to) sendto (mysocket, (const char *)buffer, bufferlen, 0, (const sockaddr *)to, sizeof(*to)); } -void BuildAddress (sockaddr_in *address, char *name) +void BuildAddress (sockaddr_in *address, const char *name) { hostent *hostentry; // host information entry u_short port; - char *portpart; + const char *portpart; bool isnamed = false; int curchar; char c; + FString target; address->sin_family = AF_INET; if ( (portpart = strchr (name, ':')) ) { - *portpart = 0; + target = FString(name, portpart - name); port = atoi (portpart + 1); if (!port) { @@ -361,11 +362,12 @@ void BuildAddress (sockaddr_in *address, char *name) } else { + target = name; port = DOOMPORT; } address->sin_port = htons(port); - for (curchar = 0; (c = name[curchar]) ; curchar++) + for (curchar = 0; (c = target[curchar]) ; curchar++) { if ((c < '0' || c > '9') && c != '.') { @@ -376,21 +378,18 @@ void BuildAddress (sockaddr_in *address, char *name) if (!isnamed) { - address->sin_addr.s_addr = inet_addr (name); - Printf ("Node number %d, address %s\n", doomcom.numnodes, name); + address->sin_addr.s_addr = inet_addr (target); + Printf ("Node number %d, address %s\n", doomcom.numnodes, target.GetChars()); } else { - hostentry = gethostbyname (name); + hostentry = gethostbyname (target); if (!hostentry) - I_FatalError ("gethostbyname: couldn't find %s\n%s", name, neterror()); + I_FatalError ("gethostbyname: couldn't find %s\n%s", target.GetChars(), neterror()); address->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; Printf ("Node number %d, hostname %s\n", doomcom.numnodes, hostentry->h_name); } - - if (portpart) - *portpart = ':'; } void CloseNetwork (void) @@ -910,7 +909,7 @@ static bool NodesOnSameNetwork() bool I_InitNetwork (void) { int i; - char *v; + const char *v; memset (&doomcom, 0, sizeof(doomcom)); diff --git a/src/m_argv.cpp b/src/m_argv.cpp index 155374c60a..b45315eeb5 100644 --- a/src/m_argv.cpp +++ b/src/m_argv.cpp @@ -38,138 +38,226 @@ IMPLEMENT_CLASS (DArgs) -DArgs::DArgs () +//=========================================================================== +// +// DArgs Default Constructor +// +//=========================================================================== + +DArgs::DArgs() { - m_ArgC = 0; - m_ArgV = NULL; } -DArgs::DArgs (int argc, char **argv) +//=========================================================================== +// +// DArgs Copy Constructor +// +//=========================================================================== + +DArgs::DArgs(const DArgs &other) { - CopyArgs (argc, argv); + Argv = other.Argv; } -DArgs::DArgs (const DArgs &other) +//=========================================================================== +// +// DArgs Argv Constructor +// +//=========================================================================== + +DArgs::DArgs(int argc, char **argv) { - CopyArgs (other.m_ArgC, other.m_ArgV); + SetArgs(argc, argv); } +//=========================================================================== +// +// DArgs Copy Operator +// +//=========================================================================== -DArgs::~DArgs () +DArgs &DArgs::operator=(const DArgs &other) { - FlushArgs (); -} - -DArgs &DArgs::operator= (const DArgs &other) -{ - FlushArgs (); - CopyArgs (other.m_ArgC, other.m_ArgV); + Argv = other.Argv; return *this; } -void DArgs::SetArgs (int argc, char **argv) -{ - FlushArgs (); - CopyArgs (argc, argv); -} - -void DArgs::CopyArgs (int argc, char **argv) -{ - int i; - - m_ArgC = argc; - m_ArgV = new char *[argc]; - for (i = 0; i < argc; i++) - m_ArgV[i] = copystring (argv[i]); -} - -void DArgs::FlushArgs () -{ - int i; - - for (i = 0; i < m_ArgC; i++) - delete[] m_ArgV[i]; - delete[] m_ArgV; - m_ArgC = 0; - m_ArgV = NULL; -} - +//=========================================================================== +// +// DArgs :: SetArgs +// +//=========================================================================== + +void DArgs::SetArgs(int argc, char **argv) +{ + Argv.Resize(argc); + for (int i = 0; i < argc; ++i) + { + Argv[i] = argv[i]; + } +} + +//=========================================================================== +// +// DArgs :: FlushArgs +// +//=========================================================================== + +void DArgs::FlushArgs() +{ + Argv.Clear(); +} + +//=========================================================================== +// +// DArgs :: CheckParm // -// CheckParm // Checks for the given parameter in the program's command line arguments. // Returns the argument number (1 to argc-1) or 0 if not present // -int DArgs::CheckParm (const char *check, int start) const -{ - for (int i = start; i < m_ArgC; ++i) - if (!stricmp (check, m_ArgV[i])) - return i; +//=========================================================================== +int DArgs::CheckParm(const char *check, int start) const +{ + for (unsigned i = start; i < Argv.Size(); ++i) + { + if (0 == stricmp(check, Argv[i])) + { + return i; + } + } return 0; } -char *DArgs::CheckValue (const char *check) const -{ - int i = CheckParm (check); +//=========================================================================== +// +// DArgs :: CheckValue +// +// Like CheckParm, but it also checks that the parameter has a value after +// it and returns that or NULL if not present. +// +//=========================================================================== - if (i > 0 && i < m_ArgC - 1) - return m_ArgV[i+1][0] != '+' && m_ArgV[i+1][0] != '-' ? m_ArgV[i+1] : NULL; - else - return NULL; -} - -char *DArgs::GetArg (int arg) const +const char *DArgs::CheckValue(const char *check) const { - if (arg >= 0 && arg < m_ArgC) - return m_ArgV[arg]; - else - return NULL; -} + int i = CheckParm(check); -char **DArgs::GetArgList (int arg) const -{ - if (arg >= 0 && arg < m_ArgC) - return &m_ArgV[arg]; - else - return NULL; -} - -int DArgs::NumArgs () const -{ - return m_ArgC; -} - -void DArgs::AppendArg (const char *arg) -{ - char **temp = new char *[m_ArgC + 1]; - if (m_ArgV) + if (i > 0 && i < (int)Argv.Size() - 1) { - memcpy (temp, m_ArgV, sizeof(*m_ArgV) * m_ArgC); - delete[] m_ArgV; + i++; + return Argv[i][0] != '+' && Argv[i][0] != '-' ? Argv[i].GetChars() : NULL; + } + else + { + return NULL; } - temp[m_ArgC] = copystring (arg); - m_ArgV = temp; - m_ArgC++; } +//=========================================================================== +// +// DArgs :: TakeValue +// +// Like CheckValue, except it also removes the parameter and its argument +// (if present) from argv. +// +//=========================================================================== + +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] != '-') + { + 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; +} + +//=========================================================================== +// +// DArgs :: GetArg +// +// Gets the argument at a particular position. +// +//=========================================================================== + +const char *DArgs::GetArg(int arg) const +{ + return ((unsigned)arg < Argv.Size()) ? Argv[arg].GetChars() : NULL; + return Argv[arg]; +} + +//=========================================================================== +// +// DArgs :: GetArgList +// +// Returns a pointer to the FString at a particular position. +// +//=========================================================================== + +FString *DArgs::GetArgList(int arg) const +{ + return ((unsigned)arg < Argv.Size()) ? &Argv[arg] : NULL; +} + +//=========================================================================== +// +// DArgs :: NumArgs +// +//=========================================================================== + +int DArgs::NumArgs() const +{ + return (int)Argv.Size(); +} + +//=========================================================================== +// +// DArgs :: AppendArg +// +// Adds another argument to argv. Invalidates any previous results from +// GetArgList(). +// +//=========================================================================== + +void DArgs::AppendArg(FString arg) +{ + Argv.Push(arg); +} + +//=========================================================================== +// +// DArgs :: GatherFiles +// +//=========================================================================== + DArgs *DArgs::GatherFiles (const char *param, const char *extension, bool acceptNoExt) const { DArgs *out = new DArgs; - int i; + unsigned int i; size_t extlen = strlen (extension); if (extlen > 0) { - for (i = 1; i < m_ArgC && *m_ArgV[i] != '-' && *m_ArgV[i] != '+'; i++) + for (i = 1; i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+'; i++) { - size_t len = strlen (m_ArgV[i]); - if (len >= extlen && stricmp (m_ArgV[i] + len - extlen, extension) == 0) - out->AppendArg (m_ArgV[i]); + 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 = m_ArgV[i] + len - 1; + const char *src = &Argv[i][0] + len - 1; - while (src != m_ArgV[i] && *src != '/' + while (src != Argv[i] && *src != '/' #ifdef _WIN32 && *src != '\\' #endif @@ -179,7 +267,7 @@ DArgs *DArgs::GatherFiles (const char *param, const char *extension, bool accept goto morefor; // it has an extension src--; } - out->AppendArg (m_ArgV[i]); + out->AppendArg(Argv[i]); morefor: ; } @@ -190,8 +278,8 @@ morefor: i = 1; while (0 != (i = CheckParm (param, i))) { - for (++i; i < m_ArgC && *m_ArgV[i] != '-' && *m_ArgV[i] != '+'; ++i) - out->AppendArg (m_ArgV[i]); + for (++i; i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+'; ++i) + out->Argv.Push(Argv[i]); } } return out; diff --git a/src/m_argv.h b/src/m_argv.h index b0d44076ae..83f86a517f 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -35,40 +35,38 @@ #define __M_ARGV_H__ #include "dobject.h" +#include "zstring.h" // // MISC // class DArgs : public DObject { - DECLARE_CLASS (DArgs, DObject) + DECLARE_CLASS(DArgs, DObject) public: - DArgs (); - DArgs (const DArgs &args); - DArgs (int argc, char **argv); - ~DArgs (); + DArgs(); + DArgs(const DArgs &args); + DArgs(int argc, char **argv); - DArgs &operator= (const DArgs &other); + DArgs &operator=(const DArgs &other); - void AppendArg (const char *arg); - void SetArgs (int argc, char **argv); - DArgs *GatherFiles (const char *param, const char *extension, bool acceptNoExt) const; - void SetArg (int argnum, const char *arg); + void AppendArg(FString arg); + void SetArgs(int argc, char **argv); + DArgs *GatherFiles(const char *param, const char *extension, bool acceptNoExt) 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; - char *CheckValue (const char *check) const; - char *GetArg (int arg) const; - char **GetArgList (int arg) const; - int NumArgs () const; - void FlushArgs (); + int CheckParm(const char *check, int start=1) const; + const char *CheckValue(const char *check) const; + const char *GetArg(int arg) const; + FString *GetArgList(int arg) const; + FString TakeValue(const char *check); + int NumArgs() const; + void FlushArgs(); private: - int m_ArgC; - char **m_ArgV; - - void CopyArgs (int argc, char **argv); + TArray Argv; }; extern DArgs *Args; diff --git a/src/m_misc.cpp b/src/m_misc.cpp index e973a4ca97..c828a965a0 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -159,7 +159,6 @@ void M_FindResponseFile (void) char **argv; char *file; int argc; - int argcinresp; FILE *handle; int size; long argsize; @@ -183,23 +182,32 @@ void M_FindResponseFile (void) file[size] = 0; fclose (handle); - argsize = ParseCommandLine (file, &argcinresp, NULL); - argc = argcinresp + Args->NumArgs() - 1; + argsize = ParseCommandLine (file, &argc, NULL); + argc = Args->NumArgs() - 1; if (argc != 0) { argv = (char **)M_Malloc (argc*sizeof(char *) + argsize); - argv[i] = (char *)argv + argc*sizeof(char *); - ParseCommandLine (file, NULL, argv+i); + argv[0] = (char *)argv + argc*sizeof(char *); + ParseCommandLine (file, NULL, argv); + // Create a new argument vector + DArgs *newargs = new DArgs; + + // Copy parameters before response file. for (index = 0; index < i; ++index) - argv[index] = Args->GetArg (index); + newargs->AppendArg(Args->GetArg(index)); - for (index = i + 1, i += argcinresp; index < Args->NumArgs (); ++index) - argv[i++] = Args->GetArg (index); + // Copy parameters from response file. + for (index = 0; index < argc; ++i) + newargs->AppendArg(argv[index]); - Args->Destroy(); - Args = new DArgs(i, argv); + // Copy parameters after response file. + for (index = i + 1, i = newargs->NumArgs(); index < Args->NumArgs(); ++index) + newargs->AppendArg(Args->GetArg(index)); + + // Use the new argument vector as the global Args object. + Args = newargs; } delete[] file; diff --git a/src/r_things.cpp b/src/r_things.cpp index a2f18de5fa..5815ca4847 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -2345,7 +2345,7 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE ) void R_InitParticles () { - char *i; + const char *i; if ((i = Args->CheckValue ("-numparticles"))) NumParticles = atoi (i); diff --git a/src/v_video.cpp b/src/v_video.cpp index f6e0eb5466..24ed1a5620 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1523,7 +1523,7 @@ CCMD (vid_setmode) void V_Init (void) { - char *i; + const char *i; int width, height, bits; atterm (V_Shutdown); diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 36524a0935..e99ac91b3c 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -233,7 +233,7 @@ static void I_SelectTimer() if (NewTicArrived) { UINT delay; - char *cmdDelay; + const char *cmdDelay; cmdDelay = Args->CheckValue("-timerdelay"); delay = 0;