diff --git a/include/decl.h b/include/decl.h index 415d710b1..9859c3e24 100644 --- a/include/decl.h +++ b/include/decl.h @@ -340,6 +340,10 @@ struct instance_globals_d { boolean decor_fumble_override; boolean decor_levitate_override; + /* new */ + boolean deferred_showpaths; + const char *deferred_showpaths_dir; + boolean havestate; unsigned long magic; /* validate that structure layout is preserved */ }; diff --git a/include/extern.h b/include/extern.h index 35bb33138..760ad30e2 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1072,11 +1072,12 @@ extern int nhclose(int); #ifdef DEBUG extern boolean debugcore(const char *, boolean); #endif -extern void reveal_paths(void); +extern void reveal_paths(int); extern boolean read_tribute(const char *, const char *, int, char *, int, unsigned); extern boolean Death_quote(char *, int) NONNULLARG1; extern void livelog_add(long ll_type, const char *) NONNULLARG2; +ATTRNORETURN extern void do_deferred_showpaths(int) NORETURN; /* ### fountain.c ### */ @@ -3379,6 +3380,7 @@ extern void append_slash(char *) NONNULLARG1; extern boolean check_user_string(const char *) NONNULLARG1; extern char *get_login_name(void); extern unsigned long sys_random_seed(void); +ATTRNORETURN extern void after_opt_showpaths(const char *) NORETURN; #endif /* UNIX */ /* ### unixtty.c ### */ diff --git a/src/decl.c b/src/decl.c index 08b54e4f7..e21cfc8db 100644 --- a/src/decl.c +++ b/src/decl.c @@ -339,6 +339,8 @@ static const struct instance_globals_d g_init_d = { /* pickup.c */ FALSE, /* decor_fumble_override */ FALSE, /* decor_levitate_override */ + FALSE, /* deferred_showpaths */ + NULL, /* deferred_showpaths_dir */ TRUE, /* havestate*/ IVMAGIC /* d_magic to validate that structure layout has been preserved */ }; diff --git a/src/files.c b/src/files.c index d7ce06f60..8a23a0175 100644 --- a/src/files.c +++ b/src/files.c @@ -4467,6 +4467,8 @@ assure_syscf_file(void) close(fd); return; } + if (gd.deferred_showpaths) + do_deferred_showpaths(1); /* does not return */ raw_printf("Unable to open SYSCF_FILE.\n"); exit(EXIT_FAILURE); } @@ -4474,6 +4476,26 @@ assure_syscf_file(void) #endif /* SYSCF_FILE */ #endif /* SYSCF */ +ATTRNORETURN void +do_deferred_showpaths(int code) +{ + gd.deferred_showpaths = FALSE; + reveal_paths(code); + +#ifdef UNIX + after_opt_showpaths(gd.deferred_showpaths_dir); +#else +#ifdef CHDIR + chdirx(gd.deferred_showpaths_dir, 0); +#endif +#if defined(WIN32) || defined(MICRO) || defined(OS2) + nethack_exit(EXIT_SUCCESS); +#else + exit(EXIT_SUCCESS); +#endif +#endif +} + #ifdef DEBUG /* used by debugpline() to decide whether to issue a message * from a particular source file; caller passes __FILE__ and we check @@ -4534,9 +4556,11 @@ debugcore(const char *filename, boolean wildcards) #endif void -reveal_paths(void) +reveal_paths(int code) { - const char *fqn, *nodumpreason; + const char *fqn, *nodumpreason, + *sysconffile = "system configuration file"; + char buf[BUFSZ]; #if defined(SYSCF) || !defined(UNIX) || defined(DLB) const char *filep; @@ -4570,7 +4594,8 @@ reveal_paths(void) #else buf[0] = '\0'; #endif - raw_printf("%s system configuration file%s:", s_suffix(gamename), buf); + raw_printf("%s %s%s:", + s_suffix(gamename), sysconffile, buf); #ifdef SYSCF_FILE filep = SYSCF_FILE; #else @@ -4582,6 +4607,10 @@ reveal_paths(void) filep = configfile; } raw_printf(" \"%s\"", filep); + if (code == 1) { + raw_printf("NOTE: The %s above is missing or inaccessible!", + sysconffile); + } #else /* !SYSCF */ raw_printf("No system configuration file."); #endif /* ?SYSCF */ diff --git a/src/options.c b/src/options.c index 0a9a7dc85..30d7709f4 100644 --- a/src/options.c +++ b/src/options.c @@ -6942,6 +6942,11 @@ initoptions(void) */ #endif #endif /* SYSCF */ + + /* Carry out options that got deferred from early_options */ + if (gd.deferred_showpaths) + do_deferred_showpaths(0); /* does not return */ + initoptions_finish(); } diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 20835dda6..289ee2c5f 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -108,14 +108,8 @@ nhmain(int argc, char *argv[]) #endif if (argcheck(argc, argv, ARG_SHOWPATHS) == 2) { -#ifdef CHDIR - chdirx((char *) 0, 0); -#endif - iflags.initoptions_noterminate = TRUE; - initoptions(); - iflags.initoptions_noterminate = FALSE; - reveal_paths(); - exit(EXIT_SUCCESS); + gd.deferred_showpaths = TRUE; + return; } if (argcheck(argc, argv, ARG_DEBUG) == 1) { argc--; diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index e6b09492c..617a1ef06 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -36,7 +36,6 @@ static void consume_two_args(int, int *, char ***); static void early_options(int *, char ***, char **); ATTRNORETURN static void opt_terminate(void) NORETURN; ATTRNORETURN static void opt_usage(const char *) NORETURN; -static void opt_showpaths(const char *); ATTRNORETURN static void scores_only(int, char **, const char *) NORETURN; #ifdef SND_LIB_INTEGRATED uint32_t soundlibchoice = soundlib_nosound; @@ -702,9 +701,10 @@ early_options(int *argc_p, char ***argv_p, char **hackdir_p) break; case 's': if (argcheck(argc, argv, ARG_SHOWPATHS) == 2) { - opt_showpaths(*hackdir_p); - opt_terminate(); - /*NOTREACHED*/ + gd.deferred_showpaths = TRUE; + gd.deferred_showpaths_dir = *hackdir_p; + config_error_done(); + return; } /* check for "-s" request to show scores */ if (lopt(arg, ((ArgValDisallowed | ArgErrComplain) @@ -785,18 +785,16 @@ opt_usage(const char *hackdir) /* show the sysconf file name, playground directory, run-time configuration file name, dumplog file name if applicable, and some other things */ -static void -opt_showpaths(const char *dir) +ATTRNORETURN void +after_opt_showpaths(const char *dir) { #ifdef CHDIR chdirx(dir, FALSE); #else nhUse(dir); #endif - iflags.initoptions_noterminate = TRUE; - initoptions(); - iflags.initoptions_noterminate = FALSE; - reveal_paths(); + opt_terminate(); + /*NOTREACHED*/ } /* handle "-s [character-names]" to show all the entries diff --git a/sys/vms/vmsmain.c b/sys/vms/vmsmain.c index dcb681caa..25c40b842 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -80,15 +80,9 @@ main(int argc, char *argv[]) exit(EXIT_SUCCESS); if (argcheck(argc, argv, ARG_SHOWPATHS) == 2) { -#ifdef CHDIR - chdirx((char *) 0, 0); -#endif - iflags.initoptions_noterminate = TRUE; - initoptions(); - iflags.initoptions_noterminate = FALSE; - reveal_paths(); - exit(EXIT_SUCCESS); - } + gd.deferred_showpaths = TRUE; + return; + } if (argcheck(argc, argv, ARG_DEBUG) == 1) { argc--; argv++; diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index df7144a20..15cb8442f 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -18,9 +18,9 @@ #error You must #define SAFEPROCS to build windmain.c #endif -static void process_options(int argc, char **argv); static void nhusage(void); static char *get_executable_path(void); +static void early_options(int argc, char **argv); char *translate_path_variables(const char *, char *); char *exename(void); boolean fakeconsole(void); @@ -242,6 +242,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ iflags.windowtype_deferred = TRUE; copy_sysconf_content(); copy_symbols_content(); + early_options(argc, argv); initoptions(); /* Now that sysconf has had a chance to set the TROUBLEPREFIX, don't @@ -249,7 +250,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ fqn_prefix_locked[TROUBLEPREFIX] = TRUE; copy_config_content(); - process_options(argc, argv); /* did something earlier flag a need to exit without starting a game? */ if (windows_startup_state > 0) { @@ -462,23 +462,18 @@ attempt_restore: RESTORE_WARNING_UNREACHABLE_CODE static void -process_options(int argc, char * argv[]) +early_options(int argc, char *argv[]) { int i; - /* - * Process options. - */ if (argc > 1) { if (argcheck(argc, argv, ARG_VERSION) == 2) nethack_exit(EXIT_SUCCESS); if (argcheck(argc, argv, ARG_SHOWPATHS) == 2) { - iflags.initoptions_noterminate = TRUE; - initoptions(); - iflags.initoptions_noterminate = FALSE; - reveal_paths(); - nethack_exit(EXIT_SUCCESS); + gd.deferred_showpaths = TRUE; + /* gd.deferred_showpaths is not used by windows */ + return; } #ifndef NODUMPENUMS if (argcheck(argc, argv, ARG_DUMPENUMS) == 2) { @@ -509,7 +504,7 @@ process_options(int argc, char * argv[]) */ argc--; argv++; - const char * dir = argv[0] + 2; + const char *dir = argv[0] + 2; if (*dir == '=' || *dir == ':') dir++; if (!*dir && argc > 1) { @@ -578,7 +573,8 @@ process_options(int argc, char * argv[]) #endif case 'u': if (argv[0][2]) - (void) strncpy(svp.plname, argv[0] + 2, sizeof(svp.plname) - 1); + (void) strncpy(svp.plname, argv[0] + 2, + sizeof(svp.plname) - 1); else if (argc > 1) { argc--; argv++; @@ -634,8 +630,8 @@ process_options(int argc, char * argv[]) break; } else raw_printf("\nUnknown switch: %s", argv[0]); - FALLTHROUGH; - /* FALLTHRU */ + FALLTHROUGH; + /* FALLTHRU */ case '?': nhusage(); nethack_exit(EXIT_SUCCESS);