From: PatR Date: Thu, 7 Apr 2016 00:06:33 +0000 (-0700) Subject: symset parsing X-Git-Tag: NetHack-3.6.1_RC01~843 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3381aa41220fac81d7cccb220d0bd39849e14fd8;p=nethack symset parsing Add support for character enclosed within single quotes. Single character without quotes would work for most characters, but not '#' and possibly not '^' or '\\'. All the values in dat/symbols are specified via backslash+digits so it isn't obvious that some other form of value is allowed. I think this parsing accepts all valid values. It doesn't reject all invalid ones: opening quote followed by valid escape sequence followed by junk followed by closing quote will ignore the junk. I don't think there's any pressing need to worry about that. --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index d4a83b64a..416b3889b 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -280,6 +280,7 @@ REPRODUCIBLE_BUILD is new config.h setting to fetch build date+time from environment instead of using current date+time, so that later rebuild could duplicate the original (disabled by default; tested for Unix) default value for vibrating square symbol changed from yellow '^' to purple '~' +allow symbol set values to be specified via char within single quotes Platform- and/or Interface-Specific New Features diff --git a/include/extern.h b/include/extern.h index bf0faf578..679d486e1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1457570257 2016/03/10 00:37:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.552 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1459987582 2016/04/07 00:06:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.554 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1661,7 +1661,7 @@ E void NDECL(free_symsets); E boolean FDECL(parsesymbols, (char *)); E struct symparse *FDECL(match_sym, (char *)); E void NDECL(set_playmode); -E int FDECL(sym_val, (char *)); +E int FDECL(sym_val, (const char *)); E const char *FDECL(clr2colorname, (int)); E int FDECL(match_str2clr, (char *)); E boolean FDECL(add_menu_coloring, (char *)); diff --git a/src/files.c b/src/files.c index 2b1832fc6..b505a4db7 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 files.c $NHDT-Date: 1455835581 2016/02/18 22:46:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.204 $ */ +/* NetHack 3.6 files.c $NHDT-Date: 1459987580 2016/04/07 00:06:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.205 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2820,14 +2820,13 @@ int which_set; mungspaces(buf); if (!*buf || *buf == '#' || !strcmp(buf, " ")) return 1; - /* remove trailing comment, if any */ - if ((commentp = rindex(buf, '#')) != 0) { - *commentp = '\0'; - /* remove space preceding the stripped comment, if any; - we know 'commentp > buf' because *buf=='#' was caught above */ - if (commentp[-1] == ' ') - *--commentp = '\0'; - } + /* remove trailing comment, if any (this isn't strictly needed for + individual symbols, and it won't matter if "X#comment" without + separating space slips through; for handling or set description, + symbol set creator is responsible for preceding '#' with a space + and that comment itself doesn't contain " #") */ + if ((commentp = rindex(buf, '#')) != 0 && commentp[-1] == ' ') + commentp[-1] = '\0'; /* find the '=' or ':' */ bufp = index(buf, '='); diff --git a/src/options.c b/src/options.c index af854e9c8..7b7e0c657 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1455357588 2016/02/13 09:59:48 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.264 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1459987581 2016/04/07 00:06:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.267 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -858,8 +858,8 @@ char *tp; } else if (*cp == '^') { /* expand control-character syntax */ cval = (*++cp & 0x1f); ++cp; - /* remaining cases are all for backslash and we know cp[1] is not - * \0 */ + + /* remaining cases are all for backslash; we know cp[1] is not \0 */ } else if (index(dec, cp[1])) { ++cp; /* move past backslash to first digit */ do { @@ -5218,11 +5218,41 @@ char *buf; int sym_val(strval) -char *strval; +const char *strval; { char buf[QBUFSZ]; + buf[0] = '\0'; - escapes(strval, buf); + if (!strval[0] || !strval[1]) { /* empty, or single character */ + /* if single char is space or tab, leave buf[0]=='\0' */ + if (!isspace(strval[0])) + buf[0] = strval[0]; + } else if (strval[0] == '\'') { /* single quote */ + /* simple matching single quote; we know strval[1] isn't '\0' */ + if (strval[2] == '\'' && !strval[3]) { + /* accepts '\' as backslash and ''' as single quote */ + buf[0] = strval[1]; + + /* if backslash, handle single or double quote or second backslash */ + } else if (strval[1] == '\\' && strval[2] && strval[3] == '\'' + && index("'\"\\", strval[2]) && !strval[4]) { + buf[0] = strval[2]; + + /* not simple quote or basic backslash; + strip closing quote and let escapes() deal with it */ + } else { + char *p, tmp[QBUFSZ]; + + (void) strncpy(tmp, strval + 1, sizeof tmp - 1); + tmp[sizeof tmp - 1] = '\0'; + if ((p = rindex(tmp, '\'')) != 0) { + *p = '\0'; + escapes(tmp, buf); + } /* else buf[0] stays '\0' */ + } + } else /* not lone char nor single quote */ + escapes(strval, buf); + return (int) *buf; }