]> granicus.if.org Git - nethack/commitdiff
groundwork for nethackrc name on command line
authorPatR <rankin@nethack.org>
Wed, 16 Feb 2022 08:36:26 +0000 (00:36 -0800)
committerPatR <rankin@nethack.org>
Wed, 16 Feb 2022 08:36:26 +0000 (00:36 -0800)
I've implemented 'nethack -nethackrc=filename' as an alternative to
'NETHACKOPTIONS='@filename' nethack' but at the moment it doesn't
work because the command line parsing comes after the run-time config
file has already been processed.  But this part should work, or maybe
have problems spotted and fixed if it doesn't.  The RC file part of
initoptions_finish() has been rewritten so that it won't need extra
replication of
|  set_error_handling()
|  process_file()
|  reset_error_handling()
|  if (NETHACKOPTIONS) {
|    set_error_handling()
|    process_options()
|    reset_error_handling()
|  }
I've tried to test all the combinations mentioned in the comment but
am not sure that I covered everything, particulary for repeating
earlier tests after making incremental changes.

include/decl.h
src/decl.c
src/options.c

index 934cc90dd18b6f6a12ba663c99406dda405426e0..a71493535fcc8e1298f6021c18a3d51b186e034e 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7  decl.h  $NHDT-Date: 1627408982 2021/07/27 18:03:02 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.265 $ */
+/* NetHack 3.7  decl.h  $NHDT-Date: 1645000560 2022/02/16 08:36:00 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.283 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2007. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -918,6 +918,7 @@ struct instance_globals {
     struct rogueroom r[3][3];
 
     /* files.c */
+    char *cmdline_rcfile;  /* set in unixmain.c, used in options.c */
     char wizkit[WIZKIT_MAX];
     int lockptr;
     char *config_section_chosen;
index 180b9f7a033f36f77c0c45ed4da042ae798cc197..e2a5f77d7b282b98dec40f18e5b6df8f64aba4e6 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 decl.c  $NHDT-Date: 1606919256 2020/12/02 14:27:36 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.221 $ */
+/* NetHack 3.7 decl.c  $NHDT-Date: 1645000574 2022/02/16 08:36:14 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.248 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2009. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -405,6 +405,7 @@ const struct instance_globals g_init = {
     UNDEFINED_VALUES,
 
     /* files.c */
+    NULL, /* cmdline_rcfile */
     UNDEFINED_VALUES, /* wizkit */
     UNDEFINED_VALUE, /* lockptr */
     NULL, /* config_section_chosen */
index ba4b5e8ad1c39548759a6a020619b2bfeb813498..5a8491138472c669900c08eec0e60629d65e4528 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 options.c       $NHDT-Date: 1644531493 2022/02/10 22:18:13 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.538 $ */
+/* NetHack 3.7 options.c       $NHDT-Date: 1645000577 2022/02/16 08:36:17 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.540 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2008. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -5843,43 +5843,85 @@ initoptions_init(void)
     nmcpy(g.pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ);
 }
 
+/*
+ *  Process user's run-time configuration file:
+ *    get value of NETHACKOPTIONS;
+ *    if command line specified -nethackrc=filename, use that;
+ *      if NETHACKOPTIONS is present,
+ *        honor it if it has a list of options to set
+ *        or ignore it if it specifies a file name;
+ *    else if not specified on command line and NETHACKOPTIONS names a file,
+ *      use that as the config file;
+ *      no extra options (normal use of NETHACKOPTIONS) will be set;
+ *    otherwise (not on command line and either no NETHACKOPTIONS or that
+ *        isn't a file name),
+ *      pass Null to read_config_file() so that it will read ~/.nethackrc
+ *        by default,
+ *      then process the value of NETHACKOPTIONS as extra options.
+ */
 void
 initoptions_finish(void)
 {
     nhsym sym = 0;
+    char *opts = 0, *xtraopts = 0;
 #ifndef MAC
-    char *opts = getenv("NETHACKOPTIONS");
-
-    if (!opts)
-        opts = getenv("HACKOPTIONS");
-    if (opts) {
-        if (*opts == '/' || *opts == '\\' || *opts == '@') {
-            if (*opts == '@')
-                opts++; /* @filename */
-            /* looks like a filename */
-            if (strlen(opts) < BUFSZ / 2) {
-                config_error_init(TRUE, opts, CONFIG_ERROR_SECURE);
-                (void) read_config_file(opts, set_in_config);
-                config_error_done();
-            }
-        } else {
-            config_error_init(TRUE, (char *) 0, FALSE);
-            (void) read_config_file((char *) 0, set_in_config);
-            config_error_done();
-            /* let the total length of options be long;
-             * parseoptions() will check each individually
-             */
-            config_error_init(FALSE, "NETHACKOPTIONS", FALSE);
-            (void) parseoptions(opts, TRUE, FALSE);
-            config_error_done();
-        }
+    const char *envname, *namesrc, *nameval;
+
+    /* getenv() instead of nhgetenv(): let total length of options be long;
+       parseoptions() will check each individually */
+    envname = "NETHACKOPTIONS";
+    opts = getenv(envname);
+    if (!opts) {
+        /* fall back to original name; discouraged */
+        envname = "HACKOPTIONS";
+        opts = getenv(envname);
+    }
+
+    if (g.cmdline_rcfile) {
+        namesrc = "command line";
+        nameval = g.cmdline_rcfile;
+        free((genericptr_t) g.cmdline_rcfile), g.cmdline_rcfile = 0;
+        xtraopts = opts;
+        if (opts && (*opts == '/' || *opts == '\\' || *opts == '@'))
+            xtraopts = 0; /* NETHACKOPTIONS is a file name; ignore it */
+    } else if (opts && (*opts == '/' || *opts == '\\' || *opts == '@')) {
+        /* NETHACKOPTIONS is a file name; use that instead of the default */
+        if (*opts == '@')
+            ++opts; /* @filename */
+        namesrc = envname;
+        nameval = opts;
+        xtraopts = 0;
     } else
 #endif /* !MAC */
     /*else*/ {
-        config_error_init(TRUE, (char *) 0, FALSE);
-        (void) read_config_file((char *) 0, set_in_config);
+        /* either no NETHACKOPTIONS or it wasn't a file name;
+           read the default configuration file */
+        nameval = namesrc = 0;
+        xtraopts = opts;
+    }
+
+    /* seemingly arbitrary name length restriction is to prevent error
+       messages, if any were to be delivered while accessing the file,
+       from potentially overflowing buffers */
+    if (nameval && (int) strlen(nameval) >= BUFSZ / 2) {
+        config_error_init(TRUE, namesrc, FALSE);
+        config_error_add(
+                   "nethackrc file name \"%.40s\"... too long; using default",
+                         nameval);
+        config_error_done();
+        nameval = namesrc = 0; /* revert to default nethackrc */
+    }
+
+    config_error_init(TRUE, nameval, nameval ? CONFIG_ERROR_SECURE : FALSE);
+    (void) read_config_file(nameval, set_in_config);
+    config_error_done();
+    if (xtraopts) {
+        /* NETHACKOPTIONS is present and not a file name */
+        config_error_init(FALSE, envname, FALSE);
+        (void) parseoptions(xtraopts, TRUE, FALSE);
         config_error_done();
     }
+    /*[end of nethackrc handling]*/
 
     (void) fruitadd(g.pl_fruit, (struct fruit *) 0);
     /*