]> granicus.if.org Git - nethack/commitdiff
END-CHOOSE directive for .nethackrc
authorPatR <rankin@nethack.org>
Thu, 6 Aug 2020 22:57:05 +0000 (15:57 -0700)
committerPatR <rankin@nethack.org>
Thu, 6 Aug 2020 22:57:05 +0000 (15:57 -0700)
Add an optional way to terminate the last section after a CHOOSE
directive in the run-time options file so that it's possible to
revert to common options.  If no END-CHOOSE directive is present
then the last CHOOSE section continues until the end of the file.
(All existing uses of CHOOSE already behave that way.)

Change the Guidebook to refer to OPTIONS=x, AUTOPICKUP_EXCEPTION=y,
CHOOSE=z, and so on as "directives" rather than "statements".  It
just feels like a better fit.

doc/Guidebook.mn
doc/Guidebook.tex
doc/fixes37.0
src/files.c

index 713d2cbafb679214aa42cb03e190ab8cbc13d987..dfa15732b4bbc599f96708b1a41cc82b96c8544e 100644 (file)
@@ -1,4 +1,4 @@
-.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.393 $ $NHDT-Date: 1595731545 2020/07/26 02:45:45 $
+.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.394 $ $NHDT-Date: 1596754607 2020/08/06 22:56:47 $
 .\"
 .\" This is an excerpt from the 'roff' man page from the 'groff' package.
 .\" Guidebook.mn currently does *not* fully adhere to these guidelines.
@@ -35,7 +35,7 @@
 .ds vr "NetHack 3.7
 .ds f0 "\*(vr
 .ds f1
-.ds f2 "July 25, 2020
+.ds f2 "August 5, 2020
 .
 .\" A note on some special characters:
 .\" \(lq = left double quote
@@ -3138,16 +3138,16 @@ Any line beginning with \(oq[\(cq and ending in \(oq]\(cq is considered
 a section marker.
 The text between the square brackets is the section name.
 Lines after a section marker belong to that section, and are
-ignored unless a CHOOSE statement was used to select that section.
+ignored unless a CHOOSE directive was used to select that section.
 Section names are case insensitive.
 .pg
-You can use different configuration statements in the file, some
+You can use different configuration directives in the file, some
 of which can be used multiple times.
-In general, the statements are
+In general, the directives are
 written in capital letters, followed by an equals sign, followed by
-settings particular to that statement.
+settings particular to that directive.
 .pg
-Here is a list of allowed statements:
+Here is a list of allowed directives:
 .lp OPTIONS
 There are two types of options, boolean and compound options.
 Boolean options toggle a setting on or off, while compound options
@@ -3155,8 +3155,8 @@ take more diverse values.
 Prefix a boolean option with \(lqno\(rq or \(oq!\(cq to turn it off.
 For compound options, the option name and value are separated by a colon.
 Some options are persistent, and apply only to new games.
-You can specify multiple OPTIONS statements, and multiple options
-separated by commas in a single OPTIONS statement.
+You can specify multiple OPTIONS directives, and multiple options
+separated by commas in a single OPTIONS directive.
 (Comma separated options are processed from right to left.)
 .lp ""
 Example:
@@ -3220,7 +3220,8 @@ Example:
 .ed
 .lp CHOOSE
 Chooses at random one of the comma-separated parameters as an active
-section name. Lines in other sections are ignored.
+section name.
+Lines in other sections are ignored.
 .lp ""
 Example:
 .sd
@@ -3231,8 +3232,18 @@ CHOOSE=char A,char B
 OPTIONS=role:arc,race:dwa,align:law,gender:fem
 [char B]
 OPTIONS=role:wiz,race:elf,align:cha,gender:mal
+END-CHOOSE
+OPTIONS=!rest_on_space
 .ft \" revert to previous font
 .ed
+.lp END-CHOOSE
+An optional way to terminate CHOOSE.
+.\" use of the \% prefix prevents END-CHOOSE from being hyphenated across
+.\" line boundary despite its hyphen; needed for the plain text output to
+.\" avoid splitting the directive name
+You can place an \%END-CHOOSE directive after the last CHOOSE section in
+order to follow that with other options which are common to all sections.
+Otherwise the last section extends to the end of the options file.
 .lp MENUCOLOR
 Highlight menu lines with different colors.
 See the \(lqConfiguring Menu Colors\(rq section.
@@ -3342,10 +3353,10 @@ to that shell), or the pair of commands
 in \fIsh\fP, \fIksh\fP, or \fIbash\fP.
 .pg
 The NETHACKOPTIONS value is effectively the same as a single OPTIONS
-statement in a configuration file.
+directive in a configuration file.
 The \(lqOPTIONS=\(rq prefix is implied and comma separated options are
 processed from right to left.
-Other types of configuration statements such as BIND or MSGTYPE are
+Other types of configuration directives such as BIND or MSGTYPE are
 not allowed.
 .pg
 Instead of a comma-separated list of options,
@@ -4338,7 +4349,7 @@ May be used to alter the value of keystrokes that the operating system
 returns to NetHack to help compensate for international keyboard issues.
 OPTIONS=subkeyvalue:171/92
 will return 92 to NetHack, if 171 was originally going to be returned.
-You can use multiple subkeyvalue statements in the configuration file
+You can use multiple subkeyvalue assignments in the configuration file
 if needed.
 Cannot be set with the \(oqO\(cq command.
 .lp video
index 47b79d3c48d28d3ab0ebcb6ef84a738fef6a149a..14c3cd84349ddcf3bdd52d803a8e8475e4de33cb 100644 (file)
@@ -45,7 +45,7 @@
 %.au
 \author{Original version - Eric S. Raymond\\
 (Edited and expanded for 3.7 by Mike Stephenson and others)}
-\date{July 25, 2020}
+\date{August 5, 2020}
 
 \maketitle
 
@@ -3359,18 +3359,18 @@ Any line in the configuration file starting with `{\tt \#}' is treated as a comm
 Empty lines are ignored. Any line beginning with `{\tt [}' and ending in `{\tt ]}' is considered a section
 marker. The text between the square brackets is the section name.
 Lines after a section marker belong to that section, and are
-ignored unless a CHOOSE -statement was used to select that section.
+ignored unless a CHOOSE -directive was used to select that section.
 Section names are case insensitive.
 
 %.pg
-You can use different configuration statements in the file, some
+You can use different configuration directives in the file, some
 of which can be used multiple times.
-In general, the statements are
+In general, the directives are
 written in capital letters, followed by an equals sign, followed by
-settings particular to that statement.
+settings particular to that directive.
 
 %.pg
-Here is a list of allowed statements:
+Here is a list of allowed directives:
 
 %.lp
 \blist{}
@@ -3381,8 +3381,8 @@ take more diverse values.
 Prefix a boolean option with `no' or `!' to turn it off.
 For compound options, the option name and value are separated by a colon.
 Some options are persistent, and apply only to new games.
-You can specify multiple OPTIONS statements, and multiple options
-separated by commas in a single OPTIONS statement.
+You can specify multiple OPTIONS directives, and multiple options
+separated by commas in a single OPTIONS directive.
 (Comma separated options are processed from right to left.)
 
 %.lp ""
@@ -3461,7 +3461,8 @@ Example:
 %.lp
 \item[\bb{CHOOSE}]
 Chooses at random one of the comma-separated parameters as an active
-section name. Lines in other sections are ignored.
+section name.
+Lines in other sections are ignored.
 
 %.lp ""
 Example:
@@ -3473,9 +3474,18 @@ Example:
    OPTIONS=role:arc,race:dwa,align:law,gender:fem
    [char B]
    OPTIONS=role:wiz,race:elf,align:cha,gender:mal
+   END-CHOOSE
+   OPTIONS=!rest_on_space
 \end{verbatim}
 %.ed
 
+%.lp
+\item[\bb{END-CHOOSE}]
+An optional way to terminate CHOOSE.
+You can place an END-CHOOSE directive after the last CHOOSE section in
+order to follow that with other options which are common to all sections.
+Otherwise the last section extends to the end of the options file.
+
 %.lp
 \item[\bb{MENUCOLOR}]
 Highlight menu lines with different colors.
@@ -3592,10 +3602,10 @@ to that shell), or the pair of commands
 
 %.pg
 The NETHACKOPTIONS value is effectively the same as a single OPTIONS
-statement in a configuration file.
+directive in a configuration file.
 The ``OPTIONS='' prefix is implied and comma separated options are
 processed from right to left.
-Other types of configuration statements such as BIND or MSGTYPE are
+Other types of configuration directives such as BIND or MSGTYPE are
 not allowed.
 
 %.pg
@@ -4745,7 +4755,7 @@ returns to {\it NetHack\/} to help compensate for international keyboard
 issues.
 OPTIONS=subkeyvalue:171/92
 will return 92 to {\it NetHack\/}, if 171 was originally going to be returned.
-You can use multiple subkeyvalue statements in the configuration file
+You can use multiple subkeyvalue assignments in the configuration file
 if needed.
 Cannot be set with the `{\tt O}' command.
 %.lp
index d23b99349878ffaafb256ea1449815aaa1e55ef7..35fb1fec0af35257e8def124a3c0a2502e4a3a21 100644 (file)
@@ -1,4 +1,4 @@
-NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.274 $ $NHDT-Date: 1596656886 2020/08/05 19:48:06 $
+NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.275 $ $NHDT-Date: 1596754606 2020/08/06 22:56:46 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -459,6 +459,11 @@ add 'Sokoban' conduct, tracking the number of times the special Sokoban rules
 reduce verbosity when a mind flayer attacks a headless monster; when a
        tentacle-to-head attack hits but fails to accomplish anything skip
        remaining attacks (mind flayer has 3, master mind flayer has 5)
+add END-CHOOSE directive for run-time config file; CHOOSE section1,section2
+       followed by [section1] ... [section2] ... forced all the rest of the
+       file to be part of the last section; that still works the same but
+       END-CHOOSE can be used to terminate the last section and revert to
+       common options for the remainder of the file
 
 
 Platform- and/or Interface-Specific New Features
index 690f88580157c86837937de3c22c36506ae47d81..b79c2a913d400b263b2a0d3dde899625ba27c48b 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 files.c $NHDT-Date: 1595006057 2020/07/17 17:14:17 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.316 $ */
+/* NetHack 3.7 files.c $NHDT-Date: 1596754598 2020/08/06 22:56:38 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.317 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -163,7 +163,8 @@ static void FDECL(adjust_prefix, (char *, int));
 static boolean FDECL(config_error_nextline, (const char *));
 static void NDECL(free_config_sections);
 static char *FDECL(choose_random_part, (char *, CHAR_P));
-static boolean FDECL(is_config_section, (const char *));
+static char *FDECL(is_config_section, (char *));
+static boolean FDECL(is_end_of_sections, (const char *));
 static boolean FDECL(handle_config_section, (char *));
 static char *FDECL(find_optparam, (const char *));
 static void FDECL(parseformat, (int *, char *));
@@ -2258,7 +2259,7 @@ int prefixid;
 
 /* Choose at random one of the sep separated parts from str. Mangles str. */
 static char *
-choose_random_part(str,sep)
+choose_random_part(str, sep)
 char *str;
 char sep;
 {
@@ -2310,29 +2311,78 @@ free_config_sections()
     }
 }
 
-static boolean
+/* check for " [ anything-except-bracket-or-empty ] # arbitrary-comment"
+   with spaces optional; returns pointer to "anything-except..." (with
+   trailing " ] #..." stripped) if ok, otherwise Null */
+static char *
 is_config_section(str)
-const char *str;
+char *str; /* trailing spaces will be stripped, ']' too iff result is good */
 {
-    const char *a = rindex(str, ']');
+    char *a, *c, *z;
 
-    return (a && *str == '[' && *(a+1) == '\0' && (int)(a - str) > 0);
+    /* remove any spaces at start and end; won't significantly interfere
+       with echoing the string in a config error message, if warranted */
+    a = trimspaces(str);
+    /* first character should be open square bracket; set pointer past it */
+    if (*a++ != '[')
+        return (char *) 0;
+    /* last character should be close bracket, ignoring any comment */
+    z = index(a, ']');
+    if (!z || z == a)
+        return (char *) 0;
+    for (c = z + 1; *c && *c != '#'; ++c)
+        continue;
+    if (*c && *c != '#')
+        return (char *) 0;
+    /* we now know that result is good; there won't be a config error
+       message so we can modify the input string */
+    *z = '\0';
+    /* 'a' points past '[' and the string ends where ']' was; remove any
+       spaces between '[' and choice-start and between choice-end and ']' */
+    return trimspaces(a);
+}
+
+static boolean
+is_end_of_sections(buf)
+const char *buf;
+{
+    /* "END-CHOOSE"; bypass match_optname()/match_varname();
+       accepts "ENDCHOOSE", "END CHOOSE", "END-CHOOSE", "END_CHOOSE" */
+    if (!strncmpi(buf, "END", 3) && buf[3]) {
+        boolean sep = index(" -_", buf[3]) != 0;
+
+        if (!strcmpi(&buf[sep ? 4 : 3], "CHOOSE")) {
+            if (!g.config_section_current)
+                config_error_add("END-CHOOSE when not in a CHOOSE section");
+            return TRUE;
+        }
+    }
+    return FALSE;
 }
 
 static boolean
 handle_config_section(buf)
 char *buf;
 {
-    if (is_config_section(buf)) {
-        char *send;
-        if (g.config_section_current) {
+    boolean was_in_section = (g.config_section_current != 0);
+    char *sect = is_config_section(buf);
+
+    if (sect) {
+        if (g.config_section_current)
             free(g.config_section_current);
+        /* is_config_section() removed brackets from 'sect' */
+        if (!g.config_section_chosen) {
+            config_error_add("Section \"[%s]\" without CHOOSE", sect);
+            return TRUE;
         }
-        g.config_section_current = dupstr(&buf[1]);
-        send = rindex(g.config_section_current, ']');
-        *send = '\0';
+        g.config_section_current = dupstr(sect);
         debugpline1("set config section: '%s'", g.config_section_current);
         return TRUE;
+    } else if (is_end_of_sections(buf)) {
+        if (was_in_section)
+            debugpline0("unset config section");
+        free_config_sections();
+        return TRUE;
     }
 
     if (g.config_section_current) {
@@ -2386,6 +2436,12 @@ char *origbuf;
        but spaces, one of them will be kept even though it leads/trails) */
     mungspaces(buf);
 
+    /* "END-CHOOSE" doesn't have a value so we need to check for it
+       before checking for that; if found here, is_end_of_sections()
+       will report a config_error */
+    if (is_end_of_sections(buf))
+        return FALSE;
+
     /* find the '=' or ':' */
     bufp = find_optparam(buf);
     if (!bufp) {
@@ -2670,8 +2726,7 @@ char *origbuf;
             retval = FALSE;
 #endif
     } else if (match_varname(buf, "WARNINGS", 5)) {
-        (void) get_uchars(bufp, translate, FALSE, WARNCOUNT,
-                          "WARNINGS");
+        (void) get_uchars(bufp, translate, FALSE, WARNCOUNT, "WARNINGS");
         assign_warnings(translate);
     } else if (match_varname(buf, "ROGUESYMBOLS", 4)) {
         if (!parsesymbols(bufp, ROGUESET)) {