'nethack --usage' and '?' menu
Write up a description of how the command line works on UNIX and put that in new file dat/usagehlp. Add support for |nethack --usage | --help | -? | ? to display it and exit. Also add a menu entry for nethack's help command to show it during play. That can be suppressed by uncommenting new '#define HIDE_USAGE' in config.h since it won't be useful on servers that don't give players access to command lines. New genl_display_file() just writes to stdout. opt_usage(), which calls it, might need some suid/sgid handling to make sure the output is done as the player rather than as nethack. doc/nethack.6 is already out of date again.
This commit is contained in:
132
dat/usagehlp
Normal file
132
dat/usagehlp
Normal file
@@ -0,0 +1,132 @@
|
||||
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.
|
||||
|
||||
@@ -421,6 +421,15 @@
|
||||
*/
|
||||
#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
|
||||
|
||||
@@ -3303,6 +3303,7 @@ extern char *encglyph(int);
|
||||
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 ### */
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#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 */
|
||||
|
||||
15
src/pager.c
15
src/pager.c
@@ -32,6 +32,9 @@ static void dispfile_optionfile(void);
|
||||
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);
|
||||
@@ -2355,6 +2358,14 @@ dispfile_debughelp(void)
|
||||
display_file(DEBUGHELP, TRUE);
|
||||
}
|
||||
|
||||
#ifndef HIDE_USAGE
|
||||
static void
|
||||
dispfile_usagehelp(void)
|
||||
{
|
||||
display_file(USAGEHELP, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
hmenu_doextversion(void)
|
||||
{
|
||||
@@ -2389,6 +2400,7 @@ static void
|
||||
domenucontrols(void)
|
||||
{
|
||||
winid cwin = create_nhwindow(NHW_TEXT);
|
||||
|
||||
show_menu_controls(cwin, FALSE);
|
||||
display_nhwindow(cwin, FALSE);
|
||||
destroy_nhwindow(cwin);
|
||||
@@ -2411,6 +2423,9 @@ static const struct {
|
||||
{ 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
|
||||
|
||||
106
src/windows.c
106
src/windows.c
@@ -3,6 +3,7 @@
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
#include "dlb.h"
|
||||
#ifdef TTY_GRAPHICS
|
||||
#include "wintty.h"
|
||||
#endif
|
||||
@@ -533,7 +534,8 @@ static win_request_info *hup_ctrl_nhwindow(winid, int, win_request_info *);
|
||||
|
||||
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 */
|
||||
@@ -577,7 +579,7 @@ static struct window_procs hup_procs = {
|
||||
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,
|
||||
};
|
||||
|
||||
@@ -634,9 +636,10 @@ hup_nhgetch(void)
|
||||
|
||||
/*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';
|
||||
@@ -673,23 +676,26 @@ hup_create_nhwindow(int type UNUSED)
|
||||
|
||||
/*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;
|
||||
}
|
||||
@@ -710,10 +716,11 @@ hup_putstr(winid window UNUSED, int attr UNUSED, const char *text UNUSED)
|
||||
|
||||
/*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;
|
||||
}
|
||||
@@ -781,9 +788,10 @@ hup_get_color_string(void)
|
||||
|
||||
/*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;
|
||||
}
|
||||
@@ -820,8 +828,9 @@ hup_void_fdecl_winid(winid window UNUSED)
|
||||
|
||||
/*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;
|
||||
}
|
||||
@@ -885,8 +894,11 @@ genl_status_finish(void)
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -897,9 +909,11 @@ DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
/* 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;
|
||||
@@ -1084,11 +1098,12 @@ static FILE *dumplog_file;
|
||||
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;
|
||||
@@ -1493,6 +1508,27 @@ genl_putmixed(winid window, int attr, const char *str)
|
||||
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.
|
||||
|
||||
@@ -1191,7 +1191,7 @@ $(TARGETPFX)vision.o: vision.c $(HACK_H)
|
||||
$(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)
|
||||
|
||||
@@ -91,7 +91,7 @@ LUA_VERSION = 5.4.4
|
||||
# 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 \
|
||||
|
||||
@@ -36,6 +36,7 @@ static void consume_arg(int, int *, char ***);
|
||||
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;
|
||||
|
||||
@@ -571,6 +572,12 @@ early_options(int *argc_p, char ***argv_p, char **hackdir_p)
|
||||
|
||||
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).
|
||||
@@ -617,6 +624,12 @@ early_options(int *argc_p, char ***argv_p, char **hackdir_p)
|
||||
#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 */
|
||||
@@ -653,6 +666,10 @@ early_options(int *argc_p, char ***argv_p, char **hackdir_p)
|
||||
/*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();
|
||||
@@ -689,6 +706,20 @@ opt_terminate(void)
|
||||
/*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
|
||||
|
||||
Reference in New Issue
Block a user