--- /dev/null
+This is a terse description of nethack's command line arguments.
+It is oriented toward UNIX (including descendants such as linux and
+macOS) and might not be accurate for other platforms.
+
+This text is available in the menu for the game's '?' command or can be
+viewed via 'nethack --usage | more' at the shell prompt.
+
+In all cases, if there is a save file for the chosen character name then
+it will be restored, otherwise a new game using that name will start.
+
+nethack
+ with no arguments; uses character name from run-time configuration file's
+ OPTIONS=name:character-name entry, or player's username if none.
+
+nethack -u character-name [-X or -D]
+ '-u character-name' specifies the name to use for this game's character;
+ -u must be lowercase; the space between it and character-name may
+ be omitted;
+ '-X' play in non-scoring explore mode also known as discovery mode;
+ -X must be uppercase; character starts with a wand of wishing and
+ player may opt to be life-saved and keep going if character dies;
+ '-D' run in debug mode also known as wizard mode; -D must be uppercase;
+ if player is not allowed then nethack will switch to -X.
+
+ A character name may have a suffix specifying any or all of role, race,
+ gender, and alignment such as -u Conan-Bar-Hum-Mal-Neu or -u Tim-Wiz.
+ The components present must be at least three letters long but can be
+ longer; their case doesn't matter. See also -p and -r, next,
+
+nethack -p Ppp -r Rrr [-@]
+ '-p Ppp' specify role; p for "profession" is used because -r is in use;
+ 'Ppp' is three or more letters of the role name such as Val for
+ Valkyrie; unlike -p itself, upper/lower case of Ppp doesn't matter
+ '-r Rrr' specify race or species: Hum[an], Elf, Orc, Dwa[rf], Gno[me];
+ '-@' force non-interactive start; any of role, race, gender, and
+ alignment that is not specified on the command line or in the
+ run-time configuration file gets chosen randomly without prompting;
+ the at-sign might need to be quoted by preceding it with backslash.
+
+ The old form for role is also still accepted: -A or -Arc[heologist],
+ -B or -Bar[barian], -C or -Cav[eman] or -Cavew[oman], -H or -Hea[ler],
+ -K or -Kni[ght], -M or -Mon[k], -P or -Pri[est] or -Prieste[ss],
+ -Ran[ger], -R or -Rog[ue], -S or -Sam[urai], -T or -Tou[rist],
+ -V or -Val[kyrie], -W or -Wiz[ard]. The single-letter form must be in
+ uppercase, the three or more letter form can be in any case. There is
+ no single-letter option for the Ranger role.
+
+nethack -DEC[graphics]
+nethack -IBM[graphics]
+ selects the DEC or IBM symbol set to use line-drawing characters on a
+ text map; might be ignored depending on interface, or ineffective or
+ even scrambled depending on display capability; -DECgraphics and
+ -IBMgraphics are mutually exclusive; they can be any case but must use
+ at least three letters.
+
+nethack -wIii
+nethack --windowtype:Iii
+ where 'Iii' represents an interface designation: tty, curses, X11, or
+ Qt; only useful if the program was built to support more than one
+ interface (the game's '#version' command will disclose that); overrides
+ OPTIONS=windowtype:Iii in run-time configuration file and build-time
+ default; '-w' or '--windowtype' must be lowercase, the interface
+ designation itself may be any case; variations '--windowtype Iii' and
+ '-w Iii' work too.
+
+ On Windows, nethack.exe might support both tty and curses; nethackW.exe
+ supports mswin only. MS-DOS is tty only.
+
+nethack -n
+ don't show the 'news' file is one is present in nethack's directory.
+
+nethack --nethackrc:File
+ use File instead of the default run-time configuration file (which is
+ usually '~/.nethackrc'); the file name should include full path unless
+ located in nethack's directory;
+nethack --no-nethackrc
+ don't use any run-time configuration file; equivalent to
+ --nethackrc:/dev/null which behaves as if an empty file.
+
+nethack -dDir
+nethack --directory:Dir
+ could be used to override the build-time value of NETHACKDIR with
+ location Dir; if used, it should precede other command line arguments.
+
+The assorted options above can be combined on a single command line;
+they're listed separately for readability.
+
+*******
+
+Other options which perform some action and then exit rather than play
+the game:
+
+nethack --usage
+nethack --help
+ show this text; 'nethack ?' and 'nethack -?' might also work but the
+ question mark will need to be quoted to prevent the shell from attempting
+ filename matching.
+
+nethack -s
+nethack --scores
+ show scores for the default character; optional additional arguments:
+nethack -s character-name [character-name2 [character-name3 [...]]]
+ show scores for one or more specific character names (might not be
+ effective if PERS_IS_UID=1 is specified in nethack's sysconf file);
+ character names may be preceded by '-u' but that isn't required;
+ special character-name "all" is used to display all scores that pass
+ other criteria;
+nethack -s -p Ppp -r Rrr
+ show scores for specific roles or races; multiple instances can be used;
+ if both '-p' and '-r' are used, scores that match either will be shown
+ rather than scores that match both;
+nethack -s -v
+ show scores only for the current version if the high scores file (record)
+ also contains entries for any older versions; when -v is used, it should
+ immediately follow -s or --scores, preceding any name(s) or -p or -r;
+nethack -dDir -s
+nethack --directory:Dir -s
+ as above; alternative directory, if specified, should come first.
+
+nethack --version
+nethack --version:paste
+ '--version' display the program's version number and exit;
+ '--version:paste' display version number and also copy it into system
+ pasteboard (should work on macOS and Windows; might not work on other
+ systems) so that it could be copied from there into a subsequent email
+ or web contact form, then exit.
+
+nethack --showpaths
+ list expected locations for various files and directorys, then exit;
+ includes the name and location for the run-time configuration file which
+ can vary from platform to platform.
+
*/
#endif /* CHDIR */
+/*
+ * Define HIDE_USAGE to keep the "description of command line" out of
+ * the help menu if players have no access to a command line or if that
+ * is radically different from the description for UNIX in dat/usagehlp
+ * (a better solution for that would be a separate file and different
+ * value for USAGEHELP in global.h).
+ */
+/* #define HIDE_USAGE */ /* */
+
/*
* Section 3: Definitions that may vary with system type.
* For example, both schar and uchar should be short ints on
extern int decode_glyph(const char *str, int *glyph_ptr);
extern char *decode_mixed(char *, const char *);
extern void genl_putmixed(winid, int, const char *);
+extern void genl_display_file(const char *, boolean);
extern boolean menuitem_invert_test(int, unsigned, boolean);
/* ### windows.c ### */
#define LICENSE "license" /* file with license information */
#define OPTIONFILE "opthelp" /* file explaining runtime options */
#define OPTMENUHELP "optmenu" /* file explaining #options command */
+#define USAGEHELP "usagehlp" /* file explaining command line use */
#define OPTIONS_USED "options" /* compile-time options, for #version */
#define SYMBOLS "symbols" /* replacement symbol sets */
#define EPITAPHFILE "epitaph" /* random epitaphs on graves */
static void dispfile_optmenu(void);
static void dispfile_license(void);
static void dispfile_debughelp(void);
+#ifndef HIDE_USAGE
+static void dispfile_usagehelp(void);
+#endif
static void hmenu_doextversion(void);
static void hmenu_dohistory(void);
static void hmenu_dowhatis(void);
display_file(DEBUGHELP, TRUE);
}
+#ifndef HIDE_USAGE
+static void
+dispfile_usagehelp(void)
+{
+ display_file(USAGEHELP, TRUE);
+}
+#endif
+
static void
hmenu_doextversion(void)
{
domenucontrols(void)
{
winid cwin = create_nhwindow(NHW_TEXT);
+
show_menu_controls(cwin, FALSE);
display_nhwindow(cwin, FALSE);
destroy_nhwindow(cwin);
{ dokeylist, "Full list of keyboard commands." },
{ hmenu_doextlist, "List of extended commands." },
{ domenucontrols, "List menu control keys." },
+#ifndef HIDE_USAGE
+ { dispfile_usagehelp, "Description of NetHack's command line." },
+#endif
{ dispfile_license, "The NetHack license." },
{ docontact, "Support information." },
#ifdef PORT_HELP
/* NetHack may be freely redistributed. See license for details. */
#include "hack.h"
+#include "dlb.h"
#ifdef TTY_GRAPHICS
#include "wintty.h"
#endif
static struct window_procs hup_procs = {
WPID(hup), 0L, 0L,
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, /* colors */
hup_init_nhwindows,
hup_void_ndecl, /* player_selection */
hup_void_ndecl, /* askname */
hup_void_ndecl, /* status_finish */
genl_status_enablefield, hup_status_update,
genl_can_suspend_no,
- hup_void_fdecl_int, /* update_inventory */
+ hup_void_fdecl_int, /* update_inventory */
hup_ctrl_nhwindow,
};
/*ARGSUSED*/
static char
-hup_yn_function(const char *prompt UNUSED,
- const char *resp UNUSED,
- char deflt)
+hup_yn_function(
+ const char *prompt UNUSED,
+ const char *resp UNUSED,
+ char deflt)
{
if (!deflt)
deflt = '\033';
/*ARGSUSED*/
static int
-hup_select_menu(winid window UNUSED, int how UNUSED,
- struct mi **menu_list UNUSED)
+hup_select_menu(
+ winid window UNUSED,
+ int how UNUSED,
+ struct mi **menu_list UNUSED)
{
return -1;
}
/*ARGSUSED*/
static void
-hup_add_menu(winid window UNUSED,
- const glyph_info *glyphinfo UNUSED,
- const anything *identifier UNUSED,
- char sel UNUSED,
- char grpsel UNUSED,
- int attr UNUSED,
- int clr UNUSED,
- const char *txt UNUSED,
- unsigned int itemflags UNUSED)
+hup_add_menu(
+ winid window UNUSED,
+ const glyph_info *glyphinfo UNUSED,
+ const anything *identifier UNUSED,
+ char sel UNUSED,
+ char grpsel UNUSED,
+ int attr UNUSED,
+ int clr UNUSED,
+ const char *txt UNUSED,
+ unsigned int itemflags UNUSED)
{
return;
}
/*ARGSUSED*/
static void
-hup_print_glyph(winid window UNUSED,
- coordxy x UNUSED, coordxy y UNUSED,
- const glyph_info *glyphinfo UNUSED,
- const glyph_info *bkglyphinfo UNUSED)
+hup_print_glyph(
+ winid window UNUSED,
+ coordxy x UNUSED, coordxy y UNUSED,
+ const glyph_info *glyphinfo UNUSED,
+ const glyph_info *bkglyphinfo UNUSED)
{
return;
}
/*ARGSUSED*/
static void
-hup_status_update(int idx UNUSED, genericptr_t ptr UNUSED, int chg UNUSED,
- int pc UNUSED, int color UNUSED,
- unsigned long *colormasks UNUSED)
+hup_status_update(
+ int idx UNUSED, genericptr_t ptr UNUSED,
+ int chg UNUSED, int pc UNUSED,
+ int color UNUSED, unsigned long *colormasks UNUSED)
{
return;
}
/*ARGUSED*/
static void
-hup_void_fdecl_winid_ulong(winid window UNUSED,
- unsigned long mbehavior UNUSED)
+hup_void_fdecl_winid_ulong(
+ winid window UNUSED,
+ unsigned long mbehavior UNUSED)
{
return;
}
}
void
-genl_status_enablefield(int fieldidx, const char *nm, const char *fmt,
- boolean enable)
+genl_status_enablefield(
+ int fieldidx,
+ const char *nm,
+ const char *fmt,
+ boolean enable)
{
status_fieldfmt[fieldidx] = fmt;
status_fieldnm[fieldidx] = nm;
/* call once for each field, then call with BL_FLUSH to output the result */
void
-genl_status_update(int idx, genericptr_t ptr, int chg UNUSED,
- int percent UNUSED, int color UNUSED,
- unsigned long *colormasks UNUSED)
+genl_status_update(
+ int idx,
+ genericptr_t ptr,
+ int chg UNUSED, int percent UNUSED,
+ int color UNUSED, unsigned long *colormasks UNUSED)
{
char newbot1[MAXCO], newbot2[MAXCO];
long cond, *condptr = (long *) ptr;
static time_t dumplog_now;
char *
-dump_fmtstr(const char *fmt, char *buf,
- boolean fullsubs) /* True -> full substitution for file name,
- False -> partial substitution for
- '--showpaths' feedback where there's
- no game in progress when executed */
+dump_fmtstr(
+ const char *fmt,
+ char *buf,
+ boolean fullsubs) /* True -> full substitution for file name,
+ * False -> partial substitution for '--showpaths'
+ * feedback where there's no game in progress */
{
const char *fp = fmt;
char *bp = buf;
putstr(window, attr, decode_mixed(buf, str));
}
+/* possibly called to show usage info during command line processing when
+ an interface hasn't yet been chosen and set up */
+void
+genl_display_file(const char *fname, boolean complain)
+{
+ char buf[BUFSZ];
+ dlb *f = dlb_fopen(fname, "r");
+
+ if (!f) {
+ if (complain) /* send complaint to stdout rather than to stderr */
+ fprintf(stdout, "\nCannot open \"%s\".\n", fname);
+ } else {
+ /* straight copy to stdout, no pagination or other interaction */
+ while (dlb_fgets(buf, BUFSZ, f)) {
+ if (fputs(buf, stdout) < 0)
+ break;
+ }
+ (void) dlb_fclose(f);
+ }
+}
+
/*
* Window port helper function for menu invert routines to move the decision
* logic into one place instead of 7 different window-port routines.
$(TARGETPFX)weapon.o: weapon.c $(HACK_H)
$(TARGETPFX)were.o: were.c $(HACK_H)
$(TARGETPFX)wield.o: wield.c $(HACK_H)
-$(TARGETPFX)windows.o: windows.c $(HACK_H) ../include/wintty.h
+$(TARGETPFX)windows.o: windows.c $(HACK_H) ../include/dlb.h ../include/wintty.h
$(TARGETPFX)wizard.o: wizard.c $(HACK_H)
$(TARGETPFX)worm.o: worm.c $(HACK_H)
$(TARGETPFX)worn.o: worn.c $(HACK_H)
# end of configuration
#
-DATHELP = help hh cmdhelp keyhelp history opthelp optmenu wizhelp
+DATHELP = help hh cmdhelp keyhelp history opthelp optmenu usagehlp wizhelp
SPEC_LEVS = asmodeus.lua baalz.lua bigrm-*.lua castle.lua fakewiz?.lua \
juiblex.lua knox.lua medusa-?.lua minend-?.lua minefill.lua \
static void consume_two_args(int, int *, char ***);
static void early_options(int *, char ***, char **);
static void opt_terminate(void) NORETURN;
+static void opt_usage(const char *) NORETURN;
static void opt_showpaths(const char *);
static void scores_only(int, char **, const char *) NORETURN;
config_error_init(FALSE, "command line", FALSE);
+ /* treat "nethack ?" as a request for usage info; due to shell
+ processing, player likely has to use "nethack \?" or "nethack '?'"
+ [won't work if used as "nethack -dpath ?" or "nethack -d path ?"] */
+ if (*argc_p > 1 && !strcmp((*argv_p)[1], "?"))
+ opt_usage(*hackdir_p); /* doesn't return */
+
/*
* Both *argc_p and *argv_p account for the program name as (*argv_p)[0];
* local argc and argv impicitly discard that (by starting 'ndx' at 1).
#endif /* CHDIR */
}
break;
+ case 'h':
+ case '?':
+ if (lopt(arg, ArgValDisallowed, "-help", origarg, &argc, &argv)
+ || lopt(arg, ArgValDisallowed, "-?", origarg, &argc, &argv))
+ opt_usage(*hackdir_p); /* doesn't return */
+ break;
case 'n':
oldargc = argc;
if (!strcmp(arg, "-no-nethackrc")) /* no abbreviation allowed */
/*NOTREACHED*/
}
break;
+ case 'u':
+ if (lopt(arg, ArgValDisallowed, "-usage", origarg, &argc, &argv))
+ opt_usage(*hackdir_p);
+ break;
case 'v':
if (argcheck(argc, argv, ARG_VERSION) == 2) {
opt_terminate();
/*NOTREACHED*/
}
+static void
+opt_usage(const char *hackdir)
+{
+#ifdef CHDIR
+ chdirx(hackdir, TRUE);
+#else
+ nhUse(hackdir);
+#endif
+ dlb_init();
+
+ genl_display_file(USAGEHELP, TRUE);
+ opt_terminate();
+}
+
/* show the sysconf file name, playground directory, run-time configuration
file name, dumplog file name if applicable, and some other things */
static void