static void
process_options(int argc, char *argv[])
{
+ static char novalue[] = "[nothing]"; /* note: not 'const' */
+ char *p, *arg, *origarg;
int i, l;
+ config_error_init(FALSE, "command line", FALSE);
/*
* Process options.
+ *
+ * We don't support "-xyz" as shortcut for "-x -y -z" and we only
+ * simulate longopts by allowing "--foo" for "-foo" when the user
+ * specifies at least 2 characters of leading substring for "foo".
+ * If "foo" takes a value, both "--foo=value" and "--foo value" work.
*/
while (argc > 1 && argv[1][0] == '-') {
argv++;
argc--;
- l = (int) strlen(*argv);
+ arg = origarg = argv[0];
+ /* allow second dash if arg is longer than one character */
+ if (arg[0] == '-' && arg[1] == '-' && arg[2] != '\0'
+ /* "--a=b" violates the "--" ok when at least 2 chars long rule */
+ && (arg[3] != '\0' && arg[3] != '=' && arg[3] != ':'))
+ ++arg;
+ l = (int) strlen(arg);
/* must supply at least 4 chars to match "-XXXgraphics" */
if (l < 4)
l = 4;
- switch (argv[0][1]) {
+ switch (arg[1]) {
case 'D':
case 'd':
- if ((argv[0][1] == 'D' && !argv[0][2])
- || !strcmpi(*argv, "-debug")) {
+ if ((arg[1] == 'D' && !arg[2]) || !strcmpi(arg, "-debug")) {
wizard = TRUE, discover = FALSE;
- } else if (!strncmpi(*argv, "-DECgraphics", l)) {
+ } else if (!strncmpi(arg, "-DECgraphics", l)) {
load_symset("DECGraphics", PRIMARY);
switch_symbols(TRUE);
} else {
- raw_printf("Unknown option: %.60s", *argv);
+ config_error_add("Unknown option: %.60s", origarg);
}
break;
case 'X':
break;
#endif
case 'u':
- if (argv[0][2]) {
- (void) strncpy(g.plname, argv[0] + 2, sizeof g.plname - 1);
+ if (arg[2]) {
+ (void) strncpy(g.plname, arg + 2, sizeof g.plname - 1);
g.plnamelen = 0; /* plname[] might have -role-race attached */
} else if (argc > 1) {
argc--;
(void) strncpy(g.plname, argv[0], sizeof g.plname - 1);
g.plnamelen = 0;
} else {
- raw_print("Player name expected after -u");
+ config_error_add("Player name expected after -u");
}
break;
case 'I':
case 'i':
- if (!strncmpi(*argv, "-IBMgraphics", l)) {
+ if (!strncmpi(arg, "-IBMgraphics", l)) {
load_symset("IBMGraphics", PRIMARY);
load_symset("RogueIBM", ROGUESET);
switch_symbols(TRUE);
} else {
- raw_printf("Unknown option: %.60s", *argv);
+ config_error_add("Unknown option: %.60s", origarg);
}
break;
case 'p': /* profession (role) */
- if (argv[0][2]) {
- if ((i = str2role(&argv[0][2])) >= 0)
+ if (arg[2]) {
+ if ((i = str2role(&arg[2])) >= 0)
flags.initrole = i;
} else if (argc > 1) {
argc--;
}
break;
case 'r': /* race */
- if (argv[0][2]) {
- if ((i = str2race(&argv[0][2])) >= 0)
+ if (arg[2]) {
+ if ((i = str2race(&arg[2])) >= 0)
flags.initrace = i;
} else if (argc > 1) {
argc--;
flags.initrace = i;
}
break;
- case 'w': /* windowtype */
- config_error_init(FALSE, "command line", FALSE);
- choose_windows(&argv[0][2]);
- config_error_done();
+ case 'w': /* windowtype: "-wfoo" or "-w[indowtype]=foo"
+ * or "-w[indowtype]:foo" or "-w[indowtype] foo" */
+ if ((p = index(arg, '=')) == 0)
+ p = index(arg, ':');
+ l = (int) (p ? (p - arg) : strlen(arg));
+ if (!strncmp(arg, "-windowtype", l)) {
+ /* "-windowtype[=foo]" */
+ if (p)
+ ++p; /* past '=' or ':' */
+ else
+ p = eos(arg); /* we have "-w[indowtype]" w/o "=foo"
+ * so we'll take foo from next element */
+ } else {
+ /* "-w..." but not "-w[indowtype[=foo]]" */
+ if (!p) {
+ p = &arg[2]; /* past 'w' of "-wfoo" */
+ } else {
+ /* "-w...=foo" but not "-w[indowtype]=foo" */
+ config_error_add("Unknown option: %.60s", origarg);
+ continue;
+ }
+ }
+ if (!*p) {
+ /* "-w[indowtype]" w/o '='/':' use next element for "foo" */
+ if (argc > 1)
+ --argc, ++argv, p = argv[0];
+ else
+ p = novalue; /* there is no next element */
+ }
+ choose_windows(p);
break;
case '@':
flags.randomall = 1;
break;
+ case '-':
+ /* "--" or "--x" or "--x=y"; need at least 2 chars after the
+ dashes in order to accept "--x" as an alternative to "-x";
+ don't just silently ignore it */
+ config_error_add("Unknown option: %.60s", origarg);
+ break;
default:
+ /* default for "-x" is to play as the role that starts with "x" */
if ((i = str2role(&argv[0][1])) >= 0) {
flags.initrole = i;
break;
}
- /* else raw_printf("Unknown option: %.60s", *argv); */
+ /* else config_error_add("Unknown option: %.60s", origarg); */
}
}
#ifdef SYSCF
if (argc > 1)
- raw_printf("MAXPLAYERS are set in sysconf file.\n");
+ config_error_add("MAXPLAYERS are set in sysconf file.\n");
#else
/* XXX This is deprecated in favor of SYSCF with MAXPLAYERS */
if (argc > 1)
if (!g.locknum || (sysopt.maxplayers && g.locknum > sysopt.maxplayers))
g.locknum = sysopt.maxplayers;
#endif
+ /* empty or "N errors on command line" */
+ config_error_done();
}
#ifdef CHDIR