applying a polearm to attempt to attack a hidden monster would report "wait!
there's a monster hidden there" and display the "remembered, unseen
monster" glyph but only use a turn if polearm wasn't already wielded
+key parsing during options processing was inconsistent between OPTIONS=foo:k
+ BINDINGS=k:foo where k represents a key designation; the OPTIONS form
+ recognized backslash escape sequences but not M-x meta characters,
+ vice versa for BINDINGS (most noticeable for menu interaction keys
+ such as menu_next_page because those can be set via either directive)
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
extern void savech(char);
extern const char *key2extcmddesc(uchar);
extern boolean bind_specialkey(uchar, const char *);
-extern uchar txt2key(char *);
extern void parseautocomplete(char *, boolean);
extern void reset_commands(boolean);
extern void rhack(char *);
/* ### options.c ### */
extern boolean match_optname(const char *, const char *, int, boolean);
+extern uchar txt2key(char *);
extern void initoptions(void);
extern void initoptions_init(void);
extern void initoptions_finish(void);
(nhassert_failed(#expression, __FILE__, __LINE__), 0))
#endif
+/* Macros for meta and ctrl modifiers:
+ * M and C return the meta/ctrl code for the given character;
+ * e.g., (C('c') is ctrl-c
+ */
+#ifndef M
+#ifndef NHSTDC
+#define M(c) (0x80 | (c))
+#else
+#define M(c) ((c) - 128)
+#endif /* NHSTDC */
+#endif
+
+#ifndef C
+#define C(c) (0x1f & (c))
+#endif
+
+#define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
+#define unmeta(c) (0x7f & (c))
+
#endif /* GLOBAL_H */
NoAlias, "deselect all items in a menu")
NHOPTC(menu_deselect_page, 4, opt_in, set_in_config, No, Yes, No, No,
NoAlias, "deselect all items on this page of a menu")
- NHOPTC(menu_first_page, 4, opt_in, set_in_config, No, No, Yes, No, NoAlias,
- "jump to the first page in a menu")
+ NHOPTC(menu_first_page, 4, opt_in, set_in_config, No, Yes, No, No,
+ NoAlias, "jump to the first page in a menu")
NHOPTC(menu_headings, 4, opt_in, set_in_game, No, Yes, No, Yes, NoAlias,
"display style for menu headings")
NHOPTC(menu_invert_all, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias,
#include "hack.h"
#include "func_tab.h"
-/* Macros for meta and ctrl modifiers:
- * M and C return the meta/ctrl code for the given character;
- * e.g., (C('c') is ctrl-c
- */
-#ifndef M
-#ifndef NHSTDC
-#define M(c) (0x80 | (c))
-#else
-#define M(c) ((c) - 128)
-#endif /* NHSTDC */
-#endif
-
-#ifndef C
-#define C(c) (0x1f & (c))
-#endif
-
-#define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
-#define unmeta(c) (0x7f & (c))
-
#ifdef ALTMETA
static boolean alt_esc = FALSE;
#endif
return name;
}
-/* returns a one-byte character from the text; may change txt[] */
-uchar
-txt2key(char *txt)
-{
- uchar uc;
- boolean makemeta = FALSE;
-
- txt = trimspaces(txt);
- if (!*txt)
- return '\0';
-
- /* simple character */
- if (!txt[1])
- return (uchar) txt[0];
-
- /* a few special entries */
- if (!strcmp(txt, "<enter>"))
- return '\n';
- if (!strcmp(txt, "<space>"))
- return ' ';
- if (!strcmp(txt, "<esc>"))
- return '\033';
-
- /* control and meta keys */
- if (highc(*txt) == 'M') {
- /*
- * M <nothing> return 'M'
- * M - <nothing> return M-'-'
- * M <other><nothing> return M-<other>
- * otherwise M is pending until after ^/C- processing.
- * Since trailing spaces are discarded, the only way to
- * specify M-' ' is via "160".
- */
- if (!txt[1])
- return (uchar) *txt;
- /* skip past 'M' or 'm' and maybe '-' */
- ++txt;
- if (*txt == '-' && txt[1])
- ++txt;
- if (!txt[1])
- return M((uchar) *txt);
- makemeta = TRUE;
- }
- if (*txt == '^' || highc(*txt) == 'C') {
- /*
- * C <nothing> return 'C' or M-'C'
- * C - <nothing> return '-' or M-'-'
- * C [-] <other><nothing> return C-<other> or M-C-<other>
- * C [-] ? return <rubout>
- * otherwise return C-<other> or M-C-<other>
- */
- uc = (uchar) *txt;
- if (!txt[1])
- return makemeta ? M(uc) : uc;
- ++txt;
- /* unlike M-x, lots of values of x are invalid for C-x;
- checking and rejecting them is not worthwhile; GIGO;
- we do accept "^-x" as synonym for "^x" or "C-x" */
- if (*txt == '-' && txt[1])
- ++txt;
- /* and accept ^?, which gets used despite not being a control char */
- if (*txt == '?')
- return (uchar) (makemeta ? '\377' : '\177'); /* rubout/delete */
- uc = C((uchar) *txt);
- return makemeta ? M(uc) : uc;
- }
- if (makemeta && *txt)
- return M((uchar) *txt);
-
- /* FIXME: should accept single-quote single-character single-quote
- and probably single-quote backslash octal-digits single-quote;
- if we do that, the M- and C- results should be pending until
- after, so that C-'X' becomes valid for ^X */
-
- /* ascii codes: must be three-digit decimal */
- if (*txt >= '0' && *txt <= '9') {
- uchar key = 0;
- int i;
-
- for (i = 0; i < 3; i++) {
- if (txt[i] < '0' || txt[i] > '9')
- return '\0';
- key = 10 * key + txt[i] - '0';
- }
- return key;
- }
-
- return '\0';
-}
-
/* returns the text for a one-byte encoding;
* must be shorter than a tab for proper formatting */
char *
bad_negation(default_menu_cmd_info[midx].name, FALSE);
return optn_err;
} else if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
- char c, op_buf[BUFSZ];
-
- escapes(op, op_buf);
- c = *op_buf;
+ char c = txt2key(op);
if (illegal_menu_cmd_key((uchar) c))
return optn_err;
*tp = '\0';
}
+/* returns a one-byte character from the text; may change txt[];
+ moved from cmd.c in order to get access to escapes() */
+uchar
+txt2key(char *txt)
+{
+ uchar uc;
+ boolean makemeta = FALSE;
+
+ txt = trimspaces(txt);
+ if (!*txt)
+ return '\0';
+
+ /* simple character */
+ if (!txt[1])
+ return (uchar) txt[0];
+
+ /* a few special entries */
+ if (!strcmp(txt, "<enter>"))
+ return '\n';
+ if (!strcmp(txt, "<space>"))
+ return ' ';
+ if (!strcmp(txt, "<esc>"))
+ return '\033';
+
+ /* handle things like \b and \7 and \mX */
+ if (*txt == '\\') {
+ char tbuf[QBUFSZ];
+
+ if (strlen(txt) >= sizeof tbuf)
+ txt[sizeof tbuf - 1] = '\0';
+ escapes(txt, tbuf);
+ return *tbuf;
+ }
+
+ /* control and meta keys */
+ if (highc(*txt) == 'M') {
+ /*
+ * M <nothing> return 'M'
+ * M - <nothing> return M-'-'
+ * M <other><nothing> return M-<other>
+ * otherwise M is pending until after ^/C- processing.
+ * Since trailing spaces are discarded, the only way to
+ * specify M-' ' is via "160".
+ */
+ if (!txt[1])
+ return (uchar) *txt;
+ /* skip past 'M' or 'm' and maybe '-' */
+ ++txt;
+ if (*txt == '-' && txt[1])
+ ++txt;
+ if (!txt[1])
+ return M((uchar) *txt);
+ makemeta = TRUE;
+ }
+ if (*txt == '^' || highc(*txt) == 'C') {
+ /*
+ * C <nothing> return 'C' or M-'C'
+ * C - <nothing> return '-' or M-'-'
+ * C [-] <other><nothing> return C-<other> or M-C-<other>
+ * C [-] ? return <rubout>
+ * otherwise return C-<other> or M-C-<other>
+ */
+ uc = (uchar) *txt;
+ if (!txt[1])
+ return makemeta ? M(uc) : uc;
+ ++txt;
+ /* unlike M-x, lots of values of x are invalid for C-x;
+ checking and rejecting them is not worthwhile; GIGO;
+ we do accept "^-x" as synonym for "^x" or "C-x" */
+ if (*txt == '-' && txt[1])
+ ++txt;
+ /* and accept ^?, which gets used despite not being a control char */
+ if (*txt == '?')
+ return (uchar) (makemeta ? '\377' : '\177'); /* rubout/delete */
+ uc = C((uchar) *txt);
+ return makemeta ? M(uc) : uc;
+ }
+ if (makemeta && *txt)
+ return M((uchar) *txt);
+
+ /* FIXME: should accept single-quote single-character single-quote
+ and probably single-quote backslash octal-digits single-quote;
+ if we do that, the M- and C- results should be pending until
+ after, so that C-'X' becomes valid for ^X */
+
+ /* ascii codes: must be three-digit decimal */
+ if (*txt >= '0' && *txt <= '9') {
+ uchar key = 0;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ if (txt[i] < '0' || txt[i] > '9')
+ return '\0';
+ key = 10 * key + txt[i] - '0';
+ }
+ return key;
+ }
+
+ return '\0';
+}
+
/*
**********************************
*