cmdhelp revamp
Implement a rudimentary if/elif/else/endif interpretor and use
conditionals in dat/cmdhelp to describe what command each keystroke
currently invokes, so that there isn't a lot of "(debug mode only)"
and "(if number_pad is off)" cluttering the feedback that the user
sees. (The conditionals add quite a bit of clutter to the raw data
but users don't see that. number_pad produces a lot of conditional
commands: basic letters vs digits, 'g' vs 'G' for '5', phone
keypad vs normal layout of digits, and QWERTZ keyboard swap between
y/Y/^Y/M-y/M-Y/M-^Y and z/Z/^Z/M-z/M-Z/M-^Z.)
The interpretor understands
'&#' for comment,
'&? option' for 'if' (also '&? !option'
or '&? option=value[,value2,...]'
or '&? !option=value[,value2,...]'),
'&: option' for 'elif' (with argument variations same as 'if';
any number of instances for each 'if'),
'&:' for 'else' (also '&: #comment';
0 or 1 instance for a given 'if'), and
'&.' for 'endif' (also '&. #comment'; required for each 'if').
The option handling is a bit of a mess, with no generality for
which options to deal with and only a comma separated list of
integer values for the '=value' part. number_pad is the only
supported option that has a value; the few others (wizard/debug,
rest_on_space, #if SHELL, #if SUSPEND) are booleans.
This commit is contained in:
+220
-127
@@ -1,127 +1,220 @@
|
|||||||
^ Show the type of a trap
|
&# cmdhelp
|
||||||
^[ Cancel command (same as ESCape key)
|
& Tell what command a keystroke invokes
|
||||||
^A Redo the previous command
|
^ Show the type of an adjacent trap
|
||||||
^C Quit the game
|
^[ Cancel command (same as ESCape key)
|
||||||
^D Kick something (usually a door, chest, or box)
|
&? debug
|
||||||
^E Search a room (available in debug mode only)
|
^E Search for nearby traps, secret doors, and unseen monsters
|
||||||
^F Map the level (available in debug mode only)
|
^F Map level; reveals traps and secret corridors but not secret doors
|
||||||
^G Create a monster (available in debug mode only)
|
^G Create a monster by name or class
|
||||||
^I Identify all items (available in debug mode only)
|
^I View inventory with all items identified
|
||||||
^O Show dungeon overview (normal play) or special levels (debug mode)
|
^O List special level locations
|
||||||
^P Toggle through previously displayed game messages
|
^V Teleport between levels
|
||||||
^R Redraw screen
|
^W Wish for something
|
||||||
^T Teleport around level
|
&: #!debug
|
||||||
^V Teleport between levels (available in debug mode only)
|
^E unavailable debugging command
|
||||||
^W Wish (available in debug mode only)
|
^F unavailable debugging command
|
||||||
^X Show your attributes (shows more in debug or explore mode)
|
^G unavailable debugging command
|
||||||
^Z Suspend game (only if defined)
|
^I unavailable debugging command
|
||||||
a Apply (use) a tool
|
^O Shortcut for '#overview': list interesting levels you have visited
|
||||||
A Remove all armor
|
^V unavailable debugging command
|
||||||
b Go southwest 1 space
|
^W unavailable debugging command
|
||||||
B Go southwest until you are on top of something
|
&. #?debug
|
||||||
^B Go southwest until you are near something
|
&? number_pad=0,-1
|
||||||
c Close a door
|
b Go southwest 1 space
|
||||||
C Call (name) a monster, an individual object, or a type of object
|
B Go southwest until you are on top of something
|
||||||
d Drop an item
|
h Go west 1 space
|
||||||
D Drop specific item types
|
H Go west until you are on top of something
|
||||||
e Eat something
|
j Go south 1 space
|
||||||
E Engrave writing on the floor
|
J Go south until you are on top of something
|
||||||
f Fire ammunition from quiver
|
k Go north 1 space
|
||||||
F Followed by direction, fight a monster (even if you don't sense it)
|
K Go north until you are on top of something
|
||||||
g Followed by direction, move until you are near something
|
l Go east 1 space
|
||||||
G Followed by direction, same as control-direction
|
L Go east until you are on top of something
|
||||||
h Go west 1 space (if number_pad is on, display help message)
|
n Go southeast 1 space
|
||||||
H Go west until you are on top of something
|
N Go southeast until you are on something
|
||||||
^H Go west until you are near something
|
u Go northeast 1 space
|
||||||
i Show your inventory
|
U Go northeast until you are on top of something
|
||||||
I Inventory specific item types
|
&# y,Y handled below
|
||||||
j Go south 1 space (or if number_pad is on, jump to another location)
|
&: #number_pad=1,2,3,4
|
||||||
J Go south until you are on top of something
|
h Help: synonym for '?'
|
||||||
^J Go south until you are near something
|
j Jump: shortcut for '#jump'
|
||||||
k Go north 1 space (or if number_pad is on, kick something)
|
k Kick: synonym for '^D'
|
||||||
K Go north until you are on top of something
|
l Loot: shortcut for '#loot'
|
||||||
^K Go north until you are near something
|
n Start a count; continue with digit(s)
|
||||||
l Go east 1 space (or if number_pad is on, loot a box on the floor)
|
N Name: shortcut for '#name'
|
||||||
L Go east until you are on top of something
|
u Untrap: shortcut for '#untrap'
|
||||||
^L Go east until you are near something
|
&. #0,-1 vs 1,2,3,4
|
||||||
m Followed by direction, move without picking anything up or fighting
|
a Apply (use) a tool or break a wand
|
||||||
M Followed by direction, move a distance without picking anything up
|
A Remove all armor and/or all accessories and/or unwield weapons
|
||||||
n Go southeast 1 space
|
^A Redo the previous command
|
||||||
N Go southeast until you are on something (if number_pad is on, name)
|
^B Go southwest until you are near something
|
||||||
^N Go southeast until you are near something
|
c Close a door
|
||||||
o Open a door
|
C Call (name) a monster, an individual object, or a type of object
|
||||||
O Show option settings, possibly change them
|
^C Interrupt: quit the game
|
||||||
p Pay your shopping bill
|
d Drop an item
|
||||||
P Put on an accessory (ring, amulet, etc)
|
D Drop specific item types
|
||||||
q Quaff (drink) something (potion, water, etc)
|
^D Kick something (usually a door, chest, or box)
|
||||||
Q Select ammunition for quiver
|
e Eat something
|
||||||
r Read a scroll or spellbook
|
E Engrave writing on the floor
|
||||||
R Remove an accessory (ring, amulet, etc)
|
f Fire ammunition from quiver
|
||||||
s Search for traps and secret doors
|
F Followed by direction, fight a monster (even if you don't sense it)
|
||||||
S Save the game
|
g Followed by direction, move until you are near something
|
||||||
t Throw something
|
G Followed by direction, same as control-direction
|
||||||
T Take off one piece of armor
|
^H Go west until you are near something
|
||||||
u Go northeast 1 space (or if number_pad is on, untrap something)
|
i Show your inventory
|
||||||
U Go northeast until you are on top of something
|
I Inventory specific item types
|
||||||
^U Go northeast until you are near something
|
^J Go south until you are near something
|
||||||
v Show version
|
^K Go north until you are near something
|
||||||
V Show long version and game history
|
^L Go east until you are near something
|
||||||
w Wield (put in use) a weapon
|
m Followed by direction, move without picking anything up or fighting
|
||||||
W Wear a piece of armor
|
M Followed by direction, move a distance without picking anything up
|
||||||
x Swap wielded and secondary weapons
|
^N Go southeast until you are near something
|
||||||
X Toggle two-weapon combat
|
o Open a door
|
||||||
y Go northwest 1 space
|
O Show option settings, possibly change them
|
||||||
Y Go northwest until you are on top of something
|
p Pay your shopping bill
|
||||||
^Y Go northwest until you are near something
|
P Put on an accessory (ring, amulet, etc; will work for armor too)
|
||||||
z Zap a wand
|
^P Toggle through previously displayed game messages
|
||||||
Z Zap (cast) a spell
|
q Quaff (drink) something (potion, water, etc)
|
||||||
< Go up a staircase
|
Q Select ammunition for quiver (use '#quit' to quit)
|
||||||
> Go down a staircase
|
r Read a scroll or spellbook
|
||||||
/ Show what type of thing a symbol corresponds to
|
R Remove an accessory (ring, amulet, etc; will work for armor too)
|
||||||
? Give a help message
|
^R Redraw screen
|
||||||
& Tell what a command does
|
s Search all immediately adjacent locations for traps and secret doors
|
||||||
! Do a shell escape (only if defined)
|
S Save the game (and exit; there is no "save and keep going")
|
||||||
\ Show what object types have been discovered
|
t Throw something (choose an item, then a direction--not a target)
|
||||||
` Show discovered types for one class of objects
|
T Take off one piece of armor (will work for accessories too)
|
||||||
_ Travel via a shortest-path algorithm to a point on the map
|
^T Teleport around level
|
||||||
. Rest one move while doing nothing
|
^U Go northeast until you are near something
|
||||||
Rest one move while doing nothing (if rest_on_space option is on)
|
v Show version ('#version' shows more information)
|
||||||
: Look at what is on the floor
|
V Show history of game's development
|
||||||
; Show what type of thing a map symbol on the level corresponds to
|
w Wield a weapon (for dual weapons: 'w' secondary, 'x', 'w' primary, 'X')
|
||||||
, Pick up things at the current location
|
W Wear a piece of armor (will work for accessories too)
|
||||||
@ Toggle the pickup option on/off
|
x Swap wielded and secondary weapons
|
||||||
) Show the weapon currently wielded
|
X Toggle two-weapon combat
|
||||||
[ Show the armor currently worn
|
^X Show your attributes (shows more in debug or explore mode)
|
||||||
= Show the ring(s) currently worn
|
&? number_pad=0,1,2,3,4
|
||||||
" Show the amulet currently worn
|
&? number_pad=0
|
||||||
( Show the tools currently in use
|
y Go northwest 1 space
|
||||||
* Show all equipment in use (combination of the ),[,=,",( commands)
|
Y Go northwest until you are on top of something
|
||||||
$ Count your gold
|
&.
|
||||||
+ List known spells
|
^Y Go northwest until you are near something
|
||||||
# Perform an extended command
|
z Zap a wand
|
||||||
M-? Display extended command help (if the platform allows this)
|
Z Zap (cast) a spell
|
||||||
M-2 Toggle two-weapon combat (unless number_pad is enabled)
|
&? suspend
|
||||||
M-a Adjust inventory letters
|
^Z Suspend game; 'fg' (foreground) to resume
|
||||||
M-A Annotate: supply a name for the current dungeon level
|
&:
|
||||||
M-c Talk to someone
|
^Z unavailable command: suspend
|
||||||
M-C Conduct: list voluntary challenges you have maintained
|
&.
|
||||||
M-d Dip an object into something
|
&: number_pad=-1
|
||||||
M-e Advance or check weapons skills
|
y Zap a wand
|
||||||
M-f Force a lock
|
Y Zap (cast) a spell
|
||||||
M-i Invoke an object's special powers
|
&? suspend
|
||||||
M-j Jump to another location
|
^Y Suspend game; 'fg' (foreground) to resume
|
||||||
M-l Loot a box on the floor
|
&:
|
||||||
M-m Use a monster's special ability
|
^Y unavailable command: suspend
|
||||||
M-n Name a monster, an individual object, or a type of object
|
&.
|
||||||
M-o Offer a sacrifice to the gods
|
z Go northwest 1 space
|
||||||
M-O Overview: show a summary of the explored dungeon
|
Z Go northwest until you are on top of something
|
||||||
M-p Pray to the gods for help
|
^Z Go northwest until you are near something
|
||||||
M-q Quit
|
&. #0,1..4 vs -1
|
||||||
M-r Rub a lamp
|
< Go up a staircase
|
||||||
M-R Ride: mount or dismount a saddled steed
|
> Go down a staircase
|
||||||
M-s Sit down
|
/ Show what type of thing a symbol corresponds to
|
||||||
M-t Turn undead
|
? Give a help message
|
||||||
M-T Tip: empty a container
|
&? shell
|
||||||
M-u Untrap something (trap, door, or chest)
|
! Do a shell escape; 'exit' shell to come back
|
||||||
M-v Print compile time options for this version of NetHack
|
&:
|
||||||
M-w Wipe off your face
|
! unavailable command: shell
|
||||||
|
&.
|
||||||
|
\ Show what object types have been discovered
|
||||||
|
` Show discovered types for one class of objects
|
||||||
|
_ Travel via a shortest-path algorithm to a point on the map
|
||||||
|
. Rest one move while doing nothing
|
||||||
|
&? rest_on_space
|
||||||
|
Rest one move while doing nothing
|
||||||
|
&.
|
||||||
|
: Look at what is on the floor
|
||||||
|
; Show what type of thing a map symbol on the level corresponds to
|
||||||
|
, Pick up things at the current location
|
||||||
|
@ Toggle the pickup option on/off
|
||||||
|
) Show the weapon(s) currently wielded or readied
|
||||||
|
[ Show the armor currently worn
|
||||||
|
= Show the ring(s) currently worn
|
||||||
|
" Show the amulet currently worn
|
||||||
|
( Show the tools currently in use
|
||||||
|
* Show all equipment in use (combination of the ),[,=,",( commands)
|
||||||
|
$ Count your gold
|
||||||
|
+ List known spells
|
||||||
|
# Perform an extended command (use '#?' to list choices)
|
||||||
|
&# number_pad:
|
||||||
|
&# -1 = numpad off, swap y with z (including Y with Z, ^Y with ^Z, M-y &c)
|
||||||
|
&# 0 = numpad off (default)
|
||||||
|
&# 1 = numpad on, normal keypad layout, '5'->'g'
|
||||||
|
&# 2 = numpad on, normal keypad layout, '5'->'G'
|
||||||
|
&# 3 = numpad on, phone keypad layout, '5'->'g'
|
||||||
|
&# 4 = numpad on, phone keypad layout, '5'->'G'
|
||||||
|
&? number_pad = 1,2,3,4
|
||||||
|
0 Show inventory
|
||||||
|
4 Move west
|
||||||
|
6 Move east
|
||||||
|
&: #-1,0
|
||||||
|
0 Continue a count
|
||||||
|
4 Start or continue a count
|
||||||
|
6 Start or continue a count
|
||||||
|
&. #1,2,3,4 vs -1,0
|
||||||
|
&? number_pad=1,2
|
||||||
|
7 Move northwest
|
||||||
|
8 Move north
|
||||||
|
9 Move northeast
|
||||||
|
1 Move southwest
|
||||||
|
2 Move south
|
||||||
|
3 Move southeast
|
||||||
|
&: number_pad=3,4
|
||||||
|
1 Move northwest
|
||||||
|
2 Move north
|
||||||
|
3 Move northeast
|
||||||
|
7 Move southwest
|
||||||
|
8 Move south
|
||||||
|
9 Move southeast
|
||||||
|
&: #-1,0
|
||||||
|
1 Start or continue a count
|
||||||
|
2 Start or continue a count
|
||||||
|
3 Start or continue a count
|
||||||
|
7 Start or continue a count
|
||||||
|
8 Start or continue a count
|
||||||
|
9 Start or continue a count
|
||||||
|
&. #1,2 vs 3,4 vs -1,0
|
||||||
|
&? number_pad=1,3
|
||||||
|
5 'g' movement prefix
|
||||||
|
&: number_pad=2,4
|
||||||
|
5 'G' movement prefix
|
||||||
|
&: #-1,0
|
||||||
|
5 Start or continue a count
|
||||||
|
M-2 Toggle two-weapon combat
|
||||||
|
&. #1,3 vs 2,4 vs -1,0
|
||||||
|
M-? Display extended command help (if the platform allows this)
|
||||||
|
M-a Adjust inventory letters
|
||||||
|
M-A Annotate: supply a name for the current dungeon level
|
||||||
|
M-c Chat: talk to an adjacent creature
|
||||||
|
M-C Conduct: list voluntary challenges you have maintained
|
||||||
|
M-d Dip an object into something
|
||||||
|
M-e Enhance: check weapons skills, advance them if eligible
|
||||||
|
M-f Force a lock
|
||||||
|
M-i Invoke an object's special powers
|
||||||
|
M-j Jump to a nearby location
|
||||||
|
M-l Loot a box on the floor
|
||||||
|
M-m When polymorphed, use a monster's special ability
|
||||||
|
M-n Name a monster, an individual object, or a type of object
|
||||||
|
M-N Name a monster, an individual object, or a type of object
|
||||||
|
M-o Offer a sacrifice to the gods
|
||||||
|
M-O Overview: show a summary of the explored dungeon
|
||||||
|
M-p Pray to the gods for help
|
||||||
|
M-q Quit (exit without saving)
|
||||||
|
M-r Rub a lamp or a touchstone
|
||||||
|
M-R Ride: mount or dismount a saddled steed
|
||||||
|
M-s Sit down
|
||||||
|
M-t Turn undead
|
||||||
|
M-T Tip: empty a container
|
||||||
|
M-u Untrap something (trap, door, or chest)
|
||||||
|
M-v Print compile time options for this version of NetHack
|
||||||
|
M-w Wipe off your face
|
||||||
|
|||||||
+163
-23
@@ -17,6 +17,8 @@ STATIC_DCL struct permonst *FDECL(lookat, (int, int, char *, char *));
|
|||||||
STATIC_DCL void FDECL(checkfile, (char *, struct permonst *,
|
STATIC_DCL void FDECL(checkfile, (char *, struct permonst *,
|
||||||
BOOLEAN_P, BOOLEAN_P));
|
BOOLEAN_P, BOOLEAN_P));
|
||||||
STATIC_DCL void FDECL(look_all, (BOOLEAN_P,BOOLEAN_P));
|
STATIC_DCL void FDECL(look_all, (BOOLEAN_P,BOOLEAN_P));
|
||||||
|
STATIC_DCL void NDECL(whatdoes_help);
|
||||||
|
STATIC_DCL boolean FDECL(whatdoes_cond, (char *, boolean *, int *, int));
|
||||||
STATIC_DCL boolean FDECL(help_menu, (int *));
|
STATIC_DCL boolean FDECL(help_menu, (int *));
|
||||||
STATIC_DCL void NDECL(docontact);
|
STATIC_DCL void NDECL(docontact);
|
||||||
#ifdef PORT_HELP
|
#ifdef PORT_HELP
|
||||||
@@ -1307,7 +1309,7 @@ doidtrap()
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC_DCL void
|
STATIC_DCL void
|
||||||
dowhatdoes_help()
|
whatdoes_help()
|
||||||
{
|
{
|
||||||
dlb *fp;
|
dlb *fp;
|
||||||
char *p, buf[BUFSZ];
|
char *p, buf[BUFSZ];
|
||||||
@@ -1332,14 +1334,131 @@ dowhatdoes_help()
|
|||||||
destroy_nhwindow(tmpwin);
|
destroy_nhwindow(tmpwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define WD_STACKLIMIT 5
|
||||||
|
|
||||||
|
STATIC_OVL boolean
|
||||||
|
whatdoes_cond(buf, stack, depth, lnum)
|
||||||
|
char *buf;
|
||||||
|
boolean *stack;
|
||||||
|
int *depth, lnum;
|
||||||
|
{
|
||||||
|
const char badstackfmt[] = "cmdhlp: too many &%c directives at line %d.";
|
||||||
|
boolean newcond, neg;
|
||||||
|
char *p, *q, act = buf[1];
|
||||||
|
int np = 0;
|
||||||
|
|
||||||
|
buf += 2;
|
||||||
|
mungspaces(buf);
|
||||||
|
if (act == '#' || *buf == '#') {
|
||||||
|
*buf = '\0';
|
||||||
|
neg = FALSE; /* lint suppression */
|
||||||
|
p = q = (char *) 0;
|
||||||
|
} else {
|
||||||
|
if ((neg = (*buf == '!')) != 0)
|
||||||
|
if (*++buf == ' ')
|
||||||
|
++buf;
|
||||||
|
p = index(buf, '='), q = index(buf, ':');
|
||||||
|
if (!p || (q && q < p))
|
||||||
|
p = q;
|
||||||
|
if (p) { /* we have a value specified */
|
||||||
|
/* handle a space before or after (or both) '=' (or ':') */
|
||||||
|
if (p > buf && p[-1] == ' ')
|
||||||
|
p[-1] = '\0'; /* end of keyword in buf[] */
|
||||||
|
*p++ = '\0'; /* terminate keyword, advance to start of value */
|
||||||
|
if (*p == ' ')
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newcond = TRUE;
|
||||||
|
if (*buf && (act == '?' || act == ':')) {
|
||||||
|
if (!strcmpi(buf, "number_pad")) {
|
||||||
|
if (!p) {
|
||||||
|
newcond = iflags.num_pad;
|
||||||
|
} else {
|
||||||
|
/* convert internal encoding (separate yes/no and 0..3)
|
||||||
|
back to user-visible one (-1..4) */
|
||||||
|
np = iflags.num_pad ? (1 + iflags.num_pad_mode) /* 1..4 */
|
||||||
|
: (-1 * iflags.num_pad_mode); /* -1..0 */
|
||||||
|
newcond = FALSE;
|
||||||
|
for (; p; p = q) {
|
||||||
|
q = index(p, ',');
|
||||||
|
if (q)
|
||||||
|
*q++ = '\0';
|
||||||
|
if (atoi(p) == np) {
|
||||||
|
newcond = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!strcmpi(buf, "rest_on_space")) {
|
||||||
|
newcond = flags.rest_on_space;
|
||||||
|
} else if (!strcmpi(buf, "debug") || !strcmpi(buf, "wizard")) {
|
||||||
|
newcond = flags.debug; /* == wizard */
|
||||||
|
} else if (!strcmpi(buf, "shell")) {
|
||||||
|
#ifdef SHELL
|
||||||
|
/* should we also check sysopt.shellers? */
|
||||||
|
newcond = TRUE;
|
||||||
|
#else
|
||||||
|
newcond = FALSE;
|
||||||
|
#endif
|
||||||
|
} else if (!strcmpi(buf, "suspend")) {
|
||||||
|
#ifdef SUSPEND
|
||||||
|
/* sysopt.shellers is also used for dosuspend()... */
|
||||||
|
newcond = TRUE;
|
||||||
|
#else
|
||||||
|
newcond = FALSE;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
impossible(
|
||||||
|
"cmdhelp: unrecognized &%c conditional at line %d: \"%.20s\"",
|
||||||
|
act, lnum, buf);
|
||||||
|
neg = FALSE;
|
||||||
|
}
|
||||||
|
/* this works for number_pad too: &? !number_pad:-1,0
|
||||||
|
would be true for 1..4 after negation */
|
||||||
|
if (neg)
|
||||||
|
newcond = !newcond;
|
||||||
|
}
|
||||||
|
switch (act) {
|
||||||
|
default:
|
||||||
|
case '#': /* comment */
|
||||||
|
break;
|
||||||
|
case '.': /* endif */
|
||||||
|
if (--*depth < 0) {
|
||||||
|
impossible(badstackfmt, '.', lnum);
|
||||||
|
*depth = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ':': /* else or elif */
|
||||||
|
if (*depth == 0) {
|
||||||
|
impossible(badstackfmt, ':', lnum);
|
||||||
|
*depth = 1; /* so that stack[*depth - 1] is a valid access */
|
||||||
|
}
|
||||||
|
if (stack[*depth] || !stack[*depth - 1])
|
||||||
|
stack[*depth] = FALSE;
|
||||||
|
else if (newcond)
|
||||||
|
stack[*depth] = TRUE;
|
||||||
|
break;
|
||||||
|
case '?': /* if */
|
||||||
|
if (++*depth >= WD_STACKLIMIT) {
|
||||||
|
impossible(badstackfmt, '?', lnum);
|
||||||
|
*depth = WD_STACKLIMIT - 1;
|
||||||
|
}
|
||||||
|
stack[*depth] = newcond && stack[*depth - 1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return stack[*depth];
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
dowhatdoes_core(q, cbuf)
|
dowhatdoes_core(q, cbuf)
|
||||||
char q;
|
char q;
|
||||||
char *cbuf;
|
char *cbuf;
|
||||||
{
|
{
|
||||||
dlb *fp;
|
dlb *fp;
|
||||||
char bufr[BUFSZ];
|
char buf[BUFSZ];
|
||||||
register char *buf = &bufr[6], ctrl, meta;
|
boolean cond, stack[WD_STACKLIMIT];
|
||||||
|
int ctrl, meta, depth = 0, lnum = 0;
|
||||||
|
|
||||||
fp = dlb_fopen(CMDHELPFILE, "r");
|
fp = dlb_fopen(CMDHELPFILE, "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
@@ -1347,25 +1466,44 @@ char *cbuf;
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrl = ((q <= '\033') ? (q - 1 + 'A') : 0);
|
meta = (0x80 & (uchar) q) != 0;
|
||||||
meta = ((0x80 & q) ? (0x7f & q) : 0);
|
if (meta)
|
||||||
while (dlb_fgets(buf, BUFSZ - 6, fp)) {
|
q &= 0x7f;
|
||||||
if ((ctrl && *buf == '^' && *(buf + 1) == ctrl)
|
ctrl = (0x1f & (uchar) q) == (uchar) q;
|
||||||
|| (meta && *buf == 'M' && *(buf + 1) == '-'
|
if (ctrl)
|
||||||
&& *(buf + 2) == meta) || *buf == q) {
|
q |= 0x40; /* NUL -> '@', ^A -> 'A', ... ^Z -> 'Z', ^[ -> '[', ... */
|
||||||
|
else if (q == 0x7f)
|
||||||
|
ctrl = 1, q = '?';
|
||||||
|
|
||||||
|
cond = stack[0] = TRUE, stack[1] = FALSE;
|
||||||
|
while (dlb_fgets(buf, sizeof buf, fp)) {
|
||||||
|
++lnum;
|
||||||
|
if (buf[0] == '&' && buf[1] && index("?:.#", buf[1])) {
|
||||||
|
cond = whatdoes_cond(buf, stack, &depth, lnum);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!cond)
|
||||||
|
continue;
|
||||||
|
if (meta ? (buf[0] == 'M' && buf[1] == '-'
|
||||||
|
&& (ctrl ? buf[2] == '^' && highc(buf[3]) == q
|
||||||
|
: buf[2] == q))
|
||||||
|
: (ctrl ? buf[0] == '^' && highc(buf[1]) == q
|
||||||
|
: buf[0] == q)) {
|
||||||
(void) strip_newline(buf);
|
(void) strip_newline(buf);
|
||||||
if (ctrl && buf[2] == '\t') {
|
if (index(buf, '\t'))
|
||||||
buf = bufr + 1;
|
(void) tabexpand(buf);
|
||||||
(void) strncpy(buf, "^? ", 8);
|
if (meta && ctrl && buf[4] == ' ') {
|
||||||
buf[1] = ctrl;
|
(void) strncpy(buf, "M-^? ", 8);
|
||||||
} else if (meta && buf[3] == '\t') {
|
buf[3] = q;
|
||||||
buf = bufr + 2;
|
} else if (meta && buf[3] == ' ') {
|
||||||
(void) strncpy(buf, "M-? ", 8);
|
(void) strncpy(buf, "M-? ", 8);
|
||||||
buf[2] = meta;
|
buf[2] = q;
|
||||||
} else if (buf[1] == '\t') {
|
} else if (ctrl && buf[2] == ' ') {
|
||||||
buf = bufr;
|
(void) strncpy(buf, "^? ", 8);
|
||||||
|
buf[1] = q;
|
||||||
|
} else if (buf[1] == ' ') {
|
||||||
|
(void) strncpy(buf, "? ", 8);
|
||||||
buf[0] = q;
|
buf[0] = q;
|
||||||
(void) strncpy(buf + 1, " ", 7);
|
|
||||||
}
|
}
|
||||||
(void) dlb_fclose(fp);
|
(void) dlb_fclose(fp);
|
||||||
Strcpy(cbuf, buf);
|
Strcpy(cbuf, buf);
|
||||||
@@ -1373,6 +1511,8 @@ char *cbuf;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void) dlb_fclose(fp);
|
(void) dlb_fclose(fp);
|
||||||
|
if (depth != 0)
|
||||||
|
impossible("cmdhelp: mismatched &? &: &. conditionals.");
|
||||||
return (char *) 0;
|
return (char *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1395,9 +1535,9 @@ dowhatdoes()
|
|||||||
if (q == '\033' && iflags.altmeta) {
|
if (q == '\033' && iflags.altmeta) {
|
||||||
/* in an ideal world, we would know whether another keystroke
|
/* in an ideal world, we would know whether another keystroke
|
||||||
was already pending, but this is not an ideal world...
|
was already pending, but this is not an ideal world...
|
||||||
if user types ESC, we'll essentially hang until another
|
if user typed ESC, we'll essentially hang until another
|
||||||
character is typed */
|
character is typed */
|
||||||
q = yn_function("", (char *) 0, '\0');
|
q = yn_function("]", (char *) 0, '\0');
|
||||||
if (q != '\033')
|
if (q != '\033')
|
||||||
q = (char) ((uchar) q | 0200);
|
q = (char) ((uchar) q | 0200);
|
||||||
}
|
}
|
||||||
@@ -1407,7 +1547,7 @@ dowhatdoes()
|
|||||||
reslt = dowhatdoes_core(q, bufr);
|
reslt = dowhatdoes_core(q, bufr);
|
||||||
if (reslt) {
|
if (reslt) {
|
||||||
if (q == '&' || q == '?')
|
if (q == '&' || q == '?')
|
||||||
dowhatdoes_help();
|
whatdoes_help();
|
||||||
pline("%s", reslt);
|
pline("%s", reslt);
|
||||||
} else {
|
} else {
|
||||||
pline("No such command '%s', char code %d (0%03o or 0x%02x).",
|
pline("No such command '%s', char code %d (0%03o or 0x%02x).",
|
||||||
@@ -1416,7 +1556,7 @@ dowhatdoes()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
STATIC_OVL void
|
||||||
docontact()
|
docontact()
|
||||||
{
|
{
|
||||||
winid cwin = create_nhwindow(NHW_TEXT);
|
winid cwin = create_nhwindow(NHW_TEXT);
|
||||||
|
|||||||
Reference in New Issue
Block a user