Skip to content

Commit

Permalink
Allow specifying "+game" and "+logfile" options for any application.
Browse files Browse the repository at this point in the history
- Fix next option being skipped and its first argument being parsed as the option name instead.
- Fix compilation errors for Visual Studio 2010.
  • Loading branch information
DreamyCecil committed Jan 24, 2025
1 parent 1a1f579 commit 0fc6882
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 35 deletions.
2 changes: 2 additions & 0 deletions Sources/DedicatedServer/DedicatedServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ static void HandleInitialArgs(const CommandLineArgs_t &aArgs) {
#endif

ded_strConfig = "Scripts\\Dedicated\\" + strConfig + "\\";

// [Cecil] NOTE: Always empty at this point, only overriden by +logfile after these initial arguments
_strLogFile = "Dedicated_" + strConfig;

// Mod directory name
Expand Down
35 changes: 28 additions & 7 deletions Sources/Engine/API/CommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,

#include "StdH.h"

// Common command line options

static void OptionGame(const CommandLineArgs_t &aArgs) {
// [Cecil] TEMP: Use base directory for the default mod
if (aArgs[0] != "SeriousSam") {
_fnmMod = "Mods\\" + aArgs[0] + "\\";
}
};

static void OptionLogFile(const CommandLineArgs_t &aArgs) {
_strLogFile = aArgs[0];
};

// Separate a string into multiple arguments (e.g. command line arguments)
// Implemented according to the rules from Microsoft docs:
// https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?view=msvc-170
Expand Down Expand Up @@ -113,11 +126,18 @@ static void StringToArgs(const char *str, CommandLineArgs_t &aArgs)
}
};

// Add common command line option processors
inline void AddCommonProcessors(CommandLineSetup *pCmd) {
pCmd->AddCommand("+game", &OptionGame, 1);
pCmd->AddCommand("+logfile", &OptionLogFile, 1);
};

// Constructor for C-like command line
CommandLineSetup::CommandLineSetup(int argc, char **argv) :
pInitialArgs(NULL, -1), pUnknownOption(NULL)
{
GetArguments(argc, argv, aArgs);
AddCommonProcessors(this);

// Cache the entire command line as a single string
strCommandLine = "";
Expand All @@ -136,6 +156,7 @@ CommandLineSetup::CommandLineSetup(const char *strCmd) :
pInitialArgs(NULL, -1), pUnknownOption(NULL)
{
GetArguments(strCmd, aArgs);
AddCommonProcessors(this);
strCommandLine = strCmd;
};

Expand Down Expand Up @@ -172,10 +193,13 @@ void SE_ParseCommandLine(const CommandLineSetup &cmd) {
const CommandLineFunction_t *pCmdFunc = NULL;

// Parse initial arguments
if (i == 0 && cmd.pInitialArgs.first != NULL) {
if (i == 0 && cmd.pInitialArgs.pFunc != NULL) {
strCmd = "Program executable";
pCmdFunc = &cmd.pInitialArgs;

// Pretend that this is a real option so it pushes arguments starting from 0
i--;

} else {
// Get command name
strCmd = cmd[i].ConstData();
Expand Down Expand Up @@ -203,15 +227,12 @@ void SE_ParseCommandLine(const CommandLineSetup &cmd) {

// Get command line function from the command
pCmdFunc = &itCmd->second;

// Skip the command argument
i++;
}

// Get command function
FCommandLineCallback pFunc = pCmdFunc->first;
FCommandLineCallback pFunc = pCmdFunc->pFunc;

INDEX ctArgs = pCmdFunc->second;
INDEX ctArgs = pCmdFunc->ctArgs;
INDEX ctLeft = ct - i;

// Not enough arguments for the last command
Expand All @@ -223,7 +244,7 @@ void SE_ParseCommandLine(const CommandLineSetup &cmd) {

// Retrieve required amount of arguments for the command
while (--ctArgs >= 0) {
aCmdArgs.Add(cmd[i++]);
aCmdArgs.Add(cmd[++i]);
}

// Call command function with the arguments
Expand Down
16 changes: 12 additions & 4 deletions Sources/Engine/API/CommandLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ typedef CStaticStackArray<CTString> CommandLineArgs_t;
typedef void (*FCommandLineCallback)(const CommandLineArgs_t &);

// Command callback with argument count (e.g. if expecting "+run MyMod 0" command, then the argument count is 2)
typedef std::pair<FCommandLineCallback, INDEX> CommandLineFunction_t;
struct CommandLineFunction_t {
FCommandLineCallback pFunc;
INDEX ctArgs;

__forceinline CommandLineFunction_t(FCommandLineCallback pSetFunc = NULL, INDEX ctSetArgs = -1) :
pFunc(pSetFunc), ctArgs(ctSetArgs) {};
};

// Setup structure for command line arguments
struct ENGINE_API CommandLineSetup {
Expand Down Expand Up @@ -70,12 +76,14 @@ struct ENGINE_API CommandLineSetup {

// Register new command callback
inline void AddCommand(const CTString &strName, FCommandLineCallback pFunc, INDEX ctArguments) {
mapCommands[strName] = std::make_pair(pFunc, ctArguments);
ASSERT(ctArguments >= 0);
mapCommands[strName] = CommandLineFunction_t(pFunc, ctArguments);
};

// Register initial arguments parser
inline void AddInitialParser(FCommandLineCallback pFunc, INDEX ctArguments) {
pInitialArgs = std::make_pair(pFunc, ctArguments);
ASSERT(ctArguments > 0); // No point in processing initial arguments with no arguments
pInitialArgs = CommandLineFunction_t(pFunc, ctArguments);
};

// Register unknown options handler
Expand All @@ -89,7 +97,7 @@ struct ENGINE_API CommandLineSetup {
};

// Accessor operator (equal to argv[i - 1])
inline const CTString &operator[](size_t i) const {
inline const CTString &operator[](INDEX i) const {
return aArgs[i];
};
};
Expand Down
15 changes: 1 addition & 14 deletions Sources/SeriousSam/CmdLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,6 @@ static void OptionQuickJoin(const CommandLineArgs_t &) {
cmd_bQuickJoin = TRUE;
};

static void OptionGame(const CommandLineArgs_t &aArgs) {
// Use base directory for the default mod
if (aArgs[0] != "SeriousSam") {
_fnmMod = "Mods\\" + aArgs[0] + "\\";
}
};

static void OptionPassword(const CommandLineArgs_t &aArgs) {
cmd_strPassword = aArgs[0];
};
Expand All @@ -69,22 +62,16 @@ static void OptionScript(const CommandLineArgs_t &aArgs) {
};

static void OptionGoTo(const CommandLineArgs_t &aArgs) {
aArgs[0].ScanF("%d", &cmd_iGoToMarker);
};

static void OptionLogFile(const CommandLineArgs_t &aArgs) {
_strLogFile = aArgs[0];
cmd_iGoToMarker = strtol(aArgs[0].ConstData(), NULL, 10);
};

// [Cecil] Register command line functions
void SetupCommandLine(CommandLineSetup &cmd) {
cmd.AddCommand("+level", &OptionLevel, 1);
cmd.AddCommand("+server", &OptionServer, 0);
cmd.AddCommand("+quickjoin", &OptionQuickJoin, 0);
cmd.AddCommand("+game", &OptionGame, 1);
cmd.AddCommand("+password", &OptionPassword, 1);
cmd.AddCommand("+connect", &OptionConnect, 1);
cmd.AddCommand("+script", &OptionScript, 1);
cmd.AddCommand("+goto", &OptionGoTo, 1);
cmd.AddCommand("+logfile", &OptionLogFile, 1);
};
9 changes: 0 additions & 9 deletions Sources/WorldEditor/WorldEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,14 +419,6 @@ static BOOL HandleUnknownOption(const CTString &strCmd) {
return TRUE;
};

// [Cecil] Command line options as functions
static void OptionGame(const CommandLineArgs_t &aArgs) {
// Use base directory for the default mod
if (aArgs[0] != "SeriousSam") {
_fnmMod = "Mods\\" + aArgs[0] + "\\";
}
};

BOOL CWorldEditorApp::SubInitInstance()
{
// required for visual styles
Expand All @@ -453,7 +445,6 @@ BOOL CWorldEditorApp::SubInitInstance()
// [Cecil] Parse command line arguments
CommandLineSetup cmd(strCmdCopy.ConstData());
cmd.AddUnknownHandler(&HandleUnknownOption);
cmd.AddCommand("+game", &OptionGame, 1);
SE_ParseCommandLine(cmd);
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/bison.simple
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ yyparse(YYPARSE_PARAM)
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
yyval = {}; /* [Cecil] Prevent runtime assertion */
yyval = YYSTYPE(); /* [Cecil] Prevent runtime assertion */

/* Initialize stack pointers.
Waste one element of value and location stack
Expand Down

0 comments on commit 0fc6882

Please sign in to comment.