Page MenuHomeWildfire Games

Implement "-help" as a command line option
AbandonedPublic

Authored by andy5995 on Sep 27 2021, 7:15 AM.

Details

Summary

This would add a "-help" command line option and display all available command line options along with their corresponding descriptions.

Test Plan

I rebuilt and ran "./pyrogenesis". The output was as expected.

Diff Detail

Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

andy5995 requested review of this revision.Sep 27 2021, 7:15 AM
andy5995 created this revision.

This obviously isn't finished yet. I wanted to get some feedback before I proceeded.

Is there a trac ticket already open for this?

Would you want the strings declared once in some type of data structure to avoid spelling errors when duplicating? for example, the strings (command line options) are used in the help output, and also later, e.g.

	const bool isVisualReplay = args.Has("replay-visual");
	const bool isNonVisualReplay = args.Has("replay");
	const bool isNonVisual = args.Has("autostart-nonvisual");
	const bool isUsingRLInterface = args.Has("rl-interface");
sera added a subscriber: sera.Sep 27 2021, 12:07 PM

IMHO the right approach is to change CmdLineArgs from an minimalist class to a proper command line parser where you register available options, does validation and has a help string for each.

source/main.cpp
538

Using a raw string is easier and more readable.

Stan added a comment.Sep 27 2021, 4:20 PM

I guess the issue was that we didn't want to duplicate the Readme inside the game's code. D4232 used a rather clever trick for that.

sera added a comment.Sep 27 2021, 5:58 PM

You won't need the readme.txt anymore if you have support for help, worst case just run "pyrogenesis -help > readme.txt" as a postbuild command. So no duplication required.

Stan added a comment.Sep 27 2021, 6:33 PM

I'm not sure debug_printf works at all on Windows. You need to have SysInternals dbgview in order to be able to see such output.

andy5995 added a comment.EditedSep 27 2021, 7:52 PM
In D4283#182511, @Stan wrote:

Thanks @Stan , now I do :)

Are you planning to use some form of D2432 or do you want to go with some form of this patch?

If so, what should I use instead of debug_printf()?

In D4283#182523, @sera wrote:

You won't need the readme.txt anymore if you have support for help, worst case just run "pyrogenesis -help > readme.txt" as a postbuild command. So no duplication required.

I see. And we could also use help2man to generate a man page.

What would you think about something like this?

enum {
  WRITABLE_ROOT,
  REPLAY,
  UNIQUE_LOGS,
  ...
  NULL
};


struct  arg {
  int enum_value;
  const char *option;
  const char *description;
};


struct arg args[] = {
  {WRITABLE_ROOT, "writableRoot", "store runtime game data in root data directory"},
  {REPLAY, "replay=PATH", "non-visual replay of a previous game, used for analysis purposes"},
  {UNIQUE_LOGS", "unique-logs", "adds unix timestamp and process id to the filename of mainlog.html, interestinglog.html"},
  ...,
 {NULL, "", ""}

};


while (args[i].enum_value != NULL)
{
  printf ("%s%s", args[i].option, args[i].description);
  i++;
}

And then we'd use the strings elsewhere. ex:

        const bool isVisualReplay = args.Has(args[REPLAY_VISUAL].option);
	const bool isNonVisualReplay = args.Has(args[REPLAY].option);
	const bool isNonVisual = args.Has(args[AUTOSTART_NONVISUAL].option);
sera added a comment.Sep 27 2021, 9:10 PM

If so, what should I use instead of debug_printf()?

std::cout

What would you think about something like this?

Use C++ instead of C :)

Basically create a parser object (Parser), create option objects (Parser::Option) and add them via parser.add(option), then call parser.parse(argv). parse() validates argv against added options and by mismatch prints either usage or help and exits. Now you can query the parser or a returned options object for whether an option is set or not and what parameter were given.

Anyway, a good cmdline parser isn't easy to design/write, you may find inspiration with pythons argparse for instance or documentation of c++ parsers like cxxopts. Beware to not read the code or properly attribute it, Maybe you even find one that is a good fit for 0ad that can be used as a dependency (I have some doubt that such exists). I don't know if such is within your capability / you are willing to spend the effort, so a heredoc approach would still get a pass from me as it's already a step up from the current situation.

In D4283#182533, @sera wrote:

std::cout

Currently std::cout is not a standard way to write to output and logs.

Basically create a parser object (Parser), create option objects (Parser::Option) and add them via parser.add(option), then call parser.parse(argv). parse() validates argv against added options and by mismatch prints either usage or help and exits. Now you can query the parser or a returned options object for whether an option is set or not and what parameter were given.

Do you need to call parse multiple times? If not why do you need the method?

Anyway, a good cmdline parser isn't easy to design/write, you may find inspiration with pythons argparse for instance or documentation of c++ parsers like cxxopts.

+

I understand you'd rather I use C++ code. I'm not famillar with C++ actually, so I'll probably not do anymore with this diff.

I'm not sure why you've mentioned implementing a command line parser. 0ad already has this. I just mentioned replacing the strings with some variables and adding "-help" output.

sera added a comment.Sep 28 2021, 12:48 AM

Do you need to call parse multiple times? If not why do you need the method?

It's not a requirement but neither poor design.

I'm not sure why you've mentioned implementing a command line parser. 0ad already has this.

A poor man solution only.

I just mentioned replacing the strings with some variables and adding "-help" output.

A better parser with validation is just the cherry on top solution which seems out of reach, I thought I was clear enough but apparently not, copy paste the readme.txt into a single c++ raw string (heredoc approach) and printing it given h/help is already good enough to treat it as an improvement. So go with that.

In D4283#182540, @sera wrote:

I'm not sure why you've mentioned implementing a command line parser. 0ad already has this.

A poor man solution only.

Do you happen to know if there Is an existing ticket for redesigning/implementing a new parser? Has using boost.program_options been considered?

I just mentioned replacing the strings with some variables and adding "-help" output.

A better parser with validation is just the cherry on top solution which seems out of reach, I thought I was clear enough but apparently not, copy paste the readme.txt into a single c++ raw string (heredoc approach) and printing it given h/help is already good enough to treat it as an improvement. So go with that.

Ok, I'll close this out then in favor of D2432

andy5995 abandoned this revision.Oct 14 2021, 8:44 PM

Duplicate of D2432