From: PatR Date: Thu, 10 Dec 2020 00:52:54 +0000 (-0800) Subject: txt2key() - parsing key binding specifications X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e1406a8c087d164e9355cb124410145b2109d686;p=nethack txt2key() - parsing key binding specifications While testing some addtional ?i (list of key assignments) changes, I wanted to give every key a binding. When I tried BIND=M-^A:exploremode the text to key conversion didn't like that. This adds support for M-^x and M-C-x plus variations where dashes are omitted. This adds support for ^? even though that isn't really a control character. I bound #terrain to it and surprising--to me at least--the key worked to invoke that command. Also changes 'char txt2key(...)' to be 'uchar txt2key(...)'. --- diff --git a/include/extern.h b/include/extern.h index 4fc957d30..bbb2fd88d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.886 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1607561572 2020/12/10 00:52:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.928 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -229,7 +229,7 @@ E void FDECL(pushch, (CHAR_P)); E void FDECL(savech, (CHAR_P)); E const char *FDECL(key2extcmddesc, (UCHAR_P)); E boolean FDECL(bind_specialkey, (UCHAR_P, const char *)); -E char FDECL(txt2key, (char *)); +E uchar FDECL(txt2key, (char *)); E void FDECL(parseautocomplete, (char *, BOOLEAN_P)); E void FDECL(reset_commands, (BOOLEAN_P)); E void FDECL(rhack, (char *)); diff --git a/src/cmd.c b/src/cmd.c index bd348ae8d..bc50986ec 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1607471879 2020/12/08 23:57:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.429 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1607561570 2020/12/10 00:52:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.430 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -379,7 +379,7 @@ const struct ext_func_tab *efp; /* if Null, add a footnote to the menu */ } } -/* here after #? - now list all full-word commands and provid +/* here after #? - now list all full-word commands and provide some navigation capability through the long list */ int doextlist(VOID_ARGS) @@ -2858,19 +2858,21 @@ const char *command; return FALSE; } -/* returns a one-byte character from the text (it may massacre the txt - * buffer) */ -char +/* returns a one-byte character from the text; may change txt[] */ +uchar txt2key(txt) char *txt; { + uchar uc; + boolean makemeta = FALSE; + txt = trimspaces(txt); if (!*txt) return '\0'; /* simple character */ if (!txt[1]) - return txt[0]; + return (uchar) txt[0]; /* a few special entries */ if (!strcmp(txt, "")) @@ -2881,25 +2883,55 @@ char *txt; return '\033'; /* control and meta keys */ - switch (*txt) { - case 'm': /* can be mx, Mx, m-x, M-x */ - case 'M': - txt++; + if (highc(*txt) == 'M') { + /* + * M return 'M' + * M - return M-'-' + * M return M- + * 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 '\0'; - return M(*txt); - case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */ - case 'C': - case '^': - txt++; + ++txt; + if (!txt[1]) + return M((uchar) *txt); + makemeta = TRUE; + } + if (*txt == '^' || highc(*txt) == 'C') { + /* + * C return 'C' or M-'C' + * C - return '-' or M-'-' + * C [-] return C- or M-C- + * C [-] ? return + * otherwise return C- or M-C- + */ + 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++; - if (txt[1]) - return '\0'; - return C(*txt); + ++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') { @@ -2929,9 +2961,9 @@ char *txt; /* sufficiently long buffer */ if (c == ' ') Sprintf(txt, ""); else if (c == '\033') - Sprintf(txt, ""); + Sprintf(txt, ""); /* "" won't fit */ else if (c == '\n') - Sprintf(txt, ""); + Sprintf(txt, ""); /* "" won't fit */ else if (c == '\177') Sprintf(txt, ""); /* "" won't fit */ else diff --git a/src/options.c b/src/options.c index e82877b5a..f4a008c9b 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1606445249 2020/11/27 02:47:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.482 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1607561571 2020/12/10 00:52:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.484 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -281,7 +281,7 @@ static boolean FDECL(is_wc2_option, (const char *)); static boolean FDECL(wc2_supported, (const char *)); static void FDECL(wc_set_font_name, (int, char *)); static int FDECL(wc_set_window_colors, (char *)); -static boolean FDECL(illegal_menu_cmd_key, (CHAR_P)); +static boolean FDECL(illegal_menu_cmd_key, (UCHAR_P)); #ifndef CHANGE_COLOR int FDECL(optfn_palette, (int, int, BOOLEAN_P, char *, char *)); #endif @@ -4664,7 +4664,7 @@ char *op; escapes(op, op_buf); c = *op_buf; - if (illegal_menu_cmd_key(c)) + if (illegal_menu_cmd_key((uchar) c)) return optn_err; add_menu_cmd_alias(c, default_menu_cmd_info[midx].cmd); } @@ -6362,10 +6362,10 @@ const char *optn; /* parse key:command */ boolean parsebindings(bindings) -char* bindings; +char *bindings; { char *bind; - char key; + uchar key; int i; boolean ret = FALSE; @@ -6400,7 +6400,7 @@ char* bindings; config_error_add("Bad menu key %s:%s", visctrl(key), bind); return FALSE; } else - add_menu_cmd_alias(key, default_menu_cmd_info[i].cmd); + add_menu_cmd_alias((char) key, default_menu_cmd_info[i].cmd); return TRUE; } } @@ -7151,18 +7151,19 @@ char **opp; /* Check if character c is illegal as a menu command key */ boolean illegal_menu_cmd_key(c) -char c; +uchar c; { - if (c == 0 || c == '\r' || c == '\n' || c == '\033' - || c == ' ' || digit(c) || (letter(c) && c != '@')) { - config_error_add("Reserved menu command key '%s'", visctrl(c)); + if (c == 0 || c == '\r' || c == '\n' || c == '\033' || c == ' ' + || digit((char) c) || (letter((char) c) && c != '@')) { + config_error_add("Reserved menu command key '%s'", visctrl((char) c)); return TRUE; } else { /* reject default object class symbols */ int j; + for (j = 1; j < MAXOCLASSES; j++) - if (c == def_oc_syms[j].sym) { + if (c == (uchar) def_oc_syms[j].sym) { config_error_add("Menu command key '%s' is an object class", - visctrl(c)); + visctrl((char) c)); return TRUE; } }