Add start parameter to FindArg()

Before this change, the FindArg() function was well suited for finding
command-line options that only appear once. It’s very resonable for
FindArg() to only support arguments that appear one time because Descent
3 doesn’t have any command-line options that should be specified
multiple times. For example, it would be pretty pointless to do
something like this:

  Descent3 -useexedir -useexedir

or something like this:

  Descent3 -aspect 1.0 -aspect 1.6

It does, however, sometimes makes sense to repeat command-line options for
other applications. For example, you can specify -e multiple times when
running grep [1]:

  grep -e pattern1 -e pattern2 file.txt

The main motivation behind this change is to make it easier to create a
future commit. That future commit will add a command-line option named
“-additionaldir”. -additionaldir will be similar to grep’s -e flag. In
other words, it will make sense to do this:

  Descent3 -additionaldir /home/user/dir1 -additionaldir /home/user/dir2

Adding a start parameter to FindArg() now will make it easier for that
future commit parse the multiple occurrences of -additionaldir.

Unfortunately, there is one drawback to this change. In Descent3/args.h,
I gave the start parameter a default value of 1. Giving the start
parameter a default value allowed me to add the start parameter without
having to change most of the calls to the FindArg() function. There was
one situation where I had to change how FindArg was called, though.
DLLFindArg is a pointer to the FindArg() function. You cannot give
function pointers default arguments [2]. As a result,
FindArg("-someargument") works, but DLLFindArg("-someargument") does
not. Instead, you have to write DLLFindArg("-someargument", 1) which is
a little bit annoying.

[1]: <https://www.gnu.org/software/grep/manual/html_node/Matching-Control.html>
[2]: <https://stackoverflow.com/a/9760710/7593853>
This commit is contained in:
Jason Yundt 2024-08-20 09:49:51 -04:00
parent 3c602b2087
commit 90e897918a
5 changed files with 12 additions and 8 deletions

View File

@ -104,7 +104,7 @@ const char *SkipArgPrefix(const char *arg) {
return arg;
}
int FindArg(const char *which) {
int FindArg(const char *which, int start) {
if (which == nullptr)
return 0;
@ -112,14 +112,18 @@ int FindArg(const char *which) {
return strcasecmp(which, SkipArgPrefix(arg)) == 0;
};
for (int i = 1; i <= TotalArgs; i++) {
for (int i = start; i <= TotalArgs; i++) {
if (which_matches(GameArgs[i])) {
LOG_INFO.printf("FindArg: Found [%s] at argument index (%d).", which, i);
return i;
}
}
LOG_VERBOSE.printf("FindArg: Did not find [%s] on command line.", which);
if (start == 1) {
LOG_VERBOSE.printf("FindArg: Did not find [%s] on command line.", which);
} else {
LOG_VERBOSE.printf("FindArg: Did not find [%s] on command line at index %i or after index %i.", which, start, start);
}
return 0;
}

View File

@ -28,7 +28,7 @@ void GatherArgs(const char *str);
void GatherArgs(char **argv);
// Returns index of argument sought, or 0 if not found
int FindArg(const char *which);
int FindArg(const char *which, int start = 1);
int FindArgChar(const char *which, char singleCharArg);
const char *GetArg(int index);

View File

@ -1207,7 +1207,7 @@ void DMFCBase::GameInit(int teams) {
Remote_Initialize();
// see if we should display Outrage logo at all
if (DLLFindArg("-nooutragelogo"))
if (DLLFindArg("-nooutragelogo", 1))
m_bDisplayOutrageLogo = false;
else
m_bDisplayOutrageLogo = true;
@ -4916,7 +4916,7 @@ void DMFCBase::ParseStartupScript(void) {
int autoexec_arg = -1;
if ((autoexec_arg = DLLFindArg("-autoexec")) != 0) {
if ((autoexec_arg = DLLFindArg("-autoexec", 1)) != 0) {
// a specific autoexec.dmfc file was specified, use that
strcpy(path, GetGameArg(autoexec_arg + 1));
mprintf(0, "Override AUTOEXEC.DMFC to %s\n", path);

View File

@ -483,7 +483,7 @@ void (*DLLg3_DrawSpecialLine)(g3Point *p0, g3Point *p1);
void (*DLLg3_DrawPlanarRotatedBitmap)(vector *pos, vector *norm, angle rot_angle, float width,
float height, int bm);
void (*DLLPlayerStopSounds)(int slot);
int (*DLLFindArg)(const char *which);
int (*DLLFindArg)(const char *which, int start);
int (*DLLFireWeaponFromObject)(object *obj, int weapon_num, int gun_num, bool f_force_forward,
bool f_force_target);
int (*DLLCreateAndFireWeapon)(vector *pos, vector *dir, object *parent, int weapon_num);

View File

@ -1591,7 +1591,7 @@ typedef void (*PlayerStopSounds_fp)(int slot);
DMFCDLLOUT(PlayerStopSounds_fp DLLPlayerStopSounds;)
// Returns index of argument sought, or 0 if not found
typedef int (*FindArg_fp)(const char *which);
typedef decltype(&FindArg) FindArg_fp;
DMFCDLLOUT(FindArg_fp DLLFindArg;)
// Given an object and a weapon, fires a shot from that object